Energieverbrauch Monat

Einrichtung der openHAB Umgebung und allgemeine Konfigurationsthemen.

Moderatoren: seppy, udo1toni

Benutzeravatar
PeterA
Beiträge: 1106
Registriert: 8. Feb 2019 12:12
Answers: 13

Energieverbrauch Monat

Beitrag von PeterA »

Hi,

unseren neuen Stromzähler lese ich mit einem hitchi/Tasmota Lesekopf aus.
Den aktuellen Zählerstand (1.8.0) lese ich aus und persistiere ihn auch damit ich zb. mit den Tagesverbrauch anzeigen lassen kann usw.

Jetzt möchte mich mir auch den Monatsverbrauch Anzeigen lassen:

Code: Alles auswählen

hitchi_in_monat.postUpdate(hitchi_in.deltaSince(now.withDayOfMonth(1).withTimeAtStartOfDay) as Number )
Warum passiert da nichts ?

Dieser Code für den Tageswert Funktioniert:

Code: Alles auswählen

hitchi_in_heute.postUpdate(hitchi_in.deltaSince(now.withTimeAtStartOfDay) as Number )
von udo1toni » 26. Jun 2023 22:52
Ach so...
udo1toni hat geschrieben: 26. Jun 2023 20:18 ob es der richtige Wert ist, steht aber auf einem anderen Blatt.
GANZ wichtig, wenn wir von rrd4j reden... rrd4j ist eine RoundRobin Datenbank, das heißt, es überschreibt die ältesten Werte mit den neuesten Werten, um die Datenbank immer auf der gleichen Größe zu halten
Ein weiterer Punkt bei rrd4j ist aber auch, dass man auf der einen Seite eine hohe Auflösung für die letzten Werte haben möchte, auf der anderen Seite aber möglichst weit in die Vergangenheit schauen möchte. Nehmen wir an, wir speichern einen Wert pro Minute, dann sind das 60 * 24 * 365 Werte pro Jahr, also 525.600 Werte, und für jeden Wert muss ein Zeitstempel und der Wert (mindestens als Float) gespeichert werden. Ohne leistungsfähige Kompression kommen wir damit auf etwa 4 MByte pro Item, und im Grund verbietet sich eine Kompression, weil dann die Dateien ständig aus- und eingepackt werden müssen, bei jedem Speichervorgang, bei jedem Lesevorgang.
Also verfolgt rrd4j einen anderen Ansatz, und das ist Datenreduktion. Es gibt mehrere Level (genaue Werte kann man konfigurieren, der Einfachheit halber denke ich mir hier mal Werte aus), z.B. ein Wert pro Minute für die letzten 24 Stunden (1440 Werte), ein Wert pro Stunde für die letzten 2 Monate (1440 Werte bei 2 * 30 Tagen) und ein Wert pro 6 Stunden für die letzten 365 Tage (1464 Werte), macht 4344 Werte insgesamt oder etwa 34 KByte pro Item (ohne weitere Kompression).
Jetzt gibt es nur ein Problem... Welchen Wert soll rrd4j für die ausgedünnten Werte nehmen? Da gibt es verschiedene Optionen und es gibt jeweils Argumente für die Optionen, die wären:
  • erster Wert der Zeitspanne
  • letzter Wert der Zeitspanne
  • mittlerer Wert der Zeitspanne
  • Durchschnittswert der Zeitspanne
Keine Ahnung ob man das anders konfigurieren könnte (ich habe mich nicht so intensiv mit rrd4j beschäftigt), aber openHAB nutzt gewöhnlich den Durchschnittswert. Im Beispiel errechnet rrd4j also stündlich einen Durchschnittswert der letzten 60 Minuten und speichert diesen in der Stundentabelle ab, alle sechs Stunden errechnet es den Durchschnittswert der letzten 360 Minuten und speichert diesen Wert in der 6-Stunden-Tabelle ab.
Wie bei der Minutentabelle auch wird jeweils der älteste Wert gelöscht.

