Stromverbrauch für Tag, Woche, Monat, Jahr berechnen

Für welche Projekte verwendet Ihr OpenHAB? Was habt Ihr automatisiert? Stellt eure Projekte hier vor.

Moderatoren: Cyrelian, seppy

Antworten
Benutzeravatar
KellerK1nd
Beiträge: 432
Registriert: 17. Jun 2019 16:45
Answers: 1
Wohnort: Griesheim

Re: Stromverbrauch für Tag, Woche, Monat, Jahr berechnen

Beitrag von KellerK1nd »

Servus,

Ich hänge mich mal hier an. Habe jetzt seit knapp 5 Tagen ein BKW am Laufen. Soweit so gut, Ertragserfassung mache ich mit einem ShellyEM. Mein Problem, an dem ich mir momentan die Zähne ausbeiße, die Ermittlung der täglichen Ausbeute.

Code: Alles auswählen

rule "36 BKW"
when
    Item ShellyEM_bkw_kwh changed
then
    val Daybeginn = ZonedDateTime.now().with(LocalTime.MIDNIGHT)
    var nTagErtrag = ShellyEM_bkw_kwh.deltaSince(Daybeginn, "influxdb") as Number
    
    ShellyEM_bkw_max_day_kwh.postUpdate(nTagErtrag)
end
Die Items ShellyEM_bkw_kwh und ShellyEM_bkw_max_day_kwh.postUpdate werden beide in der Influxdb persistiert. Nur stimmt was nicht, denn der Ertrag ist viel zu hoch. Mir zeigt es heute 4,9kWh an. In Grafana werte ich die Daten ja auch aus, da sind es bis jetzt 460Wh... Wo liegt denn da der Fehler.

Werte in Grafana:
Bild

Werte in VSC:
Bild
Betriebssystem: Proxmox 7.3-4
openHAB Container: debian11 LXC
openHAB Version: 3.4
Hardware: HomeServer Eigenbau mit einem Intel i5 9600K
Smarthome-Equipment:
- Rasperrymatic
- deConz
- HUE
- Shellys
- Mosquitto
- AVM Fritz!Box

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

Re: Stromverbrauch für Tag, Woche, Monat, Jahr berechnen

Beitrag von oh73 »

Hallo,

hab mich auch mal mit Werte aus der Datenbank abrufen beschäftigt.

was mir dabei aufgefallen ist, zumindest bei mir, die Timezone von oh und jdbc stimmt nicht immer überein!

hab mal ein paar Muster, was bei mir funktioniert.

besonders gut die Abfrage von - bis !

Code: Alles auswählen

// Strom Haus, Tag, Monat, 
rule "Stromverbrauch Haus" 

when
	Item Total_Verbrauch received update or
	Item Verbrauch changed
then
	//val dtMidnight = ZonedDateTime.now().with(LocalTime.MIDNIGHT)
	// Zeit Mitternacht um 1 Stunde verschoben
	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_Monat 	 	= Total_Verbrauch.deltaSince(dtMidnight.withDayOfMonth(1), "jdbc")  as Number
	var Number Verbrauch_Jahr 	 	= Total_Verbrauch.deltaSince(dtMidnight.withDayOfYear(1), "jdbc")  as Number

	postUpdate(Stromzaehler_Verbrauch_Tag, Verbrauch_tag)
	postUpdate(Stromz_Verbrauch_Monat, Verbrauch_Monat)
	postUpdate(Stromz_Verbrauch_Jahr, Verbrauch_Jahr)
	
// #############  von bis abfragen ################ geht ! nur beachten das Datenbank auch richtig befüllt ist!

	var von = "2023-03-31T00:00:00.000Z"
	var bis = "2023-04-30T00:00:00.000Z"
	
	// Strom Haus
	var Bereich_Strom = Total_Verbrauch.deltaBetween(ZonedDateTime.parse(von), ZonedDateTime.parse(bis))
	// Ertrag , Datenbank erst ab 2023-04-01
	var Bereich_Ertrag = inverter1TotalErtrag.deltaBetween(ZonedDateTime.parse(von), ZonedDateTime.parse(bis))
	// Verkauf, Datenbank erts ab ca 15.04.23
	var Bereich_Verkauf = Total_Verkauf.deltaBetween(ZonedDateTime.parse(von), ZonedDateTime.parse(bis))
	
	logInfo("DB_abfragen","April, Strom Total   = "+Bereich_Strom )
	logInfo("DB_abfragen","April, Ertrag Total   = "+Bereich_Ertrag )
	logInfo("DB_abfragen","April, Verkauf Total  = "+Bereich_Verkauf )
	logInfo("Uhrzeit",""+ZonedDateTime.parse(von)+" bis "+ZonedDateTime.parse(bis)) // nur Kontrolle


