Moin, Damian,
auf meinen ersten Hinweis hast Du festgestellt, dass Du meine Beobachtung nicht nachstellen konntest. Da ich Deine Genauigkeit und Sorgfalt kenne (und schätze!) habe ich nun viele Monate meine Beobachtung immer wieder verifiziert:
Ich habe das als RAW angehängte Zählermodul, das eine geringfügige Anpassung Deiner Vorlage ist. Durch den Parameter 1 in einzelnen set_Reading Statements lasse ich bei der Berechnung von Strom.Zaehlerstand.day_counter,Solar.Zaehlerstand.day_counter,PV.etotal.day_counter
jeweils ein globales Event erzeugen, um das in der Datenbank (sqllite und neuerdings MariaDB) abzuspeichern und habe auch probiert es als Log wegzuschreiben.
Das funktioniert so lange perfekt, bis ich FHEM neustarte (n muss).
Nun werden auch über viele Tage hinweg diese Events nicht mehr erzeugt.
Ändere ich aber nach einem Neustart irgendein Zeichen in der Definition und speichere einmal, werden die Events wieder zuverlässig gefeuert. So kann ich das beliebig reproduzieren. Vermutlich wird beim Wegspeichern einer DEF der Parameter 1
bei einem set_Reading("$device.$reading.day_counter",ReadingsVal($device, $reading,0),1);
korrekt inititalisiert, nicht aber bei einem Neustart des FHEM?
Vielleicht gebe ich Dir dieses Mal das Ende eines roten Fadens zum Ziel?
Liebe Grüße aus dem Norden
Christian
Ich hatte damals bereits festgestellt, dass die Logik zum Monatswechsel nicht richtig funktionieren konnte, weil du die Zeit nach Mitternacht vorgezogen hast:
https://forum.fhem.de/index.php?topic=129965.msg1242389#msg1242389
Hast du das beachtet?
Du kannst dein System durchstarten und list vom Device posten, dort kann man dann sehen, ob die Timer richtig aufgesetzt sind.
Danke, Damian, dass Du darauf noch einmal einen Gedanken verwendest.
Beim Einwand "Monatswechsel" habe ich ein Verständnisproblem: Ich time doch einen Tageswechsel und den eindeutig knapp vor Mitternacht. Mein Problem tritt nicht nur beim Monatswechsel, sondern beim jeden Tageswechsel auf. Übersehe ich da was?
Hier nun das Listing direkt nach Neustart:
Internals:
.AttrList disable:0,1 loglevel:0,1,2,3,4,5,6 notexist checkReadingEvent:0,1 addStateEvent:1,0 weekdays setList:textField-long readingList DOIF_Readings:textField-long event_Readings:textField-long uiState:textField-long uiTable:textField-long event-aggregator event-min-interval event-on-change-reading event-on-update-reading oldreadings stateFormat:textField-long timestamp-on-change-reading
.FhemMetaInternals 1
DEF ## https://wiki.fhem.de/wiki/DOIF/Automatisierung#Tages-.2C_Monats-_und_Jahresstatistik_f.C3.BCr_Strom-.2C_Gas-.2C_Wasserz.C3.A4hler_und_andere_Z.C3.A4hler
subs {
## device, reading
push (@{$_counter},["Strom","Zaehlerstand"]); ## Strom-Zähler
push (@{$_counter},["Solar","Zaehlerstand"]); ## Einspeise-Zähler
push (@{$_counter},["PV","etotal"]); ## Solarzähler des PV
sub midnight { ## Diese Funktion wird um Mitternacht ausgeführt
my ($device,$reading,$mday,$yday)=@_;
set_Reading("$device.$reading.day_counter",ReadingsVal($device, $reading,0),1);
set_Reading("$device.$reading.last_day",get_Reading("$device.$reading.day",0));
set_Reading("$device.$reading.day",0);
if ($mday == 1) {
set_Reading("$device.$reading.month_counter",ReadingsVal($device, $reading,0));
set_Reading("$device.$reading.last_month",get_Reading("$device.$reading.month",0));
set_Reading("$device.$reading.month",0);
}
if ($yday == 1) {
set_Reading("$device.$reading.year_counter",ReadingsVal($device, $reading,0));
set_Reading("$device.$reading.last_year",get_Reading("$device.$reading.year",0));
set_Reading("$device.$reading.year",0);
}
}
sub init_readings {
my ($device,$reading)=@_;
if (!get_Reading("$device.$reading.day_counter","")) { ## Initialisierung der Readings
## aktuellen Zählerstand initialisieren
set_Reading ("$device.$reading.day_counter",ReadingsVal($device,$reading,0),1);
set_Reading ("$device.$reading.month_counter",ReadingsVal($device,$reading,0));
set_Reading ("$device.$reading.year_counter",ReadingsVal($device,$reading,0));
set_Reading ("$device.$reading.day",0); ## aktueller Tagesverbrauch
set_Reading ("$device.$reading.month",0); ## aktueller Monatsverbrauch
set_Reading ("$device.$reading.year",0); ## aktueller Jahresverbrauch
set_Reading ("$device.$reading.last_day",0); ## Verbrauch des letzten Tages
set_Reading ("$device.$reading.last_month",0); ## Verbrauch des letzten Monats
set_Reading ("$device.$reading.last_year",0); ## Verbrauch des letzten Jahres
}
}
} ## Ende subs-Block
mid {[23:59:58]; ## Sicherung der Daten um Mitternacht
for (my $i=0;$i<@{$_counter};$i++) {
midnight($_counter[$i][0],$_counter[$i][1],$mday,$yday); ## Für jeden Zähler wird die Funktion midnight aufgerufen
}
}
init { ## initialisierung aller Readings
for (my $i=0;$i<@{$_counter};$i++) { ## Für jeden Zähler werden Readings über die Funktion init_readings initialisiert
init_readings($_counter[$i][0],$_counter[$i][1]);
}
}
DEF TPL_stat (
day_count_$1_$2 { ## bei einem Event des Zählers, wird der tägliche, monatliche und jährliche Verbrauch im jeweiligen Reading festgehalten
## $1 Zählerdevice, $2 Zählerreading
set_Reading ("$1.$2.day",int(([$1:$2,0]-get_Reading("$1.$2.day_counter",1))*1000)/1000,1);
set_Reading ("$1.$2.month",int(([$1:$2,0]-get_Reading("$1.$2.month_counter",0))*1000)/1000);
set_Reading ("$1.$2.year",int(([$1:$2,0]-get_Reading("$1.$2.year_counter",0))*1000)/1000);
}
)
## Pro Zähler wird über eine FOR-Schleife ein day_count_<Device>_<Reading>-Block generiert
FOR(@{$_counter},TPL_stat($1$1,$1$2)) ## $1$1 entspricht dem Device, $1$2 entspricht dem Reading
FUUID 621259ad-f33f-e1df-6aad-fa75b1679f248329
FVERSION 98_DOIF.pm:0.276160/2023-05-25
MODEL Perl
NAME DI_CN_Strom
NOTIFYDEV DI_CN_Strom,global,Strom,Solar,PV
NR 264
NTFY_ORDER 50-DI_CN_Strom
STATE initialized
TYPE DOIF
VERSION 27616 2023-05-25 17:55:36
eventCount 11
.attraggr:
.attrminint:
CHANGED:
Netto: -1791.83
CHANGEDWITHSTATE:
Netto: -1791.83
DOIF_Readings:
Netto ::ReadingValDoIf($hash,'Strom','grid_power','','d')-::ReadingValDoIf($hash,'Solar','Einspeisung','','d')
Helper:
DBLOG:
Eigenverbrauch:
logdb:
TIME 1686383551.12564
VALUE 32.0970537261698
Netto:
logdb:
TIME 1686383520.46089
VALUE -1795.83
READINGS:
2023-06-10 09:46:32 .col_72_DI_CN_Strom_Netto_168_times 1685786038,1685790063,1685797540,1685812439,1685813297,1685822413,1685831293,1685843017,1685849421,1685863185,1685870090,1685878563,1685883695,1685896127,1685896968,1685910260,1685920562,1685922138,1685935831,1685947198,1685949862,1685956371,1685965334,1685972693,1685986112,1685996993,1685997848,1686013228,1686022229,1686031197,1686039566,1686040644,1686055148,1686062406,1686072101,1686073202,1686083207,1686096344,1686103059,1686108627,1686123597,1686131240,1686137058,1686148593,1686148816,1686162907,1686173831,1686176057,1686188912,1686193600,1686207599,1686213874,1686224350,1686230689,1686232802,1686249244,1686256133,1686262125,1686268183,1686280620,1686291597,1686299552,1686300029,1686311431,1686322096,1686332614,1686333766,1686342595,1686357105,1686359077,1686367821,1686383185
2023-06-10 09:46:32 .col_72_DI_CN_Strom_Netto_168_values -2426.4,-377.42,-2422.45,103.72,741,32,699,40,758,-1433.36,-2423.63,-829.08,-2417.22,2261,-150.79,937,45,108,734,-1051.5,298.11,-2423.99,892,-2412.36,884,43,1320,27,745,-548.82,-2016.95,-652.1,-2435.62,-620,785,-2.68,889.18,34.18,63.18,729.18,-1717.01,94,-2425.72,7.58999999999992,-1684.45,2184,76,778,26,828,-1213.89,159.38,-2431.46,800.41,-1973.63,144,1508,109,178,1514,-826.69,-1932.94,43.9200000000001,-2423.43,-1.76999999999998,2132,68.7,880.7,34.7,102.7,757.7,-1789.64
2023-06-10 09:52:31 Device Solar
2023-06-10 09:52:31 Eigenverbrauch 32.0970537261698
2023-06-10 09:52:33 Netto -1791.83
2023-06-09 23:59:58 PV.etotal.day 0
2023-06-09 23:59:58 PV.etotal.day_counter 4309.592
2023-06-09 23:59:58 PV.etotal.last_day 0
2023-06-01 23:59:58 PV.etotal.last_month 0
2023-01-03 07:57:15 PV.etotal.last_year 2775.648
2023-06-01 23:59:58 PV.etotal.month 0
2023-06-01 23:59:58 PV.etotal.month_counter 4121.221
2023-04-21 15:14:37 PV.etotal.year 740.913
2023-01-02 23:59:59 PV.etotal.year_counter 2701.586
2023-06-10 09:52:31 Solar.Zaehlerstand.day 1.959
2023-06-09 23:59:58 Solar.Zaehlerstand.day_counter 6224.5252
2023-06-09 23:59:58 Solar.Zaehlerstand.last_day 18.322
2023-06-01 23:59:58 Solar.Zaehlerstand.last_month 370.982
2023-01-02 23:59:59 Solar.Zaehlerstand.last_year 2156.722
2023-06-10 09:52:31 Solar.Zaehlerstand.month 142.82
2023-06-01 23:59:58 Solar.Zaehlerstand.month_counter 6083.6641
2023-06-10 09:52:31 Solar.Zaehlerstand.year 1081.755
2023-01-02 23:59:59 Solar.Zaehlerstand.year_counter 5144.7293
2022-07-16 23:59:59 Strom.Zaehlerstand 1201.755
2023-06-10 09:25:53 Strom.Zaehlerstand.day 0.586
2023-06-09 23:59:58 Strom.Zaehlerstand.day_counter 14472.2055792
2023-06-09 23:59:58 Strom.Zaehlerstand.last_day 2.703
2023-06-01 23:59:58 Strom.Zaehlerstand.last_month 67.917
2023-01-02 23:59:59 Strom.Zaehlerstand.last_year 2441.484
2023-06-10 09:25:53 Strom.Zaehlerstand.month 12.916
2023-06-01 23:59:58 Strom.Zaehlerstand.month_counter 14459.8748805
2023-06-10 09:25:53 Strom.Zaehlerstand.year 741.818
2023-01-02 23:59:59 Strom.Zaehlerstand.year_counter 13730.9737103
2023-06-10 09:52:31 block_day_count_Solar_Zaehlerstand executed
2023-06-10 09:25:53 block_day_count_Strom_Zaehlerstand executed
2023-06-10 09:47:26 block_init executed
2023-06-10 09:52:31 e_Solar_Zaehlerstand 6226.4844
2023-06-10 09:25:53 e_Strom_Zaehlerstand 14472.7918025
2023-06-10 07:32:04 mode enabled
2023-06-10 09:52:31 stat_EigenverbrauchDay Min: 0.0000000000000000 Avg: 28.0017898915363972 Max: 100.0000000000000000
2023-06-09 23:59:55 stat_EigenverbrauchDayLast Min: 0.0000000000000000 Avg: 27.7448724145243482 Max: 100.0000000000000000
2023-06-10 09:52:31 stat_EigenverbrauchHour Min: 33.1414177761784998 Avg: 39.8648872169870714 Max: 46.9190794357832033
2023-06-10 08:59:55 stat_EigenverbrauchHourLast Min: 42.1988682295877027 Avg: 55.1440225890507492 Max: 66.6139240506329031
2023-06-10 09:52:31 stat_EigenverbrauchMonth Min: 0.0000000000000000 Avg: 27.3332182222330005 Max: 100.0000000000000000
2023-05-31 23:59:55 stat_EigenverbrauchMonthLast Min: -29250.0000000000000000 Avg: 23.5134771757151206 Max: 100.0000000000000000
2023-06-10 09:52:31 stat_EigenverbrauchYear Min: -685600.0000000000000000 Avg: 9.7018591635647251 Max: 100.0000000000000000
2022-12-31 23:59:55 stat_EigenverbrauchYearLast Min: -57162.2779519331015763 Avg: 2.1586744017215755 Max: 100.0000000000000000 (since: 2022-09-11_13:48:49 )
2023-06-10 07:32:04 state initialized
2023-06-10 09:47:26 timer_01_c01 10.06.2023 23:59:58
Regex:
DOIF_Readings:
Solar:
Netto:
Einspeisung ^Solar$:^Einspeisung:
Strom:
Netto:
grid_power ^Strom$:^grid_power:
accu:
bar:
barAvg:
collect:
DI_CN_Strom:
collect:
Netto ^DI_CN_Strom$:^Netto:
cond:
PV:
4:
etotal ^PV$:^etotal:
Solar:
0:
1:
2:
3:
Zaehlerstand ^Solar$:^Zaehlerstand:
4:
Strom:
2:
Zaehlerstand ^Strom$:^Zaehlerstand:
event_Readings:
DI_CN_Strom:
Eigenverbrauch:
Solar.Zaehlerstand.day ^DI_CN_Strom$:^Solar.Zaehlerstand.day:
PV:
Eigenverbrauch:
etoday ^PV$:^etoday:
uiTable:
DI_CN_Strom:
DI_CN_Strom_uiTable_c_0_0_0_0:
Netto ^DI_CN_Strom$:^Netto:
card:
collect:
DI_CN_Strom Netto:
168:
animate 0
dim 72
hours 168
last_slot 200759
last_v 757.7
max_value 2261
max_value_slot 13
max_value_time 1685896127
min_value -2435.62
min_value_slot 32
min_value_time 1686055148
name DI_CN_Strom
reading Netto
ring 1
time 1686383553
type col
value -1791.83
times:
1685786038
1685790063
1685797540
1685812439
1685813297
1685822413
1685831293
1685843017
1685849421
1685863185
1685870090
1685878563
1685883695
1685896127
1685896968
1685910260
1685920562
1685922138
1685935831
1685947198
1685949862
1685956371
1685965334
1685972693
1685986112
1685996993
1685997848
1686013228
1686022229
1686031197
1686039566
1686040644
1686055148
1686062406
1686072101
1686073202
1686083207
1686096344
1686103059
1686108627
1686123597
1686131240
1686137058
1686148593
1686148816
1686162907
1686173831
1686176057
1686188912
1686193600
1686207599
1686213874
1686224350
1686230689
1686232802
1686249244
1686256133
1686262125
1686268183
1686280620
1686291597
1686299552
1686300029
1686311431
1686322096
1686332614
1686333766
1686342595
1686357105
1686359077
1686367821
1686383551
values:
-2426.4
-377.42
-2422.45
103.72
741
32
699
40
758
-1433.36
-2423.63
-829.08
-2417.22
2261
-150.79
937
45
108
734
-1051.5
298.11
-2423.99
892
-2412.36
884
43
1320
27
745
-548.82
-2016.95
-652.1
-2435.62
-620
785
-2.68
889.18
34.18
63.18
729.18
-1717.01
94
-2425.72
7.58999999999992
-1684.45
2184
76
778
26
828
-1213.89
159.38
-2431.46
800.41
-1973.63
144
1508
109
178
1514
-826.69
-1932.94
43.9200000000001
-2423.43
-1.76999999999998
2132
68.7
880.7
34.7
102.7
757.7
-1805.17
condition:
0 ::DOIF_time_once($hash,0,$wday); for (my $i=0;$i<@{$hash->{var}{counter}};$i++) {
midnight($hash->{var}{counter}[$i][0],$hash->{var}{counter}[$i][1],$mday,$yday); }
1 for (my $i=0;$i<@{$hash->{var}{counter}};$i++) { init_readings($hash->{var}{counter}[$i][0],$hash->{var}{counter}[$i][1]);
}
2 set_Reading ("Strom.Zaehlerstand.day",int((::ReadingValDoIf($hash,'Strom','Zaehlerstand','0')-get_Reading("Strom.Zaehlerstand.day_counter",1))*1000)/1000,1);
set_Reading ("Strom.Zaehlerstand.month",int((::ReadingValDoIf($hash,'Strom','Zaehlerstand','0')-get_Reading("Strom.Zaehlerstand.month_counter",0))*1000)/1000);
set_Reading ("Strom.Zaehlerstand.year",int((::ReadingValDoIf($hash,'Strom','Zaehlerstand','0')-get_Reading("Strom.Zaehlerstand.year_counter",0))*1000)/1000);
3 set_Reading ("Solar.Zaehlerstand.day",int((::ReadingValDoIf($hash,'Solar','Zaehlerstand','0')-get_Reading("Solar.Zaehlerstand.day_counter",1))*1000)/1000,1);
set_Reading ("Solar.Zaehlerstand.month",int((::ReadingValDoIf($hash,'Solar','Zaehlerstand','0')-get_Reading("Solar.Zaehlerstand.month_counter",0))*1000)/1000);
set_Reading ("Solar.Zaehlerstand.year",int((::ReadingValDoIf($hash,'Solar','Zaehlerstand','0')-get_Reading("Solar.Zaehlerstand.year_counter",0))*1000)/1000);
4 set_Reading ("PV.etotal.day",int((::ReadingValDoIf($hash,'PV','etotal','0')-get_Reading("PV.etotal.day_counter",1))*1000)/1000,1);
set_Reading ("PV.etotal.month",int((::ReadingValDoIf($hash,'PV','etotal','0')-get_Reading("PV.etotal.month_counter",0))*1000)/1000);
set_Reading ("PV.etotal.year",int((::ReadingValDoIf($hash,'PV','etotal','0')-get_Reading("PV.etotal.year_counter",0))*1000)/1000);
days:
defs:
tpl:
TPL_stat
day_count_$1_$2 { set_Reading ("$1.$2.day",int(([$1:$2,0]-get_Reading("$1.$2.day_counter",1))*1000)/1000,1);
set_Reading ("$1.$2.month",int(([$1:$2,0]-get_Reading("$1.$2.month_counter",0))*1000)/1000);
set_Reading ("$1.$2.year",int(([$1:$2,0]-get_Reading("$1.$2.year_counter",0))*1000)/1000);
}
event_Readings:
Eigenverbrauch 100/::ReadingValDoIf($hash,'PV','etoday')*(::ReadingValDoIf($hash,'PV','etoday')-::ReadingValDoIf($hash,'DI_CN_Strom','Solar.Zaehlerstand.day'))
helper:
NOTIFYDEV DI_CN_Strom,global,Strom,Solar,PV
_98_statistics Statistik
event Einspeisung: 1791.83
globalinit 1
last_timer 1
sleeptimer -1
triggerDev Solar
triggerEvents:
Einspeisung: 1791.83
triggerEventsState:
Einspeisung: 1791.83
internals:
intervalfunc:
localtime:
0 1686434398
perlblock:
0 mid
1 init
2 day_count_Strom_Zaehlerstand
3 day_count_Solar_Zaehlerstand
4 day_count_PV_etotal
readings:
all Strom:Zaehlerstand Solar:Zaehlerstand PV:etotal
realtime:
0 23:59:58
time:
0 23:59:58
timeCond:
0 0
timer:
0 0
timers:
0 0
trigger:
triggertime:
1686434398:
localtime 1686434398
hash:
uiState:
uiTable:
dev DI_CN_Strom
header
<table uitabid='DOIF-DI_CN_Strom' class=' block wide uiTabledoif doif-DI_CN_Strom ' style='border-top:none;'>
package package ui_Table;
reading Netto
shownodeviceline Aktuell
table:
0:
0:
0:
0 package ui_Table;::DOIF_Widget($hash,$reg,'DI_CN_Strom_uiTable_c_0_0_0_0',card(::ReadingValDoIf($hash,'DI_CN_Strom','Netto','','col1w'),undef,undef,970,1030,0,120,"Wh",[(1007,30,1019,120,1030,60)],0,'150,,,','0,0,1,8,',"50,35,45,35,50,35"),"")
tc:
td:
0:
tr:
var:
counter:
ARRAY(0x85f2c78)
ARRAY(0x85f2ba0)
ARRAY(0x85f2a50)
Attributes:
DOIF_Readings Netto:[Strom:grid_power:d]-[Solar:Einspeisung:d]
DbLogInclude Netto,Strom.Zaehlerstand.day_counter,Solar.Zaehlerstand.day_counter,PV.etotal.day_counter,Eigenverbrauch
alias DI_CN_Strom
event_Readings Eigenverbrauch:100/[PV:etoday]*([PV:etoday]-[$SELF:Solar.Zaehlerstand.day])
room Energie
uiTable {
package ui_Table;
$SHOWNODEVICELINE = "Aktuell";
}
card([$SELF:Netto:col1w],undef,undef,970,1030,0,120,"Wh",[(1007,30,1019,120,1030,60)],0,'150,,,','0,0,1,8,',"50,35,45,35,50,35")
und hier nun, nachdem ich in der DEF hinten dran ## gehängt habe. Ich behaupe mal, nach dieser Änderung werden heute kurz vor Mitternacht die drei Events gefeuert:
Internals:
.AttrList disable:0,1 loglevel:0,1,2,3,4,5,6 notexist checkReadingEvent:0,1 addStateEvent:1,0 weekdays setList:textField-long readingList DOIF_Readings:textField-long event_Readings:textField-long uiState:textField-long uiTable:textField-long event-aggregator event-min-interval event-on-change-reading event-on-update-reading oldreadings stateFormat:textField-long timestamp-on-change-reading
.FhemMetaInternals 1
DEF ## https://wiki.fhem.de/wiki/DOIF/Automatisierung#Tages-.2C_Monats-_und_Jahresstatistik_f.C3.BCr_Strom-.2C_Gas-.2C_Wasserz.C3.A4hler_und_andere_Z.C3.A4hler
subs {
## device, reading
push (@{$_counter},["Strom","Zaehlerstand"]); ## Strom-Zähler
push (@{$_counter},["Solar","Zaehlerstand"]); ## Einspeise-Zähler
push (@{$_counter},["PV","etotal"]); ## Solarzähler des PV
sub midnight { ## Diese Funktion wird um Mitternacht ausgeführt
my ($device,$reading,$mday,$yday)=@_;
set_Reading("$device.$reading.day_counter",ReadingsVal($device, $reading,0),1);
set_Reading("$device.$reading.last_day",get_Reading("$device.$reading.day",0));
set_Reading("$device.$reading.day",0);
if ($mday == 1) {
set_Reading("$device.$reading.month_counter",ReadingsVal($device, $reading,0));
set_Reading("$device.$reading.last_month",get_Reading("$device.$reading.month",0));
set_Reading("$device.$reading.month",0);
}
if ($yday == 1) {
set_Reading("$device.$reading.year_counter",ReadingsVal($device, $reading,0));
set_Reading("$device.$reading.last_year",get_Reading("$device.$reading.year",0));
set_Reading("$device.$reading.year",0);
}
}
sub init_readings {
my ($device,$reading)=@_;
if (!get_Reading("$device.$reading.day_counter","")) { ## Initialisierung der Readings
## aktuellen Zählerstand initialisieren
set_Reading ("$device.$reading.day_counter",ReadingsVal($device,$reading,0),1);
set_Reading ("$device.$reading.month_counter",ReadingsVal($device,$reading,0));
set_Reading ("$device.$reading.year_counter",ReadingsVal($device,$reading,0));
set_Reading ("$device.$reading.day",0); ## aktueller Tagesverbrauch
set_Reading ("$device.$reading.month",0); ## aktueller Monatsverbrauch
set_Reading ("$device.$reading.year",0); ## aktueller Jahresverbrauch
set_Reading ("$device.$reading.last_day",0); ## Verbrauch des letzten Tages
set_Reading ("$device.$reading.last_month",0); ## Verbrauch des letzten Monats
set_Reading ("$device.$reading.last_year",0); ## Verbrauch des letzten Jahres
}
}
} ## Ende subs-Block
mid {[23:59:58]; ## Sicherung der Daten um Mitternacht
for (my $i=0;$i<@{$_counter};$i++) {
midnight($_counter[$i][0],$_counter[$i][1],$mday,$yday); ## Für jeden Zähler wird die Funktion midnight aufgerufen
}
}
init { ## initialisierung aller Readings
for (my $i=0;$i<@{$_counter};$i++) { ## Für jeden Zähler werden Readings über die Funktion init_readings initialisiert
init_readings($_counter[$i][0],$_counter[$i][1]);
}
}
DEF TPL_stat (
day_count_$1_$2 { ## bei einem Event des Zählers, wird der tägliche, monatliche und jährliche Verbrauch im jeweiligen Reading festgehalten
## $1 Zählerdevice, $2 Zählerreading
set_Reading ("$1.$2.day",int(([$1:$2,0]-get_Reading("$1.$2.day_counter",1))*1000)/1000,1);
set_Reading ("$1.$2.month",int(([$1:$2,0]-get_Reading("$1.$2.month_counter",0))*1000)/1000);
set_Reading ("$1.$2.year",int(([$1:$2,0]-get_Reading("$1.$2.year_counter",0))*1000)/1000);
}
)
## Pro Zähler wird über eine FOR-Schleife ein day_count_<Device>_<Reading>-Block generiert
FOR(@{$_counter},TPL_stat($1$1,$1$2)) ## $1$1 entspricht dem Device, $1$2 entspricht dem Reading
##
FUUID 621259ad-f33f-e1df-6aad-fa75b1679f248329
FVERSION 98_DOIF.pm:0.276160/2023-05-25
MODEL Perl
NAME DI_CN_Strom
NOTIFYDEV PV,Solar,Strom,global,DI_CN_Strom
NR 264
NTFY_ORDER 50-DI_CN_Strom
STATE initialized
TYPE DOIF
VERSION 27616 2023-05-25 17:55:36
eventCount 20
.attraggr:
.attrminint:
CHANGED:
Netto: -1834
CHANGEDWITHSTATE:
Netto: -1834
DOIF_Readings:
Netto ::ReadingValDoIf($hash,'Strom','grid_power','','d')-::ReadingValDoIf($hash,'Solar','Einspeisung','','d')
Helper:
DBLOG:
Eigenverbrauch:
logdb:
TIME 1686383750.16964
VALUE 31.4352314352314
Netto:
logdb:
TIME 1686383714.32912
VALUE -1828.06
READINGS:
2023-06-10 09:46:32 .col_72_DI_CN_Strom_Netto_168_times 1685786038,1685790063,1685797540,1685812439,1685813297,1685822413,1685831293,1685843017,1685849421,1685863185,1685870090,1685878563,1685883695,1685896127,1685896968,1685910260,1685920562,1685922138,1685935831,1685947198,1685949862,1685956371,1685965334,1685972693,1685986112,1685996993,1685997848,1686013228,1686022229,1686031197,1686039566,1686040644,1686055148,1686062406,1686072101,1686073202,1686083207,1686096344,1686103059,1686108627,1686123597,1686131240,1686137058,1686148593,1686148816,1686162907,1686173831,1686176057,1686188912,1686193600,1686207599,1686213874,1686224350,1686230689,1686232802,1686249244,1686256133,1686262125,1686268183,1686280620,1686291597,1686299552,1686300029,1686311431,1686322096,1686332614,1686333766,1686342595,1686357105,1686359077,1686367821,1686383185
2023-06-10 09:46:32 .col_72_DI_CN_Strom_Netto_168_values -2426.4,-377.42,-2422.45,103.72,741,32,699,40,758,-1433.36,-2423.63,-829.08,-2417.22,2261,-150.79,937,45,108,734,-1051.5,298.11,-2423.99,892,-2412.36,884,43,1320,27,745,-548.82,-2016.95,-652.1,-2435.62,-620,785,-2.68,889.18,34.18,63.18,729.18,-1717.01,94,-2425.72,7.58999999999992,-1684.45,2184,76,778,26,828,-1213.89,159.38,-2431.46,800.41,-1973.63,144,1508,109,178,1514,-826.69,-1932.94,43.9200000000001,-2423.43,-1.76999999999998,2132,68.7,880.7,34.7,102.7,757.7,-1789.64
2023-06-10 09:55:50 Device Solar
2023-06-10 09:55:50 Eigenverbrauch 31.4352314352314
2023-06-10 09:55:50 Netto -1834
2023-06-09 23:59:58 PV.etotal.day 0
2023-06-09 23:59:58 PV.etotal.day_counter 4309.592
2023-06-09 23:59:58 PV.etotal.last_day 0
2023-06-01 23:59:58 PV.etotal.last_month 0
2023-01-03 07:57:15 PV.etotal.last_year 2775.648
2023-06-01 23:59:58 PV.etotal.month 0
2023-06-01 23:59:58 PV.etotal.month_counter 4121.221
2023-04-21 15:14:37 PV.etotal.year 740.913
2023-01-02 23:59:59 PV.etotal.year_counter 2701.586
2023-06-10 09:55:50 Solar.Zaehlerstand.day 2.059
2023-06-09 23:59:58 Solar.Zaehlerstand.day_counter 6224.5252
2023-06-09 23:59:58 Solar.Zaehlerstand.last_day 18.322
2023-06-01 23:59:58 Solar.Zaehlerstand.last_month 370.982
2023-01-02 23:59:59 Solar.Zaehlerstand.last_year 2156.722
2023-06-10 09:55:50 Solar.Zaehlerstand.month 142.92
2023-06-01 23:59:58 Solar.Zaehlerstand.month_counter 6083.6641
2023-06-10 09:55:50 Solar.Zaehlerstand.year 1081.855
2023-01-02 23:59:59 Solar.Zaehlerstand.year_counter 5144.7293
2022-07-16 23:59:59 Strom.Zaehlerstand 1201.755
2023-06-10 09:25:53 Strom.Zaehlerstand.day 0.586
2023-06-09 23:59:58 Strom.Zaehlerstand.day_counter 14472.2055792
2023-06-09 23:59:58 Strom.Zaehlerstand.last_day 2.703
2023-06-01 23:59:58 Strom.Zaehlerstand.last_month 67.917
2023-01-02 23:59:59 Strom.Zaehlerstand.last_year 2441.484
2023-06-10 09:25:53 Strom.Zaehlerstand.month 12.916
2023-06-01 23:59:58 Strom.Zaehlerstand.month_counter 14459.8748805
2023-06-10 09:25:53 Strom.Zaehlerstand.year 741.818
2023-01-02 23:59:59 Strom.Zaehlerstand.year_counter 13730.9737103
2023-06-10 09:55:50 block_day_count_Solar_Zaehlerstand executed
2023-06-10 09:55:14 block_init executed
2023-06-10 09:55:50 e_Solar_Zaehlerstand 6226.5848
2023-06-10 09:55:14 mode enabled
2023-06-10 09:55:50 stat_EigenverbrauchDay Min: 0.0000000000000000 Avg: 28.0356728165296722 Max: 100.0000000000000000
2023-06-09 23:59:55 stat_EigenverbrauchDayLast Min: 0.0000000000000000 Avg: 27.7448724145243482 Max: 100.0000000000000000
2023-06-10 09:55:50 stat_EigenverbrauchHour Min: 33.0027359781121987 Avg: 39.5223321097971478 Max: 46.9190794357832033
2023-06-10 08:59:55 stat_EigenverbrauchHourLast Min: 42.1988682295877027 Avg: 55.1440225890507492 Max: 66.6139240506329031
2023-06-10 09:55:50 stat_EigenverbrauchMonth Min: 0.0000000000000000 Avg: 27.3348713434157595 Max: 100.0000000000000000
2023-05-31 23:59:55 stat_EigenverbrauchMonthLast Min: -29250.0000000000000000 Avg: 23.5134771757151206 Max: 100.0000000000000000
2023-06-10 09:55:50 stat_EigenverbrauchYear Min: -685600.0000000000000000 Avg: 9.7022094319981651 Max: 100.0000000000000000
2022-12-31 23:59:55 stat_EigenverbrauchYearLast Min: -57162.2779519331015763 Avg: 2.1586744017215755 Max: 100.0000000000000000 (since: 2022-09-11_13:48:49 )
2023-06-10 09:55:14 state initialized
2023-06-10 09:55:14 timer_01_c01 10.06.2023 23:59:58
Regex:
DOIF_Readings:
Solar:
Netto:
Einspeisung ^Solar$:^Einspeisung:
Strom:
Netto:
grid_power ^Strom$:^grid_power:
accu:
bar:
barAvg:
collect:
DI_CN_Strom:
collect:
Netto ^DI_CN_Strom$:^Netto:
cond:
PV:
4:
etotal ^PV$:^etotal:
Solar:
0:
1:
2:
3:
Zaehlerstand ^Solar$:^Zaehlerstand:
4:
Strom:
2:
Zaehlerstand ^Strom$:^Zaehlerstand:
event_Readings:
DI_CN_Strom:
Eigenverbrauch:
Solar.Zaehlerstand.day ^DI_CN_Strom$:^Solar.Zaehlerstand.day:
PV:
Eigenverbrauch:
etoday ^PV$:^etoday:
uiTable:
DI_CN_Strom:
DI_CN_Strom_uiTable_c_0_0_0_0:
Netto ^DI_CN_Strom$:^Netto:
card:
collect:
DI_CN_Strom Netto:
168:
animate 0
dim 72
hours 168
last_slot 200759
last_v 757.7
max_value 2261
max_value_slot 13
max_value_time 1685896127
min_value -2435.62
min_value_slot 32
min_value_time 1686055148
name DI_CN_Strom
reading Netto
ring 1
time 1686383750
type col
value -1834
times:
1685786038
1685790063
1685797540
1685812439
1685813297
1685822413
1685831293
1685843017
1685849421
1685863185
1685870090
1685878563
1685883695
1685896127
1685896968
1685910260
1685920562
1685922138
1685935831
1685947198
1685949862
1685956371
1685965334
1685972693
1685986112
1685996993
1685997848
1686013228
1686022229
1686031197
1686039566
1686040644
1686055148
1686062406
1686072101
1686073202
1686083207
1686096344
1686103059
1686108627
1686123597
1686131240
1686137058
1686148593
1686148816
1686162907
1686173831
1686176057
1686188912
1686193600
1686207599
1686213874
1686224350
1686230689
1686232802
1686249244
1686256133
1686262125
1686268183
1686280620
1686291597
1686299552
1686300029
1686311431
1686322096
1686332614
1686333766
1686342595
1686357105
1686359077
1686367821
1686383745
values:
-2426.4
-377.42
-2422.45
103.72
741
32
699
40
758
-1433.36
-2423.63
-829.08
-2417.22
2261
-150.79
937
45
108
734
-1051.5
298.11
-2423.99
892
-2412.36
884
43
1320
27
745
-548.82
-2016.95
-652.1
-2435.62
-620
785
-2.68
889.18
34.18
63.18
729.18
-1717.01
94
-2425.72
7.58999999999992
-1684.45
2184
76
778
26
828
-1213.89
159.38
-2431.46
800.41
-1973.63
144
1508
109
178
1514
-826.69
-1932.94
43.9200000000001
-2423.43
-1.76999999999998
2132
68.7
880.7
34.7
102.7
757.7
-1836.79
condition:
0 ::DOIF_time_once($hash,0,$wday); for (my $i=0;$i<@{$hash->{var}{counter}};$i++) {
midnight($hash->{var}{counter}[$i][0],$hash->{var}{counter}[$i][1],$mday,$yday); }
1 for (my $i=0;$i<@{$hash->{var}{counter}};$i++) { init_readings($hash->{var}{counter}[$i][0],$hash->{var}{counter}[$i][1]);
}
2 set_Reading ("Strom.Zaehlerstand.day",int((::ReadingValDoIf($hash,'Strom','Zaehlerstand','0')-get_Reading("Strom.Zaehlerstand.day_counter",1))*1000)/1000,1);
set_Reading ("Strom.Zaehlerstand.month",int((::ReadingValDoIf($hash,'Strom','Zaehlerstand','0')-get_Reading("Strom.Zaehlerstand.month_counter",0))*1000)/1000);
set_Reading ("Strom.Zaehlerstand.year",int((::ReadingValDoIf($hash,'Strom','Zaehlerstand','0')-get_Reading("Strom.Zaehlerstand.year_counter",0))*1000)/1000);
3 set_Reading ("Solar.Zaehlerstand.day",int((::ReadingValDoIf($hash,'Solar','Zaehlerstand','0')-get_Reading("Solar.Zaehlerstand.day_counter",1))*1000)/1000,1);
set_Reading ("Solar.Zaehlerstand.month",int((::ReadingValDoIf($hash,'Solar','Zaehlerstand','0')-get_Reading("Solar.Zaehlerstand.month_counter",0))*1000)/1000);
set_Reading ("Solar.Zaehlerstand.year",int((::ReadingValDoIf($hash,'Solar','Zaehlerstand','0')-get_Reading("Solar.Zaehlerstand.year_counter",0))*1000)/1000);
4 set_Reading ("PV.etotal.day",int((::ReadingValDoIf($hash,'PV','etotal','0')-get_Reading("PV.etotal.day_counter",1))*1000)/1000,1);
set_Reading ("PV.etotal.month",int((::ReadingValDoIf($hash,'PV','etotal','0')-get_Reading("PV.etotal.month_counter",0))*1000)/1000);
set_Reading ("PV.etotal.year",int((::ReadingValDoIf($hash,'PV','etotal','0')-get_Reading("PV.etotal.year_counter",0))*1000)/1000);
days:
defs:
tpl:
TPL_stat
day_count_$1_$2 { set_Reading ("$1.$2.day",int(([$1:$2,0]-get_Reading("$1.$2.day_counter",1))*1000)/1000,1);
set_Reading ("$1.$2.month",int(([$1:$2,0]-get_Reading("$1.$2.month_counter",0))*1000)/1000);
set_Reading ("$1.$2.year",int(([$1:$2,0]-get_Reading("$1.$2.year_counter",0))*1000)/1000);
}
event_Readings:
Eigenverbrauch 100/::ReadingValDoIf($hash,'PV','etoday')*(::ReadingValDoIf($hash,'PV','etoday')-::ReadingValDoIf($hash,'DI_CN_Strom','Solar.Zaehlerstand.day'))
helper:
NOTIFYDEV PV,Solar,Strom,global,DI_CN_Strom
_98_statistics Statistik
event Einspeisung: 1834.00
globalinit 1
last_timer 1
sleeptimer -1
triggerDev Solar
triggerEvents:
Einspeisung: 1834.00
triggerEventsState:
Einspeisung: 1834.00
internals:
intervalfunc:
localtime:
0 1686434398
perlblock:
0 mid
1 init
2 day_count_Strom_Zaehlerstand
3 day_count_Solar_Zaehlerstand
4 day_count_PV_etotal
readings:
all Strom:Zaehlerstand Solar:Zaehlerstand PV:etotal
realtime:
0 23:59:58
time:
0 23:59:58
timeCond:
0 0
timer:
0 0
timers:
0 0
trigger:
triggertime:
1686434398:
localtime 1686434398
hash:
uiState:
uiTable:
dev DI_CN_Strom
header
<table uitabid='DOIF-DI_CN_Strom' class=' block wide uiTabledoif doif-DI_CN_Strom ' style='border-top:none;'>
package package ui_Table;
reading Netto
shownodeviceline Aktuell
table:
0:
0:
0:
0 package ui_Table;::DOIF_Widget($hash,$reg,'DI_CN_Strom_uiTable_c_0_0_0_0',card(::ReadingValDoIf($hash,'DI_CN_Strom','Netto','','col1w'),undef,undef,970,1030,0,120,"Wh",[(1007,30,1019,120,1030,60)],0,'150,,,','0,0,1,8,',"50,35,45,35,50,35"),"")
tc:
td:
0:
tr:
var:
counter:
ARRAY(0x85f2fd8)
ARRAY(0x8736310)
ARRAY(0x85f1ab8)
Attributes:
DOIF_Readings Netto:[Strom:grid_power:d]-[Solar:Einspeisung:d]
DbLogInclude Netto,Strom.Zaehlerstand.day_counter,Solar.Zaehlerstand.day_counter,PV.etotal.day_counter,Eigenverbrauch
alias DI_CN_Strom
event_Readings Eigenverbrauch:100/[PV:etoday]*([PV:etoday]-[$SELF:Solar.Zaehlerstand.day])
room Energie
uiTable {
package ui_Table;
$SHOWNODEVICELINE = "Aktuell";
}
card([$SELF:Netto:col1w],undef,undef,970,1030,0,120,"Wh",[(1007,30,1019,120,1030,60)],0,'150,,,','0,0,1,8,',"50,35,45,35,50,35")
Um Mitternacht wird ja die Funktion midnight aufgerufen:
sub midnight { ## Diese Funktion wird um Mitternacht ausgeführt
my ($device,$reading,$mday,$yday)=@_;
set_Reading("$device.$reading.day_counter",ReadingsVal($device, $reading,0),1);
set_Reading("$device.$reading.last_day",get_Reading("$device.$reading.day",0));
set_Reading("$device.$reading.day",0);
if ($mday == 1) {
set_Reading("$device.$reading.month_counter",ReadingsVal($device, $reading,0));
set_Reading("$device.$reading.last_month",get_Reading("$device.$reading.month",0));
set_Reading("$device.$reading.month",0);
}
if ($yday == 1) {
...
Dort wird nach dem ersten Tag des Monats und des Jahre geschaut, da in meiner Version kurz nach Mitternacht diese Funktion aufgerufen wird, funktioniert die Abfrage $mday==1 bzw. $yday==1, bei dir ist aber noch der letzte Tag des Monats bzw. Jahres drin, damit wird das Monatsende erst einen Tag später erkannt, also am Ende des ersten Tages des Monats.
Nun zum eigentlichen Problem.
Nach den Readings zu urteilen, werden sie kurz vor Mitternacht korrekt gesetzt. Ob ein Event stattfindet oder nicht, kann man den Readings nicht ansehen.
Zum Testen würde ich die Mitternachts-Zeit auf jetzt + 2 Minuten setzen. Das System durchstarten und im Event-Monitor nach dem Start die Events beobachten.
Dann siehst du, ob sie kommen oder nicht.
Habe das Sub mid einfach händisch über den Setter gestartet:
1. direkt nach einem Neustart --- set_Reading mit dem Parameter ,1 (erzeuge Event) --- es wird kein Event erzeugt. Das Reading wird auch nicht aktualisiert!
2. Irgendeine beliebige Veränderung des Device mit modify abgespeichert, wiederum wird das Sub mid händisch über den Setter gestartet: Event mit neuem oder überschriebenem Wert wird erzeugt.
Der Zeitpunkt des Aufrufes von mid ist also unerheblich (Dein Woche-|Monatsanfangs-Thema beiseite gelassen).
An sich funktioniert eine set_Reading-Anweisung in einem Perl-DOIF wie gewünscht ohne Einschränkung durch einen Neustart - das habe ich mit einem auf die entscheidende Zeile reduzierten DOIF überprüft.
Wenn ich einen Tageszählerstand erzeuge und ihn mit einem eben diesem Datum (Nachvollziehbarkeit, Verständlichkeit) abspeichern will, muss ich das ja knapp vor Mitternacht tun. Da das Reading nach einem Neustart ohne ein Modify auch die Readings nicht schreibt/aktualisiert, kann ich mir auch nicht mit einem Timer-DOIF die Werte protokollieren.
Ich habe bei mir den selben Test durchgeführt und es werden bei mir nach dem Neustart korrekterweise Events generiert.
Ich könnte mir vorstellen, dass du evtl. ein zweites DOIF-Device mit ähnlicher Definition hast. Dieses überschreibt dir nach dem Hochfahren diese Definition.
DOIF subs liegen alle im gleichen package, subs mit gleichem Namen können sich dann überschreiben - das zuletzt geladene Device gewinnt.
Du könntest vor sub $SELF_midnight statt midnight definieren und im Block mid entsprechend den Aufruf auf $SELF_midnight anpassen, damit wird die sub-Routine eindeutig. Und wenn das funktioniert, dann kannst du den Übeltäter als Duplikat im System suchen.
Zum anderen Thema:
Wenn du vor Mitternacht mid aufrufen willst, dann musst du selbst in die Zukunft die Zeit etwas verschieben, um zu schauen, ob nach Mitternacht ein neuer Monat/Jahr anfängt.
z. B. für Jahr my $year=::strftime ('%Y', localtime()+300);;
Danke, Damian, für den Lösungsansatz "look ahead" für die Wechsel von Monaten und Jahren.
In Sachen Speichern nach einem Neustart habe ich noch keine Verbesserung erzielt, die sub midnight hat jetzt einen eindeutigen Namen. Es ist bei mir auch das einzige DOIF mit dieser "Macke". Da muss ich mal weiter beobachten und suchen...
Du könntest Log-Ausgaben deinem mid-Block einbauen und schauen was da kommt:
mid {[00:01]; ## Sicherung der Daten um Mitternacht
Log3 ("$SELF",1,"bin in mid");
for (my $i=0;$i<@{$_counter};$i++) { ## Für jeden Zähler wird die Funktion midnight aufgerufen
Log3 ("$SELF",1,"aufruf mit $_counter[$i][0],$_counter[$i][1]");
midnight($_counter[$i][0],$_counter[$i][1],$mday,$yday);
}
}