So. Und nun kommst Du, und möchtest den Zählerstand vom Monatsersten, 0:00 Uhr als Referenz nutzen, um den Monatsverbrauch abzulesen. Es sollte klar sein, dass sich der Zählerwert vermutlich ändert, wenn rrd4j den Wert nicht mehr aus der Minutentabelle beziehen kann, sondern die Stundentablle nutzen muss.

Unterm Strich wäre also der korrekte Weg, eine Datenbank zu verwenden, welche den Daten (wesentlich) mehr Platz einräumt.
Gehe zur vollständigen Antwort
- OpenHab 2.4
#PWRUP

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

Re: Energieverbrauch Monat

Beitrag von udo1toni »

Ich empfehle es gebetsmühlenartig ;)
Nutze Variablen. Das tut nicht weh!
Wenn Du einen Wert in einer Variablen zwischenspeicherst, kannst Du den Wert prima loggen und schauen, ob das erwartete Ergebnis vorliegt (oder auch nicht)

Seit wann schreibst Du Daten in die Persistence? Kannst Du sicher sein, dass hitchi_in für den 1.6. 0:00 Uhr einen gültigen Zählerstand hat?
Welche Persistence kommt zum Einsatz?
Wie ist die Persistence konfiguriert?
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet

oh73
Beiträge: 302
Registriert: 7. Mär 2021 14:49
Answers: 1

Re: Energieverbrauch Monat

Beitrag von oh73 »

ich hab da auch etwas länger versucht,

wichtig ist das die Datenbank richtig befüllt ist!

mein Code zum abfragen der jdbc Datenbank,

Code: Alles auswählen

	val dtMidnight = ZonedDateTime.now().with(LocalTime.now.withHour(1).withMinute(0).withSecond(0))
	Pv_Ertrag_Monat.postUpdate(inverter1TotalErtrag.deltaSince(dtMidnight.withDayOfMonth(1), "jdbc")  as Number )
andere Beispiele,

Code: Alles auswählen

	val dtMidnight = ZonedDateTime.now().with(LocalTime.now.withHour(1).withMinute(0).withSecond(0))
	var Number Verbrauch_tag 		= Total_Verbrauch.deltaSince(now.withHour(1).withMinute(0).withSecond(0), "jdbc") as Number 
//	var Number Verbrauch_ab_gestern = Total_Verbrauch.deltaSince(dtMidnight.minusDays(1), "jdbc") as Number
	var Number Verbrauch_Monat 	 	= Total_Verbrauch.deltaSince(dtMidnight.withDayOfMonth(1), "jdbc")  as Number
	var Number Verbrauch_Jahr 	 	= Total_Verbrauch.deltaSince(dtMidnight.withDayOfYear(1), "jdbc")  as Number
//	var Number Verbrauch_gestern 	= Verbrauch_ab_gestern - Verbrauch_tag
wichtig ist auch die Variable dtMidnight , hab ich auch irgend wo geklaut!
Jahresverbrauch geht bei mir auch noch nicht, weil vom Anfang des Jahres Werte fehlen!
OH 4.3.0 auf HP 26o G1 Dm Mini Pc mit MX_Linux

Benutzeravatar
PeterA
Beiträge: 1106
Registriert: 8. Feb 2019 12:12
Answers: 13

Re: Energieverbrauch Monat

Beitrag von PeterA »

Ok..
Das Item wird seit ca. Mitte Mai Persistiert. Sehe ich im Chart Widget.

So stehts in der .persist drinne für rrd4j

Code: Alles auswählen

hitchi_in   : strategy = everyMinute, everyChange, restoreOnStartup
Aber ob das genau am 1.6 00:00 einen gültigen Wert hatte kann ich natürlich nicht sagen.

Achso... OpenHab 2.4 (duck)
- OpenHab 2.4
#PWRUP

oh73
Beiträge: 302
Registriert: 7. Mär 2021 14:49
Answers: 1

Re: Energieverbrauch Monat

Beitrag von oh73 »

Aber ob das genau am 1.6 00:00 einen gültigen Wert hatte kann ich natürlich nicht sagen.
auch deshalb nehme ich die jdbc Datenbank, da kann ich den Speicherort festlegen und mit dem sqlite Browers mir auch die Datenbank anzeigen lassen!
OH 4.3.0 auf HP 26o G1 Dm Mini Pc mit MX_Linux

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