// ############ ein Wert von einem bestimmten Zeitpunkt abrufen ! #######

	val datum1 = "2023-04-12T00:00:00.000Z"
	var Ergebnis = Total_Verbrauch.historicState(ZonedDateTime.parse(datum1)).state
	logInfo("DB_abfragen_Test3=",""+Ergebnis )

end
OH 4.0.3 auf HP 26o G1 Dm Mini Pc mit MX_Linux

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

Re: Stromverbrauch für Tag, Woche, Monat, Jahr berechnen

Beitrag von udo1toni »

Es wäre interessant, ein paar Werte zu loggen:

Code: Alles auswählen

rule "36 BKW"
when
    Item ShellyEM_bkw_kwh changed
then
    val Daybeginn = ZonedDateTime.now().with(LocalTime.MIDNIGHT)
    var nTagErtrag = ShellyEM_bkw_kwh.deltaSince(Daybeginn, "influxdb") as Number

    val nKwhNew = ShellyEM_bkw_kwh.state
    val nKwhOld = ShellyEM_bkw_kwh.historicState(Daybeginn, "influxdb").state
    val dtOld = ShellyEM_bkw_kwh.historicState(Daybeginn, "influxdb").timestamp
    logInfo("bkw","neu: {} alt: {} von: {} delta: {}",nKwhNew,nKwhOld,dtOld,nTagErtrag)

    ShellyEM_bkw_max_day_kwh.postUpdate(nTagErtrag)
end
Die Ausgabe kann man dann in openhab.log nachlesen (falls es sich um eine openHABian Installation handelt, bequem über frontail)

Der Zeitstempel des Datensatzes wird in der Datenbank selbst erzeugt (bei jdbc ist das konfigurierbar). Wenn es also zu Inkonsistenzen kommt, so liegt das fast sicher daran, dass die Zeit in der Datenbank falsch ist.

An dieser Stelle nur als unpassende Randbemerkung: die alljährliche Zeitumstellung ist eine Pest!
Jegliche Zeitbezüge (was Abfrage und Speichern betrifft) sollten ausschließlich mit UTC ausgeführt werden.
Nur die Anzeige der Daten müsste auf die lokale Zeit umgerechnet werden.
Die Datenbank müsste intern ebenfalls fest mit UTC arbeiten.
So kann es auch nicht zu Doppelungen der Datenbankeinträge kommen (letzter Sonntag im Oktober, 2a - 3b Uhr)
Ich bin mir aber nicht sicher, ob das so in openHAB möglich ist - zumindest gibt es dafür meines Wissens keinen Parameter.
openHAB4.1.2 stable in einem Debian-Container (bookworm) (Proxmox 8.1.5, LXC), mit openHABian eingerichtet

Benutzeravatar
KellerK1nd
Beiträge: 432
Registriert: 17. Jun 2019 16:45
Answers: 1
Wohnort: Griesheim

Re: Stromverbrauch für Tag, Woche, Monat, Jahr berechnen

Beitrag von KellerK1nd »

Hier die Ausgabe des Loggers:

Code: Alles auswählen

2023-05-12 11:54:26.478 [INFO ] [org.openhab.core.model.script.bkw   ] - neu: 8.72737790 alt: 3.10058 von: 2023-05-07T14:40:21.604+02:00[Europe/Berlin] delta: 5.62679790
So wie du vermutet hast ist die Zeit das Problem.

Code: Alles auswählen

[11:56:32] root@openhab:~# timedatectl
               Local time: Fri 2023-05-12 11:56:36 CEST
           Universal time: Fri 2023-05-12 09:56:36 UTC
                 RTC time: n/a
                Time zone: Europe/Berlin (CEST, +0200)
System clock synchronized: yes
              NTP service: inactive
          RTC in local TZ: no
Persistiert werden die Items in der InfluxDB.

Code: Alles auswählen

root@InfluxDB:~# timedatectl
               Local time: Fri 2023-05-12 11:58:44 CEST
           Universal time: Fri 2023-05-12 09:58:44 UTC
                 RTC time: n/a
                Time zone: Europe/Berlin (CEST, +0200)
