nixos-config/pkgs/wordclock-dimmer/wordclock-dimmer.py

89 lines
2.6 KiB
Python
Raw Permalink Normal View History

#!/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)