Hallo,
ich bekomme hochsporadisch (ca. 2-4 x jährlich) sehr viele Fehler ins Log, jedoch nur immer für einige Stunden, bis die Sonne wieder die PV-Module bescheint. Ursache hierfür ist eine Division durch null, bei Berechnung des Userreadings, aber ich kann keinen Fehler in meiner Berechnung erkennen. Sollte die Formel grundsätzlich falsch aufgebaut sein, weshalb tritt dann der Fehler nicht viel häufiger auf.
Es wäre nett, ihr werft mal einen Blick über meine Berechnungsformel, ob euch da was auffällt. Vorschläge über den kompletten Umbau der Berechnung sowie Tipps zur Fehlereingrenzung sind gerne Willkommen.
Autarkiequote_Tag_aktuell {
if (ReadingsNum($name,"PV_Erzeugung_Tag_aktuell",0) > 0) {sprintf("%.0f",
(ReadingsNum($name,"PV_Erzeugung_Tag_aktuell",0) - ReadingsNum($name,"Netzeinspeisung_Tag_aktuell",0)) / (ReadingsNum($name,"PV_Erzeugung_Tag_aktuell",0) - ReadingsNum($name,"Netzeinspeisung_Tag_aktuell",0) + ReadingsNum($name,"Netzbezug_Tag_aktuell",0)) * 100)
} else {return 0}
}
Gesicherte Erkenntnisse:
Fehler tritt nur morgens (vor Sonnenaufgang), für einige Stunden, mit sehr vielen Meldungen im Log auf.
2021.06.02 05:45:31 1: Error evaluating du_Statistik_Hauskraftwerk userReading Autarkiequote_Tag_aktuell: Illegal division by zero at (eval 64010538) line 2.
Während des Fehlers ändern sich die beteiligten Werte nur im Nachkommabereich, wegen eines vorhandenen Stromspeichers.
Die Werte beziehe ich vom Stromspeicher direkt über Modbus (als aufsteigende Zählerwerte), schreibe diese in eine DbLog SQL-Datenbank und berechne die Differenz der Tageswerte mit "diffValue" über ein DbRep Device.
Anbei noch das List vom dummy, bei welchem der Fehler auftritt:
Internals:
FUUID 5ff9f311-f33f-7df9-b8a8-811b9c88f8f683bb
NAME du_Statistik_Hauskraftwerk
NR 420
STATE 0
TYPE dummy
Helper:
DBLOG:
Autarkiequote_Monat_vergangen:
DBLogging:
TIME 1622498440.02659
VALUE 99
Autarkiequote_Tag_vergangen:
DBLogging:
TIME 1622671220.02597
VALUE 99
Eigenverbrauchsquote_Monat_vergangen:
DBLogging:
TIME 1622498440.04447
VALUE 32
Eigenverbrauchsquote_Tag_vergangen:
DBLogging:
TIME 1622671220.05297
VALUE 19
Hausverbrauch_Monat_vergangen:
DBLogging:
TIME 1622498519.57491
VALUE 362.02
Hausverbrauch_Tag_vergangen:
DBLogging:
TIME 1622671225.36373
VALUE 11.40
Netzbezug_Monat_vergangen:
DBLogging:
TIME 1622498510.46974
VALUE 3.57
Netzbezug_Tag_vergangen:
DBLogging:
TIME 1622671224.95918
VALUE 0.07
Netzeinspeisung_Monat_vergangen:
DBLogging:
TIME 1622498508.74135
VALUE 786.57
Netzeinspeisung_Tag_vergangen:
DBLogging:
TIME 1622671224.81022
VALUE 49.98
PV_Erzeugung_Monat_vergangen:
DBLogging:
TIME 1622498490.89525
VALUE 1159.81
PV_Erzeugung_Tag_vergangen:
DBLogging:
TIME 1622671223.87431
VALUE 61.50
READINGS:
2021-06-03 10:09:19 Autarkiequote_Jahr_aktuell 83
2021-01-20 12:59:03 Autarkiequote_Jahr_vergangen 91
2021-06-03 10:09:19 Autarkiequote_Monat_aktuell 99
2021-06-01 00:00:40 Autarkiequote_Monat_vergangen 99
2021-06-03 10:09:19 Autarkiequote_Tag_aktuell 99
2021-06-03 00:00:20 Autarkiequote_Tag_vergangen 99
2021-06-03 10:09:19 Autarkiequote_moment 100
2021-06-03 10:09:19 Eigenverbrauchsquote_Jahr_aktuell 34
2021-01-20 13:00:36 Eigenverbrauchsquote_Jahr_vergangen 32
2021-06-03 10:09:19 Eigenverbrauchsquote_Monat_aktuell 22
2021-06-01 00:00:40 Eigenverbrauchsquote_Monat_vergangen 32
2021-06-03 10:09:19 Eigenverbrauchsquote_Tag_aktuell 98
2021-06-03 00:00:20 Eigenverbrauchsquote_Tag_vergangen 19
2021-06-03 10:09:19 Eigenverbrauchsquote_moment 83
2021-06-03 10:08:46 Hausverbrauch_Jahr_aktuell 1536.30
2021-01-17 19:17:26 Hausverbrauch_Jahr_vergangen 2613.40
2021-06-03 10:02:38 Hausverbrauch_Monat_aktuell 27.58
2021-06-01 00:01:59 Hausverbrauch_Monat_vergangen 362.02
2021-06-03 10:00:32 Hausverbrauch_Tag_aktuell 4.33
2021-06-03 00:00:25 Hausverbrauch_Tag_vergangen 11.40
2021-06-03 10:09:19 Hausverbrauch_moment 539
2021-06-03 10:08:36 Netzbezug_Jahr_aktuell 270.89
2021-01-17 19:17:23 Netzbezug_Jahr_vergangen 251.51
2021-06-03 10:02:37 Netzbezug_Monat_aktuell 0.16
2021-06-01 00:01:50 Netzbezug_Monat_vergangen 3.57
2021-06-03 10:00:32 Netzbezug_Tag_aktuell 0.05
2021-06-03 00:00:24 Netzbezug_Tag_vergangen 0.07
2021-06-03 10:09:19 Netzbezug_moment 0
2021-06-03 10:08:33 Netzeinspeisung_Jahr_aktuell 2606.60
2021-01-17 19:17:20 Netzeinspeisung_Jahr_vergangen 5243.39
2021-06-03 10:02:37 Netzeinspeisung_Monat_aktuell 101.91
2021-06-01 00:01:48 Netzeinspeisung_Monat_vergangen 786.57
2021-06-03 10:00:32 Netzeinspeisung_Tag_aktuell 0.10
2021-06-03 00:00:24 Netzeinspeisung_Tag_vergangen 49.98
2021-06-03 10:09:19 Netzeinspeisung_moment 682
2021-06-03 10:09:19 PV-Erzeugung_moment 4083
2021-06-03 10:08:14 PV_Erzeugung_Jahr_aktuell 3922.26
2021-01-17 19:17:18 PV_Erzeugung_Jahr_vergangen 7685.32
2021-06-03 10:02:35 PV_Erzeugung_Monat_aktuell 131.17
2021-06-01 00:01:30 PV_Erzeugung_Monat_vergangen 1159.81
2021-06-03 10:00:32 PV_Erzeugung_Tag_aktuell 4.82
2021-06-03 00:00:23 PV_Erzeugung_Tag_vergangen 61.50
Attributes:
DbLogExclude .*
DbLogInclude .*_vergangen
comment Dieses dummy wird zur Speicherung aller Werte des E3DC Hauskraftwerks verwendet. Zusätzlich werden noch die Werte des letzten Tags, Monats und Jahrs in die DbLog Datenbank, jeweils am Ende des Zeitabschnitts geschrieben.
Dieses dummy wird über "99_myUtils.pm" und mit dem notify "no_E3DC_Momentanwerte_schreiben" mit Werten beschrieben.
event-on-change-reading .*
event-on-update-reading .*_vergangen
group Hauskraftwerk
icon measure_power_meter@green
room Hauskraftwerk
userReadings Autarkiequote_Tag_aktuell {
if (ReadingsNum($name,"PV_Erzeugung_Tag_aktuell",0) > 0) {sprintf("%.0f",
(ReadingsNum($name,"PV_Erzeugung_Tag_aktuell",0) - ReadingsNum($name,"Netzeinspeisung_Tag_aktuell",0)) / (ReadingsNum($name,"PV_Erzeugung_Tag_aktuell",0) - ReadingsNum($name,"Netzeinspeisung_Tag_aktuell",0) + ReadingsNum($name,"Netzbezug_Tag_aktuell",0)) * 100)
} else {return 0}
},
Eigenverbrauchsquote_Tag_aktuell {
if (ReadingsNum($name,"PV_Erzeugung_Tag_aktuell",0) > 0) {sprintf("%.0f",
(ReadingsNum($name,"PV_Erzeugung_Tag_aktuell",0) - ReadingsNum($name,"Netzeinspeisung_Tag_aktuell",0)) / ReadingsNum($name,"PV_Erzeugung_Tag_aktuell",0) * 100)
} else {return 0}
},
Autarkiequote_Monat_aktuell {
if (ReadingsNum($name,"PV_Erzeugung_Monat_aktuell",0) > 0) {sprintf("%.0f",
(ReadingsNum($name,"PV_Erzeugung_Monat_aktuell",0) - ReadingsNum($name,"Netzeinspeisung_Monat_aktuell",0)) / (ReadingsNum($name,"PV_Erzeugung_Monat_aktuell",0) - ReadingsNum($name,"Netzeinspeisung_Monat_aktuell",0) + ReadingsNum($name,"Netzbezug_Monat_aktuell",0)) * 100)
} else {return 0}
},
Eigenverbrauchsquote_Monat_aktuell {
if (ReadingsNum($name,"PV_Erzeugung_Monat_aktuell",0) > 0) {sprintf("%.0f",
(ReadingsNum($name,"PV_Erzeugung_Monat_aktuell",0) - ReadingsNum($name,"Netzeinspeisung_Monat_aktuell",0)) / ReadingsNum($name,"PV_Erzeugung_Monat_aktuell",0) * 100)
} else {return 0}
},
Autarkiequote_Jahr_aktuell {
if (ReadingsNum($name,"PV_Erzeugung_Jahr_aktuell",0) > 0) {sprintf("%.0f",
(ReadingsNum($name,"PV_Erzeugung_Jahr_aktuell",0) - ReadingsNum($name,"Netzeinspeisung_Jahr_aktuell",0)) / (ReadingsNum($name,"PV_Erzeugung_Jahr_aktuell",0) - ReadingsNum($name,"Netzeinspeisung_Jahr_aktuell",0) + ReadingsNum($name,"Netzbezug_Jahr_aktuell",0)) * 100)
} else {return 0}
},
Eigenverbrauchsquote_Jahr_aktuell {
if (ReadingsNum($name,"PV_Erzeugung_Jahr_aktuell",0) > 0) {sprintf("%.0f",
(ReadingsNum($name,"PV_Erzeugung_Jahr_aktuell",0) - ReadingsNum($name,"Netzeinspeisung_Jahr_aktuell",0)) / ReadingsNum($name,"PV_Erzeugung_Jahr_aktuell",0) * 100)
} else {return 0}
}
Vielen Dank für eure Mühe
Gruß Reinhard
Hallo Reinhard,
naja wenn dieser Teilausdruck null wird, muss der Fehler auftreten.
(ReadingsNum($name,"PV_Erzeugung_Tag_aktuell",0) - ReadingsNum($name,"Netzeinspeisung_Tag_aktuell",0) + ReadingsNum($name,"Netzbezug_Tag_aktuell",0))
Einfachste Annahme: die readings sind alle nicht vorhanden/lesbar - warum auch immer - dann tritt Dein Defaultwert 0 in Aktion -> 0-0+0=0
Nimm nicht null sondern 999 :)
Der größte "Fehler" oder eher Sünde ist, dass Du keinen trigger gewählt hast z.B. so: Autarkiequote_Tag_aktuell:PV_Erzeugung_Tag_aktuell:.*
Damit wird die Berechnung bei jeder Änderung im Device ausgeführt, was im einfachsten Fall die Last erhöht, aber vielleicht auch zu diesen Fehlern führt weil einzelne Readings gerade gelöscht wurden?
Dies solltest Du bei allen Userreadings ergänzen!
Gruß Otto
Hallo Otto,
vielen Dank für deine schnelle Antwort, bei mir hat die Reaktion ein wenig gedauert, weil ich aktuell mit der Kabelverlegung für meine Wallbox gebunden war.
Du hast natürlich absolut Recht, einen Trigger bei den UserReadins zu verwenden macht absolut Sinn, denn damit wird kann ich meine Systemlast deutlich vermindern und die besagten Fehler kommen nicht mehr so häufig.
Was ich noch nicht verstanden habe ist dein Vorschlag:
ZitatNimm nicht null sondern 999
Würde es denn nicht meine Berechnungen verfälschen, wenn ich einfach den "Ersatzwert" 999 (oder einen anderen Wert) verwende, wenn ich aktuell keinen Wert lesen kann?
Ich dachte bisher, wenn ich den Wert, welcher als Teiler verwendet wird mit if
> 0 abfrage, so sollte eine Division durch 0 vermieden werden. Somit kann ich doch dann auch den "Ersatztwert" mit 0 übergeben, spätestens die if Abfrage sollte doch dann die Berechnung überspringen und einfach nur 0 zurückgeben.
Autarkiequote_Tag_aktuell:PV_Erzeugung_Tag_aktuell:.* {
if (ReadingsNum($name,"PV_Erzeugung_Tag_aktuell",0) > 0) {sprintf("%.0f",
(ReadingsNum($name,"PV_Erzeugung_Tag_aktuell",0) - ReadingsNum($name,"Netzeinspeisung_Tag_aktuell",0)) / (ReadingsNum($name,"PV_Erzeugung_Tag_aktuell",0) - ReadingsNum($name,"Netzeinspeisung_Tag_aktuell",0) + ReadingsNum($name,"Netzbezug_Tag_aktuell",0)) * 100)
} else {return 0}
}
Kann es sein, dass ich da noch etwas übersehe oder falsch verstehe?
Gruß Reinhard
Du hast drei Werte deren Summe 0 sein kann. Nur einen abzufragen führt ja offenbar nicht zum Ziel.
0 als Ersatzwert führt zu dem Fehler, ein anderer Ersatz führt zu einem falschen Ergebnis.
Exakterer Vorschlag:
my $zwischensumme = ReadingsNum($name,"PV_Erzeugung_Tag_aktuell",0) - ReadingsNum($name,"Netzeinspeisung_Tag_aktuell",0) + ReadingsNum($name,"Netzbezug_Tag_aktuell",0);
if ($zwischensumme) {sprintf("%.0f",
(ReadingsNum($name,"PV_Erzeugung_Tag_aktuell",0) - ReadingsNum($name,"Netzeinspeisung_Tag_aktuell",0)) / $zwischensumme * 100)}
Hinweis if (0) währe nicht wahr und damit die Verhinderung Division durch 0 erfüllt, jede andere $zwischensumme ergibt wahr. Du brauchst also keinen weiteren Test.
Gruß Otto
Hallo Otto,
danke für den Denkanstoß.
Ich stelle meine Berechnung so wie von dir vorgeschlagen um.
Zum Glück gibt es immer mehrere Wege ein Ziel zu erreichen ;).
Nochmals Danke für die Hilfe
Gruß Reinhard