Seite 1 von 1

[Gelöst] Probleme mit Rule für Wettertendenz seit Openhab 4

Verfasst: 2. Nov 2024 13:57
von matz
Hallo erstmal an alle.

Seit dem Upgrade auf OH4 funktioniert eine meiner Rules nicht mehr, und ich hab ich schon 2 Wochen an der Lösung.

Ich berechne eine Variable mit den Unterschied vom momentanen Luftdruck zum Luftdruck vor 3 Stunden.

Die Rule sollte dann, je nach Wert das ganze in einenText umsetzen.

Leider funktioniert das ganze nicht mehr.

Ich habe 2 Wege versucht:
1. mit einigen IF Abfragen (diese Version funktioniert noch in OH3)
2. mit switch case

Beide leider ohne Erfolg.

Code: Alles auswählen

rule "Wettertendenz"
when
	Item Pressure changed
then
	unterschied=Pressure.deltaSince(now.minusHours(3),"rrd4j") as Number  
	logInfo("unterschied","Unterschied zu Wert vor 3 Stunden: " + unterschied)	
	switch (unterschied){
	case unterschied<= -8:				{vorhersage.postUpdate("Sturm mit Hagel")}
	case unterschied<= -5 && unterschied> -8: {vorhersage.postUpdate("Regen/Unwetter")}
	case unterschied<= -3 && unterschied> -5:	{vorhersage.postUpdate("Regnerisch")}
	case unterschied<= -0.5 && unterschied> -3: {vorhersage.postUpdate("baldiger Regen")}
	case unterschied<= 0.5 && unterschied> -0.5:{vorhersage.postUpdate("gleichbleibend")}
	case unterschied<= 3 && unterschied>= 0.5: {vorhersage.postUpdate("anhaltend schön")}
	case unterschied<= 5 && unterschied>= 3:	{vorhersage.postUpdate("unbeständig schön")}
	case unterschied>5:		{vorhersage.postUpdate("Sturmwarnung")}
	}
end
Hier die Rule.

Code: Alles auswählen

Number:Pressure Pressure         "Pressure [%.2f hPa]"   		<pressure> (gWetter)
Und das Item

Leider habe ich immer "Sturm mit Hagel" oder "Sturmwarnung".


Bin für jede Hilfe dankbar.

lg

Matz

Re: Probleme mit Rule für Wettertendenz seit Openhab 4

Verfasst: 2. Nov 2024 23:04
von udo1toni
  1. Ich gehe mal davon aus, dass die Variable unterschied außerhalb der Rule definiert ist, denn ohne die Definition wird die Rule "schon immer" nicht funktioniert haben (seit OH1.0)
  2. Pressure ist ein QuantityType Item, d.h. es liefert im Status immer die Einheit mit. FrüherTM wurde die Einheit von der Persistence nicht berücksichtigt. Das ist seit OH4 nicht mehr der Fall. Die Persistence liefert ebenfalls die korrekte Einheit.
    Für Vergleiche kann das unpraktisch sein. Der einfachste Weg, die Einheit loszuwerden, ist, den Wert als Float oder Integer auszuwerten.
  3. Die Rule als solche ist außerdem unnötig kompliziert.
    Optimierung 1: Da switch() den ersten Match übergibt und die Abarbeitung der restlichen Vergleiche abbricht (es verhält sich also wie verkettete if() ... else if() ... else Konstrukte), muss nur eine Grenze abgefragt werden.
    Es ist sinnvoll, den Text in einer lokalen Variablen zu halten (weniger Text...)

Code: Alles auswählen

rule "Wettertendenz"
when
    Item Pressure changed
then
    val nDelta = (Pressure.deltaSince(now.minusHours(3),"rrd4j") as Number).floatValue
    var strMessage = ""
    logInfo("weather","Unterschied zu Wert vor 3 Stunden: {}", nDelta)
    switch(nDelta) {
        case nDelta <= -8   : strMessage = "Sturm mit Hagel"
        case nDelta <= -5   : strMessage = "Regen/Unwetter"
        case nDelta <= -3   : strMessage = "Regnerisch"
        case nDelta <= -0.5 : strMessage = "baldiger Regen"
        case nDelta <=  0.5 : strMessage = "gleichbleibend"
        case nDelta <=  3   : strMessage = "anhaltend schön"
        case nDelta <=  5   : strMessage = "unbeständig schön"
        default             : strMessage = "Sturmwarnung"
    }
    vorhersage.postUpdate(strMessage)
