Vermutlich dachtest Du, mit dem Thread::sleep(10000) könntest Du den Trigger ignorieren, aber das ist Quatsch.
openHAB arbeitet asynchron. Vor Version 3.0 standen 5+2 Threads für die Verarbeitung von Rules zur Verfügung, d.h. die Rule wurde im Zweifel einfach zweimal gestartet, wenn es zwei Ereignisse gab, die die Rule triggerten.
Seit openHAB3.0 hat jede Rule ihren eigenen Thread und kann somit auch nie mehrfach gleichzeitig ausgeführt werden. Dafür merkt openHAB sich aber, dass die Rule ein weiteres Mal getriggert wurde und startet die Rule nochmal.
Was Du haben möchtest, ist stattdessen eine Totzeit, und Du wertest den Status erst am Ende der Totzeit aus. Die vollständige Variante (mit Meldung der Lüftungsposition) sähe so aus:
Code: Alles auswählen
var Timer tTor = null // Timer für Toröffnung
var nTor = 0 // Zähler für Kontaktänderung
rule "Garagentor Position"
when
Item Garage_Tor_Sensor changed
then
if(tTor === null) {
logDebug("tor","Tortimer inaktiv! Starte Zählvorgang! Anzahl Änderungen: 1")
nTor = 1
tTor = createTimer(now.plusSeconds(11), [
var nPos = -1
if(Tor.state instanceof Number)
nPos = (Tor.state as Number).intValue
if(nPos == -1) {
logDebug("tor","Torposition nicht zu ermitteln! nehme offenes Tor an!")
nPos = 2
}
if(Garage_Tor_Sensor.state == OPEN) {
nPos = 2
} else { // Kontakt == CLOSED
switch(nTor) {
case 1 : nPos = 1 // kam von OPEN -> Lüftungsposition
case 3 : nPos = 0 // kam von OPEN -> geschlossen
case 2 : { // kam von geschlossen
if(nPos == 1) // falls vorher Lüften -> geschlossen
nPos = 0
else if(nPos == 0) // falls vorher geschlossen -> Lüften
nPos = 1
}
}
}
Tor.postUpdate(nPos)
var url = "https://api.callmebot.com/whatsapp.php?phone=XXXXXXXXXXX&text=This+is+a+test&apikey=XXXXXXX&text="
var MessageWhatsApp = "Garage "
switch(nPos) {
case 0 : MessageWhatsApp = MessageWhatsApp + "zu"
case 1 : MessageWhatsApp = MessageWhatsApp + "lüftet"
case 2 : MessageWhatsApp = MessageWhatsApp + "offen"
}
MessageWhatsApp = MessageWhatsApp.replace(" ", "%20")
sendHttpGetRequest(url + MessageWhatsApp, 10000)
logDebug("tor", "Nachricht: {}",MessageWhatsApp)
tTor = null
])
} else {
nTor += 1
logDebug("tor","Tortimer aktiv! Zähle Anzahl Änderungen: {}", nTor)
return;
}
end
Der Code zählt während der Timer läuft die Anzahl der Kontaktwechsel.
Minimal ginge auch dies:
Code: Alles auswählen
var Timer tTor = null // Timer für Toröffnung
rule "Garagentor Position"
when
Item Garage_Tor_Sensor changed
then
if(tTor === null)
tTor = createTimer(now.plusSeconds(11), [
var strPos = "zu"
if(Garage_Tor_Sensor.state == OPEN) strPos = "offen"
var url = "https://api.callmebot.com/whatsapp.php?phone=XXXXXXXXXXX&text=This+is+a+test&apikey=XXXXXXX&text="
var MessageWhatsApp = "Garage%20" + strPos
sendHttpGetRequest(url + MessageWhatsApp, 10000)
logDebug("tor", "Nachricht: {}",MessageWhatsApp)
tTor = null
])
end
Die Rule wertet einen geschlossenen Kontakt IMMER als geschlossenes Tor, also auch die Lüftungsposition ist "zu".
Die 11 Sekunden für den Timer sollten der Maximallaufzeit des Tors entsprechen, die Maximallaufzeit bestimmst Du, indem Du einmal von komplett geschlossen auf komplett offen fährst und die benötigte Zeit stoppst, sowie einmal das gleiche in die Gegenrichtung, also von komplett offen nach komplett geschlossen. Die größere der beiden gemessenen Zeiten ist dann die Maximallaufzeit des Tors, eventuell packst Du noch ein, zwei Sekunden zur Sicherheit obendrauf.
Der Punkt ist aber: die Rule wird zwar mehrfach ausgeführt, jedoch wird der Timer nur einmalig gestartet. Läuft der Timer ab (die Fahrt des Tors ist zu dem Zeitpunkt definitiv beendet), wird der Zustand des Kontakts ausgewertet.
Ich habe die "Komfortversion" auf meinem Testsystem ausprobiert. Du brauchst lediglich ein weiteres Item
Code: Alles auswählen
Number Tor "Garagentor ist" {stateDescription=""[options="0=geschlossen,1=lüftend,2=offen"]}
welches die Position des Tors auch in der UI anzeigen kann.
openHAB4.1.2 stable in einem Debian-Container (bookworm) (Proxmox 8.2.2, LXC), mit openHABian eingerichtet