Hallo.
Ich habe eine Frage, wie ich es am elegantesten löse, wenn ich mit einer Rule warten muss, bis eine andere fertig ist.
Habe das mit Variablen und While Schleifen versucht, aber habe Bedenken, dass das je nach Dauer und Anzahl der Rules mal problematisch werden kann.
In meinem Fall möchte ich bei allen Rules, die eine Sprach- oder Sound-Ausgabe machen, erstmal prüfen, ob schon eine Ausgabe läuft und dann ggfs. warten bis diese beendet ist. Oder gibt es hier andere Möglichkeiten so etwas abzufragen?
Vielen Dank im Voraus.
Best Practice: mit Rule warten, bis andere Rules 'abgearbeitet' sind
-
- Beiträge: 45
- Registriert: 3. Jul 2019 10:30
- udo1toni
- Beiträge: 15249
- Registriert: 11. Apr 2018 18:05
- Wohnort: Darmstadt
Re: Best Practice: mit Rule warten, bis andere Rules 'abgearbeitet' sind
Die einfachste Lösung für das Problem ist ein lock, wobei man höllisch aufpassen muss. Mein Vorschlag wäre, exakt eine Rule zu definieren, welche tatsächlich Meldungen als Sprache ausgibt. Die Rule triggerst Du über ein ungebundenes String Item, in dem Du den zu sprechenden Text per sendCommand ablädst. In der ausführenden Rule verwendest Du dann den lock-Mechanismus, um mehrfache Ausführung zu verhindern. Der Witz dabei: Sollte die Rule zu schnell neu getriggert werden, merkt sich das System die Meldungen und führt die Rule jeweils einmal pro empfangenen Kommando aus (so sollte es jedenfalls sein). Such mal nach lock.lock, try und finally, da solltest Du Beispielrules finden.
Allerdings wird die Sprachausgabe asynchron ausgeführt, was bedeutet, dass Du Dich innerhalb der Rule selbst darum kümmern musst, dass die Rule auf das Ende der Ausgabe wartet.
Allerdings wird die Sprachausgabe asynchron ausgeführt, was bedeutet, dass Du Dich innerhalb der Rule selbst darum kümmern musst, dass die Rule auf das Ende der Ausgabe wartet.
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet
-
- Beiträge: 45
- Registriert: 3. Jul 2019 10:30
Re: Best Practice: mit Rule warten, bis andere Rules 'abgearbeitet' sind
Hallo Udo.
Vielen Dank für die Anregungen. Will mal schauen, ob ich das mit dem Lock vermeiden kann. Ist ja tatsächlich nicht ganz einfach.
Aber mit dem ungebundenen String - Item komme ich sicherlich schon ein bisschen weiter.
Für das Warten auf Ende der Ausgabe innerhalb der Rule hast du da noch einen Alternativen Vorschlag außer dem Thread::sleep(x)?
Vielen Dank für die Anregungen. Will mal schauen, ob ich das mit dem Lock vermeiden kann. Ist ja tatsächlich nicht ganz einfach.
Aber mit dem ungebundenen String - Item komme ich sicherlich schon ein bisschen weiter.
Für das Warten auf Ende der Ausgabe innerhalb der Rule hast du da noch einen Alternativen Vorschlag außer dem Thread::sleep(x)?
- udo1toni
- Beiträge: 15249
- Registriert: 11. Apr 2018 18:05
- Wohnort: Darmstadt
Re: Best Practice: mit Rule warten, bis andere Rules 'abgearbeitet' sind
Unbedingt kein Thread::sleep() verwenden! Nimm lieber einen Timer. Wobei Dann halt alle Messages, welche während einer Ansage herein kommen, verworfen werden.
Eine passende Rule (ohne alles, nur der Timer...) sieht so aus:
Der Timer hat in diesem Fall nur eine einzige Aufgabe, nämlich den Verweis auf sich selbst zu entfernen.
Als erstes prüft die Rule, ob der Timerverweis null ist. Ist das nicht der Fall, wird die Rule umgehend beendet. (der Vergleich lautet tatsächlich !==)
Ist der Timer null, wird sofort ein Timer erzeugt und in die Variable geladen, als allererstes, damit die Rule "gesperrt" ist.
Anschließend (also direkt nach dem Befüllen der Variablen) wird der Block // machwas ausgeführt, hier kann dann also die Ansage abgespielt werden.
Nach 10 Sekunden (plusSeconds(10)) wird der Timercode ausgeführt, der nichts anderes macht, als die Variable auf null zu setzen. Mit dem nächsten empfangenen Kommando ist die Rule also wieder aufnahmebereit.
Eine passende Rule (ohne alles, nur der Timer...) sieht so aus:
Code: Alles auswählen
// globale Variablen vor der ersten Rule in der Datei platzieren
var Timer Timeout = null
rule "Timeout Sperre"
when
Item MyString received command
then
if(Timeout !== null) return;
Timeout = createTimer(now.plusSeconds(10),[|
Timeout = null
])
// machwas
end
Als erstes prüft die Rule, ob der Timerverweis null ist. Ist das nicht der Fall, wird die Rule umgehend beendet. (der Vergleich lautet tatsächlich !==)
Ist der Timer null, wird sofort ein Timer erzeugt und in die Variable geladen, als allererstes, damit die Rule "gesperrt" ist.
Anschließend (also direkt nach dem Befüllen der Variablen) wird der Block // machwas ausgeführt, hier kann dann also die Ansage abgespielt werden.
Nach 10 Sekunden (plusSeconds(10)) wird der Timercode ausgeführt, der nichts anderes macht, als die Variable auf null zu setzen. Mit dem nächsten empfangenen Kommando ist die Rule also wieder aufnahmebereit.
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet