nixos-config/pkgs/wordclock-dimmer/wordclock-dimmer.py
Simon Bruder f945341668
Relicense
This applies the REUSE specification to the repository, so the licensing
information can be tracked for every file individually.
2024-01-13 14:35:31 +01:00

89 lines
2.6 KiB
Python
Executable file
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
# SPDX-FileCopyrightText: 2021 Simon Bruder <simon@sbruder.de>
#
# SPDX-License-Identifier: AGPL-3.0-or-later
from astral.location import Location, LocationInfo
from math import cos, pi
from time import sleep
import datetime
import os
import paho.mqtt.client as mqtt
import sys
def time_as_float_hours(time: datetime.time) -> float:
return time.hour + time.minute / 60 + time.second / 3600
def set_color(client: mqtt.Client, red: int, green: int, blue: int, retain=True):
client.reconnect()
# my wordclocks red and green LEDs seem to be switched
client.publish("wordclock/color/red", green, retain=True)
client.publish("wordclock/color/green", red, retain=True)
client.publish("wordclock/color/blue", blue, retain=True)
def get_color_for_time(time: datetime.time, base=(60, 60, 60)) -> (int, int, int):
if time.hour >= 22 or time.hour < 7:
# night mode: dim red
return (3, 0, 0)
else:
# day mode: calculated depending on sun (https://www.desmos.com/calculator/nrseefnaom)
now = time_as_float_hours(time)
# returns at least (3, 3, 3)
min_factors = (3 / base[0], 3 / base[1], 3 / base[2])
rate = 5
location_info = LocationInfo(
timezone="Europe/Berlin", latitude=49.52, longitude=10.18
)
location = Location(location_info)
sunrise = time_as_float_hours(location.sunrise().time())
sunset = time_as_float_hours(location.sunset().time())
factors = []
for min_factor in min_factors:
factor = min_factor
if now > sunrise and now < sunset:
factor = 1 - (
(1 - min_factor) * cos((pi / (sunrise - sunset)) * (now - sunset))
) ** (2 * rate)
factors.append(factor)
return (
round(base[0] * factors[0]),
round(base[1] * factors[1]),
round(base[2] * factors[2]),
)
def update(client: mqtt.Client):
time = datetime.datetime.now().time()
color = get_color_for_time(time)
print(f"{time}: setting color to {color}")
sys.stdout.flush()
set_color(client, *color)
pass
client = mqtt.Client("wordclock.py")
user = os.environ["WORDCLOCK_MQTT_USER"]
try:
password = os.environ["WORDCLOCK_MQTT_PASSWORD"]
except KeyError:
with open(os.environ["WORDCLOCK_MQTT_PASSWORD_FILE"]) as f:
password = f.read().rstrip()
host = os.environ["WORDCLOCK_MQTT_HOST"]
client.username_pw_set(user, password)
client.connect(host, 1883, 60)
while True:
update(client)
sleep(300)