Rule mit Vergleich und Timer

Einrichtung der openHAB Umgebung und allgemeine Konfigurationsthemen.

Moderatoren: seppy, udo1toni

Antworten
Benutzeravatar
PeterA
Beiträge: 1106
Registriert: 8. Feb 2019 12:12
Answers: 13

Rule mit Vergleich und Timer

Beitrag von PeterA »

Hallo zusammen,

die nachfolgende Rule soll folgendes machen:
Vergleiche den State zweier Items. Da eines der beiden Items seinen State verzögert bekommt habe ich einen Timer eingebaut.
Kann das so funktionieren ? (Timer mache ich nicht so oft)

Code: Alles auswählen

var Timer myTimer = null // Variable zu Beginn der Datei definieren

rule "WAC350 Geringe feuchte Alarm"
when
    Item LuefterStufe received command 2 // Lüfterstufe auf 2 (Mittel)
    
then
    if (WAC350_Geringe_Feuchte.state != ON) { // Überprüfen, ob Item "ON" ist //!!NEUES ITEM Type Switch! MapDB!!!
        return; // Regel abbrechen, wenn Bedingung nicht erfüllt ist
    }

    if (myTimer !== null) {
        myTimer.cancel() // Timer abbrechen, falls bereits gestartet
    }
    
    myTimer = createTimer(now.plusSeconds(60), [ |
        if (LuefterStufe.state == 2 || Luefter1.state == 60) { // Wert 2 mit 60 vergleichen
        if (myTimer !== null) {
            myTimer.cancel() // Timer abbrechen, falls bereits gestartet
            myTimer = null
        }
        return; // Regel abbrechen, wenn Bedingung nicht erfüllt ist
    }
        // Wenn die Bedingung aus dem Vergleich erfüllt wurde (LuefterStufte==2 und Luefter1 nicht 60)
        WAC350_Geringe_Feuchte_Alarm.postUpdate(1) //!!NEUES ITEM Type Number! MapDB!!!
        
        // Hier den Code einfügen, um die Push-Nachricht zu versenden / Logeintrag erzeugen / Variable zurücksetzen
        sendBroadcastNotification("Alarm geringe Feuchte" + now.toString("HH:mm") + " Uhr") //Allgemeine Warnung an alle
        logWarn("WAC Alarme","Geringe Feuchte Alarm") // Logeintrag erzeugen
        myTimer = null // Variable zurücksetzen
    ])
end
Viele Grüße
Peter
- OpenHab 2.4
#PWRUP

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

Re: Rule mit Vergleich und Timer

Beitrag von udo1toni »

Der Code ist ziemlich sicher fehlerhaft...

Erst mal: Innerhalb des Timers ist die Variable myTimer niemals null (es sei denn, Du löschst sie noch an einer anderen Stelle, z.B. in einer anderen Rule)
Dann löschst Du ja beim Auslösen der Rule den Timer, falls er vorhanden ist. Da es sonst keine Überprüfung zu geben scheint, gibt es auch keine Grund, die Timer Variable innerhalb des Timers zu löschen.

Du hast innerhalb des Timers einen Vergleich

Code: Alles auswählen

if (LuefterStufe.state == 2 || Luefter1.state == 60)
, der dazu führt, dass der Timer abgebrochen wird. Der Abbruch geschieht in zwei Situationen. Entweder der Status von LuefterStufe ist 2, dann spielt der Status von Luefter1 keine Rolle, oder Luefter1 hat den Status 60, dann spielt der Status von LuefterStufe keine Rolle. Dein Kommentar besagt aber etwas anderes:

Code: Alles auswählen

// Wenn die Bedingung aus dem Vergleich erfüllt wurde (LuefterStufte==2 und Luefter1 nicht 60)
Wobei der Code nach der Bedingung genau dann ausgeführt wird, wenn keine der Bedingungen zutrifft, also LuefterStufe != 2 UND Luefter1 != 60

Dann verwendest Du ein Number Item um den Alarm zu speichern, was eher ungewöhnlich ist. Vielleicht willst Du das zur grafischen Auswertung so haben?

So, wie Du die Rule geschrieben hast, passiert folgendes: Du sendest den Befehl "2" an das Item LuefterStufe. Daraufhin wird ein eventuell noch vorhandener Timer gelöscht und anschließend neu angelegt (unter der Voraussetzung, dass WAC350_Geringe_Feuchte zu diesem Zeitpunkt ON ist).

Nach 60 Sekunden läuft der Timer ab (falls bis dahin kein weiterer Befehl "2" an das Item LuefterStufe gesendet wurde). Ist bis dahin auch keine andere Lüfterstufe gewählt worden (der Status von LuefterStufe ist immer noch 2) wird der Timer gelöscht.
Falls die Stufe nicht mehr 2 ist, aber Luefter1 den Wert 60 hat, wird der Timer gelöscht.
Trifft beides nicht zu, werden verschiedene Alarme aktiviert.

Ich denke nicht, dass dies Dein Ziel war :) insbesondere das mit dem Item1 Status 2 ODER Item2 Status 60.

Die Kommentare machen den Code so etwas unübersichtlich. Ohne Ballast sieht die Rule so aus:

Code: Alles auswählen

// globale Variablen zu vor der ersten Rule der Datei definieren

var Timer myTimer = null

rule "WAC350 Geringe feuchte Alarm"
when
    Item LuefterStufe received command 2
