Zeit-Ausloeser: "um" ergaenzt, Sonnenstand vervollstaendigt
Bei Uhrzeit und Datum gab es nur "ab" und "vor". Der haeufigste Fall - eine Aktion genau um 16:30 - liess sich damit gar nicht ausdruecken. "um" ist jetzt der erste Eintrag und damit die Vorbelegung. Der Hinweis von frueher bleibt trotzdem richtig und steht in der README: "um" trifft nur eine einzige Minute, faellt der Runner ausgerechnet in dieser Minute aus, ist die Automatik fuer den Tag verloren. "ab" holt der naechste Takt nach. Wer beides will, hakt force_once an. Beim Sonnenauf- und -untergang fehlte die halbe Tabelle: der Versatz kann davor oder danach liegen, und verglichen werden kann davor, danach oder genau. Statt zwei gibt es jetzt sechs Operatoren - "+", "-", "ab +", "ab -", "vor +", "vor -". Das Vorzeichen steckt im Operator, weil der Editor eine einzige Auswahlliste zeigt und nicht zwei Bedienelemente fuer eine Angabe. Rutscht ein Versatz rechnerisch ueber den Tagesrand (Sonnenaufgang 05:34 minus sechs Stunden), bleibt es beim Tagesrand statt auf die andere Seite von Mitternacht zu springen - "kurz vor Sonnenaufgang" soll nicht ploetzlich gestern abend bedeuten. Der Editor brauchte keine Aenderung: er liest Wert und Beschriftung der Operatoren aus dem Geraetekatalog, statt sie selbst zu kennen. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -26,11 +26,18 @@ Nur die steigende Flanke loest aus: `automations.cond_met` haelt fest, ob die
|
||||
Bedingung beim letzten Durchlauf schon erfuellt war. Ohne das wuerde
|
||||
"Temperatur ueber 22 Grad" bei jedem Takt erneut feuern.
|
||||
|
||||
Zeit-Ausloeser heissen "ab 16:30" und nicht "gleich 16:30" - damit bleibt die
|
||||
Bedingung bis Mitternacht wahr und ein verpasster Takt kostet nicht den
|
||||
ganzen Tag. Ausgeloest wird trotzdem nur einmal, eben wegen der Flanke.
|
||||
Dieselbe Ueberlegung steht hinter den breiten Zeitfenstern in
|
||||
auto_watering.py.
|
||||
Zeit-Ausloeser gibt es in drei Formen: "um 16:30" ist genau in dieser Minute
|
||||
wahr, "ab 16:30" von da an bis Mitternacht, "vor 16:30" bis dahin.
|
||||
Ausgeloest wird in allen drei Faellen nur einmal, eben wegen der Flanke -
|
||||
"ab" ist aber das robustere: faellt der Runner in der einen Minute aus, auf
|
||||
die "um" zeigt, ist die Automatik fuer den Tag verloren; bei "ab" holt der
|
||||
naechste Takt es nach. Wer "um" braucht und den Ausfall nicht riskieren
|
||||
will, hakt zusaetzlich force_once an. Dieselbe Ueberlegung steht hinter den
|
||||
breiten Zeitfenstern in auto_watering.py.
|
||||
|
||||
Beim Sonnenauf- und -untergang traegt der Operator zusaetzlich das
|
||||
Vorzeichen des Versatzes: "+ 00:30" eine halbe Stunde danach, ">=- 00:30"
|
||||
ab einer halben Stunde davor, "<+ 00:30" bis eine halbe Stunde danach.
|
||||
|
||||
Tabellen siehe homeMesh_automations.sql, Konfiguration siehe config.ini.example.
|
||||
"""
|
||||
@@ -265,26 +272,35 @@ def bedingung_erfuellt(bedingung, state, wert, jetzt):
|
||||
|
||||
if typ == "time":
|
||||
ist_m, soll_m = minuten(wert), minuten(soll)
|
||||
return ist_m >= soll_m if op == ">=" else ist_m < soll_m
|
||||
if op == "=": return ist_m == soll_m
|
||||
if op == "<": return ist_m < soll_m
|
||||
return ist_m >= soll_m
|
||||
|
||||
if typ == "deltatime":
|
||||
# Der Messwert ist der Sonnenauf- bzw. -untergang, die Schwelle
|
||||
# ein Versatz davor oder danach. Verglichen wird gegen die Uhr.
|
||||
# ein Versatz. Das Vorzeichen steckt im Operator, der Vergleich
|
||||
# davor: ">=-" heisst "ab einer halben Stunde davor".
|
||||
versatz = minuten(soll)
|
||||
ziel = minuten(wert) + (versatz if op == "+" else -versatz)
|
||||
return jetzt.hour * 60 + jetzt.minute >= ziel
|
||||
ziel = minuten(wert) + (-versatz if op.endswith("-") else versatz)
|
||||
# Ein Versatz kann rechnerisch ueber den Tagesrand rutschen
|
||||
# (Sonnenaufgang 05:34 minus sechs Stunden). Dann bleibt es beim
|
||||
# Tagesrand, statt auf die andere Seite von Mitternacht zu
|
||||
# springen - "kurz vor Sonnenaufgang" soll nicht ploetzlich
|
||||
# gestern abend bedeuten.
|
||||
ziel = max(0, min(1439, ziel))
|
||||
jetzt_m = jetzt.hour * 60 + jetzt.minute
|
||||
if op.startswith(">="): return jetzt_m >= ziel
|
||||
if op.startswith("<"): return jetzt_m < ziel
|
||||
return jetzt_m == ziel
|
||||
|
||||
if typ == "date":
|
||||
ist_d, soll_d = als_datum(wert), als_datum(soll)
|
||||
if typ in ("date", "datetime"):
|
||||
wandeln = als_datum if typ == "date" else als_zeitpunkt
|
||||
ist_d, soll_d = wandeln(wert), wandeln(soll)
|
||||
if ist_d is None or soll_d is None:
|
||||
return False
|
||||
return ist_d >= soll_d if op == ">=" else ist_d < soll_d
|
||||
|
||||
if typ == "datetime":
|
||||
ist_d, soll_d = als_zeitpunkt(wert), als_zeitpunkt(soll)
|
||||
if ist_d is None or soll_d is None:
|
||||
return False
|
||||
return ist_d >= soll_d if op == ">=" else ist_d < soll_d
|
||||
if op == "=": return ist_d == soll_d
|
||||
if op == "<": return ist_d < soll_d
|
||||
return ist_d >= soll_d
|
||||
|
||||
if typ == "bool":
|
||||
ist_b = str(wert).strip().lower() in WAHR
|
||||
|
||||
Reference in New Issue
Block a user