Seite 1 von 14

Temperatur Tendenz ermitteln

Verfasst: 12. Aug 2020 07:43
von KellerK1nd
Guten Morgen liebe Foris,

Ich versuche mich aktuell an einer neuen rule, dabei geht es darum für ein Temperaturitem eine Tendenz (steigend, fallend) zu ermitteln. Dabei tu ich mich noch schwer mit der Syntax. Mein erster Ansatz sieht so aus:

Code: Alles auswählen

Items:

Group:Number:AVG                  gTemperaturDraussen                "Temperatursensor Aussenbereich [%.2f °C]"                    <temperature>         (Home)                      ["CurrentTemperature"]

Number:Temperature		Draussen_Temperatur												"openWeatherMap Temperatursensor [%.1f °C]"	<temperature>		(gTemperaturDraussen)	{channel="openweathermap:weather-and-forecast:api:local:current#temperature"}

Number:Temperature		LokalesWetterMitVorhersageCurrentTemperature					"DarkSky Temperatursensor [%.1f °C]"		<temperature>		(gTemperaturDraussen)	{channel="darksky:weather-and-forecast:api:local:current#temperature"}

String					Aussentemperatur_Tendenz										"Temperatur Tendenz [%s]"					<temperature>

Das item Außentemperatur_Tendenz wird in der influxdb persistiert.

Mein erster rule Ansatz sieht so aus:

Code: Alles auswählen


rule "Aussentemperatur Tendenz ermitteln"
when
    Item gTemperaturDraussen changed
then
    if((gTemperaturDraussen.state as Number) >= (gTemperaturDraussen.previousState().state as Number)){
        Aussentemperatur_Tendenz.postUpdate("steigend")
        logInfo("Aussentemperatur", "steigt")
    }
    else if((gTemperaturDraussen.state as Number) == (gTemperaturDraussen.previousState().state as Number)){
        Aussentemperatur_Tendenz.postUpdate("stagnierend")
        logInfo("Aussentemperatur", "stagniert")
    }
    else if((gTemperaturDraussen.state as Number) <= (gTemperaturDraussen.previousState().state as Number)){
        Aussentemperatur_Tendenz.postUpdate("fallend")
        logInfo("Aussentemperatur", "fällt")
    }
end

Jetzt wird aber bei jeder Wertänderung immer nur die Tendenz steigend ermittelt. Mir ist auch klar das man für die Tendenzermittlung einen Zeitraum beobachten sollte, da es ja sonst zu einem Hin- und Her kommen könnte. Vielen Dank schon mal im voraus für eure Ideen.

Re: Temperatur Tendenz ermitteln

Verfasst: 12. Aug 2020 08:20
von violine21
Ersetze mal die Vergleichsoperation >= und <= durch > und <. Dadurch grenzen sich die Bedingungen voneinander ab.
Warum hast Du die Temperaturen zweier Anbieter in einer Gruppe zusammengefasst?
Bekommst Du von beiden immer identische Werte geliefert? Ich würde nur den Temperaturwert eines Anbieters verwenden.

Re: Temperatur Tendenz ermitteln

Verfasst: 12. Aug 2020 08:24
von KellerK1nd
Das mit < und > hab ich schon probiert, da passiert gar nix.

Ich hab die in einer Gruppe um einen Mittelwert zu haben, und als Redundanz, falls ein Anbieter mal keine Werte liefert.

Re: Temperatur Tendenz ermitteln

Verfasst: 12. Aug 2020 14:03
von violine21
Ich habs mal in einer Rule nachgestellt:

Code: Alles auswählen

rule "Aussentemperatur Tendenz ermitteln"
when
    Item Wetterstation1ACTUALTEMPERATURE changed or
    Time cron "0 * * * * ?"// jede Minute
then
    if((Wetterstation1ACTUALTEMPERATURE.state as Number).floatValue > (Wetterstation1ACTUALTEMPERATURE.previousState().state as Number).floatValue){
        logInfo("Aussentemperatur", "steigt")
    }
    if((Wetterstation1ACTUALTEMPERATURE.state as Number).floatValue == (Wetterstation1ACTUALTEMPERATURE.previousState().state as Number).floatValue){
        logInfo("Aussentemperatur", "stagniert")
    }
    if((Wetterstation1ACTUALTEMPERATURE.state as Number).floatValue < (Wetterstation1ACTUALTEMPERATURE.previousState().state as Number).floatValue){
        logInfo("Aussentemperatur", "fällt")
    }
end
Habe noch einen minütlichen Trigger dazu genommen, damit ich nicht so lange warten muss. Es funktioniert.

Code: Alles auswählen

