Bitte setze Thread::sleep() nicht mit Zeiten über 500 Millisekunden ein.
Die korrekte Lösung des Problems ist ein Timer (zusammen mit dem Dummy Item natürlich, immer vorausgesetzt, Du brauchst tatächlich einen Schalter, der erst verzögert zum Schalten führt).
Code: Alles auswählen
// globale Variablen und Konstanten werden immer am Beginn der Datei definiert!
var Timer tDelay = null // Zeiger auf den Timer
rule "Verzögerung"
when
Item Dummy received command // Befehl empfangen
then
tDelay?.cancel // lösche Timer, falls einer existiert
if(receivedCommand == ON) // Kommando AN
tDelay = createTimer(now.plusSeconds(3), [ |
Sonoff_P1_Schalter.sendCommand(ON) // Licht an
])
else
Sonoff_P1_Schalter.sendCommand(OFF) // Licht aus
end
Der wesentliche Unterschied zu Thread::sleep() ist, dass die Rule bei ON den Timer anlegt und zuende ist, das dauert etwa 5 Millisekunden.
Wenn der Timer abläuft, startet der Scheduler den Code (eine Zeile), was wiederum innerhalb 5 Millisekunden erledigt ist.
Thread::sleep(3000) hält die Abarbeitung des Threads für 3000 Millisekunden an, die Ausführung des Codes dauert also die 3000 + noch einige Millisekunden obendrauf, in dieser Zeit steht dem System ein Thread weniger zur Abarbeitung von Rules zur Verfügung.
Default gibt es 5 Threads für Rules plus 2 Threads für Timer. Damit ist aber der aktive Timercode gemeint.
Ich kann dutzende oder gar hunderte Timer planen, die das System dann zuverlässig zur geplanten Zeit ausführt.
Solange die Threads nicht exakt zeitgleich ausgeführt werden müssen, gibt es keine Probleme.
Ein weitere Punkt ist, dass der Code mit Thread::sleep() keine Sorge für den Fall trägt, dass die Rule mehrfach getriggert wird.
Was passiert, wenn ich den Schalter ein- und sofort wieder ausschalte?
Die Rule wird zweimal parallel gestartet, das erste Mal wird der Thread::sleep() gestartet, das zweite Mal wird einfach ein OFF-Befehl gesendet.
Nach drei Sekunden ist dann Thread::sleep() fertig und der ON-Befehl wird gesendet.
Der Dummy Schalter steht aber auf OFF.
Wer jetzt wieder kurz auf ON schaltet, um wieder auf OFF schalten zu können, stellt fest, dass er in einer Zwickmühle ist.
Erst das geduldige Warten auf den ON-Befehl hilft dann.
Mehrfaches Hin- und Herschalten kann sogar dazu führen, dass sämtliche Threads (5) belegt sind.
Die Timer-Variante hingegen löscht einen laufenden Timer und erstellt ihn bei Bedarf erneut, die Ausführung des Codes läuft so schnell, dass die Rule nur unter extremen Bedingungen zweimal gestartet sein kann, was aber keine Auswirkungen hat (der Timer wird ja gelöscht).
openHAB4.1.2 stable in einem Debian-Container (bookworm) (Proxmox 8.1.5, LXC), mit openHABian eingerichtet