diff --git a/uhr.py b/uhr.py index 5a4420c..db621cb 100644 --- a/uhr.py +++ b/uhr.py @@ -6,6 +6,7 @@ import shlex import subprocess import threading import time +from copy import deepcopy import gpiozero import toml @@ -24,30 +25,14 @@ def load_config(pfad=SKRIPTPFAD): CONFIG = load_config() - # LED strip configuration -LED_COUNT = 60 # Number of LED pixels. -LED_PIN = board.D18 # GPIO pin connected to the pixels (must support PWM!). -LED_PIXEL_ORDER = neopixel.GRB # Strip type and colour ordering +LED_COUNT = 60 # Number of LED pixels. +LED_PIN = board.D18 # GPIO pin connected to the pixels (must support PWM!). +LED_PIXEL_ORDER = neopixel.GRB # Strip type and colour ordering # Zahl stellt den Wert in Minuten dar, wie lange kein Gerät erreichbar sein darf dass die Uhr "abgeschalten" wird ABSCHALTWERT = 4 -# LED Mapping -std0 = [0, 1, 59] -std1 = [4, 5, 6] -std2 = [9, 10, 11] -std3 = [14, 15, 16] -std4 = [19, 20, 21] -std5 = [24, 25, 26] -std6 = [29, 30, 31] -std7 = [34, 35, 36] -std8 = [39, 40, 41] -std9 = [44, 45, 46] -std10 = [49, 50, 51] -std11 = [54, 55, 56] -stdliste = [std0, std1, std2, std3, std4, std5, std6, std7, std8, std9, std10, std11] - class Uhr: def __init__(self, pixels, mode): @@ -59,6 +44,9 @@ class Uhr: self._rgb_sekunde = None self._rgb_minute = None self._rgb_stunde = None + self.led_gesetzt = 0 + self.durchlauf_pause = datetime.timedelta(seconds=0) + self.sleep_time = 0 def set_helligkeit(self, helligkeit): self.helligkeit = helligkeit @@ -78,17 +66,33 @@ class Uhr: self.set_helligkeit(self.helligkeit) def rgb_farben_lesen(self): - self._rgb_leer = CONFIG["mode"][self.mode]["leer"] - self._rgb_sekunde = CONFIG["mode"][self.mode]["sekunde"] - self._rgb_minute = CONFIG["mode"][self.mode]["minute"] - self._rgb_stunde = CONFIG["mode"][self.mode]["stunde"] + config = deepcopy(CONFIG) + self._rgb_leer = config["mode"][self.mode]["leer"] + self._rgb_sekunde = config["mode"][self.mode]["sekunde"] + self._rgb_minute = config["mode"][self.mode]["minute"] + self._rgb_stunde = config["mode"][self.mode]["stunde"] rgbconf = {"rgb_leer": self._rgb_leer, "rgb_s": self._rgb_sekunde, "rgb_min": self._rgb_minute, "rgb_std": self._rgb_stunde} - print("In der Klasse:") - print(rgbconf) return rgbconf + def mode_control(self, zeit): + rgbconf = self.rgb_farben_lesen() + if int(self.mode) == 0: + stdliste = stunden_led_mapping_variante_0() + stunden_leds, minuten_leds, sekunden_leds, leer_leds, rgbdict, \ + self.led_gesetzt = stunde_minute_sekunde_einfach_modus(zeit, stdliste, rgbconf, self.led_gesetzt) + self.durchlauf_pause = datetime.timedelta(seconds=1) + self.sleep_time = 0.2 + else: + stunden_leds = [0] + minuten_leds = [0] + sekunden_leds = [0] + leer_leds = [0] + rgbdict = self.rgb_farben_lesen() + + led_setzen(stunden_leds, minuten_leds, sekunden_leds, leer_leds, rgbdict, self.pixels) + # GPIO I_MODE_TASTER = gpiozero.Button(3) @@ -107,54 +111,73 @@ def alle_led(r, g, b, pixels): pixels.show() -def led_calc(zeit, stdliste, rgbdict, led_gesetzt, pixels): +def stunden_led_mapping_variante_0(): + std0 = [0, 1, 59] + std1 = [4, 5, 6] + std2 = [9, 10, 11] + std3 = [14, 15, 16] + std4 = [19, 20, 21] + std5 = [24, 25, 26] + std6 = [29, 30, 31] + std7 = [34, 35, 36] + std8 = [39, 40, 41] + std9 = [44, 45, 46] + std10 = [49, 50, 51] + std11 = [54, 55, 56] + stdliste = [std0, std1, std2, std3, std4, std5, std6, std7, std8, std9, std10, std11] + return stdliste + + +def stunde_minute_sekunde_einfach_modus(zeit, stdliste, rgbdict, led_gesetzt): if zeit.hour > 11: index = zeit.hour - 12 else: index = zeit.hour - hour = stdliste[index] - minute = zeit.minute - second = zeit.second + stunden_leds = list(stdliste[index]) + minuten_leds = [zeit.minute] + sekunden_leds = [zeit.second] # Schnittfarben berechnen falls "Zeiger" übereinander liegen # Stunde mit Minute vergleichen - if bool(set(hour) & {minute}): + if bool(set(stunden_leds) & set(minuten_leds)): for counter in range(0, 3): rgbdict["rgb_min"][counter] = int((rgbdict["rgb_std"][counter] + rgbdict["rgb_min"][counter]) / 2) # Stunde mit Sekunde vergleichen - if set(hour) & {second}: + if set(stunden_leds) & set(sekunden_leds): for counter in range(0, 3): rgbdict["rgb_s"][counter] = int((rgbdict["rgb_std"][counter] + rgbdict["rgb_s"][counter]) / 2) # Minute mit Sekunde vergleichen - if {minute} & {second}: + if set(minuten_leds) & set(sekunden_leds): for counter in range(0, 3): rgbdict["rgb_s"][counter] = int((rgbdict["rgb_min"][counter] + rgbdict["rgb_s"][counter]) / 2) - led_gesetzt = led_setzen(hour, minute, second, rgbdict, led_gesetzt, pixels) - return zeit.second, led_gesetzt - -def led_setzen(hour, minute, second, rgbdict, led_gesetzt, pixels): - if not isinstance(led_gesetzt, list): + # Neue Leere LED berechnen + led_gesetzt_neu = set(stunden_leds) | set(minuten_leds) | set(sekunden_leds) + if isinstance(led_gesetzt, (int, float)): led_gesetzt = [led_gesetzt] + leer_leds = set(led_gesetzt) - set(led_gesetzt_neu) + return stunden_leds, minuten_leds, sekunden_leds, leer_leds, rgbdict, led_gesetzt_neu + + +def led_setzen(stunden_leds, minuten_leds, sekunden_leds, leer_leds, rgbdict, pixels): # Stunden setzen - for stunde in hour: - pixels[stunde] = rgbdict["rgb_std"][0], rgbdict["rgb_std"][1], rgbdict["rgb_std"][2] + for stunde_led in stunden_leds: + pixels[stunde_led] = rgbdict["rgb_std"][0], rgbdict["rgb_std"][1], rgbdict["rgb_std"][2] # Minute setzen - pixels[minute] = rgbdict["rgb_min"][0], rgbdict["rgb_min"][1], rgbdict["rgb_min"][2] + for minute_led in minuten_leds: + pixels[minute_led] = rgbdict["rgb_min"][0], rgbdict["rgb_min"][1], rgbdict["rgb_min"][2] # Sekunde setzen - pixels[second] = rgbdict["rgb_s"][0], rgbdict["rgb_s"][1], rgbdict["rgb_s"][2] + for sekunde_led in sekunden_leds: + pixels[sekunde_led] = rgbdict["rgb_s"][0], rgbdict["rgb_s"][1], rgbdict["rgb_s"][2] - # Neue Leere LED berechnen - led_gesetzt_neu = set(hour) | {minute} | {second} - leerliste = list(set(led_gesetzt) - led_gesetzt_neu) - for leer in leerliste: - pixels[leer] = rgbdict["rgb_leer"][0], rgbdict["rgb_leer"][1], rgbdict["rgb_leer"][2] + # Leer setzen + for leer_led in leer_leds: + pixels[leer_led] = rgbdict["rgb_leer"][0], rgbdict["rgb_leer"][1], rgbdict["rgb_leer"][2] pixels.show() - return list(led_gesetzt_neu) def shutdown(): @@ -195,7 +218,7 @@ def check_anwesenheit(uhr, pixels): wlanliste = CONFIG["ping"] interface = CONFIG["interface"] - status_anwesend_liste = [] + status_anwesend_liste = [] delta = datetime.timedelta(seconds=301) last = datetime.datetime.now() status = {} @@ -227,8 +250,8 @@ def check_anwesenheit(uhr, pixels): if len(status_anwesend_liste) < ABSCHALTWERT + 1: status_anwesend_liste.append(status["anwesend"]) print("Nichts los daheim die ", len(status_anwesend_liste), ".") - if len(status_anwesend_liste) > ABSCHALTWERT: - helligkeit = 0 + if len(status_anwesend_liste) > ABSCHALTWERT: + helligkeit = 0 if status["dimmen"]: helligkeit = 0.03 if now.hour < 5 and not status["dimmen"]: @@ -240,8 +263,7 @@ def check_anwesenheit(uhr, pixels): def main(): - lastsecond = None - led_gesetzt = 0 + letzter_durchlauf = datetime.datetime(1970, 1, 1) pixels = neopixel.NeoPixel(LED_PIN, LED_COUNT, brightness=CONFIG["led_helligkeit"], auto_write=False, pixel_order=LED_PIXEL_ORDER) @@ -250,7 +272,6 @@ def main(): thread_check_wlan.start() rgbconf = uhr.rgb_farben_lesen() - print(rgbconf) alle_led(rgbconf["rgb_leer"][0], rgbconf["rgb_leer"][1], rgbconf["rgb_leer"][2], pixels) I_PLUS_TASTER.when_pressed = uhr.helligkeit_erhoehen @@ -258,17 +279,16 @@ def main(): try: while True: - rgbconf = uhr.rgb_farben_lesen() - print(rgbconf) now = datetime.datetime.now() - if lastsecond != now.second: - lastsecond, led_gesetzt = led_calc(now, stdliste, rgbconf, led_gesetzt, pixels) + if (now - letzter_durchlauf) > uhr.durchlauf_pause: + uhr.mode_control(now) + letzter_durchlauf = now if uhr.helligkeit_geaendert is not None: if (datetime.datetime.now() - uhr.helligkeit_geaendert) > datetime.timedelta(seconds=30): CONFIG["led_helligkeit"] = uhr.helligkeit config_schreiben() uhr.helligkeit_geaendert = None - time.sleep(0.2) + time.sleep(uhr.sleep_time) finally: pixels.brightness = 0 alle_led(0, 0, 0, pixels)