System clock synchronized: yes
              NTP service: inactive
          RTC in local TZ: no
In beiden Maschinen stimmt die Zeit. Wo kann ich denn weitersuchen?
Betriebssystem: Proxmox 7.3-4
openHAB Container: debian11 LXC
openHAB Version: 3.4
Hardware: HomeServer Eigenbau mit einem Intel i5 9600K
Smarthome-Equipment:
- Rasperrymatic
- deConz
- HUE
- Shellys
- Mosquitto
- AVM Fritz!Box

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

Re: Stromverbrauch für Tag, Woche, Monat, Jahr berechnen

Beitrag von udo1toni »

Das bedeutet, in der Datenbank sind keine Messwerte zwischen heute (0 Uhr) und dem 7.5. um 14:40:21 Uhr.

Zur Erklärung:
.historicState(zeitpunkt).state liefert den Status, den das Item zu dem Zeitpunkt hatte.
.historicState(Zeitpunkt).timestamp wiederum liefert den Zeitpunkt, zu dem das Item den Status angenommen hat. Dies ist fast sicher ein Zeitpunkt, der vor dem abgefragten Zeitpunkt liegt. Dass hier mehrere Tage dazwischen liegen, erklärt den viel zu hohen Messwert.

Du musst also zunächst dafür sorgen, dass jede Änderung des Items zuverlässig in die Datenbank geschrieben wird.
openHAB4.1.2 stable in einem Debian-Container (bookworm) (Proxmox 8.1.5, LXC), mit openHABian eingerichtet

Benutzeravatar
KellerK1nd
Beiträge: 432
Registriert: 17. Jun 2019 16:45
Answers: 1
Wohnort: Griesheim

Re: Stromverbrauch für Tag, Woche, Monat, Jahr berechnen

Beitrag von KellerK1nd »

Ich konnte für diese Berechnung nur ein neues Item nutzen. Komischerweise kann ich über Grafana ja die Daten des alten Items sehen. Jetzt funktioniert es, aber wie gesagt, nur mit einem neuen Item in der Datenbank. Hab es nicht hinbekommen in der Influxdb 2 das Item selbst zu löschen...
Betriebssystem: Proxmox 7.3-4
openHAB Container: debian11 LXC
openHAB Version: 3.4
Hardware: HomeServer Eigenbau mit einem Intel i5 9600K
Smarthome-Equipment:
- Rasperrymatic
- deConz
- HUE
- Shellys
- Mosquitto
- AVM Fritz!Box

TomW80
Beiträge: 69
Registriert: 7. Mai 2021 19:11
Answers: 0

Re: Stromverbrauch für Tag, Woche, Monat, Jahr berechnen

Beitrag von TomW80 »

Hallo zusammen,

ich habe die Rule von udo1toni verwendet und die funktioniert soweit auch super. Ist alles viel einfacher gehalten wie bei meinem Versuch. ;)

Jetzt habe ich das Problem dass ich zwei Werte voneinander abziehen möchte, aber immer diesen Fehler erhalte:
Script execution of rule with UID 'energie-7' failed: cannot invoke method public abstract float java.lang.Number.floatValue() on null in energie
Was mach ich falsch?
Der Fehler entsteht hier:

Code: Alles auswählen

val eigenverbrauch_Heute = erzeugung_Heute - einspeisung_Heute
Die ganze Rule sieht so aus:

Code: Alles auswählen

rule "Stromerzeugung Tag Woche Monat Jahr"                                                              // Deutscher Zeichensatz zulässig
when
    Item Meter_EnergyProduced changed                                                        // changed reicht.
