Zeit-Schaltuhr mit Dämmerung & Schedule

  • Hallo allerseits!
    Bald ist Weihnachtszeit und somit Zeit für die Weihnachtsbeleuchtung. Bisher hatten wir das immer mit einer fixen Zeit-Schaltuhr gelöst, weil wir nicht die Beleuchtung die ganze Nacht eingeschaltet haben wollen. Dumm nur: die Zeiten haben nie so richtig gepasst, manchmal war es noch hell, dann wieder schon längst dunkel. Das manuelle Nach-Justieren der Uhr ging mir immer auf den Sack.

    Lösung: eine Uhr, welche die Dämmerungs-Zeiten berücksichtigt und anhand dieser Zeiten ein- bzw. ausschaltet. Das eigentliche Schalten erledigt ein MyStrom Wifi Switch, welcher keine Cloud Anbindung etc benötigt. Könnte man also auch gut in so Heim-Automatisierungs-Zeugs integrieren. Die eigentliche Anforderung war: Lampe soll täglich um 5.00h morgens ein- und bei der Morgendämmerung wieder ausgeschaltet werden. Ebenfalls soll die Lampe bei der Abenddämmerung ein- und um 21.00h wieder ausgeschaltet werden.

    Ich tat mich anfangs schwer mit den Zeiten, da ich zuerst die fehlerhafte Sun-Bibliothek verwendete und ewig herum probiert habe mit den Zeiten-Berechnungen zwischen UTC und lokaler Zeit. Doch dann fand ich zufällig die Astral-Bibliothek, welche die Sache enorm vereinfacht. Das ganze macht natürlich Sinn wenn es automatisch gestartet und verwaltet wird z.B. mit pm2 / systemd oder sowas in der Art. Vielleicht hilft das Prinzip und der Code jemand anders auch, um solche zeitgesteuerten Sachen zu realisieren ohne Internet, also alles nur im lokalen WLAN.

    Viel Spass damit 8)

    René

    Hier der Code:

  • Hallo,

    ein paar Anmerkungen:

    Keine nackten try-except benutzen, weil dass in 99,9% der Fälle falsch ist. Damit bügelst du alle Fehler weg, auch solche, die man eigentlich sehen möchte, wie z.B. Syntax-Fehler durch falsche Programmierung.

    Die URL für requests mit String-Formatierung zusammenbauen ist unschön, du kannst einem Request direkt Parameter mitgeben, siehe https://requests.readthedocs.io/en/latest/user…ameters-in-urls

    Ist in

    # Abends: Einschalten zur Dämmerung, Ausschalten um 21:00
    schedule.every().day.at(dusk.strftime("%H:%M")).do(switch_lamp, True)
    schedule.every().day.at("21:00").do(switch_lamp, False)

    nicht ein Logikfehler? Im Hochsommer liegt der Sonnenuntergang doch nach 21 Uhr, d.h. die Lampe brennt die ganze Nacht.

    Statt das Skript in einer Dauerschleife laufen zu lassen, könntest du es 1x pro Tag (z.B. 0:01 Uhr) per systemd Timer Unit starten, die Zeiten für Sonnenaufgang und -untergsng abfragen und dann per `subprocess` und systemd-run vier einmalige Timer Units setzen, die die Lampe ein- und ausschalten.

    Gruß, noisefloor

  • nicht ein Logikfehler? Im Hochsommer liegt der Sonnenuntergang doch nach 21 Uhr, d.h. die Lampe brennt die ganze Nacht.

    Im Hochsommer ist nicht

    Bald ist Weihnachtszeit und somit Zeit für die Weihnachtsbeleuchtung.

    ;) Ich vermute stark dass das Skript nur bei aufgebauter Weihnachtsdeko laufen soll.

    When I grow up there will be a day
    When everybody has to do what I say

  • DirtyOldFart Anmerkungen zum Quelltext: Erst sind da zwei IMHO recht offensichtliche Fehler drin, die verhindern, dass das mehr als zwei Tage lang (maximal) tatsächlich funktioniert, und zu bestimmten Jahreszeiten dann auch nicht korrekt. Dazu am Ende mehr…

    Auf Modulebene sollte nur Code stehen, der Konstanten, Funktionen, und Klassen definiert. Das Hauptprogramm steht üblicherweise in einer Funktion die main() heisst.

    Konstanten werden per Konvention KOMPLETT_GROSS benannt. Und auch wenn tz eine nicht ganz unübliche Abkürzung für timezone ist — bei einer Konstanten würde ich das ausschreiben. Dann muss man da auch keinen Kommentar dran schreiben für was der Name steht.

    Kommentare sollten dem Leser einen Mehrwert geben. Faustregel: Kommentare beschreiben nicht was der Code macht, denn das steht da ja bereits als Code, sondern warum er das macht. Sofern das nicht offensichtlich ist. Offensichtlich ist in aller Regel insbesondere was in der Dokumentation zur Sprache und den verwendeten Bibliotheken steht.

    pytz ist hier unnötig, das LocationInfo-Objekt hat doch bereits ein passendes tzinfo-Attribut. Statt datetime.datetime kann man auch astral.now() und astral.today() verwenden.

    Man müsste bei der HTTP-Anfrage noch den Status der Antwort prüfen, der muss ja nicht „200 OK“ sein und das möchte man vielleicht ganz gerne als Fehler mitbekommen.

    Zwischenstand (ungetestet):

    Die beiden (noch enthaltenen) Fehler sind:

    • Beim planen werden zuerst alle ”alten” Planungen gelöscht, was auch die tägliche Planung verwirft, wodurch das ganze maximal zwei Tage lang funktioniert (Initiale Planung + eine geplante Planung).
    • Die Schaltlogik funktioniert nur solange die Morgendämmerung nach 5 Uhr und die Abenddämmerung vor 21 Uhr liegt.

    “Gravity is a habit that is hard to shake off.” — Terry Pratchett, Small Gods

    Edited once, last by __blackjack__: pytz tatsächlich auch nicht importieren :-) (November 2, 2025 at 1:58 PM).

  • Bei uns wird der Weihnachtsbaum, der auf der Terrasse hängt, mit einem Tasmota-bedienten Switch ein und ausgeschaltet.

    denn bei dem kann man die Schaltungen nach dem "Sonnenstand" Sonnenaufgang und Sonnenuntergang (plus, minus ein paar Minuten) durchführen lassen.


    Hier muss man nur einmal dem Ding ausreichend genaue Geo-Koordinaten eingeben und dann bei den Schaltaufträgen sagen, was gemacht werden soll.

    "Bei Sonnenuntergang einschalten"

    "Um 22:00 Uhr ausschalten"

    Das hat dann auch das lästige Umstellen der Uhr von der Rolladensteuerung ersetzt.

    Computer ..... grrrrrr

Participate now!

Don’t have an account yet? Register yourself now and be a part of our community!