Sperrzeit je Automatik in drei Stufen
Die steigende Flanke allein schuetzt nicht gegen einen Messwert, der um die Schwelle pendelt: "Temperatur > 22" bei 22,1 / 21,9 / 22,1 Grad ist jedes Mal eine echte Flanke, und ueber MQTT koennen die Werte im Sekundentakt hereinkommen. Gemessen: fuenf Kommandos in einer halben Minute. automations.lockout_secs sagt jetzt, wie lange nach einer Ausloesung nicht wieder geschaltet wird. Der Editor bietet drei Stufen an - ohne, eine Minute, eine Viertelstunde -, weil die passende Wahl am Geraet haengt und nicht an einer Zahl: ein Rollladen soll nicht alle zwanzig Sekunden losfahren, eine Lichtfarbe darf das. Gespeichert werden Sekunden, damit eine vierte Stufe eine Zeile in lockoutChoices() ist und keine Wanderung durch die Datenbank. Vorbelegt ist eine Minute. Eine Flanke in der Sperrzeit wird verworfen, nicht aufgehoben. Ein Rollladen, der eine Viertelstunde spaeter doch noch losfaehrt, weil vor langer Zeit einmal eine Schwelle gestreift wurde, waere unangenehmer als einer, der gar nicht faehrt - und der naechste echte Anlass nach Ablauf der Sperre kommt ohnehin durch. Verworfene Flanken stehen auf DEBUG und nicht in automation_log, sonst waere die Tabelle bei einem zappelnden Sensor voll davon. force_once bleibt unberuehrt: es greift nur, wenn im Fenster gar nichts gelaufen ist - dann ist auch keine Sperre aktiv. Nachgemessen am pendelnden Sensor: mit 60 s Sperre ein Kommando, ohne Sperre fuenf. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -575,7 +575,11 @@ class Runner:
|
||||
self.lief_im_fenster[automatik["id"]] = False
|
||||
erfuellt = gruppen_erfuellt(automatik, self.regelwerk, self.werte, jetzt)
|
||||
if erfuellt and not automatik["cond_met"]:
|
||||
self.ausloesen(automatik, "fired")
|
||||
if self.gesperrt(automatik, jetzt):
|
||||
logger.debug("%s: Flanke faellt in die Sperrzeit, uebersprungen",
|
||||
automatik["name"])
|
||||
else:
|
||||
self.ausloesen(automatik, "fired")
|
||||
self.flanke_merken(automatik, erfuellt)
|
||||
else:
|
||||
# Das Fenster ist gerade zugegangen. Wer "auf jeden Fall"
|
||||
@@ -595,6 +599,30 @@ class Runner:
|
||||
|
||||
self.war_aktiv[automatik["id"]] = aktiv
|
||||
|
||||
@staticmethod
|
||||
def gesperrt(automatik, jetzt):
|
||||
"""
|
||||
Liegt die letzte Ausloesung noch innerhalb der Sperrzeit?
|
||||
|
||||
Gegen Messwerte, die um die Schwelle pendeln: "Temperatur > 22" bei
|
||||
22,1 / 21,9 / 22,1 Grad ist jedes Mal eine echte steigende Flanke, und
|
||||
ueber MQTT koennen die Werte im Sekundentakt hereinkommen.
|
||||
|
||||
Die Flanke wird dabei verworfen und nicht aufgehoben. Ein Rollladen,
|
||||
der eine Viertelstunde spaeter doch noch losfaehrt, weil vor langer
|
||||
Zeit einmal eine Schwelle gestreift wurde, waere unangenehmer als
|
||||
einer, der gar nicht faehrt. Der naechste echte Anlass nach Ablauf
|
||||
der Sperre kommt ohnehin durch.
|
||||
|
||||
force_once ist davon nicht betroffen: es greift nur, wenn im Fenster
|
||||
gar nichts gelaufen ist - dann ist auch keine Sperre aktiv.
|
||||
"""
|
||||
sperre = int(automatik.get("lockout_secs") or 0)
|
||||
letzter = automatik.get("last_run")
|
||||
if not sperre or not letzter:
|
||||
return False
|
||||
return (jetzt - letzter).total_seconds() < sperre
|
||||
|
||||
@staticmethod
|
||||
def lief_heute(automatik, jetzt):
|
||||
letzter = automatik.get("last_run")
|
||||
|
||||
Reference in New Issue
Block a user