Seite 1 von 3

mal wieder Fachwissen gefragt

Verfasst: 26. Aug 2021 20:50
von Snatsch
Hallo,
da ja der Sommer jetzt vorbei zu scheinen ist :cry: musste ich heute das erste mal meinen Ofen wieder anzünden :o Und das im August :oops: Ich hätte gerne wenn mein Pufferspeicher 55 Grad erreicht hat eine Nachricht auf auf mein Handy. Soweit funktioniert meine Rule auch aber :| immer wenn sich die Temperatur ändert bekomme ich diese Nachricht.

Code: Alles auswählen

rule "Pufferspeicher hat 55 Grad ereicht"

when 
     Item Pufferspeichersensor_Temperatur changed 

then
    logInfo("Pufferspeicher", "Rule triggert ! Wert : {} ", Pufferspeichersensor_Temperatur.state )
    
    if(!(Pufferspeichersensor_Temperatur.state instanceof Number)) {
       logWarn("Pufferspeicher Gradzahl", "liefert keinen gültigen Zahlenwert")
       return;
    }
    if((Pufferspeichersensor_Temperatur.state as Number).floatValue > 55) {
       logInfo("Pufferspeicher", "hat Temperatur von 55 Grad erreicht! ")
       Meldung.postUpdate ("Der Pufferspeicher hat eine Temperatur von 55 Grad ereicht !")
      
    }
    
end  
ist ja auch irgendwie logisch aber wie kann ich das unterbinden ?

MfG Snatsch

Re: mal wieder Fachwissen gefragt

Verfasst: 26. Aug 2021 21:02
von PeterA
Hi Snatsch,

versuch doch mal so:

Code: Alles auswählen

Item Pufferspeichersensor_Temperatur changed to 55
Gruß Peter

Re: mal wieder Fachwissen gefragt

Verfasst: 26. Aug 2021 21:07
von Snatsch
Das würde doch aber bedeuten das ich die Nachricht nur bekomme wenn der Pufferspeicher genau auf 55 Grad stehen würde oder?
Ich hatte schon probiert

Code: Alles auswählen

 if((Pufferspeichersensor_Temperatur.state as Number).floatValue > 56) return

aber das wollte irgendwie auch nicht richtig funktionieren

Re: mal wieder Fachwissen gefragt

Verfasst: 26. Aug 2021 22:14
von udo1toni
Der Trick ist an dieser Stelle, sich zu merken, ob die Nachricht schon geschickt wurde. das geht auf unterschiedliche Weise. Die einfachste Variante wäre eine globale Boolean Variable, welche default auf false steht, wenn die Nachricht gesendet werden soll, prüft die Rule dann, ob die Variable auf false steht, und nur wenn das der Fall ist, wird die Nachricht gesendet und zusätzlich die Variable auf true gesetzt.
Du kannst natürlich bei changed auch prüfen, ob previousState <= 55 und newState > 55 ist. previousState ist eine implizite Variable, die automatisch zur Verfügung steht, wenn das changed Event auftritt (genau wie newState auch).
Allerdings wird die Nachricht dann auch jedes Mal gesendet, wenn der Wert überschritten wird, auch wenn der Wert nur kurz unter 55 sinkt oder ständig um 55 pendelt.
Dafür musst Du Dich aber nicht um das Rücksetzen der Variablen kümmern, das wäre beim ersten Fall notwendig.

Re: mal wieder Fachwissen gefragt

Verfasst: 26. Aug 2021 22:44
von Snatsch
He udo1toni vielen Dank für deine Antwort :)
Hab ich das so richtig verstanden ?

Code: Alles auswählen

var Boolean bPufferspeichersensor_Temperatur  = false

rule "Pufferspeicher hat 55 Grad ereicht"

when 
     Item Pufferspeichersensor_Temperatur changed 

then
    logInfo("Pufferspeicher", "Rule triggert ! Wert : {} ", Pufferspeichersensor_Temperatur.state )
    
    if(!(Pufferspeichersensor_Temperatur.state instanceof Number)) {
       logWarn("Pufferspeicher Gradzahl", "liefert keinen gültigen Zahlenwert")
       return;
    }
    if((Pufferspeichersensor_Temperatur.state as Number).floatValue > 55) {
       logInfo("Pufferspeicher", "hat Temperatur von 55 Grad erreicht! ")
       bPufferspeichersensor_Temperatur = true
       Meldung.postUpdate ("Der Pufferspeicher hat eine Temperatur von 55 Grad ereicht !")
      
    }
    
end 

Re: mal wieder Fachwissen gefragt

Verfasst: 27. Aug 2021 05:40
von udo1toni
Fast. Es fehlt noch die Prüfung, ob die Variable false ist.
So sähe die Rule konkret aus:

Code: Alles auswählen

var Boolean bTempMessage  = false

rule "Pufferspeicher hat 55 Grad ereicht"
when 
    Item Pufferspeichersensor_Temperatur changed 
then
    logInfo("Pufferspeicher", "Rule getriggert! Wert : {}", Pufferspeichersensor_Temperatur.state )
    if(!(Pufferspeichersensor_Temperatur.state instanceof Number)) {
       logWarn("Pufferspeicher", "Sensor Item liefert keinen gültigen Zahlenwert.")
       return;
    }
    if(bTempMessage) {
       logInfo("Pufferspeicher", "Nachricht bereits gesendet.")
       return;
    }
    if((Pufferspeichersensor_Temperatur.state as Number).floatValue > 55) {
       logInfo("Pufferspeicher", "Pufferspeicher hat Temperatur von 55 °C erreicht! ")
       bPufferspeichersensor_Temperatur = true
       Meldung.postUpdate("Der Pufferspeicher hat eine Temperatur von 55 Grad ereicht!")
    }