then
    val ZonedDateTime zdt            = ZonedDateTime.now()                                              // jetzt
    val ZonedDateTime start_of_day   = zdt.with(LocalTime.MIDNIGHT)                                     // heute, Mitternacht
    val ZonedDateTime start_of_week  = start_of_day.minusDays(start_of_day.getDayOfWeek.getValue - 1)   // Montag 
    val ZonedDateTime start_of_month = start_of_day.withDayOfMonth(1)                                   // Erster Tag des Monats
    val ZonedDateTime start_of_year  = start_of_day.withDayOfYear(1)                                    // Erster Tag des Jahres

    val einspeisung_Heute = (Meter_EnergyProduced.deltaSince(start_of_day)   as Number).floatValue
    val einspeisung_Woche = (Meter_EnergyProduced.deltaSince(start_of_week)  as Number).floatValue
    val einspeisung_Monat = (Meter_EnergyProduced.deltaSince(start_of_month) as Number).floatValue
    val einspeisung_Jahr  = (Meter_EnergyProduced.deltaSince(start_of_year)  as Number).floatValue


    val erzeugung_Heute = (Day_Energy.deltaSince(start_of_day)   as Number).floatValue
    var eigenverbrauch_Heute = erzeugung_Heute - einspeisung_Heute

    EnergieproduktionTag.postUpdate(einspeisung_Heute)
    EnergieproduktionWoche.postUpdate(einspeisung_Woche)
    EnergieproduktionMonat.postUpdate(einspeisung_Monat)
    EnergieproduktionJahr.postUpdate(einspeisung_Jahr)

    tempEigenVerbrauch_Tag.postUpdate(eigenverbrauch_Heute)
end
Gruß Tom

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

Re: Stromverbrauch für Tag, Woche, Monat, Jahr berechnen

Beitrag von udo1toni »

Der Fehler bedeutet, dass (mindestens) eine der beiden Konstanten erzeugung_Heute und einspeisung_Heute keinen gültigen Zahlenwert enthält.

Eigentlich sollte man vor der Zuweisung immer prüfen, ob der Aufruf der Funktion einen gültigen Wert liefern wird, z.B. so:

Code: Alles auswählen

    var einspeisung_Heute = 0
    if(Meter_EnergyProduced.deltaSince(start_of_day) instanceof Number)
        einspeisung_Heute = (Meter_EnergyProduced.deltaSince(start_of_day)   as Number).floatValue
oder

Code: Alles auswählen

    val einspeisung_Woche = if(Meter_EnergyProduced.deltaSince(start_of_week) instanceof Number)
                                (Meter_EnergyProduced.deltaSince(start_of_week)  as Number).floatValue
                            else
                                0
Die erste Variante benötigt eine Variable (var), die zweite Variante kommt mit einer Konstanten (val) aus.
Die zweite Variante kann natürlich auch in einer Zeile geschrieben werden.
Auf diese Weise ist sichergestellt, dass jede der Variablen (oder Konstanten) stets einen gültigen Zahlenwert enthält. Deshalb kommt es anschließend nicht mehr zu Fehlermeldungen bei Berechnungen.
openHAB4.1.2 stable in einem Debian-Container (bookworm) (Proxmox 8.1.5, LXC), mit openHABian eingerichtet

TomW80
Beiträge: 69
Registriert: 7. Mai 2021 19:11
Answers: 0

Re: Stromverbrauch für Tag, Woche, Monat, Jahr berechnen

Beitrag von TomW80 »

udo1toni hat geschrieben: 16. Mai 2023 18:48 Der Fehler bedeutet, dass (mindestens) eine der beiden Konstanten erzeugung_Heute und einspeisung_Heute keinen gültigen Zahlenwert enthält.
Ok, dann ist die Frage warum.
udo1toni hat geschrieben: 16. Mai 2023 18:48

Code: Alles auswählen

    if(Meter_EnergyProduced.deltaSince(start_of_day) instanceof Number)
Hier erhalte ich den Fehler:
The expression of type DecimalType is already of type Number

TomW80
Beiträge: 69
Registriert: 7. Mai 2021 19:11
Answers: 0

Re: Stromverbrauch für Tag, Woche, Monat, Jahr berechnen

Beitrag von TomW80 »

Hab meinen Fehler gefunden.
Day_Energy ist ein Tageswert, anscheinend funktioniert da das deltasince nicht.

So klappt es jedenfalls:

Code: Alles auswählen

val einspeisung_Heute = (Meter_EnergyProduced.deltaSince(start_of_day)   as Number).floatValue
    val einspeisung_Woche = (Meter_EnergyProduced.deltaSince(start_of_week)  as Number).floatValue
    val einspeisung_Monat = (Meter_EnergyProduced.deltaSince(start_of_month) as Number).floatValue
    val einspeisung_Jahr  = (Meter_EnergyProduced.deltaSince(start_of_year)  as Number).floatValue

    val erzeugung_Heute = (Day_Energy.state as Number).floatValue
    val eigenverbrauch_Heute = erzeugung_Heute - einspeisung_Heute

Antworten