then
    if(WAC350_Geringe_Feuchte.state != ON)
        return;

    myTimer?.cancel

    myTimer = createTimer(now.plusSeconds(60), [ |
        if(LuefterStufe.state == 2 || Luefter1.state == 60)
            return;

        WAC350_Geringe_Feuchte_Alarm.postUpdate(1)
        sendBroadcastNotification("Alarm geringe Feuchte um " + now.toString("HH:mm") + " Uhr")
        logWarn("WAC Alarme","Geringe Feuchte Alarm")
    ])
end
Insbesondere möchte ich auf die Zeile myTimer?.cancel hinweisen, das ist gleichbedeutend mit if(myTimer !== null) myTimer.cancel, aber wesentlich besser lesbar.

Was ist Luefter1? Was ist WAC350_Geringe_Feuchte? Wo wird die eigentliche Messung vorgenommen?

Gewöhnlich wird man die Luftfeuchte in % angeben, falls also Luefter1 in Wirklichkeit die Luftfeuchte ist, müsstest Du eigentlich auf >= 60 prüfen, um bei 60 % oder mehr den Timer abzubrechen. Es scheint mir aber der falsche Ansatz, dies exakt einmal 60 Sekunden nach Schalten auf Stufe 2 zu prüfen und dann nie mehr.
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet

Benutzeravatar
PeterA
Beiträge: 1106
Registriert: 8. Feb 2019 12:12
Answers: 13

Re: Rule mit Vergleich und Timer

Beitrag von PeterA »

Hi Udo vielen lieben Dank Deine Antwort!

Zum besseren Verständnis:
Luefter1 (Luefter2 gibt's auch noch) bildet die Drehzahl der Lüfter in Prozent ab.
LuefterStufe2 bedeutet das die Lüfter mit 60% Laufen sollen.
Es gibt noch LuefterStufe1 das bedeutet das die Lüfter mit 35% Laufen sollen.
WAC350_Geringe_Feuchte ist ein ungebundenes Item und dafür Vorgesehenen die Rule zu Aktivieren oder zu Deaktivieren oder besser vorzeitig Abzubrechen.

Nun passiert ab und zu folgendes:
Wenn Anlage zu geringe Luftfeuchtigkeit erkennt geht die Anlage quasi in einen "Safemode" und Dreht die Lüfter nur noch mit 35%.
Wenn sich die Anlage in diesem Status befindet werden keine weiteren Befehle angenommen.
Das muss ich nicht sofort gemeldet bekommen.
Mir fällt es erst dann auf wenn das Item LuefterStufe den command 2 sendet aber die Anlage nicht auf 60% Drehzahl geht.
Die LuefterStufe(n) kommen von einer anderen Rule.
Somit war mein Ansatz zu prüfen wenn LuefterStufe den command 2 gesendet hat danach zu prüfen ob die Lüfter wirklich mit 60% Drehen. Den Timer hatte vorgesehen weil die Anlage mit etwas Verzögerung die Drehzahl anpasst.
Falls nun LuefterStufe 2 gesendet wurde aber nach 60sek die Lüfter nicht mit 60% Drehen soll das AlarmItem (ja könnte auch ein Switch sein) einen anderen Status bekommen ON oder 1.
Über anderes Item kann ich den Fehler oder "Safemode" der Anlage wieder zurücksetzen und auch das AlarmItem wieder auf OFF oder 0 setzen.
Ich hoffe das war so einigermaßen Verständlich?

Gruß
Peter
- OpenHab 2.4
#PWRUP

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

Re: Rule mit Vergleich und Timer

Beitrag von udo1toni »

Ja, ok, dann passt die Verknüpfung ja grundsätzlich. Hier noch eine andere Variante:

Code: Alles auswählen

// globale Variablen zu vor der ersten Rule der Datei definieren

var Timer myTimer = null

rule "WAC350 Geringe feuchte Alarm"
when
    Item LuefterStufe changed
then
    if(WAC350_Geringe_Feuchte.state != ON)         // Hauptschalter aktiv?
        return;                                    // falls nicht, Abbruch

    myTimer?.cancel                                // Timer löschen, falls vorhanden

    if(LuefterStufe.state != 2)                    // Lüfterstufe ungleich 2?
        return;                                    // dann Abbruch

    myTimer = createTimer(now.plusSeconds(60), [ | 
        if(Luefter1.state == 60)                   // entspricht Drehzahl dem Soll?
            return;                                // dann Abbruch

        WAC350_Geringe_Feuchte_Alarm.postUpdate(1)
        sendBroadcastNotification("Alarm geringe Feuchte um " + now.toString("HH:mm") + " Uhr")
        logWarn("WAC Alarme","Geringe Feuchte Alarm")
    ])
end
Die Rule triggert bei jedem Statuswechsel von LuefterStufe.
Der Timer wird immer gelöscht.
Nur wenn die Stufe 2 gewählt ist, wird der Timer angelegt.
Daraus folgt, dass Stufe 2 gilt, wenn der Timer abläuft (weshalb das nicht mehr geprüft werden muss).
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet

Benutzeravatar
PeterA
Beiträge: 1106
Registriert: 8. Feb 2019 12:12
Answers: 13

Re: Rule mit Vergleich und Timer

Beitrag von PeterA »

Danke Udo.

Schaut natürlich gleich viel Aufgeräumter aus!

Werde das bei Gelegenheit dann mal Implementieren und Testen.

Gruß
Peter
- OpenHab 2.4
#PWRUP

Antworten