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

89 lines
2.6 KiB
Python
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#!/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]),
)
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)
color = (0, 0, 0)
while True:
time = datetime.datetime.now().time()
new_color = get_color_for_time(time)
if new_color != color:
color = new_color
print(f"setting color to {color}")
sys.stdout.flush()
set_color(client, *color)
sleep(300)