2020-08-12 14:01:00.062 [INFO ] [rthome.model.script.Aussentemperatur] - stagniert
Da ja reine Zahlen verglichen werden, entferne ich immer die Einheit (UoM) mit

Code: Alles auswählen

.floatValue

Re: Temperatur Tendenz ermitteln

Verfasst: 12. Aug 2020 18:53
von KellerK1nd
Auf den Trigger Time cron funktioniert die Regels tatsächlich so wie ich sie geschrieben habe, aber warum nicht auf den Wechsel des Gruppenzustands? Auch funktioniert es jetzt auch mit dem größer und kleiner als ohne "=".

Code: Alles auswählen

2020-08-12 18:33:27.734 [vent.ItemStateChangedEvent] - Aussentemperatur_Tendenz changed from fallend to stagnierend

2020-08-12 18:35:25.553 [vent.ItemStateChangedEvent] - Aussentemperatur_Tendenz changed from stagnierend to fallend

2020-08-12 18:36:00.003 [vent.ItemStateChangedEvent] - Aussentemperatur_Tendenz changed from fallend to stagnierend

2020-08-12 18:36:53.740 [vent.ItemStateChangedEvent] - Aussentemperatur_Tendenz changed from stagnierend to steigend

2020-08-12 18:37:00.002 [vent.ItemStateChangedEvent] - Aussentemperatur_Tendenz changed from steigend to stagnierend

2020-08-12 18:37:26.003 [vent.ItemStateChangedEvent] - Aussentemperatur_Tendenz changed from stagnierend to fallend

2020-08-12 18:38:00.002 [vent.ItemStateChangedEvent] - Aussentemperatur_Tendenz changed from fallend to stagnierend
Die minütlichen Ereignisse sind ja die, die auf den Time cron reagieren, die anderen auf den Item Change. Vielleicht war ich zu ungeduldig.. ^^ Wie könnte man die Regel jetzt ändern, neu schreiben, wenn man sage ich mal die letzte 15 Minuten überwachen will. deltaSince(now minus 15 Minutes), also so was in der Art.

Eventuell so?:

Code: Alles auswählen

rule "Aussentemperatur Tendenz ermitteln"
when
    Item gTemperaturDraussen changed
then
    var Number gTemperaturDraussenTendenz = gTemperaturDraussen.deltaSince(now.minusMinutes(15)) as Number

    if((gTemperaturDraussen.state as Number) > (gTemperaturDraussenTendenz.state as Number)){
        if(Aussentemperatur_Tendenz.state.toString !="steigend"){
            Aussentemperatur_Tendenz.postUpdate("steigend")
            logInfo("Aussentemperatur", "steigt")
        }
    }
    else if((gTemperaturDraussen.state as Number) == (gTemperaturDraussenTendenz.state as Number)){
        if(Aussentemperatur_Tendenz.state.toString !="stagnierend"){
            Aussentemperatur_Tendenz.postUpdate("stagnierend")
            logInfo("Aussentemperatur", "stagniert")
        }
    }
    else if((gTemperaturDraussen.state as Number) < (gTemperaturDraussenTendenz.state as Number)){
        if(Aussentemperatur_Tendenz.state.toString !="fallend"){
            Aussentemperatur_Tendenz.postUpdate("fallend")
            logInfo("Aussentemperatur", "fällt")
        }
    }
end


Re: Temperatur Tendenz ermitteln

Verfasst: 13. Aug 2020 00:51
von violine21
KellerK1nd hat geschrieben: 12. Aug 2020 18:53 Wie könnte man die Regel jetzt ändern, neu schreiben, wenn man sage ich mal die letzte 15 Minuten überwachen will. deltaSince(now minus 15 Minutes), also so was in der Art.
In dem Fall würde ich die Rule nur per Time-Cron alle 15 Minuten triggern.
Dazu noch ein zusätzliches Proxy-Item, in dem die Temperatur am Ende der Regel gespeichert wird, nachdem die Vergleiche stattfanden.
Am Beispiel meines Codes:

Code: Alles auswählen

rule "Aussentemperatur Tendenz ermitteln"
when
    Time cron "0 0/15/30/45 * * *  ?"// jede 15. Minute