Re: Energieverbrauch Monat

Beitrag von udo1toni »

Ja, dann steht schon ein Wert zur Verfügung, wenn rrd4j seit mehr als einem Monat persistiert, dann wird es auch einen Wert für den abgefragten Moment bereitstellen - ob es der richtige Wert ist, steht aber auf einem anderen Blatt.

Lege bitte mal eine kleine Rule an, um zu sehen, was da kommt:

Code: Alles auswählen

rule "lese Wert aus"
when
    Item MySwitch received command                                         // irgend ein passender Trigger, z.B. ein Item empfängt einen Befehl
then
    val startOfMonth = now.withDayOfMonth(1).withTimeAtStartOfDay
    logInfo("getval","startOfMonth = {}",startOfMonth)

    if(!(hitchi_in.historicState(startOfMonth).state instanceof Number)) {
        logWarn("getval","hitchi_in.hitoricState.state ungültig: {}",hitchi_in.historicState(startOfMonth).state)
        return;
    }
    if(!(hitchi_in.state instanceof Number)) {
        logWarn("getval","hitchi_in.state ungültig: {}",hitchi_in.state)
        return;
    }
    val Number nStart = (hitchi_in.historicState(startOfMonth).state as Number).floatValue
    val Number nEnd   = (hitchi_in.state as Number).floatValue
    logInfo("getval","nStart = {} nEnd = {} Differenz = {}",nStart,nEnd,nEnd - nStart)
    val Number nDiff  = (hitchi_in.deltaSince(startOfMonth) as Number).floatValue
    logInfo("getval","nDiff ermittelt mit deltaSince = {}",nDiff)
end
Der Code sollte auf jeden Fall eine aufschlussreiche Ausgabe liefern, so oder so...
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet

Benutzeravatar
PeterA
Beiträge: 1106
Registriert: 8. Feb 2019 12:12
Answers: 13

Re: Energieverbrauch Monat

Beitrag von PeterA »

Das kommt dann:

Code: Alles auswählen

2023-06-26 20:29:15.254 [INFO ] [clipse.smarthome.model.script.getval] - startOfMonth = 2023-06-01T00:00:00.000+02:00

2023-06-26 20:29:15.262 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'lese Wert aus': cannot invoke method public abstract org.eclipse.smarthome.core.types.State org.eclipse.smarthome.core.persistence.HistoricItem.getState() on null
- OpenHab 2.4
#PWRUP

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

Re: Energieverbrauch Monat

Beitrag von udo1toni »

Oh. Das bedeutet, er kann von vornherein nicht auf die Historie zugreifen.
Ich hatte Dein Ausgangsposting so verstanden, dass Du schon auf historische Werte des Items zugreifst.

Was sein könnte: Deine default Persistence verweist nicht auf rrd4j (welche Du ja für die Persistence nutzt). Also kleine Änderung:

Code: Alles auswählen

rule "lese Wert aus"
when
    Item MySwitch received command                                         // irgend ein passender Trigger, z.B. ein Item empfängt einen Befehl
then
    val startOfMonth = now.withDayOfMonth(1).withTimeAtStartOfDay
    logInfo("getval","startOfMonth = {}",startOfMonth)

    if(!(hitchi_in.historicState(startOfMonth,"rrd4j").state instanceof Number)) {
        logWarn("getval","hitchi_in.hitoricState.state ungültig: {}",hitchi_in.historicState(startOfMonth,"rrd4j").state)
        return;
    }
    if(!(hitchi_in.state instanceof Number)) {
        logWarn("getval","hitchi_in.state ungültig: {}",hitchi_in.state)
        return;
    }
    val Number nStart = (hitchi_in.historicState(startOfMonth,"rrd4j").state as Number).floatValue
    val Number nEnd   = (hitchi_in.state as Number).floatValue
    logInfo("getval","nStart = {} nEnd = {} Differenz = {}",nStart,nEnd,nEnd - nStart)
    val Number nDiff  = (hitchi_in.deltaSince(startOfMonth,"rrd4j") as Number).floatValue
    logInfo("getval","nDiff ermittelt mit deltaSince = {}",nDiff)