end
Beachte auch die leicht andere Art, logInfo zu verwenden. Die log-Befehle beherrschen Substitution, jedes Auftauchen von {} im Text wird mit dem nächsten ungenutzten Parameterinhalt ersetzt (im Beispiel gibt es nur ein geschweiftes Klammerpaar und nur einen extra Parameter, nDelta. Bei der Substitution wird der Wert automatisch in einen String umgewandelt (wäre die Variable als Primitive definiert, könnte openHAB das bei der Verkettung per + nicht on the fly erledigen, da ein Primitive keine Methode .toString hat)

Optimierung 2: Es geht allerdings noch "eleganter"

Code: Alles auswählen

rule "Wettertendenz"
when
    Item Pressure changed
then
    val nDelta = (Pressure.deltaSince(now.minusHours(3),"rrd4j") as Number).floatValue
    logInfo("weather","Unterschied zu Wert vor 3 Stunden: {}", nDelta)
    val strMessage = transform("SCALE","deltaPressure.scale",nDelta)
    vorhersage.postUpdate(strMessage)
end
Dafür musst Du nun allerdings noch die SCALE Transformation installieren und die Datei deltaPressure.scale anlegen (in $OPENHAB_CONF/transform/):

Code: Alles auswählen

[..-8]=Sturm mit Hagel
]-8..-5]=Regen/Unwetter
]-5..-3]=Regnerisch
]-3..-0.5]=baldiger Regen
]-0.5..0.5]=gleichbleibend
]0.5..3]=anhaltend schön
]3..5]=unbeständig schön
]5..]=Sturmwarnung
[..-8] bedeutet: alle Werte kleiner oder gleich -8
]-8..-5] bedeutet: alle Werte größer -8 und kleiner oder gleich -5
]5..] bedeutet: alle Werte größer als 5

Man könnte auch ]7..8[ schreiben für: alle Werte größer 7 und kleiner 8, genauso könnte man auch [9..10] schreiben für: Alle Werte größer oder gleich 9 und kleiner oder gleich 10.

Natürlich kann man in diesem Fall auch sehr gut auf die lokale Variable verzichten, also so:

Code: Alles auswählen

vorhersage.postUpdate(transform("SCALE","deltaPressure.scale",nDelta))
Das ist ja immer noch sehr gut lesbar und nicht übermäßig komplex ;)

Re: Probleme mit Rule für Wettertendenz seit Openhab 4

Verfasst: 4. Nov 2024 16:57
von matz
Hallo UDO,
danke für die INFO.

Ich werde das morgen vormittags prüfen.

Ich wusste z.B. nicht das der Persistence die Einheit mitspeichert.


DANKE

Re: Probleme mit Rule für Wettertendenz seit Openhab 4

Verfasst: 4. Nov 2024 17:15
von matz
Hallo UDO.

Beide Rules probiert.

Leider bei beiden eine Fehlermeldung:

Version 1:
2024-11-04 17:11:44.464 [INFO ] [rg.openhab.core.model.script.weather] - Unterschied zu Wert vor 3 Stunden: 0.5
2024-11-04 17:11:44.465 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'wetterstatus-5' failed: An error occurred during the script execution: Could not invoke method: org.openhab.core.model.script.actions.Transformation.transform(java.lang.String,java.lang.String,java.lang.String) on instance: null in wetterstatus


Version2:
2024-11-04 17:08:44.388 [INFO ] [rg.openhab.core.model.script.weather] - Unterschied zu Wert vor 3 Stunden: 0.4
2024-11-04 17:08:44.401 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'wetterstatus-5' failed: An error occurred during the script execution: Could not invoke method: org.openhab.core.model.script.actions.Transformation.transform(java.lang.String,java.lang.String,java.lang.String) on instance: null in wetterstatus

Re: Probleme mit Rule für Wettertendenz seit Openhab 4

