Seite 1 von 1

Mal wieder: Rule funktioniert nicht :-(

Verfasst: 26. Feb 2020 16:47
von kaloschke
Hallo,
stehe auf dem Schlauch und hoffe auf Hilfe.
Ich möchte über einen Temperatursensor einen Alarm auslösen. Meine Rule dazu:

Code: Alles auswählen

val alerted = 0     // Holds the alertes state (0=no, 1=yes)
val toleranz = 0.5
val setPoint = 25.0

rule "Stack alert"
when
    Item StackTemperature changed
then
    val temp = StackTemperature.state as Number 
    logInfo("Temperatur: ",temp.toString)
    logInfo("alerted vorher:",alerted.toString)
    // StackTemperature grows above setpoint, should we alert?
    if (temp > (setPoint + toleranz)) {
        if (alerted == 0) {
            // Send an alert....
            alerted = 1
            logInfo("Alarm ausgelöst bei ", "Temperatur: " + temp.toString)
        }
    }    
    else if (temp <= (setPoint - toleranz)) {
        alerted = 0
    }
    logInfo("alerted nachher:",alerted.toString)
end
Allerdings wird der Alarm beim Start der Regel auch bei Temperaturen kleiner als dem Setpoint ausgelöst. Und das verstehe ich nicht.
Das Log zeigt dazu:

Code: Alles auswählen

2020-02-26 16:32:58.367 [INFO ] [el.core.internal.ModelRepositoryImpl] - Refreshing model 'home.rules'
2020-02-26 16:36:45.980 [INFO ] [.smarthome.model.script.Temperatur: ] - 22.0 °C
2020-02-26 16:36:45.982 [INFO ] [arthome.model.script.alerted vorher:] - 0
2020-02-26 16:36:45.989 [INFO ] [me.model.script.Alarm ausgelöst bei ] - Temperatur: 22.0 °C
2020-02-26 16:36:45.992 [INFO ] [rthome.model.script.alerted nachher:] - 1
2020-02-26 16:44:04.672 [INFO ] [.smarthome.model.script.Temperatur: ] - 25.53 °C
2020-02-26 16:44:04.677 [INFO ] [arthome.model.script.alerted vorher:] - 1
2020-02-26 16:44:04.692 [INFO ] [rthome.model.script.alerted nachher:] - 1
2020-02-26 16:44:13.363 [INFO ] [.smarthome.model.script.Temperatur: ] - 26.09 °C
2020-02-26 16:44:13.367 [INFO ] [arthome.model.script.alerted vorher:] - 1
2020-02-26 16:44:13.375 [INFO ] [rthome.model.script.alerted nachher:] - 1
Habe noch mal nachgerechnet: setPoint + toleranz macht wirklich 25,5 :-)

P.S.: Der alerted Wert geht auch nicht wieder auf 0 bei Temperaturen kleinen 24,5

Re: Mal wieder: Rule funktioniert nicht :-(

Verfasst: 26. Feb 2020 17:14
von udo1toni
Es kommen hier gleich mehrere Fehler zusammen.
Aber die erste Frage: Das Log kann nicht von dem angegebenen Code stammen, denn Du hast alerted als Konstante definiert, welche also nicht mehr geändert werden kann...
Anhand des Logs kannst Du sehen, dass die gemeldete Temperatur mit einer Einheit ausgegeben wird, nur hast Du diese Einheit nirgends mit angegeben. Diese kommt also mit extrem hoher Wahrscheinlichkeit aus dem Item, welches dann als UoM Item in der Form Number StackTemperature:Temperature definiert ist. Nun vergleichst Du eine einheitenbehaftete Zahl mit einer Zahl ohne Einheit, was zwangsläufig schief gehen muss.
Außerdem verwendest Du den logInfo Befehl falsch, indem Du den Loggernamen (der erste zu übergebende String) für Text verwendest.

Korrekt sollte die Rule so aussehen:

Code: Alles auswählen

var Boolean alerted = false
val Number toleranz = 0.5
val Number setPoint = 25

rule "Stack alert"
when
    Item StackTemperature changed
then
    val Number temp = (StackTemperature.state as Number).floatValue
    logInfo("alert", "Temperatur: {} °C",temp)
    logInfo("alert","alerted vorher: {}",alerted)
    // StackTemperature grows above setpoint, should we alert?
    if(temp > setPoint + toleranz) {
        if(!alerted) {
            // Send an alert....
            alerted = true
            logInfo("alert","Alarm ausgelöst bei {} °C", temp)
        }
    }    
    else if (temp <= setPoint - toleranz) {
        alerted = false
    }
    logInfo("alert","alerted nachher: {}",alerted)
end
Es bietet sich an, die Variable alerted als Boolean zu definieren, denn es handelt sich ja um eine Boolean Information. Auch für die Konstanten toleranz und setPoint ist die Definition auf den korrekten Typ sinnnvoll.
Innerhalb der Rule ist die Konstante temp ebenfalls vom Typ Number. Um die Einheit loszuwerden, wird nach dem Typecasting des Status nach Number noch eine Umwandlung nach Float vorgenommen und schon ist die Einheit verschwunden.
da alerted als Boolena definiert ist, ist die Abfrage extrem einfach :)
In den logInfo Befehlen ist jeweils der loggername alert gesetzt.
Die log-Befehle beherrschen Parameterersetzung, das bedeutet, im angegebenen String wird die {} durch den nächsten Parameter ersetzt. Dabei wird automatisch nach String konvertiert. Leider funktioniert das nicht überall. Man kann auch mehrere {} verwenden und dann entsprechend mehrere Parameter mit angeben.

Re: Mal wieder: Rule funktioniert nicht :-(

Verfasst: 26. Feb 2020 17:42
von kaloschke
Jetzt funktioniert es "natürlich"! Danke!!!

Aber vor allem vielen vielen Dank für Deine ausführlichen Erläuterungen. Eigentlich hatte ich das mit dem Item vom Typ Number:Temperature in einer IF-Abfrage schon woanders gelesen, aber in meinem kleinen Koipf nicht mehr auf dem Schirm :-(
Aber jetzt ist - für einen Moment :-) - alles klar.

Viele Grüße bis zum nächsten Mal.