end
Esfehlt dann noch ein Reset der Variablen, damit "irgendwann" wieder eine Meldung ausgegeben wird.

Der Vollständigkeit halber hier noch die andere Variante:

Code: Alles auswählen

rule "Pufferspeicher Nachricht"
when 
    Item Pufferspeichersensor_Temperatur changed 
then
    logDebug("warmwasser", "Rule getriggert! Wert : {} ", Pufferspeichersensor_Temperatur.state )
    if(!(previousState instanceof Number))
       logWarn("warmwasser", "kein gültiger Vergleichswert! Setze Wert unter 55.")
    val nPrev = if(previousState instanceof Number) (previousState as Number).floatValue else 50
    if(!(newState instanceof Number)) {
       logWarn("warmwasser", "Sensor Item liefert keinen gültigen Zahlenwert. Abbruch!")
       return;
    }
    val nNew = (newState as Number).floatValue
    if(nNew > 55 && nPrev <= 55) {
       logInfo("warmwasser", "Pufferspeicher hat Temperatur 55 °C überschritten! ")
       bPufferspeichersensor_Temperatur = true
       Meldung.postUpdate("Der Pufferspeicher hat die Temperatur 55 °C überschritten!")
    }
end
Noch ein paar Hinweise:

Die log-Befehle erwarten zwei Strings als Parameter. Dabei ist der erste String der Logger Name. Das hat nur am Rande etwas mit der Meldung zu tun. Hier sollte eigentlich nur ein Bezug auf die Rule erkennbar sein, der Text sollte aber nicht als Teil der Meldung verstanden werden. Stattdessen ist dieser Parameter eine Größe, die zur Steuerung des Verhaltens herangezogen wird.
Man kann zur Laufzeit über die Karaf Konsole mittels log:set <loglevel> <loggername> gezielt Meldungen unterdrücken oder ausgeben lassen. Der genaue Name des Loggers ist leider hochgradig von der verwendeten Version von openHAB abhängig, geht aber natürlich aus den Meldungen hervor. Aktuell (openHAB3.x) sollte er z.B. org.openhab.core.model.script.warmwasser für die 2. Rule lauten, der in der Rule angegebene Name ist also nur ein Teil des Logger Namens. Mit log:set DEBUG org.openhab.core.model.script.warmwasser wird die erste Meldung (Rule getriggert) ausgegeben, mit log:set INFO org.openhab.core.model.script.warmwasser wird diese Meldung nicht ausgegeben, aber die Meldung, wenn die Temperatur überschritten wird. Mit log:set WARN org.openhab.core.model.script.warmwasser werden nur die Warnmeldungen ausgegeben. Dazu ist es aber essenziell, dass der Logger Name thematisch verwendet wird, nicht als individueller Bestandteil der Meldungen. Genauso ist es eher fragwürdig, einfach "rule" in das Feld zu schreiben, zumal dies eine bereits vorhandene Information ist (das geht aus org.openhab.core.model.script hervor).

sprechende Namen für Variablen sind toll, aber je länger ein Variablenname, desto unübersichtlicher wird der Code. Also: so lang wie nötig, so kurz wie möglich. Temp mag als Kürzel zweideutig sein (temporär vs. Temperatur) aber im Kontext ist es eindeutig genug.

Mit dem ternären Operator

Code: Alles auswählen

a = if(b) c else d
ist es sehr einfach, einen Default Wert zu setzen. Alternativ kann man natürlich auch

Code: Alles auswählen

var a
if(b)
 a = c
else
 a = d
schreiben. Letztlich ist das egal, nimmt aber entsprechend mehr Platz weg.

Re: mal wieder Fachwissen gefragt

Verfasst: 27. Aug 2021 17:12
von Snatsch
Lieben vielen Dank udo1toni für deine ausführliche Erklärung v :)

Re: mal wieder Fachwissen gefragt

Verfasst: 25. Okt 2021 17:46
von Snatsch
Hallo ich mal wieder ;)
jetzt wo die Heiz Zeit wieder los geht :( Habe ich die Rule ausprobiert :D leider funktioniert sie nicht :cry: vielleicht könnte einer von den Fachleuten noch mal drüber schauen.

Code: Alles auswählen

rule "Pufferspeicher Nachricht"
when 
    Item Pufferspeichersensor_Temperatur changed 
then
    logDebug("warmwasser", "Rule getriggert! Wert : {} ", Pufferspeichersensor_Temperatur.state )
    if(!(previousState instanceof Number))
       logWarn("warmwasser", "kein gültiger Vergleichswert! Setze Wert unter 55.")
    val nPrev = if(previousState instanceof Number) (previousState as Number).floatValue else 50
    if(!(newState instanceof Number)) {
       logWarn("warmwasser", "Sensor Item liefert keinen gültigen Zahlenwert. Abbruch!")
       return;
    }
    val nNew = (newState as Number).floatValue
    if(nNew > 55 && nPrev <= 55) {
       logInfo("warmwasser", "Pufferspeicher hat Temperatur 55 °C überschritten! ")
       bPufferspeichersensor_Temperatur = true
       Meldung.postUpdate("Der Pufferspeicher hat die Temperatur 55 °C überschritten!")
    }
end 
wäre euch wie immer sehr Dankbar wenn ihr mir auf die Sprünge helfen könntet :)

Re: mal wieder Fachwissen gefragt

Verfasst: 25. Okt 2021 21:23
von peter-pan
Snatsch hat geschrieben: 25. Okt 2021 17:46 leider funktioniert sie nicht
Was funktioniert denn nicht ?

Re: mal wieder Fachwissen gefragt

Verfasst: 25. Okt 2021 21:37
von Snatsch
Es kommt leider keine Meldung