end
Nun fragen historicState() und deltaSince() explizit rrd4j nach den Werten.
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet

Benutzeravatar
PeterA
Beiträge: 1106
Registriert: 8. Feb 2019 12:12
Answers: 13

Re: Energieverbrauch Monat

Beitrag von PeterA »

Ah ja...
Fehler gefunden!

Irrtümlicherweise hatte ich angenommen das dieses Item "hichi_in" schon länger als einen Monat persistiert wird.
Dem ist nicht so. Wird erst ab ca. Mitte diesen Monat persistiert... Habs mir im Chart noch mal angesehen.

Also werde ich wohl noch warten müssen. Denn auch die geänderte Rule wirft den selben Fehler.
- OpenHab 2.4
#PWRUP

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

Re: Energieverbrauch Monat

Beitrag von udo1toni »

Ach so...
udo1toni hat geschrieben: 26. Jun 2023 20:18 ob es der richtige Wert ist, steht aber auf einem anderen Blatt.
GANZ wichtig, wenn wir von rrd4j reden... rrd4j ist eine RoundRobin Datenbank, das heißt, es überschreibt die ältesten Werte mit den neuesten Werten, um die Datenbank immer auf der gleichen Größe zu halten
Ein weiterer Punkt bei rrd4j ist aber auch, dass man auf der einen Seite eine hohe Auflösung für die letzten Werte haben möchte, auf der anderen Seite aber möglichst weit in die Vergangenheit schauen möchte. Nehmen wir an, wir speichern einen Wert pro Minute, dann sind das 60 * 24 * 365 Werte pro Jahr, also 525.600 Werte, und für jeden Wert muss ein Zeitstempel und der Wert (mindestens als Float) gespeichert werden. Ohne leistungsfähige Kompression kommen wir damit auf etwa 4 MByte pro Item, und im Grund verbietet sich eine Kompression, weil dann die Dateien ständig aus- und eingepackt werden müssen, bei jedem Speichervorgang, bei jedem Lesevorgang.
Also verfolgt rrd4j einen anderen Ansatz, und das ist Datenreduktion. Es gibt mehrere Level (genaue Werte kann man konfigurieren, der Einfachheit halber denke ich mir hier mal Werte aus), z.B. ein Wert pro Minute für die letzten 24 Stunden (1440 Werte), ein Wert pro Stunde für die letzten 2 Monate (1440 Werte bei 2 * 30 Tagen) und ein Wert pro 6 Stunden für die letzten 365 Tage (1464 Werte), macht 4344 Werte insgesamt oder etwa 34 KByte pro Item (ohne weitere Kompression).
Jetzt gibt es nur ein Problem... Welchen Wert soll rrd4j für die ausgedünnten Werte nehmen? Da gibt es verschiedene Optionen und es gibt jeweils Argumente für die Optionen, die wären:
  • erster Wert der Zeitspanne
  • letzter Wert der Zeitspanne
  • mittlerer Wert der Zeitspanne
  • Durchschnittswert der Zeitspanne
Keine Ahnung ob man das anders konfigurieren könnte (ich habe mich nicht so intensiv mit rrd4j beschäftigt), aber openHAB nutzt gewöhnlich den Durchschnittswert. Im Beispiel errechnet rrd4j also stündlich einen Durchschnittswert der letzten 60 Minuten und speichert diesen in der Stundentabelle ab, alle sechs Stunden errechnet es den Durchschnittswert der letzten 360 Minuten und speichert diesen Wert in der 6-Stunden-Tabelle ab.
Wie bei der Minutentabelle auch wird jeweils der älteste Wert gelöscht.

So. Und nun kommst Du, und möchtest den Zählerstand vom Monatsersten, 0:00 Uhr als Referenz nutzen, um den Monatsverbrauch abzulesen. Es sollte klar sein, dass sich der Zählerwert vermutlich ändert, wenn rrd4j den Wert nicht mehr aus der Minutentabelle beziehen kann, sondern die Stundentablle nutzen muss.

Unterm Strich wäre also der korrekte Weg, eine Datenbank zu verwenden, welche den Daten (wesentlich) mehr Platz einräumt.
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet

Antworten