Problem mit der Persistence

Einrichtung der openHAB Umgebung und allgemeine Konfigurationsthemen.

Moderatoren: seppy, udo1toni

Antworten
violine21
Beiträge: 600
Registriert: 20. Sep 2019 05:49
Answers: 7

Problem mit der Persistence

Beitrag von violine21 »

Hallo,
ich wollte mir von meiner Photovoltaik-Batterie die zeitliche Reichweite der Ladung anzeigen lassen.
Dazu habe ich in der RRD4J-Persistence folgendes eingetragen:

Code: Alles auswählen

Items {
        Varta_SOC : strategy = everyChange, everyMinute, restoreOnStartup
        
}
Testweise habe ich in einer Seitemap ein Chart erzeugt, der mir die Werte anzeigt:

Code: Alles auswählen

Text item=Varta_SOC label="Batterie Ladung [%d]" {
                Frame label="Chart" {
	                 Chart item=Varta_SOC period=h
			}
		}
Nun wollte ich in einer Rule den Zeitpunkt definieren, an dem die Batterie leer ist:

Code: Alles auswählen

if ((Varta_SOC.previousState as Number > 0) && (Varta_SOC.state as Number == 0))
        {virtual_Ladungsende.sendCommand(now.toString("EEE  HH:mm")+" Uhr")}
Leider ergibt das einen Fehler:

Code: Alles auswählen

2020-02-13 09:24:10.050 [ERROR] [ntime.internal.engine.ExecuteRuleJob] - Error during the execution of rule 'VARTA_auslesen': Could not cast org.openhab.core.persistence.internal.QueryablePersistenceServiceDelegate$1@6b430e to java.lang.Number; line 50, column 10, length 33
Schreibe ich in der Rule:

Code: Alles auswählen

if (Varta_SOC.state > 0)
        {virtual_Ladungsende.sendCommand(now.toString("EEE  HH:mm")+" Uhr")}
habe ich kein Problem, nur das die Zeit mitläuft, solange die Batterie geladen ist. Das wollte ich verhindern,
indem ich genau den Übergang zu "Leer" abfange.
Wo liegt mein Fehler in dieser Zeile?

Code: Alles auswählen

if ((Varta_SOC.previousState as Number > 0) && (Varta_SOC.state as Number == 0))
Vielen Dank!
von udo1toni » 13. Feb 2020 12:59
Das Problem ist, dass Item.previousState nicht den Status zurück liefert :)
Dazu muss man sich klar machen, dass es hier zumindest zwei höchst interessante Informationen gibt, nämlich den Status und den Zeitpunkt. Entsprechend muss man also Item.previousState.state abfragen.
Keine Sorge, darüber stolpert fast jeder zu Anfang.

Im Vorteil ist, wer mal testweise den Wert loggt:

Code: Alles auswählen

logInfo("regel","Item previousState: {}",Item.previousState)
Dann sieht man plötzlich, dass hier zusätzlich zum Wert auch noch ein Zeitstempel mit ausgegeben wird.

Es ist immer eine gute Idee, zu prüfen, ob ein Wert überhaupt vom gecasteten Typ ist, also nicht einfach

Code: Alles auswählen

if((Varta_SOC.previousState.state as Number > 0) && (Varta_SOC.state as Number == 0))
sondern

Code: Alles auswählen

if(Varta_SOC.previousState.state instanceof Number && Varta_SOC.state instanceof Number)
    if((Varta_SOC.previousState.state as Number > 0) && (Varta_SOC.state as Number == 0))
Falls die Bedingung nicht zutrifft (also einer der beiden Werte nicht vom Typ Number ist) kann man dann gleich eine Fehlermeldung mittels logWarn ausgeben und die hässliche NullPointerException verhindern.
Wenn die Rule auf changed triggert, gibt es für das triggernde Item zusätzlich eine implizite Variable previousState (die hat nichts mit dem .previousState der Persistence zu tun!), diese Variable enthält dann den Wert vor dem change. In der aktuellen openHAB Version (stable, 2.5) gibt es außerdem noch newState. Wenn die Rule auf Varta_SOC changed triggert, reicht also die Zeile

Code: Alles auswählen

if(previousState > 0 && newState == 0)
Gehe zur vollständigen Antwort

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

Re: Problem mit der Persistence

Beitrag von udo1toni »

Das Problem ist, dass Item.previousState nicht den Status zurück liefert :)
Dazu muss man sich klar machen, dass es hier zumindest zwei höchst interessante Informationen gibt, nämlich den Status und den Zeitpunkt. Entsprechend muss man also Item.previousState.state abfragen.
Keine Sorge, darüber stolpert fast jeder zu Anfang.

Im Vorteil ist, wer mal testweise den Wert loggt:

Code: Alles auswählen

logInfo("regel","Item previousState: {}",Item.previousState)
Dann sieht man plötzlich, dass hier zusätzlich zum Wert auch noch ein Zeitstempel mit ausgegeben wird.

Es ist immer eine gute Idee, zu prüfen, ob ein Wert überhaupt vom gecasteten Typ ist, also nicht einfach

Code: Alles auswählen

if((Varta_SOC.previousState.state as Number > 0) && (Varta_SOC.state as Number == 0))
sondern

Code: Alles auswählen

if(Varta_SOC.previousState.state instanceof Number && Varta_SOC.state instanceof Number)
    if((Varta_SOC.previousState.state as Number > 0) && (Varta_SOC.state as Number == 0))
Falls die Bedingung nicht zutrifft (also einer der beiden Werte nicht vom Typ Number ist) kann man dann gleich eine Fehlermeldung mittels logWarn ausgeben und die hässliche NullPointerException verhindern.
Wenn die Rule auf changed triggert, gibt es für das triggernde Item zusätzlich eine implizite Variable previousState (die hat nichts mit dem .previousState der Persistence zu tun!), diese Variable enthält dann den Wert vor dem change. In der aktuellen openHAB Version (stable, 2.5) gibt es außerdem noch newState. Wenn die Rule auf Varta_SOC changed triggert, reicht also die Zeile

Code: Alles auswählen

if(previousState > 0 && newState == 0)
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet

violine21
Beiträge: 600
Registriert: 20. Sep 2019 05:49
Answers: 7

Re: Problem mit der Persistence

Beitrag von violine21 »

udo1toni hat geschrieben: 13. Feb 2020 12:59 Keine Sorge, darüber stolpert fast jeder zu Anfang.
Danke Udo für Deine aufmunternden Worte ;)

Das Item wurde von einer Zeitgetriggertem Rule mit Werten gefüllt.
Ich habe jetzt, wie von Dir vorgeschlagen, eine Rule nur für das Item Varta_SOC mit dem changed-Ereignis geschrieben.
Das funzt!!!

So ganz nebenbei hast Du noch ein anderes wichtiges Thema benannt.
Es ist immer eine gute Idee, zu prüfen, ob ein Wert überhaupt vom gecasteten Typ ist, also nicht einfach
Das hatte ich bisher in einer anderen Rule gelegentlich, konnte mir aber keinen Reim daraus machen.

Ich danke Dir für Deine ausführlichen Erklärungen!

VG André

Antworten