Rule erzeugt einen Error, aber warum ????

Einrichtung der openHAB Umgebung und allgemeine Konfigurationsthemen.

Moderatoren: seppy, udo1toni

Antworten
Joerg
Beiträge: 44
Registriert: 2. Jan 2020 10:38

Rule erzeugt einen Error, aber warum ????

Beitrag von Joerg »

Hallo,
die untere Regel erzeugt nach 10 Minuten folgende Meldung:
An error occurred during the script execution: null
Zur Erklärung, der "zaehler" soll nur verhindern, dass die Tante gleich beim öffnen quatscht.
wartezeit = eine Angabe in Minuten, der Sound soll dann alle 10 Minuten abgespielt werden.
Was ist da falsch ????
Gruß und Dank'
Jörg

Code: Alles auswählen

var zaehler = 0
var wartezeit = 10

rule "WC_Fenster_offen"
when
    Item Fenster_Gaeste_WC_LEQ0405783_1_State changed
then

        while (Fenster_Gaeste_WC_LEQ0405783_1_State.state != CLOSED) {
                if(zaehler == 1) {
                        playSound("Es_sind_noch_Fenster_offen.mp3");
                }
                else {
                        zaehler = 1
                }
                Thread::sleep(wartezeit*60*1000)
        }
end

Benutzeravatar
udo1toni
Beiträge: 13944
Registriert: 11. Apr 2018 18:05
Answers: 222
Wohnort: Darmstadt

Re: Rule erzeugt einen Error, aber warum ????

Beitrag von udo1toni »

Die Rule ist so nicht gut.
Was nun konkret den Fehler auslöst, weiß ich auch nicht, aber wie gesagt ist die Rule ohnehin nicht gut. openHAB Rules arbeiten eventbasiert. Dazu stellt openHAB 5 Threads zur Verfügung, in denen Rules ablaufen können. Deine Rule blockiert einen Thread, solange das Fenster geöffnet ist. Beim Schließen wird gar die Rule ein zweites Mal ausgeführt, parallel zum ersten Thread (auch wenn die Rule dann exakt nichts tut).
Der elegantere Ansatz ist folgender:

Code: Alles auswählen

// Globale Variablen werden zu Beginn der Datei definiert
var Timer tWindow = null                                   // Timervariable global definieren

rule "WC_Fenster_offen"
when
    Item Fenster_Gaeste_WC_LEQ0405783_1_State changed      // Zustand Fensterkontakt hat sich geändert
then
    tWindow?.cancel                                        // Falls Timer vorhanden, abbrechen
    if(Fenster_Gaeste_WC_LEQ0405783_1_State.state == OPEN) // Falls Fenster offen
        tWindow = createTimer(now.plusMinutes(10),[|       // Timer starten (Ablauf nach 10 Minuten)
            playSound("Es_sind_noch_Fenster_offen.mp3")    // Nachricht abspielen
            tWindow.reschedule(now.plusMinutes(10))        // Timer erneut planen (Ablauf nach 10 Minuten)
        ])
end
Wen das Fenster geöffnet oder geschlossen wird, löst die Rule aus. In beiden Fällen wird ein eventuell laufender Timer abgebrochen.
Falls das Fenster geöffnet wurde, wird ein neuer Timer angelegt. Nach Ablauf des Timers wird das mp3-File abgespielt und der Timer erneut geplant.
Soll das Ganze variabel gestaltet werden (Variable wartezeit aus Deiner Rule) so ist es wichtig, die Variable als Integer zu definieren, da .plusMinutes(int) zwingend ein Argument vom Typ Integer erwartet.
Im Unterschied zur While-Schleife mit Thread::sleep() belegt die Rule nur wenige Millisekunden einen Thread (eben die Zeit, die sie braucht, den Scheduler zu füttern). Der Scheduler benötigt erst mit Ablauf des Timers einen Thread, um den Code auszuführen (wieder nur wenige Millisekunden, denn playsound läuft asynchron in einem eigenen Thread).
Da wir das Thema gerade mehrere Tage in einem anderen Thread hatten: welcher Itemtyp verbirgt sich hinter Fenster_Gaeste_WC_LEQ0405783_1_State? Sollte es ein Contact Item sein, ist alles prima und die Rule sollte so funktionieren. Sollte es ein String Item sein, müsste das Wort OPEN in Anführungszeichen gesetzt werden.
openHAB4.1.2 stable in einem Debian-Container (bookworm) (Proxmox 8.1.5, LXC), mit openHABian eingerichtet

Joerg
Beiträge: 44
Registriert: 2. Jan 2020 10:38

Re: Rule erzeugt einen Error, aber warum ????

Beitrag von Joerg »

Wow hast Du Dir viel Arbeit gemacht, vielen Dank dafür!!
Meine erste rule hatte auch einen Timer, weil ich das "sleep" auch nicht so toll fand, allerdings war das nur ein Gefühl, denn Dein Wissen habe ich nicht.
Leider habe ich zur Syntax des Timers nichts finden können und wußte somit auch nichts von Timer.cancel und Timer.reschedule. Bei meinem Versuch stand ich nach 10 Minuten in einer Bahnhofshalle und hunderte Mädels haben auf mich eingeredet, das noch ein Fenster offen ist :-))
Jup, es ist ein Contact Item.
Also nochmal vielen Dank für die Mühe und besonders für die Hintergrunderklärung.

Antworten