Verfasst: 4. Nov 2024 21:18
von udo1toni
matz hat geschrieben: 4. Nov 2024 16:57 Ich wusste z.B. nicht das der Persistence die Einheit mitspeichert.
Oh, das tut sie nicht. Sie liefert sie aber mit aus (wenn das Item korrekt konfiguriert ist)
Genauer: Die Persistence liest die Unit des Items aus und verwendet diese als Einheit.
matz hat geschrieben: 4. Nov 2024 17:15 Leider bei beiden eine Fehlermeldung:
Was meinst Du mit Version 1? Die Fehlermeldungen stammen wenn, dann beide von der zweiten Version (also der mit

Code: Alles auswählen

transform("SCALE","deltaPressure.scale",nDelta)
Wie erwähnt muss die Datei deltaPressure.scale existieren, mit passendem Inhalt, an der korrekten Stelle im Dateisystem, außerdem muss der Scale Transformation Service installiert sein.

Version 1 wäre evtl. die mit switch(nDelta){}, diese kann keine Fehlermeldung mit actions.Transformation.transform erzeugen, da dort kein transform() aufgerufen wird.

Re: Probleme mit Rule für Wettertendenz seit Openhab 4

Verfasst: 5. Nov 2024 08:36
von matz
So.

Danke nochmals für deine Hilfe.

Die Version ohne actions.Transformation.transform läuft jetzt.
Die Version mit actions.Transformation.transform geht nach wie vor nicht, abwohl ich die Datei angelegt habe im Ordner transform.

Weiterhin folgender Fehler:

Code: Alles auswählen

Script execution of rule with UID 'wetterstatus-5' failed: An error occurred during the script execution: Could not invoke method: org.openhab.core.model.script.actions.Transformation.transform(java.lang.String,java.lang.String,java.lang.String) on instance: null in wetterstatus
Komische Sache ?????

Trotzdem eine Lösung.

Danke Udo für deine tolle Hilfestellung.

Ich komme wieder.

Re: [Gelöst] Probleme mit Rule für Wettertendenz seit Openhab 4

Verfasst: 5. Nov 2024 23:28
von udo1toni
Prima, dass es mit switch() nun funktioniert.
Was SCALE betrifft, so hatte ich hier tatsächlich beim testen auch zu kämpfen. Vor allem ist mein jetzt funktionierendes Ergebnis vergleichbar mit verschiedenen Phasen meiner Tests, wo es dann nicht funktionierte...!?!

Der wesentliche Punkt ist aber vermutlich, dass transform() zwingend drei Strings erwartet, und im Gegensatz zu früher (das hat mal funktioniert...) muss man den Zahlenwert nach String konvertieren... So sieht meine funktionierende Rule aus:

Code: Alles auswählen

rule "Wettertendenz"
when
    Item Pressure changed
then
//    val Number nDelta = (Pressure.deltaSince(now.minusHours(3),"rrd4j") as Number).floatValue
val nDelta = (newState as Number).floatValue
    logInfo("weather","Unterschied zu Wert vor 3 Stunden: {}", nDelta)
    val String strMessage = transform("SCALE", "deltaPressure.scale", nDelta.toString)
    logInfo("weather","Vorhersage: {}", strMessage)
    vorhersage.postUpdate(strMessage)
end
ich habe das Auslesen der Persistence beim Testen ignoriert, weil es auch so nicht funktionierte.
Schlüssel sind das .toString, um nDelta als String zu übergeben sowie die starke Typisierung val String strMessage [...] um zu erzwingen, dass der Wert als String gespeichert wird.
Wie gesagt, das hat mal komplett ohne Typisierung funktioniert...
deltaPressure.scale habe ich nun so angelegt:

Code: Alles auswählen

[..-8]      = Sturm mit Hagel
]-8..-5]    = Regen oder Unwetter
]-5..-3]    = Regnerisch
]-3..-0.5]  = baldiger Regen
]-0.5..0.5] = gleichbleibend
]0.5..3]    = anhaltend schön
]3..5]      = unbeständig schön
]5..]       = Sturmwarnung
aber die Auflösung funktioniert auch ohne die Leerzeichen, nur ist es so etwas leichter lesbar...

Aber wie erwähnt, switch() ist auch prima, und wenn Du nicht gerade auf Experimente aus bist, solltest Du am besten dabei bleiben :)