then
    if((Wetterstation1ACTUALTEMPERATURE.state as Number).floatValue > (letzte_Temperatur.state){
        logInfo("Aussentemperatur", "steigt")
    }
    if((Wetterstation1ACTUALTEMPERATURE.state as Number).floatValue == (letzte_Temperatur.state){
        logInfo("Aussentemperatur", "stagniert")
    }
    if((Wetterstation1ACTUALTEMPERATURE.state as Number).floatValue < (letzte_Temperatur.state){
        logInfo("Aussentemperatur", "fällt")
    }
   letzte_Temperatur.postUpdate((Wetterstation1ACTUALTEMPERATURE.state as Number).floatValue) 
end
Das Item

Code: Alles auswählen

letzte_Temperatur
ist vom Typ Number, darum ist es wichtig, die Einheiten (UoM) zu entfernen,
falls Dein Item eine Einheit liefert.
Dazu benötigst Du dann keine Persistenz und keinen Timer.
Im 1. Durchlauf wird allerdings erst das Proxy-Item beschrieben, da funktionieren die Vergleichsoperationen noch nicht.

Re: Temperatur Tendenz ermitteln

Verfasst: 13. Aug 2020 04:34
von udo1toni
Der Time cron Ausdruck ist verkehrt :)

Entweder eine Frequenz mit Startwert, das wäre 0/15 für "jeder 15te Wert, beginnend mit 0" oder eine Auflistung der Werte (die dann aber kommasepariert) 0,15,30,45. also so:

Code: Alles auswählen

Time cron "0 0,15,30,45 * * * ?"// zur Viertelstunde
Time cron "0 0/15 * * *  ?"// zur Viertelstunde
Beide Schreibweisen funktionieren, und bei beiden Varianten kann man den Zeitpunkt auch über die Viertelstunde verschieben (z.B. wenn man schon andere Rules hat, die ebenfalls zur vollen Viertelstunde laufen):

Code: Alles auswählen

Time cron "0 2,17,32,47 * * * ?"// Zwei Minuten nach der Viertelstunde
Time cron "0 2/15 * * *  ?"// Zwei Minuten nach der Viertelstunde
Man sollte immer daran denken, dass openHAB nur eine begrenzte Anzahl Threads zur Ausführung von Rules zur Verfügung hat. Die Threads erlauben das parallele Abarbeiten der Rules, aber sie benötigen auch dann Speicher und (ein wenig) Rechenzeit, wenn gerade keine Rule läuft, entsprechend gibt es default 5 + 2 Threads für Rules, fünf für normale eventgetriggerte Rules, zwei weitere für vom Scheduler ausgeführte Rules (Time cron und createTimer).
Evtl. wurde gerade der letzte Wert etwas nach oben angepasst.
Der Punkt ist aber, man sollte vermeiden, viele Rules zeitgleich zu triggern, und bei solchen zeitlich geplanten Rules ist das vergleichsweise leicht möglich.

Re: Temperatur Tendenz ermitteln

Verfasst: 13. Aug 2020 07:49
von PeterA
Weshalb triggerst Du nicht auf ein Changed der Betreffenden Items direkt ?

Ich hab auch viele Sensoren in AVG Gruppen und meine gesehen zu haben das die Gruppe ab und zu NICHT Changed auch
wenn sich ein Item aus der Gruppe ändert.

Ich versuche das mal bei Gelegenheit hier zu Implementieren.

Gruß Peter

Re: Temperatur Tendenz ermitteln

Verfasst: 13. Aug 2020 07:58
von KellerK1nd
Letzten Endes ändert sich doch der Wert der Gruppe sowieso. Ich will eigentlich gar nicht die Time cron nutzen, das war ja nur versuchshalber. Ich würde ja gerne den Status nur schreiben, wenn sich in den letzten 15 Minuten der Wert geändert hat. Daher versuche ich mich momentan mit dem deltaSince, aber ich finde nicht die passende Lösung.

Re: Temperatur Tendenz ermitteln

Verfasst: 13. Aug 2020 08:05
von violine21
udo1toni hat geschrieben: 13. Aug 2020 04:34 Der Time cron Ausdruck ist verkehrt :)
Danke Udo für den Hinweis! Ich habe es in meinen Rules tatsächlich richtig.
Ich bevorzuge diese Schreibweise:

Code: Alles auswählen

Time cron "0 0,15,30,45 * * * ?"// zur Viertelstunde
udo1toni hat geschrieben: 13. Aug 2020 04:34 Der Punkt ist aber, man sollte vermeiden, viele Rules zeitgleich zu triggern, und bei solchen zeitlich geplanten Rules ist das vergleichsweise leicht möglich.
Das habe ich bei meinen zeitgetriggerten Rules insofern beachtet, das ich den Wert der Sekunde bei jeder Rule unterschiedlich lege.
Mir ist ja egal, ob nun z.B. 14:00:00 oder 14:00:05 die Rule ausgeführt wird.
udo1toni hat geschrieben: 13. Aug 2020 04:34aber sie benötigen auch dann Speicher und (ein wenig) Rechenzeit, wenn gerade keine Rule läuft
Ist das ein Ernst zu nehmender Fakt?