Der Punkt ist, ein Event ist
immer ein Zeitpunkt,
niemals eine Zeitspanne.
Was Du beschreibst, ist also: Du möchtest, falls ein Event A eintritt, danach aber für eine Zeitspanne x nicht das Event A', eine Action auslösen.
A verhält sich zu A' gegenteilig, also z.B. A -> Tür wurde geöffnet, A' -> Tür wurde geschlossen.
Das "anhaltende Event" ist ein Status, oder zu deutsch Zustand, kein Event.
Es ist sehr wichtig, den Unterschied zu verstehen, denn dann wird es auch einfacher, die Rule Engine zu verstehen.
Die Rule Engine ist eventgesteuert, Rules werden
ausschließlich zu Zeitpunkten ausgelöst,
niemals, weil ein Zustand anhält.
Entsprechend muss Deine Rule folgendermaßen aussehen:
Ereignis A oder Ereignis A' tritt ein -> starte Rule
Innerhalb der Rule prüfen, welches Ereignis aufgetreten ist (das geht leicht anhand des aktuellen Zustands, der ja zwingend dem letzten Ereignis entspricht)
Trat A auf, so starte einen Timer der Zeitspanne X
Trat A' auf, so stoppe den Timer und verwerfe ihn.
Soweit die Rule.
Erreicht der Timer seinen Ablaufzeitpunkt (ein Event...), so wird der enthaltene Code ausgeführt. Da zu diesem Zeitpunkt der Zustand immer noch A ist, kannst Du in diesem Teil des Codes also einfach Deine Action ausführen lassen.
Es gibt verschiedene Möglichkeiten zum Implementieren der Funktion.
Z.B. kannst Du ein Switch Item
Timeout definieren, welches mit einem Expiration Timer versehen wird. Der Expiration Timer soll nach Ablauf der eingestellten (fixen) Zeit den Befehl OFF senden.
Nun kannst Du z.B. über die UI zwei Rules erstellen, die eine Rule triggert, wenn die Tür geöffnet wird, die andere triggert, wenn die Tür geschlossen wird.
Die beiden Rules tun exakt das gegensätzliche, die eine setzt
Timeout auf den Status ON, die andere setzt
Timeout auf den Status OFF (
NICHT per sendCommand, sondern per postUpdate).
Als Folge wird also das Item Timeout beim Öffnen der Tür auf ON gesetzt, beim Schließen auf OFF.
Bleibt die Tür aber offen, so wird der Expiration Timer ein sendCommand OFF absetzen, das ist ein Ereignis, welches eine Rule triggern kann.
Eine andere Möglichkeit wäre das Programmieren über eine DSL Rule. Dazu ist zu sagen, dass Du die volle Kontrolle über den Timer brauchst, das geht leider nur, wenn die DSL Rule als Text in einer *.rules Datei im Verzeichnis $OPENHAB_CONF/rules/ gespeichert ist. Z.B. unter openHABian in
/etc/openhab/rules/meine.rules:
Code: Alles auswählen
// globale Variablen und Konstanten müssen zwingend am Anfang der Datei stehen!
var Timer tDoor = null // definiere eine globale Variable für den Tür Timeout
val Integer iDoor = 60 // Länge des Timeouts für die Tür
rule "Tür Timeout"
when
Item myDoor changed // Türkontakt hat Zustand geändert
then
tDoor?.cancel // evtl. laufenden Timer abbrechen
if(newState == OPEN) // Tür ist geöffnet
tDoor = createTimer(now.plusSeconds(iDoor),[| // Timer anlegen
Ventilator.sendCommand(OFF) // Ventilator ausschalten
])
end
Ja, das ist hinreichend!
Innerhalb der Rule passiert folgendes:
1. Falls ein Timer existiert (das ist das ? nach tDoor), wird dieser abgebrochen
2. Falls der aktuelle Status (newState enthält den Status des Items, welches die Rule per changed getriggert hat) OPEN ist, wird ein Timer angelegt. Der Zeiger auf den Timer (den brauchen wir, um den Timer stoppen zu können) wird dabei in der vorher definierten Variablen gespeichert. Die Laufzeit des Timers in Sekunden wird über die globale Konstante iDoor definiert, welche zwingend einen Integer Wert enthalten muss. (Man könnte den Wert natürlich auch direkt rein schreiben)
An dieser Stelle ist die Rule mit ihrer Arbeit fertig und ist beendet. Auch das ist wichtig zu verstehen. Die Rule selbst läuft etwa zwei Millisekunden, mehr nicht!
Läuft der Timer ab (d.h. die Rule wurde zwischenzeitlich nicht nochmal getriggert und hat deshalb den Timer nicht per .cancel gestoppt), so wird der angegebene Code ausgeführt, in diesem Fall also der Befehl, den Ventilator auszuschalten.
Ich weiß, ChatGPT wird als die Wunderwaffe verkauft, aber lass Dich davon nicht einlullen, es handelt sich nur um ein einigermaßen trainiertes Expertensystem, welches mitnichten gute Antworten auf jede Frage hat, ganz besonders nicht im Bereich von openHAB - dazu ist die Datenlage mit nur einigen zehntausend Programmbeispielen viel zu klein.
Außerdem kann ChatGPT nicht zwischen gutem und schlechtem Code unterscheiden, es ist auch nicht in der Lage, zu verstehen, was der Code bewirkt - ich habe dazu schon einige Beispiele gesehen, und 90 % ist großer Quatsch, das heißt, wenn tatsächlich vernünftige Rules raus kommen, dann hat ChatGPT die bei einem Anwender abgeschrieben und lag damit zufällig richtig.