Hallo,
ich bin auf der Suche nach einer eleganten Lösung um den Stromverbrauch festzustellen und zu visualisieren.
Dabei bin ich auf dieses DOIF gestossen:
https://forum.fhem.de/index.php/topic,125192.msg1200988.html#msg1200988 (https://forum.fhem.de/index.php/topic,125192.msg1200988.html#msg1200988)
Allerdings erschließt sich mir die Funktionalität nicht ganz.
- Wann oder von wem wird die Funktion "reset_$2" aufgerufen.
Mir ist klar, dass das dann eigentlich die Funktion z.B. "reset_<Reading>" ist.
- Das DOIF funktioniert nur, weil die <Reading> anders heißen.
Bei mir wären das mehrere Shellys und die <Reading> wären bei jedem gleich.
Daher überschreiben sich die Readings mit dem Prefix "$2" doch. Oder?
Mit diesen Templates bin ich immer noch nicht ganz auf Gleich. Vielleicht klappt das ja doch so wie es ist.
@Damian: Ich traue mich ja kaum mehr zu fragen, aber könntest Du das DOIF Deiner Visualisierung vielleicht posten?
https://forum.fhem.de/index.php/topic,125192.msg1198074.html#msg1198074 (https://forum.fhem.de/index.php/topic,125192.msg1198074.html#msg1198074)
Vielen Dank im Voraus
lg, Gerhard
Hier habe ich den Code bereits verfeinert: https://forum.fhem.de/index.php/topic,84969.msg1207068.html#msg1207068
Da jetzt das Device im Readingnamen steckt, ist es eindeutig.
reset-Block musste zuvor manuell ausgeführt werden. Jetzt gibt es init-Blöcke, die automatisch bei der Definition ausgeführt werden.
Ich werde bald einen Wiki-Beitrag dazu machen - ich warte nur bis sich die Grafiken etwas mehr gefüllt haben.
Hier mein aktueller Code für Stromertrag und Strombezug:
defmod di_counter DOIF DEF TPL_stat (midnight_$1_$2 { [00:01];;\
set_Reading("$1_$2_counter",[?$1:$2]);;\
set_Reading("$1_$2_last_day",get_Reading("$1_$2_day",0),1);;\
set_Reading("$1_$2_day",0,1);;\
set_Reading("$1_$2_month",get_Reading("$1_$2_month",0)+get_Reading("$1_$2_last_day",0),1);;\
if ($mday == 1) {\
set_Reading("$1_$2_last_month",get_Reading("$1_$2_month",0),1);;\
set_Reading("$1_$2_month",0,1);;\
set_Reading("$1_$2_year",get_Reading("$1_$2_year",0)+get_Reading("$1_$2_last_month",0),1);;\
}\
if ($yday == 1) {\
set_Reading("$1_$2_last_year",get_Reading("$1_$2_year",0),1);;\
set_Reading("$1_$2_year",0,1);;\
}\
}\
\
day_count_$1_$2 {set_Reading ("$1_$2_day",int(([$1:$2,0]-get_Reading("$1_$2_counter",0))*1000)/1000,1);;}\
\
init_$1_$2 {\
if (!get_Reading("$1_$2_counter","")) {\
set_Reading("$1_$2_counter",[?$1:$2]);;\
set_Reading ("$1_$2_day",0);;\
set_Reading ("$1_$2_month",0);;\
set_Reading ("$1_$2_year",0);;\
set_Reading ("$1_$2_last_day",0);;\
set_Reading ("$1_$2_last_month",0);;\
set_Reading ("$1_$2_last_year",0);;\
} \
}\
)\
TPL_stat (Stromzaehler,total_c)\
TPL_stat (Stromzaehler,total_f)
attr di_counter room CUL_EM
attr di_counter uiTable {package ui_Table}\
\
card([[$SELF:Stromzaehler_total_f_day:col1w],[$SELF:Stromzaehler_total_c_day:col1w]],"Energie in kWh pro Tag","fa_bolt\@silver",-20,20,0,90,["Ertrag","Bezug"],undef,"1","130,,1,0,1","0,0,0,0,2")|\
card([[$SELF:Stromzaehler_total_f_month:col365d],[$SELF:Stromzaehler_total_c_month:col365d]],"Energie in kWh pro Monat","fa_bolt\@silver",-300,600,0,90,["Ertrag","Bezug"],undef,"1","130,,1,0,1","0,0,0,0,2")
Dargestellt wird der tägliche und monatliche Verbrauch/Bezug, siehe Anhang. Da es erst zwei Tage lang läuft, sieht man den monatlichen Anstieg noch nicht besonders gut.
Man kann natürlich auch auf die Readings last_day, last_month oder last_year triggern und diese z. B. loggen.
Hallo Damian,
unglaublich, was Du da alles mit Deinem DOIF anstellt.
Schaut so einfach aus ;)
Wenn ich es so vor mir sehe, dann ist alles klar. Aber wenn ich es selbst angehen müsste, dann ...
Danke, lg, Gerhard
Zitat von: gestein am 14 Februar 2022, 18:04:48
Hallo Damian,
unglaublich, was Du da alles mit Deinem DOIF anstellt.
Schaut so einfach aus ;)
Wenn ich es so vor mir sehe, dann ist alles klar. Aber wenn ich es selbst angehen müsste, dann ...
Danke, lg, Gerhard
Die Grafik ist hier ein nicht ganz unwichtiges Nebenprodukt :) Der Schwerpunkt bei der Definition ist allerdings das Template TPL_stat, welches mit allen fortlaufenden Zählern funktioniert und in den Readings ...day,...month,...year,...last_day, ...last_month, ...last_year die jeweiligen Verbräuche zum Loggen bzw. Plotten bestimmt.
Das stimmt.
Zwei Fragen bitte noch:
1) wie würdest Du das folgende lösen?
Ich habe mehrere Shelly's und würde gerne den Verbrauch z.B. pro Zimmer und/oder pro Gruppe (Licht, Steckdose, Haushaltsgeräte) sehen.
Und dann noch den Gesamtverbrauch dazu.
Heißt das, für jedes Zimmer, jede Gruppe ein so ein DOIF anlegen?
2) wenn fhem neu gestartet wird, sind dann die Werte weg?
Wenn man die Definition ändert, sind dann die Werte weg?
Vielen Dank im Voraus
Lg, Gerhard
Zitat von: gestein am 14 Februar 2022, 20:14:37
Das stimmt.
Zwei Fragen bitte noch:
1) wie würdest Du das folgende lösen?
Ich habe mehrere Shelly's und würde gerne den Verbrauch z.B. pro Zimmer und/oder pro Gruppe (Licht, Steckdose, Haushaltsgeräte) sehen.
Und dann noch den Gesamtverbrauch dazu.
Heißt das, für jedes Zimmer, jede Gruppe ein so ein DOIF anlegen?
2) wenn fhem neu gestartet wird, sind dann die Werte weg?
Wenn man die Definition ändert, sind dann die Werte weg?
Vielen Dank im Voraus
Lg, Gerhard
Du kannst in einem DOIF-Device mehrfach das TPL_stat-Template aufrufen. Ich habe in meinem Beispiel zwei Zähler definiert:
TPL_stat (Stromzaehler,total_c)
TPL_stat (Stromzaehler,total_f)
Eine Summation über mehrere Zähler (Gruppe) ist nicht programmiert.
card speichert die Werte in versteckten Readings des DOIFs, mit save werden sie in der FHEM-Config gesichert. Damit bleiben die Grafiken nach dem Neustart erhalten. Wird dagegen die Definition des DOIF geändert (defmod), so werden alle Daten gelöscht. Man kann aber ein DOIF mit TPL_state definieren zum Bestimmen der Verbräuche und ein DOIF mit der Definition der cards zum Visualisieren, solange nur uiTable angepasst wird, bleiben die Grafiken ebenfalls erhalten.
Will man auf Nummer sicher gehen, dann sollte man die Tages-, Monats- und Jahresverbräuche zusätzlich loggen.
Und hier die Definition für den momentanen Verbrauch/Produktion, also die aktuelle Leistung. Hier werden die entsprechenden Readings der Zähler direkt angegeben.
card([[CUL_WZ:current:144col1d],[Stromzaehler:power_neg:144col1d]],"Leistung in kW","fa_bolt\@silver",-3.6,3.6,0,90,["Solar","Netz"],[(-1,0,-0.01,30,1,60,3.6,90)],"2","130,,1,0,1,0","1,,1,0,1")
Zitat von: Damian am 14 Februar 2022, 17:40:21
Hier habe ich den Code bereits verfeinert: https://forum.fhem.de/index.php/topic,84969.msg1207068.html#msg1207068
...
Erst einmal ein Dankeschön für die tolle Anregung.
Im Gegensatz zu Electricity/Gas/Water-Calculator werden hier deutlich weniger Daten erzeugt und die Beschränkung auf das wesentliche ist einfacher. Für mich habe ich die Template-Definition noch um die Parameter $3 (Erzeugung eines kürzeren und lesbareren Namens für die erstellten Readings) und $4 (Anzahl der zu betrachtenden Nachkommastellen) ergänzt, um die Universalität zu erhöhen.
defmod myCounter DOIF DEF TPL_stat (\
midnight_$3 { [00:00:05];;\
set_Reading ("$3_counter",sprintf("%.$4f", [?$1:$2]));;\
set_Reading ("$3_last_day",get_Reading("$3_day",0),1);;\
set_Reading ("$3_day",0,1);;\
set_Reading ("$3_month",get_Reading("$3_month",0)+get_Reading("$3_last_day",0),1);;\
if ($mday == 1) {\
set_Reading ("$3_last_month",get_Reading("$3_month",0),1);;\
set_Reading ("$3_month",0,1);;\
set_Reading ("$3_year",get_Reading("$3_year",0)+get_Reading("$3_last_month",0),1);;\
}\
if ($yday == 1) {\
set_Reading ("$3_last_year",get_Reading("$3_year",0),1);;\
set_Reading ("$3_year",0,1);;\
}\
}\
\
day_count_$3 {set_Reading ("$3_day",sprintf("%.$4f", [$1:$2,0]-get_Reading("$3_counter",0)),1);;}\
\
init_$3 {\
if (!get_Reading("$3_counter","")) {\
set_Reading ("$3_counter",sprintf("%.$4f", [$1:$2,0]));;\
set_Reading ("$3_day",0);;\
set_Reading ("$3_month",0);;\
set_Reading ("$3_year",0);;\
set_Reading ("$3_last_day",0);;\
set_Reading ("$3_last_month",0);;\
set_Reading ("$3_last_year",0);;\
} \
}\
)\
TPL_stat (KgFlurStromzaehler,zaehler,Strom,4)\
TPL_stat (KgWsGasRaspi,zaehler,Gas,2)\
TPL_stat (KgFlurWasserzaehler,zaehlerstand,Wasser,4)\
TPL_stat (dummyDgBueroZbDwRegen,mm,Regen,1)
attr myCounter DbLogExclude .*
attr myCounter DbLogInclude Gas.*,Strom.*,Regen.*,Wasser.*
attr myCounter icon helper_doif
MfG
Willi
Schön, dass du mit dem Codeschnipsel etwas anfangen konntest. Wenn du es erweitern konntest, dann hast du offenbar die Funktionsweise des Schnipsels nachvollziehen können :)
Komisch, hatte das Schnipsel am Laufen, mit einem 2. TPL_ rumgebastelt und den shelly (der events liefert) an den Gefrirschrank gesteckt.
Nun kann ich beim set <device> nur noch "disable, enable" wählen.
Was muss ich löschen, restoren?
defmod myCounter DOIF DEF TPL_stat ( \
midnight_$3 { [00:05];;\
set_Reading ("$3_counter",sprintf("%.$4f", [?$1:$2]));;\
set_Reading ("$3_last_day",get_Reading("$3_day",0),1);;\
set_Reading ("$3_day",0,1);;\
set_Reading ("$3_month",get_Reading("$3_month",0)+get_Reading("$3_last_day",0),1);;\
if ($mday == 1) {\
set_Reading ("$3_last_month",get_Reading("$3_month",0),1);;\
set_Reading ("$3_month",0,1);;\
set_Reading ("$3_year",get_Reading("$3_year",0)+get_Reading("$3_last_month",0),1);;\
}\
if ($yday == 1) {\
set_Reading ("$3_last_year",get_Reading("$3_year",0),1);;\
set_Reading ("$3_year",0,1);;\
}\
}\
day_count_$3 {set_Reading ("$3_day",sprintf("%.$4f", [$1:$2,0]-get_Reading("$3_counter",0)),1);;}\
init_$3 {\
if (!get_Reading("$3_counter","")) {\
set_Reading ("$3_counter",sprintf("%.$4f", [$1:$2,0]));;\
set_Reading ("$3_day",0);;\
set_Reading ("$3_month",0);;\
set_Reading ("$3_year",0);;\
set_Reading ("$3_last_day",0);;\
set_Reading ("$3_last_month",0);;\
set_Reading ("$3_last_year",0);;\
} \
}\
)\
\
TPL_stat (shelly_s_2,energyTotal,Gefr-Schr,3)
attr myCounter room 2.5 Shelly
attr myCounter uiTable {package ui_Table}
setstate myCounter initialized
setstate myCounter 2022-02-17 17:56:20 mode enabled
setstate myCounter 2022-02-17 17:56:20 state initialized
TPL_stat (shelly_s_2,energyTotal,Gefr-Schr,3)
Minus im Readingnamen ist keine gute Idee ;)
Danke, das war's
Kann man aus Gründen der Übersichtlichkeit die Readings "block_.* executed" evtl. unterdrücken. loglevel ist wohl obsolet.
Zitat von: jkriegl am 17 Februar 2022, 19:55:53
Kann man aus Gründen der Übersichtlichkeit die Readings "block_.* executed" evtl. unterdrücken. loglevel ist wohl obsolet.
Ist z. Zt. nicht möglich.
Ich habe mal eine neue Version des Stromzählers programmiert.
Hier gibt es nur noch einen Mitternachtsblock und nur einen Initialisierungsblock für alle Zähler. Dadurch reduziert sich die Anzahl der Blöcke erheblich. Die Zählerangaben werden jetzt direkt am Anfang im subs-Block definiert. Die Anzahl der Zähler ist weiterhin beliebig. Die Visualisierung über card-Funktion ist geblieben.
defmod di_counter_new DOIF subs {\
## device, read \
push (@{$_counter},["Stromzaehler","total_c"]);; ## Angaben für den ersten Zähler\
push (@{$_counter},["Stromzaehler","total_f"]);; ## Angaben für den zweiten Zähler\
\
sub midnight {\
my ($device,$reading,$mday,$yday)=@_;;\
set_Reading("$device.$reading.counter",ReadingsVal($device, $reading,0));; \
set_Reading("$device.$reading.last_day",get_Reading("$device.$reading.day",0),1);;\
set_Reading("$device.$reading.day",0,1);;\
set_Reading("$device.$reading.month",get_Reading("$device.$reading.month",0)+get_Reading("$device.$reading.last_day",0),1);;\
if ($mday == 1) {\
set_Reading("$device.$reading.last_month",get_Reading("$device.$reading.month",0),1);;\
set_Reading("$device.$reading.month",0,1);;\
set_Reading("$device.$reading.year",get_Reading("$device.$reading.year",0)+get_Reading("$device.$reading.last_month",0),1);;\
}\
if ($yday == 1) {\
set_Reading("$device.$reading.last_year",get_Reading("$device.$reading.year",0),1);;\
set_Reading("$device.$reading.year",0,1);;\
}\
}\
\
sub init {\
my ($device,$reading)=@_;;\
if (!get_Reading("$device.$reading.counter","")) { ## Initialisierung der Readings\
set_Reading("$device.$reading.counter",ReadingsVal($device,$reading,0));; ## aktueller Zählerstand\
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\
} \
}\
}\
\
mid {[00:01];; ## Sicherung der Daten um Mitternacht\
for (my $i=0;;$i<@{$_counter};;$i++) {\
midnight($_counter[$i][0],$_counter[$i][1],$mday,$yday);;\
}\
}\
\
init { ## initialisierung aller Readings\
for (my $i=0;;$i<@{$_counter};;$i++) {\
init($_counter[$i][0],$_counter[$i][1]);;\
}\
}\
\
DEF TPL_stat (\
day_count_$1_$2 {set_Reading ("$1.$2.day",int(([$1:$2,0]-get_Reading("$1.$2.counter",0))*1000)/1000,1);;}\
)\
\
\
## Definition aller day_count-Blöcke zum Zählen des Tagesverbrauchs\
FOR(@{$_counter},TPL_stat($1$1,$1$2))
attr di_counter_new uiTable {package ui_Table} ## Optionale Visualisierung der Tageswerte im DOIF-Device\
card([[$SELF:Stromzaehler.total_f.day:col1w],[$SELF:Stromzaehler.total_c.day:col1w]],"Energie in kWh pro Tag","fa_bolt\@silver",-25,25,0,90,["Ertrag","Bezug"],undef,"1","130,,1,0,1","0,0,0,0,2")
Beim Schnipsel kommt "di_counter_new DOIF: Perlblck: no right bracket: {\"
Ist deutlich komplizierter zu verstehen. Auf die (readings-)blöcke kommt es nicht darauf an.
Zitat von: jkriegl am 22 Februar 2022, 19:06:19
Beim Schnipsel kommt "di_counter_new DOIF: Perlblck: no right bracket: {\"
Bei mir nicht.
Zitat
Ist deutlich komplizierter zu verstehen.
Klar, ist nichts für Anfänger. :)
Zitat
Auf die (readings-)blöcke kommt es nicht darauf an.
ZitatKann man aus Gründen der Übersichtlichkeit die Readings "block_.* executed" evtl. unterdrücken. loglevel ist wohl obsolet
Auf diese aber schon ;)
[gelöst, Siehe https://forum.fhem.de/index.php/topic,126199.msg1211057.html#msg1211057 ]
Natürlich bin ich auf diesen Vorschlag auch sofort "aufgesprungen", weil es mir Stringzerlegungen beim Statistik-Modul erspart und ermöglicht, mich genau auf die Readings zu konzentrieren, die für mich wichtig sind.
Aktuell habe ich noch genau ein Problemchen: Anders als meine Tachos, die ich bisher zur Darstellung der Momentan-Verbräuche benutzt haben, aktualisieren in der Programmversion aus dem Wiki in der Card die Werte nicht beim Ändern des Readings durch das Programm.
In meinem Dashboard muss ich daher immer eigens ein Aktualisieren der Seite auslösen.
Mit diesem Attribut habe ich immerhin schon einmal Events ausgelöst, die das Wegschreiben der Tageswerte in ein Filelog auslösen:
attr DI_CN_Strom DOIF_Readings Solar_Zaehlerstand_counter:[$SELF:Solar_Zaehlerstand_counter],Strom_Zaehlerstand_counter:[$SELF:Strom_Zaehlerstand_counter]
Auch würde ich gerne nur dann ein Event auslösen, wenn sich mindestens die erste Nachkommastelle geändert hat. Also etwa in der Schreibweise, wie wir es von event-on-change-reading etc. kenne: Reading:0.001
In welche Richtung muss ich meine Hirnzellen bewegen?
Sonnige Grüße
Christian
Das verstehe ich nicht, wenn ein Reading mit Event geändert wird, dann muss card sich automatisch anpassen.
DOIF_Readings produzieren keine Events nach außen.
Du musst mir den konkreten Fall als List posten, damit ich mir ein Bild davon machen kann.
Danke, Damian, dass Du Dir das anschauen willst. Das Erzeugen bzw. Nicht-Erzeugen von Events habe ich mit Eventviewer kontrolliert. Da die Momentanwerte meines Stromverbrauchs, der Überschusseinspeisung im Sekundentakt erzeugt werden, habe ich da ausreichend Gelgenheit zur Kontrolle. Ich hätte z.B. erwartet, dass beim Sprung von 2,45 nach 2,51 kwh die Anzeige im Tacho der Card auch von 2,4 auf 2,5 springt. Tut es seit vielen Monaten toll in verschiedenen ring2 Ausprägungen:
defmod DI_CN_Strom DOIF DEF TPL_stat (midnight_$1_$2 { [23:59:59];; ## Definition des Templates TPL_stat für einen Zähler\
set_Reading("$1_$2_counter",[?$1:$2]);; ## $1 Devicename, $2 Devicereading\
set_Reading("$1_$2_last_day",get_Reading("$1_$2_day",0),1);;\
set_Reading("$1_$2_day",0,1);;\
set_Reading("$1_$2_month",get_Reading("$1_$2_month",0)+get_Reading("$1_$2_last_day",0),1);;\
if ($mday == 1) {\
set_Reading("$1_$2_last_month",get_Reading("$1_$2_month",0),1);;\
set_Reading("$1_$2_month",0,1);;\
set_Reading("$1_$2_year",get_Reading("$1_$2_year",0)+get_Reading("$1_$2_last_month",0),1);;\
}\
if ($yday == 1) {\
set_Reading("$1_$2_last_year",get_Reading("$1_$2_year",0),1);;\
set_Reading("$1_$2_year",0,1);;\
}\
}\
\
day_count_$1_$2 {set_Reading ("$1_$2_day",int(([$1:$2,0]-get_Reading("$1_$2_counter",0))*1000)/1000,1);;}\
\
init_$1_$2 { ## $1 Devicename, $2 Devicereading\
if (!get_Reading("$1_$2_counter","")) { ## Initialisierung der Readings\
set_Reading("$1_$2_counter",[?$1:$2]);; ## aktueller Zählerstand\
set_Reading ("$1_$2_day",0);; ## aktueller Tagesverbrauch\
set_Reading ("$1_$2_month",0);; ## aktueller Monatsverbrauch\
set_Reading ("$1_$2_year",0);; ## aktueller Jahresverbrauch\
set_Reading ("$1_$2_last_day",0);; ## Verbrauch des letzten Tages\
set_Reading ("$1_$2_last_month",0);; ## Verbrauch des letzten Monats\
set_Reading ("$1_$2_last_year",0);; ## Verbrauch des letzten Jahres\
} \
}\
)\
## mehrere Zähler können durch Hinzufügen eines Template-Aufrufs jeweils angegeben werden mit: TPL_stat(<Zähler-Device>,<Reading>)\
TPL_stat (Strom,Zaehlerstand) ## Zählerangaben für den Stromverbrauch\
TPL_stat (Solar,Zaehlerstand) ## Zählerangaben für Stromeinspeisung
attr DI_CN_Strom DOIF_Readings Solar_Zaehlerstand_counter:[$SELF:Solar_Zaehlerstand_counter],Strom_Zaehlerstand_counter:[$SELF:Strom_Zaehlerstand_counter]
attr DI_CN_Strom room Test
attr DI_CN_Strom uiTable {package ui_Table} ## Optionale Visualisierung der Tageswerte im DOIF-Device\
card([[$SELF:Strom_Zaehlerstand_day:col1w],[$SELF:Solar_Zaehlerstand_day:col1w]],"Energie in kWh pro Tag","fa_bolt\@silver",0,15,0,90,["Bezug","Abgabe"],undef,"1","130,,1,0,1","0,0,0,0,2")
Zum Testen hier noch zwei Dummys, die meine Zähler abbilden:
defmod Solar dummy
attr Solar DbLogExclude .*
attr Solar stateFormat power
setstate Solar 0.00
setstate Solar 2022-02-23 17:08:09 Zaehlerstand 3061.8553
setstate Solar 2022-02-23 16:24:53 kWh_lfd 7.9219
setstate Solar 2022-02-23 18:00:47 power 0.00
setstate Solar 2022-02-23 12:45:57 power_max 1656.66
defmod Strom dummy
attr Strom DbLogExclude .*
attr Strom stateFormat power
setstate Strom 119.95
setstate Strom 2022-02-23 18:01:36 Zaehlerstand 11844.4477749
setstate Strom 2022-02-23 17:39:12 kWh_lfd 5.5121649
setstate Strom 2022-02-23 18:01:37 power 119.95
setstate Strom 2022-02-23 13:49:00 power_L1 3.31
setstate Strom 2022-02-23 18:01:37 power_L2 81.3
setstate Strom 2022-02-23 17:53:41 power_L3 35.49
setstate Strom 2022-02-23 07:32:55 power_max 2962.18
hg
Christian
Die Nachkommastellen werden mit sprintf formatiert, das Verhalten ist in card wie auch in ring/ring2 gleich, da card ring/ring2 aufruft.
2.45 ist auf eine Nachkommastelle gerundet 2,5 (kaufmännisches Runden), genauso wie 2.51 es wird in card als auch in ring2 mit 2.5 dargestellt.
2.54 ist kaufmännisch gerundet 2.5, also ändert sich nicht.
Habe beides gerade noch mal bei mir getestet
Hallo Damian, danke für Deine neuerliche Rückmeldung und ja, mein Zahlenbeispiel war falsch gewählt. Da hast Du recht. Allerdings funktioniert es bei mir nicht, wie gewünscht. Ich habe jetzt extra über 2 Stunden das Bild auf dem Schirm gelassen und kann nun mein Thema mit einem Bild zeigen. Oben rechts zeigt der Status den stets aktualisiert laufenden Tageszähler. Im Ring allerdings hat sich der obere Wert (Bezug) nicht angepasst. Drunter montiert habe ich die Ansicht nach Aktualisierung im Browser (F5).
Wie gesagt, in meinen verschiedenen ring2 werden die sich ändernden Readings fortlaufend gezeigt.
Herzliche Grüße
Christian
Zitat von: cwagner am 23 Februar 2022, 23:17:23
Hallo Damian, danke für Deine neuerliche Rückmeldung und ja, mein Zahlenbeispiel war falsch gewählt. Da hast Du recht. Allerdings funktioniert es bei mir nicht, wie gewünscht. Ich habe jetzt extra über 2 Stunden das Bild auf dem Schirm gelassen und kann nun mein Thema mit einem Bild zeigen. Oben rechts zeigt der Status den stets aktualisiert laufenden Tageszähler. Im Ring allerdings hat sich der obere Wert (Bezug) nicht angepasst. Drunter montiert habe ich die Ansicht nach Aktualisierung im Browser (F5).
Wie gesagt, in meinen verschiedenen ring2 werden die sich ändernden Readings fortlaufend gezeigt.
Herzliche Grüße
Christian
Dann scheint bei dir irgendwas mit den Events verkorkst zu sein.
Alleine diese Definition ist nicht sinnvoll:
attr DI_CN_Strom DOIF_Readings Solar_Zaehlerstand_counter:[$SELF:Solar_Zaehlerstand_counter],Strom_Zaehlerstand_counter:[$SELF:Strom_Zaehlerstand_counter]
Ich denke, du hast dir irgendwo einen Loop eingebaut.
Da Deine Tipps & Analysen bisher immer zielführend waren, bin ich Deiner Vermutung ernsthaft nachgegangen, bin aber weiterhin am Rätsel. Im angehängten Foto siehst Du, dass sowohl Status wie auch ein *zusätzlich* eingebauter ring2 mit denselben Readings aktualisiert werden, hingegen der Ring in der Card nicht. Diese Beobachtung hatte ich in der Vergangenheit auch schon mal gemacht, ohne ihr nachzugehen. Das von Dir kritisierte DOIF-readings attribut war eine Verzweiflungstat. Mit event-on-change-reading funktioniert es an vielen Stellen sehr gut.
attr DI_CN_Strom event-on-change-reading Solar_Zaehlerstand_counter,Strom_Zaehlerstand_counter,Strom_Zaehlerstand_day,Solar_Zaehlerstand_day
attr DI_CN_Strom stateFormat Strom_Zaehlerstand_day | Solar_Zaehlerstand_day kWh
attr DI_CN_Strom uiTable {package ui_Table} ## Optionale Visualisierung der Tageswerte im DOIF-Device\
card([[$SELF:Strom_Zaehlerstand_day:col1w],[$SELF:Solar_Zaehlerstand_day:col1w]],"Energie in kWh pro Tag","fa_bolt\@silver",0,15,0,90,["Bezug","Abgabe"],undef,"1","130,,1,0,1","0,0,0,0,2")\
ring2([$SELF:Strom_Zaehlerstand_day],0,15,undef,undef,"Bezug",120,undef,1,[$SELF:Solar_Zaehlerstand_day],0,10,undef,undef," PV kWh",undef,1)
Kann es sein, dass eine von DOIF gebrauchte Bibliothek nicht aktuell ist, sodass es zu diesem Effekt kommt? Für mich spricht dagegen, dass auf einem zweiten, vor zwei Monaten from scratch aufgesetzten System das Verhalten sich reproduzieren lässt.
Herzliche Grüße
Christian
Zitat von: cwagner am 25 Februar 2022, 13:36:23
Da Deine Tipps & Analysen bisher immer zielführend waren, bin ich Deiner Vermutung ernsthaft nachgegangen, bin aber weiterhin am Rätsel. Im angehängten Foto siehst Du, dass sowohl Status wie auch ein *zusätzlich* eingebauter ring2 mit denselben Readings aktualisiert werden, hingegen der Ring in der Card nicht. Diese Beobachtung hatte ich in der Vergangenheit auch schon mal gemacht, ohne ihr nachzugehen. Das von Dir kritisierte DOIF-readings attribut war eine Verzweiflungstat. Mit event-on-change-reading funktioniert es an vielen Stellen sehr gut.
attr DI_CN_Strom event-on-change-reading Solar_Zaehlerstand_counter,Strom_Zaehlerstand_counter,Strom_Zaehlerstand_day,Solar_Zaehlerstand_day
attr DI_CN_Strom stateFormat Strom_Zaehlerstand_day | Solar_Zaehlerstand_day kWh
attr DI_CN_Strom uiTable {package ui_Table} ## Optionale Visualisierung der Tageswerte im DOIF-Device\
card([[$SELF:Strom_Zaehlerstand_day:col1w],[$SELF:Solar_Zaehlerstand_day:col1w]],"Energie in kWh pro Tag","fa_bolt\@silver",0,15,0,90,["Bezug","Abgabe"],undef,"1","130,,1,0,1","0,0,0,0,2")\
ring2([$SELF:Strom_Zaehlerstand_day],0,15,undef,undef,"Bezug",120,undef,1,[$SELF:Solar_Zaehlerstand_day],0,10,undef,undef," PV kWh",undef,1)
Kann es sein, dass eine von DOIF gebrauchte Bibliothek nicht aktuell ist, sodass es zu diesem Effekt kommt? Für mich spricht dagegen, dass auf einem zweiten, vor zwei Monaten from scratch aufgesetzten System das Verhalten sich reproduzieren lässt.
Herzliche Grüße
Christian
Dann musst du dich herantasten. Nimm die ersten beiden Attribute stateFormat und event-on-change-readings raus, dann beobachtest du, ob sich die Uhrzeit von card im Minutentakt (beim Event ändert) bzw. was mit ring2 passiert.
Tja, ich komme nicht vorwärts: Habe das Device neu generiert und kein Attribut stateformat oder event.* gesetzt. Es werden events gesetzt, das sieht man ja auch an der Aktualisierung von ring2. Ich habe jetzt mal mehrere Stunden nicht aktualisiert und das Ergebnis ist eindeutig. Die card wird gar nicht (von selbst) aktualisiert. ring2 wird fortlaufend aktualisiert. Im Event-Monitor tauchen die geänderten Werte auch auf.
Nun, ich kann auch mit einem Tacho lesen und die elegante Erzeugung der wichtigsten statistischen Werte ist es wert, dass ich mich mit Deinem Vorschlag auseinandergesetzt habe.
Christian
Zitat von: cwagner am 26 Februar 2022, 14:05:54
Tja, ich komme nicht vorwärts: Habe das Device neu generiert und kein Attribut stateformat oder event.* gesetzt. Es werden events gesetzt, das sieht man ja auch an der Aktualisierung von ring2. Ich habe jetzt mal mehrere Stunden nicht aktualisiert und das Ergebnis ist eindeutig. Die card wird gar nicht (von selbst) aktualisiert. ring2 wird fortlaufend aktualisiert. Im Event-Monitor tauchen die geänderten Werte auch auf.
Nun, ich kann auch mit einem Tacho lesen und die elegante Erzeugung der wichtigsten statistischen Werte ist es wert, dass ich mich mit Deinem Vorschlag auseinandergesetzt habe.
Christian
OK. Dann ändere bitte die Readings zur Darstellung von ring2 und card auf Readings eines neuen Dummys. Die kannst du mit setreading setzen und schauen, ob die Anzeigen mit einem Dummy bei beiden klappt.
Du brauchst nicht weiter suchen, ich konnte das Problem bei mir jetzt in der Konstellation nachvollziehen.
Ich versuche es morgen zu beheben.
Durch dein hartnäckiges Dranbleiben am Problem, konnte ich Fehler nun beheben :)
siehe: https://forum.fhem.de/index.php/topic,120088.msg1211014.html#msg1211014
Vielen Dank, Damian. Dein unglaublicher Einsatz für FHEM z.B. mit DOIF und Deine Präsenz in diesem Projekt macht es ja auch so lohnenswert, sich bei einem Thema dann auch einzubringen und wenigstens durch simples Ausprobieren ein Sandkorn zurückzugeben.
Neue Version eingebunden, Neustart, funktioniert! Vielen Dank
Christian
Ich habe den Wikibeitrag aktuallisiert: 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
Jetzt wird bei jedem Countertrigger auch Monats- und Jahresverbrauch aktualisiert, man muss nicht bis zum Ende des Tages bzw. Monats warten.
Hi Damian,
gibt es irgendein Kniff wie man fehlerhafte Werte in den Charts manuell bereinigen kann?
Ich habe schon versucht den fehlerhaften Wert im passenden Reading durch einen korrekten zu ersetzen, aber das Chart hat sich dadurch nicht verändert. :(
Reading: .col_7_DOIF_counter_SEN_EM_Elektro.000_EM_All.day_168_values
aktueller (falscher) Wert: ,,,,,0.652,2.233
setreading DOIF_DashBoard .col_7_DOIF_counter_SEN_EM_Elektro.000_EM_All.day_168_values ,,,,,2.652,2.233
Zitat von: Tobias am 19 Mai 2022, 06:58:26
Hi Damian,
gibt es irgendein Kniff wie man fehlerhafte Werte in den Charts manuell bereinigen kann?
Ich habe schon versucht den fehlerhaften Wert im passenden Reading durch einen korrekten zu ersetzen, aber das Chart hat sich dadurch nicht verändert. :(
Reading: .col_7_DOIF_counter_SEN_EM_Elektro.000_EM_All.day_168_values
aktueller (falscher) Wert: ,,,,,0.652,2.233
setreading DOIF_DashBoard .col_7_DOIF_counter_SEN_EM_Elektro.000_EM_All.day_168_values ,,,,,2.652,2.233
Die Werte werden intern im Array gehalten und überschreiben deine Änderung beim speichern bzw. beim Beenden von FHEM.
Am besten du stoppst FHEM und änderst die Werte in der save-Datei.
Ich habe den Wiki-Beitrag aktualisiert:
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
Hallöchen,
ich hab bisher ehrlicherweise nie viel mit DOIF gemacht (ich verstehs einfach nicht so wirklich, komme mit "einfachen" Perl Aufgaben besser klar) ... Aber in diesem Fall habe ich es versucht. Hab das DOIF kopiert, mein Device und Reading angepasst und einen Tag gewartet. Leider passiert dort bisher nicht viel außer dass ein paar Readings mit ein paar Werten entstanden sind und im Device "di_counter_new initialized" steht..... Hat jemand eine Idee woran es liegen könnte? Den "Copy for forum.fhem.de" Auszug habe ich unten angehangen.
## EDIT: Code entfernt, Text wird zu lang und unten abgeschnitten.
Vielen Dank im Voraus &
Viele Grüße
Andreas
Leg mal bitte den Code in einen codeblock, kann man garnicht lesen
Zitat von: flummy1978 am 02 Dezember 2022, 01:20:02
Hallöchen,
ich hab bisher ehrlicherweise nie viel mit DOIF gemacht (ich verstehs einfach nicht so wirklich, komme mit "einfachen" Perl Aufgaben besser klar) ... Aber in diesem Fall habe ich es versucht. Hab das DOIF kopiert, mein Device und Reading angepasst und einen Tag gewartet.
Dann ist es keine gute Idee, mit dieser komplexen Definition anzufangen. Für die Darstellung muss das uiTable-Attribut entsprechend angepasst werden. Dazu muss man ebenfalls verstehen, wie die card-Funktion (es ist übrigens eine reine Perlfunktion) aufgebaut ist.
siehe: https://wiki.fhem.de/wiki/DOIF/uiTable_Schnelleinstieg#Anzeige_eines_Werteverlaufs_und_des_aktuellen_Wertes_mit_Hilfe_der_SVG-Funktion_card
Holla,
Zitat von: Tobias am 02 Dezember 2022, 06:39:49
Leg mal bitte den Code in einen codeblock, kann man garnicht lesen
Das hatte ich ursprünglich auch getan. In der Vorschau wird es auch korrekt angezeigt, beim Abschicken danach wird es leider einfach abgeschnitten. Ist aber korrigiert ;) Muss das mal als Forums Bug melden.....
@Damian:
Zitat von: Damian am 02 Dezember 2022, 08:12:43
Dann ist es keine gute Idee, mit dieser komplexen Definition anzufangen. Für die Darstellung muss das uiTable-Attribut entsprechend angepasst werden. Dazu muss man ebenfalls verstehen, wie die card-Funktion (es ist übrigens eine reine Perlfunktion) aufgebaut ist.
siehe: https://wiki.fhem.de/wiki/DOIF/uiTable_Schnelleinstieg#Anzeige_eines_Werteverlaufs_und_des_aktuellen_Wertes_mit_Hilfe_der_SVG-Funktion_card
Schade, das konnte ich in der Wiki so nicht lesen, denn
Zitat"Die folgenden Beispieldefinitionen arbeiten mit konkreten Geräten und Readings, sie können als RAW-Definition ins eigene System übernommen werden, dazu müssen die Gerätenamen, Readings, ggf. auch Icons den existierenden Namen des eigenen Systems angepasst werden. Zum Ausprobieren der Beispiele können statt echter Geräte auch Dummys benutzt werden."
suggerierte für mich nicht, dass ich dazu, tiefer in der Materie, vieles mehr verstehen muss .... Schade :-[
Vielleicht hat jemand ne einfache Methode, wie ich meinen Stromverbrauch einfach direkt anzeigen lassen kann ohne ein überlagerters Modul zu nutzen, wie den "ElectricityCalculator". Ich habe mir einen Zähler gebaut, der alle X Sek den aktuellen Verbrauch schreibt und nicht bei jedem "Tick" (wie groß auch immer es ist) einen Impuls erstellt, wie dieses Modul es braucht.
VG
Andreas
Zitat von: flummy1978 am 02 Dezember 2022, 11:04:49
@Damian: Schade, das konnte ich in der Wiki so nicht lesen, denn suggerierte für mich nicht, dass ich dazu, tiefer in der Materie, vieles mehr verstehen muss .... Schade :-[
Deswegen hättest du für die Zeilen, die du rausgenommen hast die entsprechenden card-Aufrufe löschen müssen und die geänderten Readings in der push-Zeile in der entsprechenden card ebenfalls ändern müssen.
Ich will aber den Wiki-Code so anpassen, dass die Visualisierung automatisch erzeugt wird.
Vielen Dank für die schnelle Antwort
Zitat von: Damian am 02 Dezember 2022, 11:19:08
Deswegen hättest du für die Zeilen, die du rausgenommen hast die entsprechenden card-Aufrufe löschen müssen und die geänderten Readings in der push-Zeile in der entsprechenden card ebenfalls ändern müssen.
Ich will aber den Wiki-Code so anpassen, dass die Visualisierung automatisch erzeugt wird.
Ich werde mir nochmal anschauen, vielleicht verstehe ich es ja doch irgendwie ???
Das zweite wäre natürlich ein absolutes Träumchen ::)
VG
Andreas
Hallo nochmal
@Damian
Zitat von: Damian am 02 Dezember 2022, 11:19:08
Deswegen hättest du für die Zeilen, die du rausgenommen hast die entsprechenden card-Aufrufe löschen müssen und die geänderten Readings in der push-Zeile in der entsprechenden card ebenfalls ändern müssen.
Ich habe jetzt versucht das Ganze zu verstehen bzw zumindest auf meine Bedürfnisse umzustellen. Soweit bin ich jetzt derzeit nicht unzufrieden (zumindest sieht es schonmal nach etwas aus ;) ), ob es die korrekten Daten sind, kann ich erst nach Mitternacht sehen oder?
Ich habe allerdings 2 Fragen dazu:
1.
event_Readings
power_ALL:sprintf("%0.3f",[zaehler:COUNTER_C1:diff]*1440),
power_KG:sprintf("%0.3f",[zaehler:COUNTER_C2:diff]*1440),
power_EG:sprintf("%0.3f",[zaehler:COUNTER_C3:diff]*1440),
power_OG:sprintf("%0.3f",[zaehler:COUNTER_C4:diff]*1440)
Ist das in meinem Falle korrekt? In den reading Counter_C1..C4 ist lediglich immer der aktuelle zählwert der letzten Minute. (Daher eben *1440)
2. Gäbe es eine Möglichkeit mit den vorhandenen Mitteln, nicht nur als Tagesverlauf sondern eben aktuell für den heutigen Tag anzuzeigen? also quasi den aktuellen Verbrauch?
VG
Andreas
p.s. Das list aus dem Device verursacht übrigens das Problem, dass der Beitrag zu lang wird. Es werden insg. 1400 zeilen "undef" erstellt - diese hab ich in meinem List gelöscht. Außerdem alles ab....
# .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
# CFGFN
Wenn Du davon also was brauchst, muss ich es einzeln rausschneiden
define doif_zaehler_stats DOIF subs {\
## Device Reading \
push (@{$_counter},["zaehler","standALL"]);; ## Wasserzähler\
push (@{$_counter},["zaehler","standKG"]);; ## Solarenergie\
push (@{$_counter},["zaehler","standEG"]);; ## Bezugszähler\
push (@{$_counter},["zaehler","standOG"]);; ## Einspeisezähler \
\
sub midnight { ## Diese Funktion wird um Mitternacht ausgeführt\
my ($device,$reading,$mday,$yday)=@_;;\
set_Reading("$device.$reading.day_counter",ReadingsVal($device, $reading,1));; \
set_Reading("$device.$reading.last_day",get_Reading("$device.$reading.day",0),1);;\
set_Reading("$device.$reading.day",0,1);;\
set_Reading ("$device.$reading.month",int((ReadingsVal($device, $reading,0)-(get_Reading("$device.$reading.month_counter",0)))*1000)/1000,1);;\
set_Reading ("$device.$reading.year",int((ReadingsVal($device, $reading,0)-(get_Reading("$device.$reading.year_counter",0)))*1000)/1000,1);;\
\
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),1);;\
set_Reading("$device.$reading.month",0,1);;\
}\
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),1);;\
set_Reading("$device.$reading.year",0,1);;\
}\
}\
\
sub init_readings {\
my ($device,$reading)=@_;;\
if (get_Reading("$device.$reading.day_counter","") eq "") { ## Initialisierung der Readings\
## aktuellen Zählerstand initialisieren\
set_Reading("$device.$reading.last_counter",ReadingsVal($device, $reading,0));;\
set_Reading("$device.$reading.day_counter",ReadingsVal($device, $reading,0));; \
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\
## Log definieren\
fhem ("defmod log.counter.$device.$reading FileLog ./log/counter.$device.$reading.log $SELF:$device.$reading.(last_(day|month|year)|(day|month)_counter):.*");;\
fhem ("attr log.counter.$device.$reading room Filelogs");;\
## Tasmota-Zähler setzen: set MQTT2_FHEM_Server publish cmnd/tasmota_C58DCB/Counter1 <Zählerstand>\
}\
\
}\
} ## Ende subs-Block\
\
mid {[00:01];; ## Sicherung der Daten um Mitternacht\
for (my $i=0;;$i<@{$_counter};;$i++) { ## Für jeden Zähler wird die Funktion midnight aufgerufen\
midnight($_counter[$i][0],$_counter[$i][1],$mday,$yday);;\
}\
}\
\
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\
\
my $diff = int(([$1:$2,0]-(get_Reading("$1.$2.last_counter",0)))*1000)/1000;;\
##if ($diff < 0 and get_Reading("$1.$2.last_counter",0) > 0 or $diff > 0 and get_Reading("$1.$2.last_counter",0) < 0) { ## Wenn der Zähler zurückgesetzt wurde, dann Zählerstände zurückrechnen\
## set_Reading("$1.$2.day_counter",-(get_Reading("$1.$2.day",0)));;\
## set_Reading("$1.$2.month_counter",-(get_Reading("$1.$2.month",0)));;\
## set_Reading("$1.$2.year_counter",-(get_Reading("$1.$2.year",0)));;\
## } else {\
set_Reading ("$1.$2.last_counter",[$1:$2,0]);;\
set_Reading ("$1.$2.day",int(([$1:$2,0]-(get_Reading("$1.$2.day_counter",0)))*1000)/1000,1);;\
set_Reading ("$1.$2.month",int(([$1:$2,0]-(get_Reading("$1.$2.month_counter",0)))*1000)/1000,1);;\
set_Reading ("$1.$2.year",int(([$1:$2,0]-(get_Reading("$1.$2.year_counter",0)))*1000)/1000,1);;\
}\
##}\
)\
\
\
\
## 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
attr doif_zaehler_stats DbLogExclude .*
attr doif_zaehler_stats event-on-change-reading .*
attr doif_zaehler_stats event_Readings power_ALL:sprintf("%0.3f",[zaehler:COUNTER_C1:diff]*1440),\
power_KG:sprintf("%0.3f",[zaehler:COUNTER_C2:diff]*1440),\
power_EG:sprintf("%0.3f",[zaehler:COUNTER_C3:diff]*1440),\
power_OG:sprintf("%0.3f",[zaehler:COUNTER_C4:diff]*1440)\
attr doif_zaehler_stats room Verbrauch
attr doif_zaehler_stats uiTable {package ui_Table;;$ANIMATE=0} ## Optionale Visualisierung der Energie-Verbräuche/-Produktion im DOIF-Device\
card([doif_zaehler_stats:zaehler.standALL.day:col1w],"Gesamtverbrauch Tagesverlauf",undef,0,50,90,0,"kWh",undef,"0","150,1,1,0,1,,220","0,0,0,0")|\
card([doif_zaehler_stats:zaehler.standALL.last_day:col4w],"Gesamtverbrauch letzten Tag",undef,0,50,90,0,"kWh",undef,"0","150,1,1,0,1,0,200","0,0,0,0")|\
card([doif_zaehler_stats:zaehler.standALL.last_month:col365d],"Gesamtverbrauch letzten Monat",undef,0,1000,90,0,"kWh",undef,"0","150,1,1,0,1,0,200","0,0,0,0")\
\
card([doif_zaehler_stats:zaehler.standKG.day:col1w],"KG-Zähler Tagesverlauf in kWh",undef,0,30,30,0,"kWh",undef,"0","150,1,1,0,1,,220","0,0,0,0")|\
card([doif_zaehler_stats:zaehler.standKG.last_day:col4w],"KG-Zähler letzten Tag",undef,0,30,30,0,"kWh",undef,"0","150,1,1,0,1,0,200","0,0,0,0")|\
card([doif_zaehler_stats:zaehler.standKG.last_month:col365d],"KG-Zähler letzten Monat",undef,0,100,90,0,"kWh",undef,"0","150,1,1,0,1,0,200","0,0,0,0")\
\
card([doif_zaehler_stats:zaehler.standEG.day:col1w],"EG-Zähler Tagesverlauf in kWh",undef,0,30,30,0,"kWh",undef,"0","150,1,1,0,1,,220","0,0,0,0")|\
card([doif_zaehler_stats:zaehler.standEG.last_day:col4w],"EG-Zähler letzten Tag",undef,0,30,30,0,"kWh",undef,"0","150,1,1,0,1,0,200","0,0,0,0")|\
card([doif_zaehler_stats:zaehler.standEG.last_month:col365d],"EG-Zähler letzten Monat",undef,0,100,90,0,"kWh",undef,"0","150,1,1,0,1,0,200","0,0,0,0")\
\
card([doif_zaehler_stats:zaehler.standOG.day:col1w],"OG-Zähler Tagesverlauf in kWh",undef,0,30,30,0,"kWh",undef,"0","150,1,1,0,1,,220","0,0,0,0")|\
card([doif_zaehler_stats:zaehler.standOG.last_day:col4w],"OG-Zähler letzten Tag",undef,0,30,30,0,"kWh",undef,"0","150,1,1,0,1,0,200","0,0,0,0")|\
card([doif_zaehler_stats:zaehler.standOG.last_month:col365d],"OG-Zähler letzten Monat",undef,0,100,90,0,"kWh",undef,"0","150,1,1,0,1,0,200","0,0,0,0")\
Naja, es geht ja hier nur um Energie und nicht um Leistung, daher wird nur der Counter benötigt. Was du über event_Readings berechnest, ist wohl die Leistung und diese wird hier nicht benutzt.
Das steht im Wiki-Beitrag:
ZitatDas obige Beispiel funktioniert nur mit Zählern, die mit aufsteigenden Werten (positiv/negativ) arbeiten, wie z. B. Stromverbrauch in kWh, Wasserverbrauch in Litern usw.. Es funktioniert nicht mit momentanen Werten, wie z. B. aktuelle Leistungsaufnahme eines Verbrauchers in Watt, diese müssten zunächst kumuliert werden.
Was du haben willst, ist eher so etwas:
https://forum.fhem.de/index.php/topic,97959.msg1225965.html#msg1225965
und ein Visualisierungsbeispiel, welches den aktuellen Leistungsverlauf darstellt und die gesamte Energie des Tages, ist das letzte Beispiel
Beispieldefinition mit zusätzlichen Informationen zu der card-Funktion:
https://wiki.fhem.de/wiki/DOIF/uiTable_Schnelleinstieg#Anzeige_eines_Werteverlaufs_und_des_aktuellen_Wertes_mit_Hilfe_der_SVG-Funktion_card
Vielen Dank für die Beispiele und deine Antwort.
Ich werde es mir in Ruhe mal anschauen und mich dann mit entsprechenden Fragen melden 😉
Zu dem Power reading....dass Leistung nicht Energie ist, ist mir bewusst - bringt mein Beruf allein schon mit sich. Ich hab die Sachen jetzt nur nicht umbenannt und wollte nur wissen ob sie in meinem Fall relevant sind bzw dann korrekt ..... Scheinbar nein ;)
Kurz weil mobil
VG
Andreas
siehe: https://forum.fhem.de/index.php/topic,120088.msg1249115.html#msg1249115
Ich habe die Definition jetzt besser dokumentiert, für die Visualisierung muss man jeweils nur noch einen Template-Aufruf im uiTable-Attribut für seine Bedürfnisse anpassen:
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
Hallo Damian
2 Wochen lief dein doif super gut
heute morgen hatte ich aber Probleme mit meiner WP,
hatte gestern was an den Einstellungen geändert, zu, Dank heute morgen dann Störung
da ich eh mit der Zeit knapp war, schnell Sicherung raus dann wieder an etc.
nun sind die Werte alle durcheinander.
Gibt es eine einfache Möglichkeit alle Werte auf 0 zu setzen?
zB
setreading di_counter_new MQTT2_HeishaMo*.* 0
Sorry für den Code sicher falsch ;-)
aktueller_Wert: 723..Watt passt
heute: -109511.5..Wh eher der letzte Wert
gestern: 12332..Wh ok
Monat: 46364.00..Wh ok
Vor_Monat: 27264..Wh ok
Jahr: 7823.50..Wh ev von heute
ja, du kannst einfach die Readings, die mit "counter" enden mit setreading überschreiben.
Guten Morgen Damian,
sag mal ist es auch möglich auf vorhandene Werte in einem DB Log zurückzugreifen?
Zitat von: der-Lolo am 17 Dezember 2022, 10:21:12
Guten Morgen Damian,
sag mal ist es auch möglich auf vorhandene Werte in einem DB Log zurückzugreifen?
z. Zt. nicht. Das Modul sammelt selbst über die Zeit die Daten und legt sie intern in Readings ab.
Zitat von: der-Lolo am 17 Dezember 2022, 10:21:12
sag mal ist es auch möglich auf vorhandene Werte in einem DB Log zurückzugreifen?
das würde mich auch brennend interessieren ;D
Zitat von: enno am 17 Dezember 2022, 11:08:37
das würde mich auch brennend interessieren ;D
Bereits Post vorher beantwortet.
Ist das ein riesiger umbau?
Der kompakte Card-Style gefällt mir doch sehr sehr gut....
Zitat von: der-Lolo am 17 Dezember 2022, 12:42:27
Ist das ein riesiger umbau?
Der kompakte Card-Style gefällt mir doch sehr sehr gut....
z. Zt. ja. Ich bin noch dabei das hier zu realisieren: https://forum.fhem.de/index.php/topic,130437.msg1246847.html#msg1246847
Danach werde ich mir Gedanken machen, wie man Daten aus bestehenden Logs übernehmen kann.
Auch das schaut sehr gut aus - also ich bin sehr interessiert an einer DB-Log anbindung.
Hallo Damian,
hier passt das wohl am besten:
Es war der Jahreswechsel und ich hatte mich schon gefreut, dem DOIF** (quasi) zuzuschauen, wie es die Daten verschiebt und das neue Jahr zu zählen beginnt.....
Hat aber nicht geklappt, folgendes hab ich dann rausgefunden:
es wird in der midnight-sub auf $mday und $yday geprüft. Das sind ja Perl-Variablen in fhem, die nicht "angepasst" sind, wie z.B. $year oder $month (->1...12). Ich habe dann in "perldoc -f localtime" nachgesehen und dort steht: $mday is the day of the month, also 1...Monatsende, das passt auch, aber $yday: is the day of the year, in the range 0..364 (or 0..365 in leap years.) Hat am 1.1. auch 0 ergeben. Damit wurde natürlich der Teil, der "midnight" am 1.1. ausführen soll, nicht abgearbeitet. Hier muss dann wohl auf $yday==0 geprüft werden.
Da ich 2 der DOIFs eingerichtet habe, habe ich nur bei einem das so geändert und die Werte händisch korrigiert, das 2te habe ich gelassen und gehofft, es läuft dann heute Nacht. Auch wieder nicht, Problem hier: die subs haben keine eindeutigen Namen, und es gilt ja immer die letzte geänderte Version, das war dann die mit dem $yday==0, also kanns am 2.1. ($yday=1) auch nicht gehen....
Hab ich mir dann auch korrigiert, sollte dann nächstes Jahr korrekt laufen.
Und ich hab noch die Jahresprüfung in die Klammer der Monatsprüfung geschoben, dann wird das nur jeden 1. des Monats und nicht täglich geprüft.
sub $SELF_midnight { ## Diese Funktion wird um Mitternacht ausgeführt
my ($device,$reading,$mday,$yday)=@_;
set_Reading("$device.$reading.day_counter",ReadingsVal($device, $reading,1));
set_Reading("$device.$reading.last_day",get_Reading("$device.$reading.day",0),1);
set_Reading("$device.$reading.day",0,1);
set_Reading ("$device.$reading.month",int((ReadingsVal($device, $reading,0)-(get_Reading("$device.$reading.month_counter",0)))*1000)/1000,1);
set_Reading ("$device.$reading.year",int((ReadingsVal($device, $reading,0)-(get_Reading("$device.$reading.year_counter",0)))*1000)/1000,1);
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),1);
set_Reading("$device.$reading.month",0,1);
if ($yday == 0) {
set_Reading("$device.$reading.year_counter",ReadingsVal($device, $reading,0));
set_Reading("$device.$reading.last_year",get_Reading("$device.$reading.year",0),1);
set_Reading("$device.$reading.year",0,1);
}
}
Vielleicht ist das ja hilreich.
Noch ne Frage zu der Art, wie Du das geschrieben hast: Beim Aufruf der sub wird $mday und $yday übergeben, das sind ja die fhem-perl Variablen. In der sub nimmst Du aber die selben Bezeichnungen, deklarierst diese aber neu (my(...$mday,$yday)=@_
Ist das üblich? Ich hätte hier vermutlich eigene Namen genutzt, allerdings gilt die Deklaration nur innerhalb der sub, von daher kann die Variable heissen wie sie will....
Gruß
Sany
** 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 (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)
Danke für das Feedback - ist mir gestern noch gar nicht aufgefallen.
Ich habe die Änderung im Wiki nachgetragen.
Lokale Variablen, und das sind auch die Übergabeparameter, überlagern die globalen Variablen. Das ist in allen mir bekannten Programmiersprachen so.
Man kann ja auch Variablen in einem if-block definieren oder in einer for-Schleife, die leben noch kürzer und überlagern auch die vorherigen.
Ob man die jetzt gleich nennt oder nicht ist eher Geschmacksache.
Es gibt heute eine neue DOIF-Version. Mir ist gestern aufgefallen, dass bei großen Zeiträumen, wie im letzten Jahresdiagramm der Plot etwas verschoben war.
Allerdings ist ja die Darstellung der kumulierten Größen immer um einen Tag bzw. Monat verschoben - das ist zwar prinzipbedingt, aber suboptimal. Daher bastle ich schon fleißig an der card-bars-Darstellung, die für kumulierte Größen besser geeignet ist.
Zitat von: Damian am 02 Januar 2023, 13:37:48Man kann ja auch Variablen in einem if-block definieren oder in einer for-Schleife, die leben noch kürzer und überlagern auch die vorherigen.
Perl ist immer für eine Überraschung gut. Wieder was gelernt!
Zitat von: Per am 02 Januar 2023, 16:05:53
Perl ist immer für eine Überraschung gut. Wieder was gelernt!
Du kannst in Perl an beliebiger Stelle sogar einen Block mit eigenen Variablen definieren:
...
{my $var="test";print ($var)}
...
Hallo,
ich habe einige Shellys, die den aktuellen Verbrauch messen.
Und ich habe es endlich geschafft, das DOIF von Damian anzupassen.
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 (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)
Soweit ich verstanden habe, wird hier die Energie und nicht die Leistung anzugeben.
Das wäre also das Reading "energy" aus dem Shelly.
Zusätzlich habe ich dort noch ein UserReading angelegt "relay_0_energy_total:relay_0_energy:.* monotonic {ReadingsNum("$name","relay_0_energy",0)}".
Im Shelly für den Kühlschrank steht z.B.
energy 17776
energy_total 251159
Wenn ich nun im DOIF di_counter_new das Reading energy verwende, dann bekomme ich eine Anzeige von "157 kWh".
Welches Reading der Shelly muss ich verwenden (oder eventuell ein UserReading anlegen)?
Danke im Voraus
lg, Gerhard
Zitat von: gestein am 24 Januar 2023, 15:08:18
Hallo,
ich habe einige Shellys, die den aktuellen Verbrauch messen.
Und ich habe es endlich geschafft, das DOIF von Damian anzupassen.
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 (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)
Soweit ich verstanden habe, wird hier die Energie und nicht die Leistung anzugeben.
Das wäre also das Reading "energy" aus dem Shelly.
Zusätzlich habe ich dort noch ein UserReading angelegt "relay_0_energy_total:relay_0_energy:.* monotonic {ReadingsNum("$name","relay_0_energy",0)}".
Im Shelly für den Kühlschrank steht z.B.
energy 17776
energy_total 251159
Wenn ich nun im DOIF di_counter_new das Reading energy verwende, dann bekomme ich eine Anzeige von "157 kWh".
Welches Reading der Shelly muss ich verwenden (oder eventuell ein UserReading anlegen)?
Danke im Voraus
lg, Gerhard
Wenn der Shelly die Energie (es ist ein Zählerwert der immer aufsteigend sein muss) liefert, dann kannst du doch direkt das Reading vom Shelly angeben und braucht nicht userReading anlegen.
Das habe ich ja nun.
Aber wenn man einfach so startet wie ich und die Shellys schon länger laufen, dann hat das Reading "energy" mitunter schon einen sehr hohen Wert.
Damit wird dann am Anfang viel zu viel angezeigt.
lg, Gerhard
Jetzt habe ich mal den Fernseher eingeschaltet.
Ich wusste ja, dass der relativ viel verbraucht, aber da bräuchte ich fast ein eigenes Kraftwerk :)
energy Anzeige kWh
148380 2464
148706 2790
148995 3079
149260 3344
Und das ca. jede Minute.#
lt. Forum gibt der Shelly über MQTT (so wie ich sie angelegt habe) die Energie-Werte in Wmin aus.
Und die Shellys resetten den Zählstand bei FW-Update oder Reboot.
https://forum.fhem.de/index.php/topic,116554.0.html (https://forum.fhem.de/index.php/topic,116554.0.html)
Daher habe ich das userReading "energy_total" angelegt.
Also wäre es besser, doch das UserReading für die Anzeige zu verwenden.
Aber wie müsste ich die Energiewerte umrechnen, damit sie im DOIF richtig angezeigt werden?
lg, Gerhard
Zitat von: gestein am 24 Januar 2023, 16:59:35
Aber wie müsste ich die Energiewerte umrechnen, damit sie im DOIF richtig angezeigt werden?
60 Wmin entspricht 1 Wh :60 (Eine 60 Watt Lampe, die 1 Minute brennt, braucht genauso viel Energie wie eine 1 Watt Lampe, die 60 Minuten lang brennt)
1 Wmin entspricht 1/60 Wh
149260 Wmin entspricht dann 149260/60=2487,67 Wh und das sind 2,487 kWh
Also Reading in Wmin / 60000 ist der Verbrauch in kWh
Das verstehe ich. Danke.
Aber wo würdest Du die Umrechnung am besten im DOIF einbauen, damit Rundungsfehler minimiert/vermieden werden?
Dein DOIF benötigt ja anscheinend kWh. Richtig?
Hier im Def-Teil etwa?
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
my $diff = int(([$1:$2,0]-(get_Reading("$1.$2.last_counter",0)))*1000)/1000;
set_Reading ("$1.$2.last_counter",[$1:$2,0]);
set_Reading ("$1.$2.day",int(([$1:$2,0]-(get_Reading("$1.$2.day_counter",0)))*1000)/1000,1);
set_Reading ("$1.$2.month",int(([$1:$2,0]-(get_Reading("$1.$2.month_counter",0)))*1000)/1000,1);
set_Reading ("$1.$2.year",int(([$1:$2,0]-(get_Reading("$1.$2.year_counter",0)))*1000)/1000,1);
}
)
Kleine Werte werden ja sonst gnadenlos auf 0 gekürzt, wenn ich das Reading "energy" selbst durch 60.000 teile.
Könntest Du mir da bitte noch helfen?
Vielen Dank im Voraus
lg, Gerhard
hiernach
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
wird gar nichts umgerechnet, es wird in der Einheit dargestellt, in der das angegebene Reading ist.
Das Beispiel verwende ich ja :)
Demnach hätte ich also in der Anzeige Wmin.
Klar geht das. Ist aber nicht sehr aussagekräftig.
Werde dann wohl extra Readings für die kWh im DOIF anlegen und entsprechend umrechnen.
Danke jedenfalls.
Lg, Gerhard
Zitat von: gestein am 24 Januar 2023, 20:48:12
Das Beispiel verwende ich ja :)
Demnach hätte ich also in der Anzeige Wmin.
Klar geht das. Ist aber nicht sehr aussagekräftig.
Werde dann wohl extra Readings für die kWh im DOIF anlegen und entsprechend umrechnen.
Danke jedenfalls.
Lg, Gerhard
Üblicherweise benutzt man kWh, du kannst das Reading auf drei Nachkommastellen genau anzeigen, dann hast du die Genauigkeit von Wh - das reicht allemal. Das Umrechnen kannst du in dem DOIF-Device per DOIF_Readings machen oder z.B. über userReadings im Ursprungsdevice.
Das mit dem Umbau des DOIF ist keine gute Idee.
Besser ist es die Umrechnung in den Devices selbst vorzunehmen und überall das entsprechende Reading gleich zu nennen.
Anscheinend kommen sogar bei den einzelnen Shelly-Modellen die Werte unterschiedlich.
lg, Gerhard
Ich hätte eine Frage zu dem DOIF für die Berechnung des Stromverbrauchs.
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 (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)
Im Template TPL_stat wird eine Differenz-Variable definiert:
my $diff = int(([$1:$2,0]-(get_Reading("$1.$2.last_counter",0)))*1000)/1000;
Die wird aber dann nicht mehr weiter verwendet.
Sollte nicht eigentlich mit der Differenz weitergereichter werden?
Lg, Gerhard
Zitat von: gestein am 28 Januar 2023, 14:26:14
Ich hätte eine Frage zu dem DOIF für die Berechnung des Stromverbrauchs.
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 (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)
Im Template TPL_stat wird eine Differenz-Variable definiert:
my $diff = int(([$1:$2,0]-(get_Reading("$1.$2.last_counter",0)))*1000)/1000;
Die wird aber dann nicht mehr weiter verwendet.
Sollte nicht eigentlich mit der Differenz weitergereichter werden?
Lg, Gerhard
Ich habe die Definition mehrfach geändert, das scheint noch eine Altlast zu sein.
Zitat von: Damian am 28 Januar 2023, 15:11:49
Ich habe die Definition mehrfach geändert, das scheint noch eine Altlast zu sein.
Ich werde demnächst einen neuen Wiki-Beitrag zum Energieverbrauch liefern, siehe https://forum.fhem.de/index.php/topic,131479.msg1260669.html#msg1260669
Zitat von: Damian am 28 Januar 2023, 15:11:49
Ich habe die Definition mehrfach geändert, das scheint noch eine Altlast zu sein.
Kein Problem. Danke.
Da bin ich mal auf die neue Version gespannt.
Schaut sehr schön aus.
Lg, Gerhard
Hier ein Vorgeschmack der neuen Darstellung.
Im Anhang eine Gegenüberstellung der bisherigen Darstellung oben und der neuen unten.
@Damian Ich wollte mal die Verbrauchstatistik via DOIF (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) probieren, aber bei mir funktioniert das nicht.
Events des Quell-Devices (eine Steckdose mit Messfunktion) werden ignoriert.
Ich glaube die Ursache gefunden zu haben:
Meine Devicenamen enthalten Punkte, und bei so einem Device funktioniert es nicht.
Ich hab auch mit 2 Dummies probiert:
dummy_strom --> DOIF funktioniert
dummy.strom --> DOIF funktioniert nicht.
Ich habe den DOIF-Code komplett aus dem Wiki kopiert und lediglich die push Zeilen am Anfang, und die uiTable-Definitionen für die Devices angepasst.
Hat DOIF hier ein Problem mit Punkten in Gerätenamen?
ja, der Name des Readings geht in den Namen des DOIF-Blocks ein. Dort sind keine Punkte erlaubt.
Du kannst den Namen des Blocks in der Definition (rot) löschen, dann werden die Blöcke automatisch benannt:
Zitat day_count_$1_$2 { ## bei einem Event des Zählers, wird der tägliche, monatliche und jährliche Verbrauch im jeweiligen Reading festgehalten
Ich habe eine DOIF-Version eingecheckt. Nun sind auch Punkte im DOIF-Blocknamen erlaubt, damit funktioniert die Definition mit Readings, die Punkte im Namen haben :)
Vielen Dank für die schnelle Ursachenanalyse!
Mit Anpassung des Funktionsnamen klappts wie erwartet.
Und dass es ab morgen auch ohne Anpassung funktioniert ist natürlich auch super!
Zitat von: KyleK am 08 Februar 2023, 19:23:25
Vielen Dank für die schnelle Ursachenanalyse!
Mit Anpassung des Funktionsnamen klappts wie erwartet.
Und dass es ab morgen auch ohne Anpassung funktioniert ist natürlich auch super!
Ich werde demnächst eine neue Version hochladen. Dann mit Säulendiagrammen und einer Statistik auch über Jahre. Als Vorgeschmack siehe: https://forum.fhem.de/index.php/topic,131479.msg1256553.html#msg1256553
Zitat von: Damian am 08 Februar 2023, 19:27:18
Ich werde demnächst eine neue Version hochladen. Dann mit Säulendiagrammen und einer Statistik auch über Jahre. Als Vorgeschmack siehe: https://forum.fhem.de/index.php/topic,131479.msg1256553.html#msg1256553
siehe: https://forum.fhem.de/index.php/topic,120088.msg1263037.html#msg1263037
Hi Damian,
ich habe mal das Beispiel von
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 (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)
über Telnet in mein FHEM eingefügt.
Erhalte leider die Fehlermeldung:
di_counter_new DOIF: Perlblck: no right bracket: {
und kann den Fehler nicht finden.
Was mache ich falsch?
//Roger
Das hatte ich auch.
Am besten zuerst das DOIF nur mit leerer Definition anlegen und dann erst den Teil aus dem Beispiel ins def übernehmen.
Also zuerst
defmod di_counter_new DOIF subs {}
mit allen Attributen und dann die def ändern.
So hat es bei mir funktioniert.
Lg, Gerhard
Hi Gerhard,
danke für Deinen Hinweis. Ja, so bekomme ich das DOIF definiert.
Es wird Warning:
condition c01: "state" variable @_ masks earlier declaration in same scope
angezeigt und bei der Ausführung von init und mid werden Syntaxfehler:
block_init
condition c03: syntax error at (eval 4569878) line 1, at EOF
syntax error at (eval 4569878) line 2, at EOF
syntax error at (eval 4569878) line 3, at EOF
block_mid
condition c01: syntax error at (eval 4571068) line 4, near "\
sub midnight "
Can't use global @_ in "my" at (eval 4571068) line 4, near "=@_"
syntax error at (eval 4571068) line 11, near "\
if"
syntax error at (eval 4571068) line 15, near "\
if"
syntax error at (eval 4571068) line 19, at EOF
Can't use global @_ in "my" at (eval 4571068) line 24, near "=@_"
syntax error at (eval 4571068) line 25, near "\
if"
syntax error at (eval 4571068) line 30, near "; }"
Komme hier leider nicht weiter. :(
Hast Du noch Ideen? Kannst Du mal Deine funktionierende DEF für Tages- Monats- und Jahres-Werte posten?
//Roger
Die Beispiele sind für RAW-Definition (siehe Pluszeichen oben in der Weboberfläche). Manuelles Einfügen in DEF oder in Attributen wird nicht gut funktionieren.
Hallo Damian,
ich habe Deine DOIF nutzen wollen, um mir die Verbrauchstwerte schon darzstellen. Aber irgendwie kommt da bei mir nichts an.
Das Device und die Readings stimmen zu 100%.Wo liegt der Fehler? Im Log ist auch nichts drin.
Hier mal ein List des Device.
Internals:
DEF subs {
## Device Reading hier die push-Zeilen löschen bzw. durch eigene Readings ersetzen
push (@{$_counter},["Stromzaehler","Erzeugte_kWh"]); ## Solarenergie
push (@{$_counter},["Stromzaehler","Bezug180"]); ## Bezugszähler
push (@{$_counter},["Stromzaehler","Einspeisung280"]); ## Einspeisezähler
## Die restliche Code-Definition muss nicht angepasst werden
## Anpassung der Visualisierung wird im uiTable-Attribut weiter unten vorgenommen
sub midnight { ## Diese Funktion wird um Mitternacht ausgeführt
my ($device,$reading,$mday,$yday)=@_;
set_Reading("$device.$reading.day_counter",ReadingsVal($device, $reading,1));
set_Reading("$device.$reading.last_day",get_Reading("$device.$reading.day",0),1);
set_Reading("$device.$reading.day",0,1);
set_Reading ("$device.$reading.month",int((ReadingsVal($device, $reading,0)-(get_Reading("$device.$reading.month_counter",0)))*1000)/1000,1);
set_Reading ("$device.$reading.year",int((ReadingsVal($device, $reading,0)-(get_Reading("$device.$reading.year_counter",0)))*1000)/1000,1);
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),1);
set_Reading("$device.$reading.month",0,1);
if ($yday == 0) {
set_Reading("$device.$reading.year_counter",ReadingsVal($device, $reading,0));
set_Reading("$device.$reading.last_year",get_Reading("$device.$reading.year",0),1);
set_Reading("$device.$reading.year",0,1);
}
}
}
sub init_readings {
my ($device,$reading)=@_;
if (get_Reading("$device.$reading.day_counter","") eq "") { ## Initialisierung der Readings
## aktuellen Zählerstand initialisieren
set_Reading("$device.$reading.last_counter",ReadingsVal($device, $reading,0));
set_Reading("$device.$reading.day_counter",ReadingsVal($device, $reading,0));
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
## Log definieren
fhem ("defmod log.counter.$device.$reading FileLog ./log/counter.$device.$reading.log $SELF:$device.$reading.(last_(day|month|year)|(day|month)_counter):.*");
fhem ("attr log.counter.$device.$reading room Filelogs");
## Tasmota-Zähler setzen: set MQTT2_FHEM_Server publish cmnd/tasmota_C58DCB/Counter1 <Zählerstand>
}
}
} ## Ende subs-Block
mid {[00:01]; ## Sicherung der Daten um Mitternacht
for (my $i=0;$i<@{$_counter};$i++) { ## Für jeden Zähler wird die Funktion midnight aufgerufen
midnight($_counter[$i][0],$_counter[$i][1],$mday,$yday);
}
}
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
my $diff = int(([$1:$2,0]-(get_Reading("$1.$2.last_counter",0)))*1000)/1000;
set_Reading ("$1.$2.last_counter",[$1:$2,0]);
set_Reading ("$1.$2.day",int(([$1:$2,0]-(get_Reading("$1.$2.day_counter",0)))*1000)/1000,1);
set_Reading ("$1.$2.month",int(([$1:$2,0]-(get_Reading("$1.$2.month_counter",0)))*1000)/1000,1);
set_Reading ("$1.$2.year",int(([$1:$2,0]-(get_Reading("$1.$2.year_counter",0)))*1000)/1000,1);
}
)
## 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 63d65423-f33f-8212-e291-070e723705f81e15
MODEL Perl
NAME di_Stromwerte
NOTIFYDEV Stromzaehler,global,di_Stromwerte
NR 223
NTFY_ORDER 50-di_Stromwerte
STATE initialized
TYPE DOIF
VERSION 26938 2023-01-01 18:13:32
eventCount 169
READINGS:
2023-02-14 11:03:15 Stromzaehler.Bezug180.day 0
2023-02-14 11:03:15 Stromzaehler.Bezug180.day_counter 1678
2023-02-14 10:50:52 Stromzaehler.Bezug180.last_counter 1678
2023-02-14 11:03:15 Stromzaehler.Bezug180.last_day 0
2023-02-14 10:50:52 Stromzaehler.Bezug180.last_month 0
2023-02-14 10:50:52 Stromzaehler.Bezug180.last_year 0
2023-02-14 11:03:15 Stromzaehler.Bezug180.month 0
2023-02-14 10:50:52 Stromzaehler.Bezug180.month_counter 1678
2023-02-14 11:03:15 Stromzaehler.Bezug180.year 0
2023-02-14 10:50:52 Stromzaehler.Bezug180.year_counter 1678
2023-02-14 10:50:10 Stromzaehler.Bezug_1.8.0.day 0
2023-02-14 10:50:10 Stromzaehler.Bezug_1.8.0.day_counter 1678
2023-01-29 12:16:53 Stromzaehler.Bezug_1.8.0.last_counter 985
2023-02-14 10:50:10 Stromzaehler.Bezug_1.8.0.last_day 0
2023-02-01 00:01:00 Stromzaehler.Bezug_1.8.0.last_month 642.23
2023-01-29 12:16:53 Stromzaehler.Bezug_1.8.0.last_year 0
2023-02-14 10:50:10 Stromzaehler.Bezug_1.8.0.month 1648
2023-02-04 00:25:41 Stromzaehler.Bezug_1.8.0.month_counter 30
2023-02-14 10:50:10 Stromzaehler.Bezug_1.8.0.year 693
2023-01-29 12:16:53 Stromzaehler.Bezug_1.8.0.year_counter 985
2023-02-14 11:03:15 Stromzaehler.Einspeisung280.day 0
2023-02-14 11:03:15 Stromzaehler.Einspeisung280.day_counter 4965
2023-02-14 10:50:52 Stromzaehler.Einspeisung280.last_counter 4965
2023-02-14 11:03:15 Stromzaehler.Einspeisung280.last_day 0
2023-02-14 10:50:52 Stromzaehler.Einspeisung280.last_month 0
2023-02-14 10:50:52 Stromzaehler.Einspeisung280.last_year 0
2023-02-14 11:03:15 Stromzaehler.Einspeisung280.month 0
2023-02-14 10:50:52 Stromzaehler.Einspeisung280.month_counter 4965
2023-02-14 11:03:15 Stromzaehler.Einspeisung280.year 0
2023-02-14 10:50:52 Stromzaehler.Einspeisung280.year_counter 4965
2023-02-14 10:50:10 Stromzaehler.Einspeisung_2.8.0.day 0
2023-02-14 10:50:10 Stromzaehler.Einspeisung_2.8.0.day_counter 4965
2023-01-29 12:16:53 Stromzaehler.Einspeisung_2.8.0.last_counter 4942
2023-02-14 10:50:10 Stromzaehler.Einspeisung_2.8.0.last_day 0
2023-02-01 00:01:00 Stromzaehler.Einspeisung_2.8.0.last_month 0
2023-01-29 12:16:53 Stromzaehler.Einspeisung_2.8.0.last_year 0
2023-02-14 10:50:10 Stromzaehler.Einspeisung_2.8.0.month 23
2023-02-01 00:01:00 Stromzaehler.Einspeisung_2.8.0.month_counter 4942
2023-02-14 10:50:10 Stromzaehler.Einspeisung_2.8.0.year 23
2023-01-29 12:16:53 Stromzaehler.Einspeisung_2.8.0.year_counter 4942
2023-02-14 11:03:15 Stromzaehler.Erzeugte_kWh.day 0
2023-02-14 11:03:15 Stromzaehler.Erzeugte_kWh.day_counter 195
2023-02-04 00:20:58 Stromzaehler.Erzeugte_kWh.last_counter 195
2023-02-14 11:03:15 Stromzaehler.Erzeugte_kWh.last_day 0
2023-02-01 00:01:00 Stromzaehler.Erzeugte_kWh.last_month 0
2023-01-29 12:16:53 Stromzaehler.Erzeugte_kWh.last_year 0
2023-02-14 11:03:15 Stromzaehler.Erzeugte_kWh.month -63
2023-02-01 00:01:00 Stromzaehler.Erzeugte_kWh.month_counter 258
2023-02-14 11:03:15 Stromzaehler.Erzeugte_kWh.year -63
2023-01-29 12:16:53 Stromzaehler.Erzeugte_kWh.year_counter 258
2023-02-14 10:50:52 block_init executed
2023-02-14 11:03:15 block_mid executed
2023-02-14 10:50:52 mode enabled
2023-02-14 10:50:52 state initialized
2023-02-14 10:50:52 timer_01_c01 15.02.2023 00:01:00
Regex:
accu:
collect:
di_Stromwerte:
collect:
Stromzaehler.Bezug180.day ^di_Stromwerte$:^Stromzaehler.Bezug180.day:
Stromzaehler.Bezug180.last_day ^di_Stromwerte$:^Stromzaehler.Bezug180.last_day:
Stromzaehler.Bezug180.last_month ^di_Stromwerte$:^Stromzaehler.Bezug180.last_month:
Stromzaehler.Einspeisung280.day ^di_Stromwerte$:^Stromzaehler.Einspeisung280.day:
Stromzaehler.Einspeisung280.last_day ^di_Stromwerte$:^Stromzaehler.Einspeisung280.last_day:
Stromzaehler.Einspeisung280.last_month ^di_Stromwerte$:^Stromzaehler.Einspeisung280.last_month:
Stromzaehler.Erzeugte_kWh.day ^di_Stromwerte$:^Stromzaehler.Erzeugte_kWh.day:
Stromzaehler.Erzeugte_kWh.last_day ^di_Stromwerte$:^Stromzaehler.Erzeugte_kWh.last_day:
Stromzaehler.Erzeugte_kWh.last_month ^di_Stromwerte$:^Stromzaehler.Erzeugte_kWh.last_month:
cond:
Stromzaehler:
2:
Erzeugte_kWh ^Stromzaehler$:^Erzeugte_kWh:
3:
Bezug180 ^Stromzaehler$:^Bezug180:
4:
Einspeisung280 ^Stromzaehler$:^Einspeisung280:
uiTable:
di_Stromwerte:
di_Stromwerte_uiTable_c_0_0_0_0:
Stromzaehler.Bezug180.day ^di_Stromwerte$:^Stromzaehler.Bezug180.day:
di_Stromwerte_uiTable_c_0_1_0_0:
Stromzaehler.Bezug180.last_day ^di_Stromwerte$:^Stromzaehler.Bezug180.last_day:
di_Stromwerte_uiTable_c_0_2_0_0:
Stromzaehler.Bezug180.last_month ^di_Stromwerte$:^Stromzaehler.Bezug180.last_month:
di_Stromwerte_uiTable_c_1_0_0_0:
Stromzaehler.Einspeisung280.day ^di_Stromwerte$:^Stromzaehler.Einspeisung280.day:
di_Stromwerte_uiTable_c_1_1_0_0:
Stromzaehler.Einspeisung280.last_day ^di_Stromwerte$:^Stromzaehler.Einspeisung280.last_day:
di_Stromwerte_uiTable_c_1_2_0_0:
Stromzaehler.Einspeisung280.last_month ^di_Stromwerte$:^Stromzaehler.Einspeisung280.last_month:
di_Stromwerte_uiTable_c_2_0_0_0:
Stromzaehler.Erzeugte_kWh.day ^di_Stromwerte$:^Stromzaehler.Erzeugte_kWh.day:
di_Stromwerte_uiTable_c_2_1_0_0:
Stromzaehler.Erzeugte_kWh.last_day ^di_Stromwerte$:^Stromzaehler.Erzeugte_kWh.last_day:
di_Stromwerte_uiTable_c_2_2_0_0:
Stromzaehler.Erzeugte_kWh.last_month ^di_Stromwerte$:^Stromzaehler.Erzeugte_kWh.last_month:
card:
collect:
di_Stromwerte Stromzaehler.Bezug180.day:
168:
animate 0
dim 72
hours 168
last_v
max_value 0
max_value_slot 71
max_value_time 1676369038
min_value 0
min_value_slot 71
min_value_time 1676369038
name di_Stromwerte
reading Stromzaehler.Bezug180.day
time 1676369038
value 0
times:
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
1676369038
values:
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
0
di_Stromwerte Stromzaehler.Bezug180.last_day:
672:
animate 0
dim 72
hours 672
last_v
max_value 0
max_value_slot 71
max_value_time 1676369038
min_value 0
min_value_slot 71
min_value_time 1676369038
name di_Stromwerte
reading Stromzaehler.Bezug180.last_day
time 1676369038
value 0
times:
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
1676369038
values:
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
0
di_Stromwerte Stromzaehler.Bezug180.last_month:
8760:
animate 0
dim 72
hours 8760
last_v
max_value 0
max_value_slot 71
max_value_time 1676369038
min_value 0
min_value_slot 71
min_value_time 1676369038
name di_Stromwerte
reading Stromzaehler.Bezug180.last_month
time 1676369038
value 0
times:
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
1676369038
values:
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
0
di_Stromwerte Stromzaehler.Bezug_1.8.0.day:
168:
animate 0
dim 72
hours 168
last
last_v 0
last_value 0
max_value 0
max_value_slot 71
max_value_time 1676367598
min_value 0
min_value_slot 71
min_value_time 1676367598
name di_Stromwerte
reading Stromzaehler.Bezug_1.8.0.day
time 1676368210
value 0
times:
undef
undef
undef
undef
undef
1675810860
undef
undef
undef
undef
undef
undef
undef
undef
undef
1675897260
undef
undef
undef
undef
undef
undef
undef
undef
undef
1675983660
1675985004
undef
undef
undef
undef
undef
undef
undef
undef
undef
1676070060
undef
undef
undef
undef
undef
undef
undef
undef
undef
1676156463
undef
undef
undef
undef
undef
undef
undef
undef
undef
1676242860
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
1676329260
undef
undef
undef
1676367598
values:
undef
undef
undef
undef
undef
0
undef
undef
undef
undef
undef
undef
undef
undef
undef
0
undef
undef
undef
undef
undef
undef
undef
undef
undef
0
0
undef
undef
undef
undef
undef
undef
undef
undef
undef
0
undef
undef
undef
undef
undef
undef
undef
undef
undef
0
undef
undef
undef
undef
undef
undef
undef
undef
undef
0
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
0
undef
undef
undef
0
di_Stromwerte Stromzaehler.Bezug_1.8.0.last_day:
672:
animate 0
dim 72
hours 672
last
last_v 0
max_value 0
max_value_slot 71
max_value_time 1676367598
min_value 0
min_value_slot 71
min_value_time 1676367598
name di_Stromwerte
reading Stromzaehler.Bezug_1.8.0.last_day
time 1676368210
value 0
times:
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
1674992900
1674995440
1675033260
undef
1675119660
undef
undef
1675206060
undef
1675292460
undef
undef
1675378860
1675418291
1675435539
1675464926
1675523422
1675543355
1675587255
undef
1675638060
undef
1675724460
undef
undef
1675810860
undef
1675897260
undef
undef
1675983660
undef
undef
1676070060
undef
1676156463
undef
undef
1676242860
undef
1676329260
1676367598
values:
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
0
0
0
undef
0
undef
undef
0
undef
0
undef
undef
0
0
0
0
0
0
0
undef
0
undef
0
undef
undef
0
undef
0
undef
undef
0
undef
undef
0
undef
0
undef
undef
0
undef
0
0
di_Stromwerte Stromzaehler.Bezug_1.8.0.last_month:
8760:
animate 0
dim 72
hours 8760
last
last_v 642.23
max_value 642.23
max_value_slot 71
max_value_time 1676367598
min_value 642.23
min_value_slot 71
min_value_time 1676367598
name di_Stromwerte
reading Stromzaehler.Bezug_1.8.0.last_month
time 1676368157
value 642.23
times:
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
1675206060
1675543355
1675984686
1676367598
values:
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
642.23
642.23
642.23
642.23
di_Stromwerte Stromzaehler.Einspeisung280.day:
168:
animate 0
dim 72
hours 168
last_v
max_value 0
max_value_slot 71
max_value_time 1676369038
min_value 0
min_value_slot 71
min_value_time 1676369038
name di_Stromwerte
reading Stromzaehler.Einspeisung280.day
time 1676369038
value 0
times:
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
undef
Zitat von: Roger am 13 Februar 2023, 23:46:09
Hast Du noch Ideen? Kannst Du mal Deine funktionierende DEF für Tages- Monats- und Jahres-Werte posten?
Wenn Du beim def den Code aus dem Wiki-Beispiel einfügst, musst Du die "\" am Ende entfernen - wie Damian schon sagte.
Dann hat es bei mir ohne Probleme funktioniert.
Mittlerweile habe ich das Bespiel von Damian aber ziemlich verändert, da ich dort nun keine starre Definition der Devices haben möchte (sondern über eine Regex) und auch Gruppen bilden möchte (also z.B. den Verbrauch aller Haushaltsgeräte).
Das klappt aber noch nicht ganz.
lg, Gerhard
Habe die \ jetzt überall entfernt. Funktioniert aber trotzdem nicht.
Gruss
Dennis
Lt. Auszug werden entsprechende Readings erzeugt und intern die Werte gesammelt.
Aber die Grafik zeigt nichts an :(
Zitat von: dennis_n am 14 Februar 2023, 13:23:23
Aber die Grafik zeigt nichts an :(
Es hängt von der Grafik ab. Der Tagesverlauf (erste Spalte) sollte sofort etwas zeigen, die anderen erst am nächsten Tag, Monat oder Jahr
So sieht es bei mir aus. Also keine Werte.
Habe auch niergends ein Fehler, im Log oder bei den Readings.
Zitat von: dennis_n am 14 Februar 2023, 13:31:14
So sieht es bei mir aus. Also keine Werte.
Habe auch niergends ein Fehler, im Log oder bei den Readings.
Hast du auch die aktuelle DOIF-Version ;)
Du meinst die von hier?
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
Nein, sorry. Habe eben erst gelesen, dass es eine neue gibt :-X
Zitat von: dennis_n am 14 Februar 2023, 13:41:35
Du meinst die von hier?
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
Nein, sorry. Habe eben erst gelesen, dass es eine neue gibt :-X
Ich meine die aktuelle Version des Beispiels, sondern die aktuelle Version des Programms (update).
Achso ja sorry.
Habe mein fhem und somit doif letzte Woche erneuert.
Gruss
Dennis
Zitat von: dennis_n am 14 Februar 2023, 13:48:09
Achso ja sorry.
Habe mein fhem und somit doif letzte Woche erneuert.
Gruss
Dennis
Nimm am besten die aktuelle (von heute).
Hallo Damian,
gerade eben musste ich meinen fhem nach einem Update neu starten und das DOIF für den Stromverbrauch hat es wieder nicht überlebt.
Es ist zwar noch in der fhem.cfg, aber es wird nicht angelegt.
Es erscheint auch keine Fehlermeldung im log.
Wenn ich nun das nächste Mal die Konfig abspeichere, ist natürlich das Device auch im fhem.cfg weg.
Kann das mit dem Problem zusammenhängen, dass man das Bespiel nicht einfach so kopieren und das define ausführen kann?
lg, Gerhard
Zitat von: gestein am 14 Februar 2023, 15:25:19
Hallo Damian,
gerade eben musste ich meinen fhem nach einem Update neu starten und das DOIF für den Stromverbrauch hat es wieder nicht überlebt.
Es ist zwar noch in der fhem.cfg, aber es wird nicht angelegt.
Es erscheint auch keine Fehlermeldung im log.
Wenn ich nun das nächste Mal die Konfig abspeichere, ist natürlich das Device auch im fhem.cfg weg.
Kann das mit dem Problem zusammenhängen, dass man das Bespiel nicht einfach so kopieren und das define ausführen kann?
lg, Gerhard
Die Daten werden in versteckten Readings des Devices abgelegt, diese werden bei save oder shutdown in der save-Datei vom FHEM gespeichert. Möglicherweise ist in global autosave bei dir durch einen Absturz abgeschaltet (Wert 0).
Hallo Damian,
es geht um das Device an sich, nicht nur um die Readings.
Bei einem Reboot wird das Device nicht mehr angelegt, obwohl es in der fhem.cfg steht.
lg, Gerhard
ZitatKann das mit dem Problem zusammenhängen, dass man das Bespiel nicht einfach so kopieren und das define ausführen kann?
wie legst du das Ding denn an? Das sollte sich einfach über "Raw input" einfügen lassen.
Lässt es sich aber leider nicht (siehe auch den Beitrag von z.B. Roger).
Bei komplexeren Definitionen von DOIF klappt das Anlegen per "+" nicht.
Dann muss man das DOIF mit einer leeren Definition anlegen und die komplexe Definition dann in einem zweiten Schritt in der Device-Ansicht ändern.
lg, Gerhard
Zitat von: gestein am 14 Februar 2023, 16:59:36
Lässt es sich aber leider nicht (siehe auch den Beitrag von z.B. Roger).
Bei komplexeren Definitionen von DOIF klappt das Anlegen per "+" nicht.
Dann muss man das DOIF mit einer leeren Definition anlegen und die komplexe Definition dann in einem zweiten Schritt in der Device-Ansicht ändern.
lg, Gerhard
Kann ich bei mir nicht bestätigen. Das aktuelle Beispiel kann ich per + ohne Probleme definieren. Es handelt sich um ein Testsystem, wo zuvor dieses Device nicht existierte. Es handelte sich um einen schwachen PI-2. An der Performance des Rechners kann es also auch nicht liegen.
Ich kann Entwarnung geben.
Nach update geht das Anlegen im Telnet (also auch ohne erst ein leeres Device anzulegen) ohne Fehler.
Nun muss ich die Definition an meine Konfiguration anpassen.
Danke //Roger
Auch bei mir klappt das Importieren des Beispiels nach dem gestrigen Update nun ohne Probleme.
Allerdings verschwindet mein selbstgeschriebenes DOIF nach einem Reboot immer noch.
Es steht zwar im fhem.cfg (zumindest bis ich eine Änderung speichere), wird aber nicht angelegt.
Im log erscheint dafür die gesamte Definition des Devices, aber ohne eine Fehlermeldung.
Wenn ich den Code aus fhem.cfg kopiere und per "+" in FHEM einfüge, bekomme ich wieder die altbekannte Fehlermeldung.
- Import mit "\" am Zeilenende -> Fehlermeldung "di_counter_new2 DOIF: :energy_total_kWh: subs {"
Dann folgt der Code der Definition. Leider aber im Dialogfenster abgeschnitten, da zu lang
- Import ohne "\" am Zeilenende -> Fehlermeldung "di_counter_new DOIF: Perlblck: no right bracket: {"
Das ist aber klar.
@Damian: Könntest Du bitte mal versuchen meine Defintion des "di_counter_new2" zu importieren?
Klappt das bei Dir auch?
Überlebt die Definition des Devices auch einen Reboot von FHEM?
Danke im Voraus
lg, Gerhard
define di_counter_new2 DOIF subs {\
\
sub CalculateSums {\
my $Reading=::AttrVal("$SELF","EnergyReading","");;\
my $Prefix=::AttrVal("$SELF","SummaryPrefix","");;\
my ($DefFilterName,$DefFilter)=split /;;/, ::AttrVal("$SELF","SummaryFilter","");;\
\
## my $readings = $::defs{$d}->{READINGS};;\
my @Categories=split /,/, ::AttrVal("$SELF","SummaryList","");;\
\
if (@Categories > 0) {\
foreach my $Category (@Categories) {\
my ($Name,$Filter)=split /;;/, $Category;;\
$Filter =~s/$DefFilterName/$DefFilter/ig;;\
my @Devices = ::devspec2array($Filter);;\
my $counter_temp=0;;\
my $hour_temp=0;;\
my $hour_counter_temp=0;;\
my $quarter_temp=0;;\
my $quarter_counter_temp=0;;\
\
set_Reading("test_$Name","$Filter;; $DefFilterName, $DefFilter",0);;\
\
foreach my $Device (@Devices) {\
$counter_temp+=get_Reading("$Device\.$Reading\_counter",0);;\
$hour_temp+=get_Reading("$Device\.$Reading\_hour",0);;\
$hour_counter_temp+=get_Reading("$Device.$Reading\_hour_counter",0);;\
$quarter_temp+=get_Reading("$Device\.$Reading\_quarter",0);;\
$quarter_counter_temp+=get_Reading("$Device\.$Reading\_quarter_counter",0);;\
}\
set_Reading($Prefix."$Name\_counter",$counter_temp);;\
set_Reading($Prefix."$Name\_hour",$hour_temp);;\
set_Reading($Prefix."$Name\_hour_counter",$hour_counter_temp);;\
set_Reading($Prefix."$Name\_quarter",$quarter_temp);;\
set_Reading($Prefix."$Name\_quarter_counter",$quarter_counter_temp);;\
}\
}\
}\
\
sub SumUpCategories {\
my ($device,$reading,$diff)=@_;;\
my ($DefFilterName,$DefFilter)=split /;;/, ::AttrVal("$SELF","SummaryFilter","");;\
my @Categories=split /,/, ::AttrVal("$SELF","SummaryList","");;\
\
return if (@Categories == 0);;\
\
foreach my $Category (@Categories) {\
my ($Name,$Filter)=split /;;/, $Category;;\
$Filter =~s/$DefFilterName/$DefFilter/ig;;\
my @Devices = ::devspec2array($Filter);;\
if(grep(/^$device$/, @Devices )) {\
my $alias=::AttrVal("$device","alias","");;\
set_Reading("test.$device","gefunden in $Name ($alias): $diff",0);;\
::Log 1, "SumUpCategories;; $diff;; $device;; $Name ($alias);; ".get_Reading("$Name.$reading.day",0);;\
## set_Reading("$Name.$reading.last_counter",get_Reading ("$Name.$reading.last_counter",0)+$diff,1);;\
set_Reading("$Name.$reading.day",get_Reading("$Name.$reading.day",0)+$diff,1);;\
set_Reading("$Name.$reading.month",get_Reading("$Name.$reading.month",0)+$diff,1);;\
set_Reading("$Name.$reading.year",get_Reading("$Name.$reading.year",0)+$diff,1);;\
}\
} \
}\
\
sub midnight { ## Diese Funktion wird um Mitternacht ausgeführt\
my ($device,$reading,$mday,$yday,$newval)=@_;;\
set_Reading("$device.$reading.day_counter",$newval);;\
set_Reading("$device.$reading.last_day",get_Reading("$device.$reading.day",0),1);;\
set_Reading("$device.$reading.day",0,1);;\
set_Reading("$device.$reading.month",int(($newval-(get_Reading("$device.$reading.month_counter",0)))*1000)/1000,1);;\
set_Reading("$device.$reading.year",int(($newval-(get_Reading("$device.$reading.year_counter",0)))*1000)/1000,1);;\
\
if ($mday == 1) {\
set_Reading("$device.$reading.month_counter",$newval);;\
set_Reading("$device.$reading.last_month",get_Reading("$device.$reading.month",0),1);;\
set_Reading("$device.$reading.month",0,1);;\
if ($yday == 0) {\
set_Reading("$device.$reading.year_counter",$newval);;\
set_Reading("$device.$reading.last_year",get_Reading("$device.$reading.year",0),1);;\
set_Reading("$device.$reading.year",0,1);;\
}\
}\
}\
\
sub init_readings {\
my ($device,$reading,$newval)=@_;;\
my $alias=::AttrVal($device, "alias","");;\
\
if($alias ne "") {set_Reading("$device.$reading",$alias);;}\
if (get_Reading("$device.$reading.day_counter","") eq "") { ## Initialisierung der Readings\
## aktuellen Zählerstand initialisieren\
set_Reading("$device.$reading.last_counter",$newval);;\
set_Reading("$device.$reading.day_counter",$newval);; \
set_Reading("$device.$reading.month_counter",$newval);;\
set_Reading("$device.$reading.year_counter",$newval);;\
\
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\
\
## Log definieren\
fhem ("defmod log.counter.$device.$reading FileLog ./log/counter.$device.$reading.log $SELF:$device.$reading.last_(day|month|year):.*");;\
fhem ("attr log.counter.$device.$reading room Filelogs");;\
}\
}\
} ## Ende subs-Block\
\
resetAllEnergyData {\
foreach my $Device (::devspec2array(::AttrVal("$SELF","UsedDevFilter",""))) {\
if(ReadingsVal("$Device","relay_0_energy_total","err") ne "err") {\
fhem("setreading $Device relay_0_energy_total 0");;\
fhem("setreading $Device energy_total 0");;\
fhem("setreading $Device energy_total_kWh 0");;\
fhem("setreading $Device energy_total_reset done");;\
} elsif(ReadingsVal("$Device","relay_1_energy_total","err") ne "err") {\
fhem("setreading $Device relay_1_energy_total 0");;\
fhem("setreading $Device energy_total 0");;\
fhem("setreading $Device energy_total_kWh 0");;\
fhem("setreading $Device energy_total_reset done");;\
} elsif(ReadingsVal("$Device","light_0_energy_total","err") ne "err") {\
fhem("setreading $Device light_0_energy_total 0");;\
fhem("setreading $Device energy_total 0");;\
fhem("setreading $Device energy_total_kWh 0");;\
fhem("setreading $Device energy_total_reset done");;\
}\
}\
}\
\
get_data { ## Optionale Übernahme bestehender Daten aus dem Log\
my $reading=::AttrVal("$SELF","EnergyReading","");;\
\
foreach my $Device (::devspec2array(::AttrVal("$SELF","UsedDevFilter",""))) {\
::DOIF_set_card_data ("$SELF","$SELF","$Device.$reading.last_day","bar1month",-300,fhem("get log.counter.$Device.$reading ./log/counter.$Device.$reading.log - 2000 3000 4:last_day"));;\
::DOIF_set_card_data ("$SELF","$SELF","$Device.$reading.last_month","bar2year",-300,fhem("get log.counter.$Device.$reading ./log/counter.$Device.$reading.log - 2000 3000 4:last_month"));;\
::DOIF_set_card_data ("$SELF","$SELF","$Device.$reading.last_year","bar2decade",-300,fhem("get log.counter.$Device.$reading ./log/counter.$Device.$reading.log - 2000 3000 4:last_year"));;\
}\
}\
\
deleteAllReadings {\
fhem("deletereading $SELF .*");;\
}\
\
mid {[00:01];; ## Sicherung der Daten um Mitternacht\
my $newval=ReadingsVal($device, $reading,0);;\
my $reading=::AttrVal("$SELF","EnergyReading","");;\
foreach my $Device (::devspec2array(::AttrVal("$SELF","UsedDevFilter",""))) { ## Für jeden Zähler wird die Funktion midnight aufgerufen\
midnight($Device,$reading,$mday,$yday,$newval);;\
}\
my @Categories=split /,/, ::AttrVal("$SELF","SummaryList","");;\
foreach my $Category (@Categories) {\
my ($Name,$Filter)=split /;;/, $Category;;\
$newval=get_Reading("$Name.$reading.day",0);;\
midnight($Name,$reading,$mday,$yday,$newval);;\
}\
}\
\
init { ## initialisierung aller Readings\
my $reading=::AttrVal("$SELF","EnergyReading","");;\
my $newval=0;;\
foreach my $Device (::devspec2array(::AttrVal("$SELF","UsedDevFilter",""))) {## Für jeden Zähler werden Readings über die Funktion init_readings initialisiert\
$newval=ReadingsVal($Device, $reading,0);;\
init_readings($Device,$reading,$newval);;\
}\
my @Categories=split /,/, ::AttrVal("$SELF","SummaryList","");;\
foreach my $Category (@Categories) {\
my ($Name,$Filter)=split /;;/, $Category;;\
my ($DefFilterName,$DefFilter)=split /;;/, ::AttrVal("$SELF","SummaryFilter","");;\
$Filter =~s/$DefFilterName/$DefFilter/ig;;\
my @Devices = ::devspec2array($Filter);;\
set_Reading("$Name.members","@Devices");;\
$newval=0;;\
foreach my $Device (@Devices) {\
$newval+=ReadingsVal("$Device","$reading",0);;\
}\
init_readings($Name,$reading,$newval);;\
}\
}\
\
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\
\
my $diff = int(([$1:$2,0]-(get_Reading("$1.$2.last_counter",0)))*1000)/1000;;\
set_Reading ("$1.$2.last_counter",[$1:$2,0]);;\
set_Reading ("$1.$2.day",int(([$1:$2,0]-(get_Reading("$1.$2.day_counter",0)))*1000)/1000,1);;\
set_Reading ("$1.$2.month",int(([$1:$2,0]-(get_Reading("$1.$2.month_counter",0)))*1000)/1000,1);;\
set_Reading ("$1.$2.year",int(([$1:$2,0]-(get_Reading("$1.$2.year_counter",0)))*1000)/1000,1);;\
\
if ($diff>0) {\
SumUpCategories("$1","$2",$diff);;\
}\
}\
)\
\
##https://forum.fhem.de/index.php/topic,84969.msg1208710.html#msg1208710\
CalculateQuarterSums { [([+:15]+[00:01])];;\
## set_Reading("Summary_Total_last_quarter_sum",[?#sum:"^$SELF$":"last_quarter$"]);;\
## CalculateSums();;\
}\
CalculateHourSums { [:01];;\
## set_Reading("Summary_Total_last_hour_sum",[?#sum:"^$SELF$":"last_hour$"]);;\
## CalculateSums();;\
}\
\
\
## 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\
## FOR(::devspec2array("id=shelly.*:FILTER=disable!=1"), TPL_stat ($_,energy_total))\
FOR(::devspec2array(::AttrVal("$SELF","UsedDevFilter","")), TPL_stat ($_,energy_total_kWh))
attr di_counter_new2 userattr SummaryList SummaryPrefix SummaryFilter UsedDevFilter EnergyReading
attr di_counter_new2 EnergyReading energy_total_kWh
attr di_counter_new2 SummaryFilter <default>;;id=shelly.*:FILTER=disable!=1
attr di_counter_new2 SummaryList Haushalt;;<default>:FILTER=group=Haushaltsgeräte,Multimedia;;<default>:FILTER=group=Multimedia,Licht;;<default>:FILTER=group=Licht,IT;;<default>:FILTER=group=IT
attr di_counter_new2 UsedDevFilter id=shelly.*:FILTER=disable!=1
attr di_counter_new2 comment 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
attr di_counter_new2 room Verbrauch
attr di_counter_new2 uiTable {package ui_Table;;} ## Optionale Visualisierung der Energie-Verbräuche/-Produktion im DOIF-Device\
\
## Template für die Darstellung eines Wertes\
DEF TPL_single (\
card([$SELF:$2.$3.day:col1w],"$1 Tagesverlauf",undef,$4,$5,$8,$9,"$10",undef,"1","130,1,1,0,1,0,200","0,0,0,0")|card([$SELF:$2.$3.last_day:col4w],"$1 in $10 pro Tag",undef,$4,$5,$8,$9,"$10",undef,"1","130,1,1,0,1,0,200","0,0,0,0")|card([$SELF:$2.$3.last_month:col365d],"$1 in $10 pro Monat",undef,$6,$7,$8,$9,"$10",undef,"0","130,1,1,0,1,0,200","0,0,0,0")\
)\
## Template für die Darstellung von zwei Werten\
DEF TPL_double (\
card([[$SELF:$3.$4.day:col1w],[$SELF:$6.$7.day:col1w]],"$1 Tagesverlauf in $14",undef,$8,$9,$12,$13,["$2","$5"],undef,"1","130,1,1,0,1,0,200","0,0,0,0,2")|\
card([[$SELF:$3.$4.last_day:col4w],[$SELF:$6.$7.last_day:col4w]],"$1 in $14 pro Tag",undef,$8,$9,$12,$13,["$2","$5"],undef,"1","130,1,1,0,1,0,200","0,0,0,0,2")|\
card([[$SELF:$3.$4.last_month:col365d],[$SELF:$6.$7.last_month:col365d]],"$1 in $14 pro Monat",undef,$10,$11,$12,$13,["$2","$5"],undef,"0","130,1,1,0,1,0,200","0,0,0,0,2")\
)\
\
DEF TPL_single_bar (\
card([$SELF:$2.$3.day:col1w],"$1 Tagesverlauf",undef,$4,$5,$10,$11,"$12",undef,"1","130,1,1,0,1,0,200")|\
card([$SELF:$2.$3.last_day:bar1month-300],"$1 in $12 pro Tag",undef,$4,$5,$10,$11,"$12",undef,"1","130,1,1,0,1,0,200")|\
card([$SELF:$2.$3.last_month:bar2year-300],"$1 in $12 pro Monat",undef,$6,$7,$10,$11,"$12",undef,"0","130,1,1,0,1,0,200")|\
card([$SELF:$2.$3.last_year:bar2decade-300],"$1 in $12 pro Jahr",undef,$8,$9,$10,$11,"$12",undef,"0","130,1,1,0,1,0,200")\
)\
\
DEF TPL_double_bar (\
card([[$SELF:$3.$4.day:col1w],[$SELF:$6.$7.day:col1w]],"$1 Tagesverlauf in $16",undef,$8,$9,$14,$15,["$2","$5"],undef,"1","130,1,1,0,1,0,200","0,0,0,0,2")|\
card([[$SELF:$3.$4.last_day:bar1month-300],[$SELF:$6.$7.last_day:bar1month-300]],"$1 in $16 pro Tag",undef,$8,$9,$14,$15,["$2","$5"],undef,"1","130,1,1,0,1,0,200","0,0,0,0,2")|\
card([[$SELF:$3.$4.last_month:bar2year-300],[$SELF:$6.$7.last_month:bar2year-300]],"$1 in $16 pro Monat",undef,$10,$11,$14,$15,["$2","$5"],undef,"0","130,1,1,0,1,0,200","0,0,0,0,2")|\
card([[$SELF:$3.$4.last_year:bar2decade-300],[$SELF:$6.$7.last_year:bar2year-300]],"$1 in $16 pro Jahr",undef,$12,$13,$14,$15,["$2","$5"],undef,"0","130,1,1,0,1,0,200","0,0,0,0,2")\
)\
## Die Visualisierung einer Tabellenzeile wird über die obigen beiden Templates vorgenommen, hier zeilenweise anpassen/löschen:\
\
## Über das Template TPL_single wird jeweils pro card ein Wert visualisiert\
## Überschrift,Device,Reading,minTag,maxTag,minMonat,maxMonat,minColor,maxColor,Einheit\
## TPL_single (Frischwasser,MQTT2_DVES_C58DCB,total_w,0,500,0,10000,90,0,Liter)\
TPL_single_bar (Kühlkombi,MQTT2_shelly1pm_8CAAB50568DC,energy_total_kWh,0,0.2,0,20,0,200,90,0,kWh)\
TPL_single_bar (Tiefkühler Küche,MQTT2_shellyswitch25_4C752533F65D_CH2,energy_total_kWh,0,1,0,20,0,200,90,0,kWh)\
TPL_single_bar (Kühlschrank Küche,MQTT2_shellyswitch25_4C752533F65D,energy_total_kWh,0,0.5,0,20,0,200,90,0,kWh)\
\
card([$SELF:MQTT2_shellyplus1pm_3C610579C02C.energy_total_kWh.day:col1w],"Backrohr Tagesverlauf",undef,0,5,90,0,"kWh",undef,"1","130,1,1,0,1,0,200")\
TPL_single_bar (Backrohr,MQTT2_shellyplus1pm_3C610579C02C,energy_total_kWh,0,3,0,20,0,200,90,0,kWh)\
TPL_single_bar (Geschirrspüler,MQTT2_shellyplug_s_EA69D4,energy_total_kWh,0,1,0,20,0,200,90,0,kWh)\
TPL_single_bar (Fernseher,MQTT2_shellyplug_s_B587C8,energy_total_kWh,0,2,0,20,0,200,90,0,kWh)\
TPL_single_bar (Haushaltsgeräte, Haushalt,energy_total_kWh,0,5,0,20,0,200,90,0,kWh)\
TPL_single_bar (IT, IT,energy_total_kWh,0,5,0,20,0,200,90,0,kWh)\
card([$SELF:IT.energy_total_kWh.day:col1w],"IT Tagesverlauf",undef,0,5,90,0,"kWh",undef,"1","130,1,1,0,1,0,200")|\
card([$SELF:IT.energy_total_kWh.last_day:bar1month-300],"IT in kWh pro Tag",undef,0,5,90,0,"kWh",undef,"1","130,1,1,0,1,0,200")|\
card([$SELF:IT.energy_total_kWh.last_month:bar2year-300],"IT in kWh pro Monat",undef,0,20,90,0,"kWh",undef,"0","130,1,1,0,1,0,200")|\
card([$SELF:IT.energy_total_kWh.last_year:bar2decade-300],"IT in kWh pro Jahr",undef,0,200,90,0,"kWh",undef,"0","130,1,1,0,1,0,200")
Hast du bei dir im Device global beim Attribut autosave schon geschaut?
Das Attribut ist tatsächlich auf "0" gesetzt.
Aber ich sichere die fhem.cfg auch immer manuell.
Und wie gesagt, in der fhem.cfg steht die definition ja auch drinnen.
Dann versuche mit mal mein Glück mit "autosave 1".
Danke, lg, Gerhard
Du verwechselt da was. Die Daten werden nicht in der cfg-Datei gespeichert, sondern in der save-Datei. Das eine ist die Konfiguration, das andere sind die Inhalte der Readings und dort sind die gesammelten Daten gespeichert.
Die Trennung verstehe ich schon - aber den Zusammenhang (noch) nicht.
Wird also das Device aus der fhem.cfg nicht angelegt, wenn keine entsprechenden Daten im fhem.save stehen?
Und wird fhem.save nicht auch abgespeichert, wenn man die Konfiguration manuell speichert?
lg, Gerhard
ZitatWenn ich den Code aus fhem.cfg kopiere und per "+" in FHEM einfüge, bekomme ich wieder die altbekannte Fehlermeldung.
- Import mit "\" am Zeilenende -> Fehlermeldung "di_counter_new2 DOIF: :energy_total_kWh: subs {"
Dann folgt der Code der Definition. Leider aber im Dialogfenster abgeschnitten, da zu lang
- Import ohne "\" am Zeilenende -> Fehlermeldung "di_counter_new DOIF: Perlblck: no right bracket: {"
Das ist aber klar.
Das Backslash-Zeichen wird beim Einfügen einer RAW-Definition über Plus-Symbol direkt vom FHEM-Interpreter als Fortsetzungszeichen erkannt und herausgefiltert. Danach darf es dort nicht mehr drinstehen. Wenn sich DOIF über \ beschwert, dann stimmt vorher schon was nicht.
Zitat von: gestein am 15 Februar 2023, 11:19:14
Die Trennung verstehe ich schon - aber den Zusammenhang (noch) nicht.
Wird also das Device aus der fhem.cfg nicht angelegt, wenn keine entsprechenden Daten im fhem.save stehen?
Und wird fhem.save nicht auch abgespeichert, wenn man die Konfiguration manuell speichert?
lg, Gerhard
Die Definition wird natürlich in der cfg gespeichert und dort musst du sie auch sehen können. Sie save-Datei wird beim Drücken auf save gespeichert, beim DOIF wird auch beim shutdown save mit den gesammelten Daten ausgeführt (autosave muss auf 1 stehen).
Zu Problemen beim Einlesen der Definition hatte ich vorhin schon etwas geschrieben. Das sieht so aus, als wenn jemand über den DEF-Knopf die RAW-Daten aus dem Beispiel oder aus der cfg-Datei einlesen wollte.
Daran versuche ich mich mal.
Das autosave ist "0", weil ein Fehler beim Start erkannt wurde.
Im Internal vom global "init_errors" steht bei mir:
Messages collected while initializing FHEM:configfile: di_counter_new DOIF: :energy_total_kWh: subs {
sub CalculateSums {
my $Reading=::AttrVal("di_counter_new","EnergyReading","");
my $Prefix=::AttrVal("di_counter_new","SummaryPrefix","");
my ($DefFilterName,$DefFilter)=split /;/, ::AttrVal("di_counter_new","SummaryFilter","");
my @Categories=split /,/, ::AttrVal("di_counter_new","SummaryList","");
if (@Categories > 0) {
foreach my $Category (@Categories) {
my ($Name,$Filter)=split /;/, $Category;
$Filter =~s/$DefFilterName/$DefFilter/ig;
my @Devices = ::devspec2array($Filter);
my $counter_temp=0;
my $hour_temp=0;
my $hour_counter_temp=0;
my $quarter_temp=0;
my $quarter_counter_temp=0;
set_Reading("test_$Name","$Filter; $DefFilterName, $DefFilter",0);
foreach my $Device (@Devices) {
$counter_temp+=get_Reading("$Device\.$Reading\_counter",0);
$hour_temp+=get_Reading("$Device\.$Reading\_hour",0);
$hour_counter_temp+=get_Reading("$Device.$Reading\_hour_counter",0);
$quarter_temp+=get_Reading("$Device\.$Reading\_quarter",0);
$quarter_counter_temp+=get_Reading("$Device\.$Reading\_quarter_counter",0);
}
set_Reading($Prefix."$Name\_counter",$counter_temp);
set_Reading($Prefix."$Name\_hour",$hour_temp);
set_Reading($Prefix."$Name\_hour_counter",$hour_counter_temp);
set_Reading($Prefix."$Name\_quarter",$quarter_temp);
set_Reading($Prefix."$Name\_quarter_counter",$quarter_counter_temp);
}
}
}
sub SumUpCategories {
my ($device,$reading,$diff)=@_;
my ($DefFilterName,$DefFilter)=split /;/, ::AttrVal("di_counter_new","SummaryFilter","");
my @Categories=split /,/, ::AttrVal("di_counter_new","SummaryList","");
return if (@Categories == 0);
foreach my $Category (@Categories) {
my ($Name,$Filter)=split /;/, $Category;
$Filter =~s/$DefFilterName/$DefFilter/ig;
my @Devices = ::devspec2array($Filter);
if(grep(/^$device$/, @Devices )) {
my $alias=::AttrVal("$device","alias","");
set_Reading("test.$device","gefunden in $Name ($alias): $diff",0);
::Log 1, "SumUpCategories; $diff; $device; $Name ($alias); ".get_Reading("$Name.$reading.day",0);
set_Reading("$Name.$reading.day",get_Reading("$Name.$reading.day",0)+$diff,1);
set_Reading("$Name.$reading.month",get_Reading("$Name.$reading.month",0)+$diff,1);
set_Reading("$Name.$reading.year",get_Reading("$Name.$reading.year",0)+$diff,1);
}
}
}
sub midnight { my ($device,$reading,$mday,$yday,$newval)=@_;
set_Reading("$device.$reading.day_counter",$newval);
set_Reading("$device.$reading.last_day",get_Reading("$device.$reading.day",0),1);
set_Reading("$device.$reading.day",0,1);
set_Reading("$device.$reading.month",int(($newval-(get_Reading("$device.$reading.month_counter",0)))*1000)/1000,1);
set_Reading("$device.$reading.year",int(($newval-(get_Reading("$device.$reading.year_counter",0)))*1000)/1000,1);
if ($mday == 1) {
set_Reading("$device.$reading.month_counter",$newval);
set_Reading("$device.$reading.last_month",get_Reading("$device.$reading.month",0),1);
set_Reading("$device.$reading.month",0,1);
if ($yday == 0) {
set_Reading("$device.$reading.year_counter",$newval);
set_Reading("$device.$reading.last_year",get_Reading("$device.$reading.year",0),1);
set_Reading("$device.$reading.year",0,1);
}
}
}
sub init_readings {
my ($device,$reading,$newval)=@_;
my $alias=::AttrVal($device, "alias","");
if($alias ne "") {set_Reading("$device.$reading",$alias);}
if (get_Reading("$device.$reading.day_counter","") eq "") { set_Reading("$device.$reading.last_counter",$newval);
set_Reading("$device.$reading.day_counter",$newval);
set_Reading("$device.$reading.month_counter",$newval);
set_Reading("$device.$reading.year_counter",$newval);
set_Reading ("$device.$reading.day",0); set_Reading ("$device.$reading.month",0); set_Reading ("$device.$reading.year",0); set_Reading ("$device.$reading.last_day",0); set_Reading ("$device.$reading.last_month",0); set_Reading ("$device.$reading.last_year",0);
fhem ("defmod log.counter.$device.$reading FileLog ./log/counter.$device.$reading.log di_counter_new:$device.$reading.last_(day|month|year):.*");
fhem ("attr log.counter.$device.$reading room Filelogs");
}
}
}
resetAllEnergyData {
foreach my $Device (::devspec2array(::AttrVal("di_counter_new","UsedDevFilter",""))) {
if(ReadingsVal("$Device","relay_0_energy_total","err") ne "err") {
fhem("setreading $Device relay_0_energy_total 0");
fhem("setreading $Device energy_total 0");
fhem("setreading $Device energy_total_kWh 0");
fhem("setreading $Device energy_total_reset done");
} elsif(ReadingsVal("$Device","relay_1_energy_total","err") ne "err") {
fhem("setreading $Device relay_1_energy_total 0");
fhem("setreading $Device energy_total 0");
fhem("setreading $Device energy_total_kWh 0");
fhem("setreading $Device energy_total_reset done");
} elsif(ReadingsVal("$Device","light_0_energy_total","err") ne "err") {
fhem("setreading $Device light_0_energy_total 0");
fhem("setreading $Device energy_total 0");
fhem("setreading $Device energy_total_kWh 0");
fhem("setreading $Device energy_total_reset done");
}
}
}
get_data { my $reading=::AttrVal("di_counter_new","EnergyReading","");
foreach my $Device (::devspec2array(::AttrVal("di_counter_new","UsedDevFilter",""))) {
::DOIF_set_card_data ("di_counter_new","di_counter_new","$Device.$reading.last_day","bar1month",-300,fhem("get log.counter.$Device.$reading ./log/counter.$Device.$reading.log - 2000 3000 4:last_day"));
::DOIF_set_card_data ("di_counter_new","di_counter_new","$Device.$reading.last_month","bar2year",-300,fhem("get log.counter.$Device.$reading ./log/counter.$Device.$reading.log - 2000 3000 4:last_month"));
::DOIF_set_card_data ("di_counter_new","di_counter_new","$Device.$reading.last_year","bar2decade",-300,fhem("get log.counter.$Device.$reading ./log/counter.$Device.$reading.log - 2000 3000 4:last_year"));
}
}
deleteAllReadings {
fhem("deletereading di_counter_new .*");
}
mid {[00:01]; my $newval=ReadingsVal($device, $reading,0);
my $reading=::AttrVal("di_counter_new","EnergyReading","");
foreach my $Device (::devspec2array(::AttrVal("di_counter_new","UsedDevFilter",""))) { midnight($Device,$reading,$mday,$yday,$newval);
}
my @Categories=split /,/, ::AttrVal("di_counter_new","SummaryList","");
foreach my $Category (@Categories) {
my ($Name,$Filter)=split /;/, $Category;
$newval=get_Reading("$Name.$reading.day",0);
midnight($Name,$reading,$mday,$yday,$newval);
}
}
init { my $reading=::AttrVal("di_counter_new","EnergyReading","");
my $newval=0;
foreach my $Device (::devspec2array(::AttrVal("di_counter_new","UsedDevFilter",""))) { $newval=ReadingsVal($Device, $reading,0);
init_readings($Device,$reading,$newval);
}
my @Categories=split /,/, ::AttrVal("di_counter_new","SummaryList","");
foreach my $Category (@Categories) {
my ($Name,$Filter)=split /;/, $Category;
my ($DefFilterName,$DefFilter)=split /;/, ::AttrVal("di_counter_new","SummaryFilter","");
$Filter =~s/$DefFilterName/$DefFilter/ig;
my @Devices = ::devspec2array($Filter);
set_Reading("$Name.members","@Devices");
$newval=0;
foreach my $Device (@Devices) {
$newval+=ReadingsVal("$Device","$reading",0);
}
init_readings($Name,$reading,$newval);
}
}
CalculateQuarterSums { [([+:15]+[00:01])];
}
CalculateHourSums { [:01];
}
day_count__energy_total_kWh {
my $diff = int(([:energy_total_kWh,0]-(get_Reading(".energy_total_kWh.last_counter",0)))*1000)/1000;
set_Reading (".energy_total_kWh.last_counter",[:energy_total_kWh,0]);
set_Reading (".energy_total_kWh.day",int(([:energy_total_kWh,0]-(get_Reading(".energy_total_kWh.day_counter",0)))*1000)/1000,1);
set_Reading (".energy_total_kWh.month",int(([:energy_total_kWh,0]-(get_Reading(".energy_total_kWh.month_counter",0)))*1000)/1000,1);
set_Reading (".energy_total_kWh.year",int(([:energy_total_kWh,0]-(get_Reading(".energy_total_kWh.year_counter",0)))*1000)/1000,1);
if ($diff>0) {
SumUpCategories("","energy_total_kWh",$diff);
}
}
setuuid: Please define di_counter_new first
Leider steht keine Fehlermeldung, da die definition anscheinend zu lange ist.
Zumindest wird di_counter_new nicht bei Neustart angelegt.
Ich lege das jetzt nochmal an und setze autosave auf "1".
Und dann starte ich fhem nochmal neu.
lg, Gerhard
Hallo,
also auch der neuerliche Versuch hat nicht geklappt.
So bin ich vorgegangen:
1) autosave auf "1" gestellt.
2) mein Device do_counter_new erstellt (zuerst mit leerer Definition und dann die Definiton geändert)
Die Readings wurden richtig erstellt und die Diagramme sind zu sehen
3) die Konfig über "save config" gespeichert.
4) fhem.cfg und log/fhem.save überprüft. In beiden Dateien ist di_counter_new drinnen.
5) "shutdown restart"
6) di_counter_new wurde nicht als Device angelegt.
Im Internal "init_errors" steht wieder die u.a. Fehlermeldung
Ist die Definition zu lange bzw. zu komplex?
lg, Gerhard
Inhalt von global:init_errors
Messages collected while initializing FHEM:configfile: di_counter_new DOIF: :energy_total_kWh: subs {
sub CalculateSums {
my $Reading=::AttrVal("di_counter_new","EnergyReading","");;
my $Prefix=::AttrVal("di_counter_new","SummaryPrefix","");;
my ($DefFilterName,$DefFilter)=split /;;/, ::AttrVal("di_counter_new","SummaryFilter","");;
my @Categories=split /,/, ::AttrVal("di_counter_new","SummaryList","");;
if (@Categories > 0) {
foreach my $Category (@Categories) {
my ($Name,$Filter)=split /;;/, $Category;;
$Filter =~s/$DefFilterName/$DefFilter/ig;;
my @Devices = ::devspec2array($Filter);;
my $counter_temp=0;;
my $hour_temp=0;;
my $hour_counter_temp=0;;
my $quarter_temp=0;;
my $quarter_counter_temp=0;;
set_Reading("test_$Name","$Filter;; $DefFilterName, $DefFilter",0);;
foreach my $Device (@Devices) {
$counter_temp+=get_Reading("$Device\.$Reading\_counter",0);;
$hour_temp+=get_Reading("$Device\.$Reading\_hour",0);;
$hour_counter_temp+=get_Reading("$Device.$Reading\_hour_counter",0);;
$quarter_temp+=get_Reading("$Device\.$Reading\_quarter",0);;
$quarter_counter_temp+=get_Reading("$Device\.$Reading\_quarter_counter",0);;
}
set_Reading($Prefix."$Name\_counter",$counter_temp);;
set_Reading($Prefix."$Name\_hour",$hour_temp);;
set_Reading($Prefix."$Name\_hour_counter",$hour_counter_temp);;
set_Reading($Prefix."$Name\_quarter",$quarter_temp);;
set_Reading($Prefix."$Name\_quarter_counter",$quarter_counter_temp);;
}
}
}
sub SumUpCategories {
my ($device,$reading,$diff)=@_;;
my ($DefFilterName,$DefFilter)=split /;;/, ::AttrVal("di_counter_new","SummaryFilter","");;
my @Categories=split /,/, ::AttrVal("di_counter_new","SummaryList","");;
return if (@Categories == 0);;
foreach my $Category (@Categories) {
my ($Name,$Filter)=split /;;/, $Category;;
$Filter =~s/$DefFilterName/$DefFilter/ig;;
my @Devices = ::devspec2array($Filter);;
if(grep(/^$device$/, @Devices )) {
my $alias=::AttrVal("$device","alias","");;
set_Reading("test.$device","gefunden in $Name ($alias): $diff",0);;
::Log 1, "SumUpCategories;; $diff;; $device;; $Name ($alias);; ".get_Reading("$Name.$reading.day",0);;
set_Reading("$Name.$reading.day",get_Reading("$Name.$reading.day",0)+$diff,1);;
set_Reading("$Name.$reading.month",get_Reading("$Name.$reading.month",0)+$diff,1);;
set_Reading("$Name.$reading.year",get_Reading("$Name.$reading.year",0)+$diff,1);;
}
}
}
sub midnight { my ($device,$reading,$mday,$yday,$newval)=@_;;
set_Reading("$device.$reading.day_counter",$newval);;
set_Reading("$device.$reading.last_day",get_Reading("$device.$reading.day",0),1);;
set_Reading("$device.$reading.day",0,1);;
set_Reading("$device.$reading.month",int(($newval-(get_Reading("$device.$reading.month_counter",0)))*1000)/1000,1);;
set_Reading("$device.$reading.year",int(($newval-(get_Reading("$device.$reading.year_counter",0)))*1000)/1000,1);;
if ($mday == 1) {
set_Reading("$device.$reading.month_counter",$newval);;
set_Reading("$device.$reading.last_month",get_Reading("$device.$reading.month",0),1);;
set_Reading("$device.$reading.month",0,1);;
if ($yday == 0) {
set_Reading("$device.$reading.year_counter",$newval);;
set_Reading("$device.$reading.last_year",get_Reading("$device.$reading.year",0),1);;
set_Reading("$device.$reading.year",0,1);;
}
}
}
sub init_readings {
my ($device,$reading,$newval)=@_;;
my $alias=::AttrVal($device, "alias","");;
if($alias ne "") {set_Reading("$device.$reading",$alias);;}
if (get_Reading("$device.$reading.day_counter","") eq "") { set_Reading("$device.$reading.last_counter",$newval);;
set_Reading("$device.$reading.day_counter",$newval);;
set_Reading("$device.$reading.month_counter",$newval);;
set_Reading("$device.$reading.year_counter",$newval);;
set_Reading ("$device.$reading.day",0);; set_Reading ("$device.$reading.month",0);; set_Reading ("$device.$reading.year",0);; set_Reading ("$device.$reading.last_day",0);; set_Reading ("$device.$reading.last_month",0);; set_Reading ("$device.$reading.last_year",0);;
fhem ("defmod log.counter.$device.$reading FileLog ./log/counter.$device.$reading.log di_counter_new:$device.$reading.last_(day|month|year):.*");;
fhem ("attr log.counter.$device.$reading room Filelogs");;
}
}
}
resetAllEnergyData {
foreach my $Device (::devspec2array(::AttrVal("di_counter_new","UsedDevFilter",""))) {
if(ReadingsVal("$Device","relay_0_energy_total","err") ne "err") {
fhem("setreading $Device relay_0_energy_total 0");;
fhem("setreading $Device energy_total 0");;
fhem("setreading $Device energy_total_kWh 0");;
fhem("setreading $Device energy_total_reset done");;
} elsif(ReadingsVal("$Device","relay_1_energy_total","err") ne "err") {
fhem("setreading $Device relay_1_energy_total 0");;
fhem("setreading $Device energy_total 0");;
fhem("setreading $Device energy_total_kWh 0");;
fhem("setreading $Device energy_total_reset done");;
} elsif(ReadingsVal("$Device","light_0_energy_total","err") ne "err") {
fhem("setreading $Device light_0_energy_total 0");;
fhem("setreading $Device energy_total 0");;
fhem("setreading $Device energy_total_kWh 0");;
fhem("setreading $Device energy_total_reset done");;
}
}
}
get_data { my $reading=::AttrVal("di_counter_new","EnergyReading","");;
foreach my $Device (::devspec2array(::AttrVal("di_counter_new","UsedDevFilter",""))) {
::DOIF_set_card_data ("di_counter_new","di_counter_new","$Device.$reading.last_day","bar1month",-300,fhem("get log.counter.$Device.$reading ./log/counter.$Device.$reading.log - 2000 3000 4:last_day"));;
::DOIF_set_card_data ("di_counter_new","di_counter_new","$Device.$reading.last_month","bar2year",-300,fhem("get log.counter.$Device.$reading ./log/counter.$Device.$reading.log - 2000 3000 4:last_month"));;
::DOIF_set_card_data ("di_counter_new","di_counter_new","$Device.$reading.last_year","bar2decade",-300,fhem("get log.counter.$Device.$reading ./log/counter.$Device.$reading.log - 2000 3000 4:last_year"));;
}
}
deleteAllReadings {
fhem("deletereading di_counter_new .*");;
}
mid {[00:01];; my $newval=ReadingsVal($device, $reading,0);;
my $reading=::AttrVal("di_counter_new","EnergyReading","");;
foreach my $Device (::devspec2array(::AttrVal("di_counter_new","UsedDevFilter",""))) { midnight($Device,$reading,$mday,$yday,$newval);;
}
my @Categories=split /,/, ::AttrVal("di_counter_new","SummaryList","");;
foreach my $Category (@Categories) {
my ($Name,$Filter)=split /;;/, $Category;;
$newval=get_Reading("$Name.$reading.day",0);;
midnight($Name,$reading,$mday,$yday,$newval);;
}
}
init { my $reading=::AttrVal("di_counter_new","EnergyReading","");;
my $newval=0;;
foreach my $Device (::devspec2array(::AttrVal("di_counter_new","UsedDevFilter",""))) { $newval=ReadingsVal($Device, $reading,0);;
init_readings($Device,$reading,$newval);;
}
my @Categories=split /,/, ::AttrVal("di_counter_new","SummaryList","");;
foreach my $Category (@Categories) {
my ($Name,$Filter)=split /;;/, $Category;;
my ($DefFilterName,$DefFilter)=split /;;/, ::AttrVal("di_counter_new","SummaryFilter","");;
$Filter =~s/$DefFilterName/$DefFilter/ig;;
my @Devices = ::devspec2array($Filter);;
set_Reading("$Name.members","@Devices");;
$newval=0;;
foreach my $Device (@Devices) {
$newval+=ReadingsVal("$Device","$reading",0);;
}
init_readings($Name,$reading,$newval);;
}
}
CalculateQuarterSums { [([+:15]+[00:01])];;
}
CalculateHourSums { [:01];;
}
day_count__energy_total_kWh {
my $diff = int(([:energy_total_kWh,0]-(get_Reading(".energy_total_kWh.last_counter",0)))*1000)/1000;;
set_Reading (".energy_total_kWh.last_counter",[:energy_total_kWh,0]);;
set_Reading (".energy_total_kWh.day",int(([:energy_total_kWh,0]-(get_Reading(".energy_total_kWh.day_counter",0)))*1000)/1000,1);;
set_Reading (".energy_total_kWh.month",int(([:energy_total_kWh,0]-(get_Reading(".energy_total_kWh.month_counter",0)))*1000)/1000,1);;
set_Reading (".energy_total_kWh.year",int(([:energy_total_kWh,0]-(get_Reading(".energy_total_kWh.year_counter",0)))*1000)/1000,1);;
if ($diff>0) {
SumUpCategories("","energy_total_kWh",$diff);;
}
}
setuuid: Please define di_counter_new first
./log/fhem.save: Unknown command <default>:FILTER=group=Haushaltsgeräte.energy_total_kWh.day, try help.
Unknown command <default>:FILTER=group=Haushaltsgeräte.energy_total_kWh.day_counter, try help.
Unknown command <default>:FILTER=group=Haushaltsgeräte.energy_total_kWh.last_counter, try help.
Unknown command <default>:FILTER=group=Haushaltsgeräte.energy_total_kWh.last_day, try help.
Unknown command <default>:FILTER=group=Haushaltsgeräte.energy_total_kWh.last_month, try help.
Unknown command <default>:FILTER=group=Haushaltsgeräte.energy_total_kWh.last_year, try help.
Unknown command <default>:FILTER=group=Haushaltsgeräte.energy_total_kWh.month, try help.
Unknown command <default>:FILTER=group=Haushaltsgeräte.energy_total_kWh.month_counter, try help.
Unknown command <default>:FILTER=group=Haushaltsgeräte.energy_total_kWh.year, try help.
Unknown command <default>:FILTER=group=Haushaltsgeräte.energy_total_kWh.year_counter, try help.
Unknown command <default>:FILTER=group=Haushaltsgeräte.members, try help.
Unknown command <default>:FILTER=group=IT.energy_total_kWh.day, try help.
Unknown command <default>:FILTER=group=IT.energy_total_kWh.day_counter, try help.
Unknown command <default>:FILTER=group=IT.energy_total_kWh.last_counter, try help.
Unknown command <default>:FILTER=group=IT.energy_total_kWh.last_day, try help.
Unknown command <default>:FILTER=group=IT.energy_total_kWh.last_month, try help.
Unknown command <default>:FILTER=group=IT.energy_total_kWh.last_year, try help.
Unknown command <default>:FILTER=group=IT.energy_total_kWh.month, try help.
Unknown command <default>:FILTER=group=IT.energy_total_kWh.month_counter, try help.
Unknown command <default>:FILTER=group=IT.energy_total_kWh.year, try help.
Unknown command <default>:FILTER=group=IT.energy_total_kWh.year_counter, try help.
Unknown command <default>:FILTER=group=IT.members, try help.
Unknown command <default>:FILTER=group=Licht.energy_total_kWh.day, try help.
Unknown command <default>:FILTER=group=Licht.energy_total_kWh.day_counter, try help.
Unknown command <default>:FILTER=group=Licht.energy_total_kWh.last_counter, try help.
Unknown command <default>:FILTER=group=Licht.energy_total_kWh.last_day, try help.
Unknown command <default>:FILTER=group=Licht.energy_total_kWh.last_month, try help.
Unknown command <default>:FILTER=group=Licht.energy_total_kWh.last_year, try help.
Unknown command <default>:FILTER=group=Licht.energy_total_kWh.month, try help.
Unknown command <default>:FILTER=group=Licht.energy_total_kWh.month_counter, try help.
Unknown command <default>:FILTER=group=Licht.energy_total_kWh.year, try help.
Unknown command <default>:FILTER=group=Licht.energy_total_kWh.year_counter, try help.
Unknown command <default>:FILTER=group=Licht.members, try help.
Unknown command <default>:FILTER=group=Multimedia.energy_total_kWh.day, try help.
Unknown command <default>:FILTER=group=Multimedia.energy_total_kWh.day_counter, try help.
Unknown command <default>:FILTER=group=Multimedia.energy_total_kWh.last_counter, try help.
Unknown command <default>:FILTER=group=Multimedia.energy_total_kWh.last_day, try help.
Unknown command <default>:FILTER=group=Multimedia.energy_total_kWh.last_month, try help.
Unknown command <default>:FILTER=group=Multimedia.energy_total_kWh.last_year, try help.
Unknown command <default>:FILTER=group=Multimedia.energy_total_kWh.month, try help.
Unknown command <default>:FILTER=group=Multimedia.energy_total_kWh.month_counter, try help.
Unknown command <default>:FILTER=group=Multimedia.energy_total_kWh.year, try help.
Unknown command <default>:FILTER=group=Multimedia.energy_total_kWh.year_counter, try help.
Unknown command <default>:FILTER=group=Multimedia.members, try help.
wenn ich zuhause bin, werde ich in meinem Testsystem deine Definition versuchen einzuspielen.
Deine gepostete Definition klappt bei mir auch nicht. es liegt an dieser Zeile:
FOR(::devspec2array(::AttrVal("$SELF","UsedDevFilter","")), TPL_stat ($_,energy_total_kWh))
Die FOR-Schleife soll die DOIF-Blöcke definieren, das geschieht als erstes, zu dem Zeitpunkt sind aber die Attribute noch nicht gesetzt, die Definitionen der Attribute kommt erst danach.
Wenn das System bereits läuft und du die Definition anpasst, dann klappt es offenbar, weil die Attribute dann schon bekannt sind.
Darauf wäre ich nie gekommen.
Vielen Dank für Deine Hilfe!
Dann müsste ich das Anlegen der Readings in den Init-Block verlegen.
Der wird ja aufgerufen, wenn das Device vollkommen definiert ist. Oder?
Lg, Gerhard
Zitat von: gestein am 15 Februar 2023, 20:44:56
Darauf wäre ich nie gekommen.
Vielen Dank für Deine Hilfe!
Dann müsste ich das Anlegen der Readings in den Init-Block verlegen.
Der wird ja aufgerufen, wenn das Device vollkommen definiert ist. Oder?
Lg, Gerhard
mit TPL_stat werden die DOIF-Blöcke definiert, das kommt unmittelbar nach der Definition der Subroutinen und ist ziemlich elementar. Die Definition eines DOIF-Blocks macht viele Dinge im Hintergrund, wie z. B. das Aufsetzen der Trigger-Mechanismen. Es ist ein Teil der Definition des Devices und da kann man nicht warten bis das System komplett initialisiert ist.
Das funktioniert dagegen in meiner Definition, weil ich bereits im subs-Block das interne Array mit den Readings definiere. Man kann schon eine ganze Menge dynamisch machen, allerdings kann sich das Device nicht selbst dynamisch definieren.
Wenn ich den FOR-Block rausnehme, dann wird das Device wirklich angelegt.
Soweit ich das verstehe, wird mit jedem Aufruf in der FOR-Schleife über das Template eine Funktion mit dem Namen "day_count_$1_$2" ($1 = Device-Name; $2 = Reading-Name) angelegt.
Getriggert wird auf eine der Angaben [$1:$2,0] in der Funktion. Richtig?
lg, Gerhard
Zitat von: gestein am 16 Februar 2023, 09:47:10
Wenn ich den FOR-Block rausnehme, dann wird das Device wirklich angelegt.
Soweit ich das verstehe, wird mit jedem Aufruf in der FOR-Schleife über das Template eine Funktion mit dem Namen "day_count_$1_$2" ($1 = Device-Name; $2 = Reading-Name) angelegt.
Getriggert wird auf eine der Angaben [$1:$2,0] in der Funktion. Richtig?
lg, Gerhard
Richtig. Entscheidend ist, dass man pro Reading einen DOIF-Block hat mit dem entsprechenden Trigger - das geschieht während der Definitionsphase bevor das System hochgefahren ist (init_done), d. h. bevor Attribute und gesicherte Readings geladen sind - das sind FHEM-Mechanismen.
Ich glaube ich habe meinen Fehler gefunden.
Bei mir führt der Timer, der die Werte nachts schreiben soll nicht ordnungsgemäß aus.
*{at_ultimo(23,59,55)} setreading Stromzaehler Bezug180 [MQTT2_DVES_74ED88:MT681_Bezug]; setreading Stromzaehler Einspeisung280 [MQTT2_DVES_74ED88:MT681_Einspeisung]
Ich sammele ja alle Werte in einem dummy und hole mir dann mit dem DOIF von Damian die Werte aus dem dummy.
Aber dort wird nichts reingeschrieben. Im log steht:
at_ultimo: Unknown command (setreading, try help.
Kann ich ein reading meines dummys nicht per setreading füllen?
Wenn nein, wie sonst?
Danke
Gruss
Dennis
Zitat von: dennis_n am 18 Februar 2023, 20:06:29
Iat_ultimo: Unknown command (setreading, try help.
Kann ich ein reading meines dummys nicht per setreading füllen?
Bei AT bist Du außerhalb der Welt von DOIF und da "setzt" man einen Wert mit set.
Es sollte also gehen mit set Stromzaehler [Wert]Mein Beitrag war leider falsch - siehe nachfolgende Korrektur durch Damian.
Christian
Zitat von: cwagner am 19 Februar 2023, 08:23:54
Bei AT bist Du außerhalb der Welt von DOIF und da "setzt" man einen Wert mit set.
Es sollte also gehen mit set Stromzaehler [Wert]
Christian
setreading geht genauso gut - es ist ein FHEM-Befehl. Bei set musst du readingsList und setList im Dummy setzen. Bei mir funktioniert jedenfalls setreading im at - aber das ist ja eine andere Baustelle. Bei at-Fragen ist man im Automatisierungs-Board besser aufgehoben.
Hi Damian,
Wahnsinn was Du da geschaffen hast. Die tolle Grafik. Was für Darstellungsmöglichkeiten.
Allein schon die Doku im Wiki ist überwältigend. :) :) :)
Eine Kleinigkeit ist mir aufgefallen. Die erzeugten Filelogs haben kein NOTIFYDEV.
Dadurch ist die Performance des Gesamtsystems etwas schlechter.
Ich habe das Regex zu "$SELF:$device.$reading.last_.*" geändert.
Dann wird NOTIFYDEV benutzt und es sollte auch nicht mehr gelogged werden.
Vielleicht kann Du das übernehmen. (Ich verwende auch %L im Pfad, aber das führt vielleicht zu weit.)
Derzeit bin ich gerade dabei historische Werte (Monate, Jahre) zu übernehmen.
Trage die händisch ins Log-File ein und lese sie dann über DOIF_set_card_data ein.
2020-01-01_00:01:00 DoIF_Strom_Statistik PV_Erzeugung_s.Erzeugung.last_year: 5706 kWh
2021-01-01_00:01:00 DoIF_Strom_Statistik PV_Erzeugung_s.Erzeugung.last_year: 6130 kWh
2022-01-01_00:01:00 DoIF_Strom_Statistik PV_Erzeugung_s.Erzeugung.last_year: 5504 kWh
2023-01-01_00:01:00 DoIF_Strom_Statistik PV_Erzeugung_s.Erzeugung.last_year: 6380 kWh
Über get_data habe ich es (noch) nicht hinbekommen.
Gibt es da bessere/einfachere Wege?
//Roger
Zitat von: Roger am 19 Februar 2023, 11:51:54
Hi Damian,
Wahnsinn was Du da geschaffen hast. Die tolle Grafik. Was für Darstellungsmöglichkeiten.
Allein schon die Doku im Wiki ist überwältigend. :) :) :)
Eine Kleinigkeit ist mir aufgefallen. Die erzeugten Filelogs haben kein NOTIFYDEV.
Dadurch ist die Performance des Gesamtsystems etwas schlechter.
Ich habe das Regex zu "$SELF:$device.$reading.last_.*" geändert.
Dann wird NOTIFYDEV benutzt und es sollte auch nicht mehr gelogged werden.
Vielleicht kann Du das übernehmen. (Ich verwende auch %L im Pfad, aber das führt vielleicht zu weit.)
Derzeit bin ich gerade dabei historische Werte (Monate, Jahre) zu übernehmen.
Trage die händisch ins Log-File ein und lese sie dann über DOIF_set_card_data ein.
2020-01-01_00:01:00 DoIF_Strom_Statistik PV_Erzeugung_s.Erzeugung.last_year: 5706 kWh
2021-01-01_00:01:00 DoIF_Strom_Statistik PV_Erzeugung_s.Erzeugung.last_year: 6130 kWh
2022-01-01_00:01:00 DoIF_Strom_Statistik PV_Erzeugung_s.Erzeugung.last_year: 5504 kWh
2023-01-01_00:01:00 DoIF_Strom_Statistik PV_Erzeugung_s.Erzeugung.last_year: 6380 kWh
Über get_data habe ich es (noch) nicht hinbekommen.
Gibt es da bessere/einfachere Wege?
//Roger
Danke für den Tipp mit dem NOTIFYDEV. Als DOIF-Nutzer bin ich da etwas verwöhnt, da man sich hier keine Gedanken über NOTIFYDEV machen muss - es wird immer gesetzt :)
Ich werde es anpassen.
In der Doku steht, dass man einfach eine Liste (kommagetrennt oder mit \n) angeben kann, da ist sogar ein Beispiel:
ZitatDOIF_modify_card_data ("di_pv","energie","pv","col4w",0,"2023.02.04_11:00 10,2023.02.04_11:02 5.6")
Bei dir dann:
DOIF_modify_card_data(...,"2020 5706,2021 6130,2022 5504,2023 6380")
Bei
modify werden im Gegensatz zu
set bisherige gesammelte Daten nicht gelöscht - steht aber auch in der Doku.
Hi Damian,
ich steige da noch nicht durch. >:(
Ich habe ein Geräte nach "Tages-, Monats- und Jahresstatistik für Strom-, Gas-, Wasserzähler und andere Zähler" angelegt. 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 (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)
Heißt bei mir DoIF_Strom_Statistik. eigene Readings:
push (@{$_counter},["PV_Erzeugung_s" ,"Erzeugung"]);; ## Summe Strom-Erzeugung\
push (@{$_counter},["PV_EigVerbrauch_s","Eigenverbrauch"]);; ## Summe Strom-Eigenverbrauch\
push (@{$_counter},["PV_Einspeisung_s" ,"Einspeisung"]);; ## Summe Strom-Einspeisung\
push (@{$_counter},["PV_Bezug_s" ,"Bezug"]);; ## Summe Strom-Bezug\
push (@{$_counter},["PV_GesVerbrauch_s","Gesamtverbrauch"]);; ## Summe Strom-Gesamtverbrauch\
Nun will ich die historischen Werte darstellen.
Zunächst mal die Erzeugung der vergangenen Jahre:
{DOIF_modify_card_data("DoIF_Strom_Statistik","PV_Erzeugung_s","Erzeugung","col4w",0,"2015 1360,2016 5793,2017 5379,2018 6469,2019 5706,2020 6130,2021 5504,2022 6380")}
funktioniert nicht: Meldung "undefined DoIF_Strom_Statistik, PV_Erzeugung_s, Erzeugung, col4w combination"
Was mache ich falsch? Wie bekomme ich die Werte der vergangenen Jahre, Monate und Tage eingelesen?
Mein derzeitiger Weg. Mit:
{DOIF_modify_card_data("DoIF_Strom_Statistik","DoIF_Strom_Statistik","PV_Erzeugung_s.Erzeugung.last_year","bar2decade",0,"2015 1360,2016 5793,2017 5379,2018 6469,2019 5706,2020 6130,2021 5504,2022 6380")}
klappt das Einlesen der Jahre.
Nun die Werte der vergangenen Monate:
{DOIF_modify_card_data("DoIF_Strom_Statistik","DoIF_Strom_Statistik","PV_Erzeugung_s.Erzeugung.last_month","bar2year",0,"2022-01-01 85,2022-02-01 245,2022-03-01 754,2022-04-01 768,2022-05-01 810,2022-06-01 873,2022-07-01 817,2022-08-01 801,2022-09-01 531,2022-10-01 463,2022-11-01 146,2022-12-01 87,2023-01-01 103")}
Ist das der richtige Weg? Jahre, Monate, Tage einzeln (für jedes Reading)? Wie besser?
//Roger
Zitat{DOIF_modify_card_data("DoIF_Strom_Statistik","PV_Erzeugung_s","Erzeugung","col4w",0,"2015 1360,2016 5793,2017 5379,2018 6469,2019 5706,2020 6130,2021 5504,2022 6380")}
col4w ist das erste Diagramm. Dort wird der tägliche Verlauf dargestellt. Ich würde nicht mehr als eine Woche nehmen (col1w statt col4w), da es sonst wegen der geringen Auflösung zu ungenau wird.
Also macht es keinen Sinn dort die Jahresverbräuche abzulegen. ;) Der tägliche Verlauf wird nicht geloggt, da würde ich einfach abwarten und nichts tun.
Ob du zuerst Jahre einliest oder Monate, das ist dir überlassen. Das Einlesen der Daten kann man erst dann, wenn die cards definiert sind und angezeigt werden.
Ich sichere einmal pro Stunde die Readings per fhem"save", damit im Falle eines Crashes keine Daten verloren gehen, die nicht geloggt sind, sondern nur in cards gesammelt wurden bzw. manuell eingepflegt wurden.
OK, col4w ist falsch --> muss col1w heißen.
Aber auch:
{DOIF_modify_card_data("DoIF_Strom_Statistik","PV_Erzeugung_s","Erzeugung","col1w",0,"2015 1360,2016 5793,2017 5379,2018 6469,2019 5706,2020 6130,2021 5504,2022 6380")}
geht nicht.
Kann ich Deine Antwort so verstehen, dass es sinnfrei ist die Jahreswerte in col1w einzulesen und mein eingeschlagener Weg die Werte einzeln einzulesen richtig ist?
- Tageswerte in bar1month
- Monatswerte in bar2year
- Jahreswerte in bar2decade
Also dreimal (Tag, Monat, Jahr) für jedes meiner 4 Readings?
//Roger
PS: save mache ich übrigens in einem at bei mir schon (und öfter als einmal/h). So hat man bei einem möglichen Absturz fast den aktuellen Stand.
Edit2: Du hast das FileLog ja im Wiki schon angepasst. :)
Zitat von: Roger am 19 Februar 2023, 20:55:07
OK, col4w ist falsch --> muss col1w heißen.
Aber auch:
{DOIF_modify_card_data("DoIF_Strom_Statistik","PV_Erzeugung_s","Erzeugung","col1w",0,"2015 1360,2016 5793,2017 5379,2018 6469,2019 5706,2020 6130,2021 5504,2022 6380")}
geht nicht.
Kann ich Deine Antwort so verstehen, dass es sinnfrei ist die Jahreswerte in col1w einzulesen und mein eingeschlagener Weg die Werte einzeln einzulesen richtig ist?
- Tageswerte in bar1month
- Monatswerte in bar2year
- Jahreswerte in bar2decade
Also dreimal (Tag, Monat, Jahr) für jedes meiner 4 Readings?
//Roger
PS: save mache ich übrigens in einem at bei mir schon (und öfter als einmal/h). So hat man bei einem möglichen Absturz fast den aktuellen Stand.
Edit2: Du hast das FileLog ja im Wiki schon angepasst. :)
ja. Solche langfristigen Daten, wie bei Jahren oder Monaten würde ich über Exceltabellen einpflegen. Diese lassen sich besser bearbeiten und zur Not noch mal einspielen. Ich werde dazu aber auch noch eine Funktion entsprechend dem Filelog bereitstellen.
Zitat{DOIF_modify_card_data("DoIF_Strom_Statistik","PV_Erzeugung_s","Erzeugung","col1w",0,"2015 1360,2016 5793,2017 5379,2018 6469,2019 5706,2020 6130,2021 5504,2022 6380")}
Wie kommst du auf diese Kombination? Es wird definiert:
[$SELF:$2.$3.day:col1w] es wird also auf die internen day-Readings des eigenen Moduls getriggert und nicht auf die ursprünglichen Wert, und dass es keine Jahreswerte sind, habe ich ja schon erzählt, sondern vielmehr sekundengenauer Werte des aktuellen Tages, die um Mitternacht auf Null gesetzt werden.
{DOIF_modify_card_data("DoIF_Strom_Statistik","DoIF_Strom_Statistik","PV_Erzeugung_s.Erzeugung.day","col1w",...
Hi Damian
Zitata. Solche langfristigen Daten, wie bei Jahren oder Monaten würde ich über Exceltabellen einpflegen. Diese lassen sich besser bearbeiten und zur Not noch mal einspielen. Ich werde dazu aber auch noch eine Funktion entsprechend dem Filelog bereitstellen.
Ja, ich habe alle Daten in Excel. Wäre toll, wenn Du die Übernahme aus Excel vereinfachen kannst.
Sag gern Bescheid, wenn Du was zum Testen hast.ZitatWie kommst du auf diese Kombination?
Aus dem Wiki:
get_data { ## Optionale Übernahme bestehender Daten aus dem Log\
for (my $i=0;;$i<@{$_counter};;$i++) {\
::DOIF_set_card_data ("$SELF","$SELF","$_counter[$i][0].$_counter[$i][1].last_day","bar1month",-300,fhem("get log.counter.$_counter[$i][0].$_counter[$i][1] ./log/counter.$_counter[$i][0].$_counter[$i][1].log - 2000 3000 4:last_day"));;\
::DOIF_set_card_data ("$SELF","$SELF","$_counter[$i][0].$_counter[$i][1].last_month","bar2year",-300,fhem("get log.counter.$_counter[$i][0].$_counter[$i][1] ./log/counter.$_counter[$i][0].$_counter[$i][1].log - 2000 3000 4:last_month"));;\
::DOIF_set_card_data ("$SELF","$SELF","$_counter[$i][0].$_counter[$i][1].last_year","bar2decade",-300,fhem("get log.counter.$_counter[$i][0].$_counter[$i][1] ./log/counter.$_counter[$i][0].$_counter[$i][1].log - 2000 3000 4:last_year"));;\
}\
}\
#{DOIF_modify_card_data("DoIF_Strom_Statistik","DoIF_Strom_Statistik","PV_Erzeugung_s.Erzeugung.last_month","bar2year",0,"2022-01-01 85,2022-02-01 245,2022-03-01 754,2022-04-01 768,2022-05-01 810,2022-06-01 873,2022-07-01 817,2022-08-01 801,2022-09-01 531,2022-10-01 463,2022-11-01 146,2022-12-01 87,2023-01-01 103")}
{DOIF_modify_card_data("DoIF_Strom_Statistik","PV_Erzeugung_s","PV_Erzeugung_s.Erzeugung.last_month","bar2year",0,"2022-01-01 85,2022-02-01 245,2022-03-01 754,2022-04-01 768,2022-05-01 810,2022-06-01 873,2022-07-01 817,2022-08-01 801,2022-09-01 531,2022-10-01 463,2022-11-01 146,2022-12-01 87,2023-01-01 103")}
Das erst geht, beim zweiten (so wie von Dir vorgeschlagen), kommt: Can't use string ("") as a HASH ref while "strict refs" in use at ./FHEM/98_DOIF.pm line 1461.
//Roger
So ich habe fertig. Ich habe die Import-Schnittstelle etwas aufgebohrt.
Man kann jetzt sowohl das englische als auch deutsche Zeitformat verwenden, ebenso wird das Kommazeichen statt Punkt bei Zahlen erkannt. Es wird auch erkannt, ob es sich um eine Kommagetrennte Liste oder um eine Liste mit Zeilenumbrüchen handelt. Das bedeutet, dass man direkt Excel csv-Dateien ohne Umwandlung importieren kann. Man kann auch im deutschen Format die Uhrzeit weglassen, ebenso können Sekunden bei Uhrzeitangaben weggelassen werden.
Beispiel
Auszug aus einer csv-Datei mit möglichen Formatierungen:
2023;4,142
02.01.2023 00:01:00;5,159
03.01.2023 00:01;3,170
04.01.2023;5,420
Die csv-Datei wird einfach ins System z. B. in das log-Verzeichnis kopiert und mit der neuen Funktion DOIF_getFileData ausgelesen. Fehlerhafte Datensätze werden am Ende des Importvorgangs auf dem Bildschirm ausgegeben.
Beispiel:
{DOIF_set_card_data ("di","bla","day",'bar1month',0,DOIF_getFileData("./log/Gas_Januar.csv"))}
Die Version ist abwärtskompatibel.
Edit: Neue Version eingecheckt
Hallo Damian,
ich finde deine Darstellung total gut, allerdings kann ich mir nicht erklären, warum bei mir die Doppelanzeige nicht erstellt wird:
defmod di_counter_new DOIF subs {\
## Device Reading hier die push-Zeilen löschen bzw. durch eigene Readings ersetzen\
push (@{$_counter},["Solar","yield_today-1"]);; ## Solarenergie\
push (@{$_counter},["powerfox","Gesamtverbrauch"]);; ## Bezugszähler Strom\
push (@{$_counter},["Buderus","/recordings/heatSources/actualDHWPower_Today_kWh"]);; ## Bezugszähler Gas Warmwasser (DHW)\
push (@{$_counter},["Buderus","/recordings/heatSources/actualCHPower_Today_kWh"]);; ## Bezugszähler Gas Heizung (CH)\
\
## Die restliche Code-Definition muss nicht angepasst werden\
## Anpassung der Visualisierung wird im uiTable-Attribut weiter unten vorgenommen\
\
sub midnight { ## Diese Funktion wird um Mitternacht ausgeführt\
my ($device,$reading,$mday,$yday)=@_;;\
set_Reading("$device.$reading.day_counter",ReadingsVal($device, $reading,1));; \
set_Reading("$device.$reading.last_day",get_Reading("$device.$reading.day",0),1);;\
set_Reading("$device.$reading.day",0,1);;\
set_Reading ("$device.$reading.month",int((ReadingsVal($device, $reading,0)-(get_Reading("$device.$reading.month_counter",0)))*1000)/1000,1);;\
set_Reading ("$device.$reading.year",int((ReadingsVal($device, $reading,0)-(get_Reading("$device.$reading.year_counter",0)))*1000)/1000,1);;\
\
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),1);;\
set_Reading("$device.$reading.month",0,1);;\
if ($yday == 0) {\
set_Reading("$device.$reading.year_counter",ReadingsVal($device, $reading,0));;\
set_Reading("$device.$reading.last_year",get_Reading("$device.$reading.year",0),1);;\
set_Reading("$device.$reading.year",0,1);;\
}\
}\
}\
\
sub init_readings {\
my ($device,$reading)=@_;;\
if (get_Reading("$device.$reading.day_counter","") eq "") { ## Initialisierung der Readings\
## aktuellen Zählerstand initialisieren\
set_Reading("$device.$reading.last_counter",ReadingsVal($device, $reading,0));;\
set_Reading("$device.$reading.day_counter",ReadingsVal($device, $reading,0));; \
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\
## Log definieren\
fhem ("defmod log.counter.$device.$reading FileLog ./log/counter.$device.$reading.log $SELF:$device.$reading.last_.*");;\
fhem ("attr log.counter.$device.$reading room Filelogs");;\
}\
\
}\
} ## Ende subs-Block\
\
get_data { ## Optionale Übernahme bestehender Daten aus dem Log\
for (my $i=0;;$i<@{$_counter};;$i++) {\
::DOIF_set_card_data ("$SELF","$SELF","$_counter[$i][0].$_counter[$i][1].last_day","bar1month",-300,fhem("get log.counter.$_counter[$i][0].$_counter[$i][1] ./log/counter.$_counter[$i][0].$_counter[$i][1].log - 2000 3000 4:last_day"));;\
::DOIF_set_card_data ("$SELF","$SELF","$_counter[$i][0].$_counter[$i][1].last_month","bar2year",-300,fhem("get log.counter.$_counter[$i][0].$_counter[$i][1] ./log/counter.$_counter[$i][0].$_counter[$i][1].log - 2000 3000 4:last_month"));;\
::DOIF_set_card_data ("$SELF","$SELF","$_counter[$i][0].$_counter[$i][1].last_year","bar2decade",-300,fhem("get log.counter.$_counter[$i][0].$_counter[$i][1] ./log/counter.$_counter[$i][0].$_counter[$i][1].log - 2000 3000 4:last_year"));;\
}\
}\
\
\
mid {[00:01];; ## Sicherung der Daten um Mitternacht\
for (my $i=0;;$i<@{$_counter};;$i++) { ## Für jeden Zähler wird die Funktion midnight aufgerufen\
midnight($_counter[$i][0],$_counter[$i][1],$mday,$yday);;\
}\
}\
\
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\
\
# my $diff = int(([$1:$2,0]-(get_Reading("$1.$2.last_counter",0)))*1000)/1000;;\
set_Reading ("$1.$2.last_counter",[$1:$2,0]);;\
set_Reading ("$1.$2.day",int(([$1:$2,0]-(get_Reading("$1.$2.day_counter",0)))*1000)/1000,1);;\
set_Reading ("$1.$2.month",int(([$1:$2,0]-(get_Reading("$1.$2.month_counter",0)))*1000)/1000,1);;\
set_Reading ("$1.$2.year",int(([$1:$2,0]-(get_Reading("$1.$2.year_counter",0)))*1000)/1000,1);;\
}\
)\
\
## 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\
attr di_counter_new room 93_Energie
attr di_counter_new uiTable {package ui_Table;;} ## Optionale Visualisierung der Energie-Verbräuche/-Produktion im DOIF-Device\
\
## Template für die Darstellung eines Wertes\
DEF TPL_single (\
card([$SELF:$2.$3.day:col1w],"$1 Tagesverlauf",undef,$4,$5,$10,$11,"$12",undef,"1","130,1,1,0,1,,200")|\
card([$SELF:$2.$3.last_day:bar1month-300],"$1 in $12 pro Tag",undef,$4,$5,$10,$11,"$12",undef,"1","130,1,1,0,1,0,200")|\
card([$SELF:$2.$3.last_month:bar2year-300],"$1 in $12 pro Monat",undef,$6,$7,$10,$11,"$12",undef,"0","130,1,1,0,1,0,200")|\
card([$SELF:$2.$3.last_year:bar2decade-300],"$1 in $12 pro Jahr",undef,$8,$9,$10,$11,"$12",undef,"0","130,1,1,0,1,0,200")\
)\
\
## Template für die Darstellung von zwei Werten\
DEF TPL_double (\
card([[$SELF:$3.$4.day:col1w],[$SELF:$6.$7.day:col1w]],"$1 Tagesverlauf in $16",undef,$8,$9,$14,$15,["$2","$5"],undef,"1","130,1,1,0,1,,200","0,0,0,0,2")|\
card([[$SELF:$3.$4.last_day:bar1month-300],[$SELF:$6.$7.last_day:bar1month-300]],"$1 in $16 pro Tag",undef,$8,$9,$14,$15,["$2","$5"],undef,"1","130,1,1,0,1,0,200","0,0,0,0,2")|\
card([[$SELF:$3.$4.last_month:bar2year-300],[$SELF:$6.$7.last_month:bar2year-300]],"$1 in $16 pro Monat",undef,$10,$11,$14,$15,["$2","$5"],undef,"0","130,1,1,0,1,0,200","0,0,0,0,2")|\
card([[$SELF:$3.$4.last_year:bar2decade-300],[$SELF:$6.$7.last_year:bar2year-300]],"$1 in $16 pro Jahr",undef,$12,$13,$14,$15,["$2","$5"],undef,"0","130,1,1,0,1,0,200","0,0,0,0,2")\
)\
\
\
## Die Visualisierung einer Tabellenzeile wird über die obigen beiden Templates vorgenommen, hier zeilenweise anpassen/löschen:\
\
## Über das Template TPL_single wird jeweils pro card ein Wert visualisiert\
## Überschrift,Device,Reading,minTag,maxTag,minMonat,maxMonat,minJahr,maxJahr,minColor,maxColor,Einheit\
TPL_single (Stromverbrauch,powerfox,Gesamtverbrauch,0,50,0,800,0,8000,90,0,kWh)\
TPL_single (Stromproduktion,Solar,yield_today-1,0,100,0,500,0,1000,90,0,kWh)\
##\
## Über das Template TPL_double werden jeweils pro card zwei Werte visualisiert\
## Überschrift,Device1,Reading1,Bezeichnung1,Device2,Reading2,Bezeichnung2,minTag,maxTag,minMonat,maxMonat,minJahr,maxJahr,minColor,maxColor,Einheit\
TPL_double (Gasverbrauch,Buderus,/recordings/heatSources/actualDHWPower_Today_kWh,Warmwasser,Buderus,/recordings/heatSources/actualCHPower_Today_kWh,Waerme,0,100,0,2000,0,20000,90,0,m³)\
TPL_double (Elektrizität,Ertrag,MQTT2_DVES_C58DCB,total_pv,Bezug,MQTT2_DVES_C58DCB,total_c,-10,25,-400,800,-4000,6000,0,90,kWh)
Hast Du einen Tip?
Außerdem aktualisieren sich die Werte des Buderus-Device nicht, obwohl im Device bereits neue Werte vorhanden sind. Warum kann das sein?
Gruß
Marco
Zitat von: marboj am 21 Februar 2023, 07:49:16
Hallo Damian,
ich finde deine Darstellung total gut, allerdings kann ich mir nicht erklären, warum bei mir die Doppelanzeige nicht erstellt wird:
push (@{$_counter},["Buderus","/recordings/heatSources/actualDHWPower_Today_kWh"]);; ## Bezugszähler Gas Warmwasser (DHW)\
Hast Du einen Tip?
Außerdem aktualisieren sich die Werte des Buderus-Device nicht, obwohl im Device bereits neue Werte vorhanden sind. Warum kann das sein?
Gruß
Marco
Slash im Readingnamen ist keine gute Idee.
wie trennt man denn dann?
Zitat von: marboj am 21 Februar 2023, 09:56:59
wie trennt man denn dann?
Ein Readingname ist ein eindeutiger Name bestehend aus
Buchstaben, Zahlen, Unterstrichen und Punkten innerhalb eines Devices. Was wills du da trennen?
Entschuldigung, falsch ausgedrückt.
Habe das Modul KM200 installiert für die Heizungssteuerung. Hier werden die Readings genau so im Device angezeigt, mit Slash.
Wie muss ich die Readings denn in dein Modul schreiben, wenn die mit Slash im Device vorhanden sind?
Zitat von: marboj am 21 Februar 2023, 10:02:55
Entschuldigung, falsch ausgedrückt.
Habe das Modul KM200 installiert für die Heizungssteuerung. Hier werden die Readings genau so im Device angezeigt, mit Slash.
Wie muss ich die Readings denn in dein Modul schreiben, wenn die mit Slash im Device vorhanden sind?
Der Readingname wird in der Definition für verschiedene Dinge benutzt. Der geht z. B. in den Namen des Perlblocks und in den Namen des Filelogs ein. Für beides funktioniert das nicht.
Ich habe jetzt auch das Slashzeichen im Perlblocknamen erlaubt (neue DOIF-Version wird vermutlich heute noch eingecheckt), aber im Filelognamen wird es dennoch nicht funktionieren, weil es ein Verzechnis-Trenner ist - das ist nur mal so unter Unix. ;)
Am besten machst du dir in deinem Device ein userReading für das jeweilige Reading mit einem Namen ohne Slashzeichen und gibst es in der DOIF-Definition an.
Habe es jetzt genauso gemacht: userreadings angelegt und die in das Modul als Reading geschrieben.
Leider wird der doppelte Graph trotzdem nicht angezeigt...
Woran kann es liegen?
defmod di_counter_new DOIF subs {\
## Device Reading hier die push-Zeilen löschen bzw. durch eigene Readings ersetzen\
push (@{$_counter},["Solar","total_yield-1"]);; ## Solarenergie\
push (@{$_counter},["powerfox","Gesamtverbrauch"]);; ## Bezugszähler Strom\
push (@{$_counter},["Buderus","DHWMonat"]);; ## Bezugszähler Gas Warmwasser (DHW)\
push (@{$_counter},["Buderus","CHMonat"]);; ## Bezugszähler Gas Heizung (CH)\
## Über das Template TPL_single wird jeweils pro card ein Wert visualisiert\
## Überschrift,Device,Reading,minTag,maxTag,minMonat,maxMonat,minJahr,maxJahr,minColor,maxColor,Einheit\
TPL_single (Stromverbrauch,powerfox,Gesamtverbrauch,0,50,0,800,0,8000,90,0,kWh)\
TPL_single (Stromproduktion,Solar,total_yield-1,0,100,0,500,0,1000,90,0,kWh)\
##\
## Über das Template TPL_double werden jeweils pro card zwei Werte visualisiert\
## Überschrift,Device1,Reading1,Bezeichnung1,Device2,Reading2,Bezeichnung2,minTag,maxTag,minMonat,maxMonat,minJahr,maxJahr,minColor,maxColor,Einheit\
TPL_double (Gasverbrauch,Buderus,DHWMonat,Warmwasser,Buderus,CHMonat,Waerme,0,100,0,2000,0,20000,90,0,m³)\
TPL_double (Elektrizität,Ertrag,MQTT2_DVES_C58DCB,total_pv,Bezug,MQTT2_DVES_C58DCB,total_c,-10,25,-400,800,-4000,6000,0,90,kWh)
Gruß
Marco
Du musst am besten die vorherige Definition löschen.
Du hast es heute mit den Sonderzeichen :)
Nächster Kandidat: Das Minuszeichen
Es ist immer ungünstig Sonderzeichen zu nutzen, die in Perlbezeichnern (Außer Buchstaben und Zahlen ist nur _ erlaubt) nichts verloren haben.
Also, ich bin mit meinem (wenig) Latein am Ende:
Habe alle Readings mit Sonderzeichen durch userReadings ohne Sonderzeichen ersetzt.
Habe testweise die Definition des TPL_double in 2 TPL_single geschrieben.
Als Single werden sie angezeigt, double nicht.
@Damian: Noch eine Idee?
Gruß
Marco
Zitat von: marboj am 21 Februar 2023, 14:44:38
Also, ich bin mit meinem (wenig) Latein am Ende:
Habe alle Readings mit Sonderzeichen durch userReadings ohne Sonderzeichen ersetzt.
Habe testweise die Definition des TPL_double in 2 TPL_single geschrieben.
Als Single werden sie angezeigt, double nicht.
@Damian: Noch eine Idee?
Gruß
Marco
Dann poste doch mal deine komplette Definition.
da ist sie:
defmod di_counter_new DOIF subs {\
## Device Reading hier die push-Zeilen löschen bzw. durch eigene Readings ersetzen\
push (@{$_counter},["Solar","Gesamtertrag"]);; ## Solarenergie\
push (@{$_counter},["powerfox","Gesamtverbrauch"]);; ## Bezugszähler Strom\
push (@{$_counter},["Buderus","DHWMonat"]);; ## Bezugszähler Gas Warmwasser (DHW)\
push (@{$_counter},["Buderus","CHMonat"]);; ## Bezugszähler Gas Heizung (CH)\
\
## Die restliche Code-Definition muss nicht angepasst werden\
## Anpassung der Visualisierung wird im uiTable-Attribut weiter unten vorgenommen\
\
sub midnight { ## Diese Funktion wird um Mitternacht ausgeführt\
my ($device,$reading,$mday,$yday)=@_;;\
set_Reading("$device.$reading.day_counter",ReadingsVal($device, $reading,1));; \
set_Reading("$device.$reading.last_day",get_Reading("$device.$reading.day",0),1);;\
set_Reading("$device.$reading.day",0,1);;\
set_Reading ("$device.$reading.month",int((ReadingsVal($device, $reading,0)-(get_Reading("$device.$reading.month_counter",0)))*1000)/1000,1);;\
set_Reading ("$device.$reading.year",int((ReadingsVal($device, $reading,0)-(get_Reading("$device.$reading.year_counter",0)))*1000)/1000,1);;\
\
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),1);;\
set_Reading("$device.$reading.month",0,1);;\
if ($yday == 0) {\
set_Reading("$device.$reading.year_counter",ReadingsVal($device, $reading,0));;\
set_Reading("$device.$reading.last_year",get_Reading("$device.$reading.year",0),1);;\
set_Reading("$device.$reading.year",0,1);;\
}\
}\
}\
\
sub init_readings {\
my ($device,$reading)=@_;;\
if (get_Reading("$device.$reading.day_counter","") eq "") { ## Initialisierung der Readings\
## aktuellen Zählerstand initialisieren\
set_Reading("$device.$reading.last_counter",ReadingsVal($device, $reading,0));;\
set_Reading("$device.$reading.day_counter",ReadingsVal($device, $reading,0));; \
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\
## Log definieren\
fhem ("defmod log.counter.$device.$reading FileLog ./log/counter.$device.$reading.log $SELF:$device.$reading.last_.*");;\
fhem ("attr log.counter.$device.$reading room Filelogs");;\
}\
\
}\
} ## Ende subs-Block\
\
get_data { ## Optionale Übernahme bestehender Daten aus dem Log\
for (my $i=0;;$i<@{$_counter};;$i++) {\
::DOIF_set_card_data ("$SELF","$SELF","$_counter[$i][0].$_counter[$i][1].last_day","bar1month",-300,fhem("get log.counter.$_counter[$i][0].$_counter[$i][1] ./log/counter.$_counter[$i][0].$_counter[$i][1].log - 2000 3000 4:last_day"));;\
::DOIF_set_card_data ("$SELF","$SELF","$_counter[$i][0].$_counter[$i][1].last_month","bar2year",-300,fhem("get log.counter.$_counter[$i][0].$_counter[$i][1] ./log/counter.$_counter[$i][0].$_counter[$i][1].log - 2000 3000 4:last_month"));;\
::DOIF_set_card_data ("$SELF","$SELF","$_counter[$i][0].$_counter[$i][1].last_year","bar2decade",-300,fhem("get log.counter.$_counter[$i][0].$_counter[$i][1] ./log/counter.$_counter[$i][0].$_counter[$i][1].log - 2000 3000 4:last_year"));;\
}\
}\
\
\
mid {[00:01];; ## Sicherung der Daten um Mitternacht\
for (my $i=0;;$i<@{$_counter};;$i++) { ## Für jeden Zähler wird die Funktion midnight aufgerufen\
midnight($_counter[$i][0],$_counter[$i][1],$mday,$yday);;\
}\
}\
\
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\
\
# my $diff = int(([$1:$2,0]-(get_Reading("$1.$2.last_counter",0)))*1000)/1000;;\
set_Reading ("$1.$2.last_counter",[$1:$2,0]);;\
set_Reading ("$1.$2.day",int(([$1:$2,0]-(get_Reading("$1.$2.day_counter",0)))*1000)/1000,1);;\
set_Reading ("$1.$2.month",int(([$1:$2,0]-(get_Reading("$1.$2.month_counter",0)))*1000)/1000,1);;\
set_Reading ("$1.$2.year",int(([$1:$2,0]-(get_Reading("$1.$2.year_counter",0)))*1000)/1000,1);;\
}\
)\
\
## 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\
attr di_counter_new room 93_Energie
attr di_counter_new uiTable {package ui_Table;;} ## Optionale Visualisierung der Energie-Verbräuche/-Produktion im DOIF-Device\
\
## Template für die Darstellung eines Wertes\
DEF TPL_single (\
card([$SELF:$2.$3.day:col1w],"$1 Tagesverlauf",undef,$4,$5,$10,$11,"$12",undef,"1","130,1,1,0,1,,200")|\
card([$SELF:$2.$3.last_day:bar1month-300],"$1 in $12 pro Tag",undef,$4,$5,$10,$11,"$12",undef,"1","130,1,1,0,1,0,200")|\
card([$SELF:$2.$3.last_month:bar2year-300],"$1 in $12 pro Monat",undef,$6,$7,$10,$11,"$12",undef,"0","130,1,1,0,1,0,200")|\
card([$SELF:$2.$3.last_year:bar2decade-300],"$1 in $12 pro Jahr",undef,$8,$9,$10,$11,"$12",undef,"0","130,1,1,0,1,0,200")\
)\
\
## Template für die Darstellung von zwei Werten\
DEF TPL_double (\
card([[$SELF:$3.$4.day:col1w],[$SELF:$6.$7.day:col1w]],"$1 Tagesverlauf in $16",undef,$8,$9,$14,$15,["$2","$5"],undef,"1","130,1,1,0,1,,200","0,0,0,0,2")|\
card([[$SELF:$3.$4.last_day:bar1month-300],[$SELF:$6.$7.last_day:bar1month-300]],"$1 in $16 pro Tag",undef,$8,$9,$14,$15,["$2","$5"],undef,"1","130,1,1,0,1,0,200","0,0,0,0,2")|\
card([[$SELF:$3.$4.last_month:bar2year-300],[$SELF:$6.$7.last_month:bar2year-300]],"$1 in $16 pro Monat",undef,$10,$11,$14,$15,["$2","$5"],undef,"0","130,1,1,0,1,0,200","0,0,0,0,2")|\
card([[$SELF:$3.$4.last_year:bar2decade-300],[$SELF:$6.$7.last_year:bar2year-300]],"$1 in $16 pro Jahr",undef,$12,$13,$14,$15,["$2","$5"],undef,"0","130,1,1,0,1,0,200","0,0,0,0,2")\
)\
\
\
## Die Visualisierung einer Tabellenzeile wird über die obigen beiden Templates vorgenommen, hier zeilenweise anpassen/löschen:\
\
## Über das Template TPL_single wird jeweils pro card ein Wert visualisiert\
## Überschrift,Device,Reading,minTag,maxTag,minMonat,maxMonat,minJahr,maxJahr,minColor,maxColor,Einheit\
TPL_single (Stromverbrauch,powerfox,Gesamtverbrauch,0,50,0,800,0,8000,90,0,kWh)\
TPL_single (Stromproduktion,Solar,Gesamtertrag,0,100,0,500,0,1000,90,0,kWh)\
#TPL_single (Gasverbrauch,Buderus,DHWMonat,Warmwasser,0,100,0,2000,0,20000,90,0,m³)\
#TPL_single (Gasverbrauch,Buderus,CHMonat,Waerme,0,100,0,2000,0,20000,90,0,m³)\
##\
## Über das Template TPL_double werden jeweils pro card zwei Werte visualisiert\
## Überschrift,Device1,Reading1,Bezeichnung1,Device2,Reading2,Bezeichnung2,minTag,maxTag,minMonat,maxMonat,minJahr,maxJahr,minColor,maxColor,Einheit\
#TPL_double (Elektrizität,Ertrag,MQTT2_DVES_C58DCB,total_pv,Bezug,MQTT2_DVES_C58DCB,total_c,-10,25,-400,800,-4000,6000,0,90,kWh)\
TPL_double (Gasverbrauch,Buderus,DHWMonat,Warmwasser,Buderus,CHMonat,Waerme,0,100,0,2000,0,20000,90,0,m³)
Es waren in meinem Beispiel die Überschriften vertauscht.
## Überschrift,Device1,Reading1,Bezeichnung1,Device2,Reading2,Bezeichnung2,minTag,maxTag,minMonat,maxMonat,minJahr,maxJahr,minColor,maxColor,Einheit
Die korrekte Reihenfolge ist aber (kann man im Beispiel meiner Angaben sehen):
## Überschrift,Bezeichnung1,Device1,Reading1,Bezeichnung2,Device2,Reading2,minTag,maxTag,minMonat,maxMonat,minJahr,maxJahr,minColor,maxColor,Einheit
Bei dir dann:
TPL_double (Gasverbrauch,Warmwasser,Buderus,DHWMonat,Waerme,Buderus,CHMonat,0,100,0,2000,0,20000,90,0,m³)
Ich habe es nun im Wiki korrigiert :)
Jetzt passt es... Dankeschön
Zitat von: Damian am 20 Februar 2023, 22:42:45
So ich habe fertig. Ich habe die Import-Schnittstelle etwas aufgebohrt.
Beispiel:
{DOIF_set_card_data ("di","bla","day",'bar1month',0,DOIF_getFileData("./log/Gas_Januar.csv"))}
Hi Damian,
man bist Du schnell. :)
So habe csv-Dateien erstellt und kann diese einlesen. :D
Allerdings habe und hätte ich gern weiterhin eine Überschriftszeile drin. Da wird eine Fehlermeldung angezeigt - aber trotzdem die weiteren Zeilen verarbeitet.
error at: Datum; Gesamt-Bezug
Vielleicht kannst Du die Meldung unterdrücken ...
Mehr Gedanken macht mir der unterschiedliche Syntax der
DOIF_set_card_data().
Mit Deinem vorgeschlagenen Syntax komme ich bei dem Tages-, Monats- und Jahresstatistik für Strom-, Gas-, Wasserzähler und andere Zähler nicht klar.
Habe das Device nach 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 (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) eingerichtet.
Dort ist unter "get_data ## Optionale Übernahme bestehender Daten aus dem Log" ein anderer Syntax angegeben:
get_data { ## Optionale Übernahme bestehender Daten aus dem Log\
for (my $i=0;;$i<@{$_counter};;$i++) {\
::DOIF_set_card_data ("$SELF","$SELF","$_counter[$i][0].$_counter[$i][1].last_day","bar1month",-300,fhem("get log.counter.$_counter[$i][0].$_counter[$i][1] ./log/counter.$_counter[$i][0].$_counter[$i][1].log - 2000 3000 4:last_day"));;\
::DOIF_set_card_data ("$SELF","$SELF","$_counter[$i][0].$_counter[$i][1].last_month","bar2year",-300,fhem("get log.counter.$_counter[$i][0].$_counter[$i][1] ./log/counter.$_counter[$i][0].$_counter[$i][1].log - 2000 3000 4:last_month"));;\
::DOIF_set_card_data ("$SELF","$SELF","$_counter[$i][0].$_counter[$i][1].last_year","bar2decade",-300,fhem("get log.counter.$_counter[$i][0].$_counter[$i][1] ./log/counter.$_counter[$i][0].$_counter[$i][1].log - 2000 3000 4:last_year"));;\
}\
}\
Und nur dieser funktioniert bei mir.
Mit Deinem Syntax bekomme ich die Fehlermeldung: undefined DoIF_Strom_Statistik, PV_Einspeisung_s, Einspeisung, bar1month combination
Was ist hier richtig?Ich möchte gern die historischen Werte der letzten Tage, Monate und Jahre einlesen.
Wie macht man das genau?Mit 3* DOIF_set_card_data() und drei unterschiedlichen csv-Dateien?
{DOIF_set_card_data("DoIF_Strom_Statistik","DoIF_Strom_Statistik","PV_Bezug_s.Bezug.last_day" ,"bar1month" ,0,DOIF_getFileData("../_data/Bezug_day.csv"))}
{DOIF_set_card_data("DoIF_Strom_Statistik","DoIF_Strom_Statistik","PV_Bezug_s.Bezug.last_month","bar2year" ,0,DOIF_getFileData("../_data/Bezug_month.csv"))}
{DOIF_set_card_data("DoIF_Strom_Statistik","DoIF_Strom_Statistik","PV_Bezug_s.Bezug.last_year" ,"bar2decade",0,DOIF_getFileData("../_data/Bezug_year.csv"))}
Sind wirklich 3 DOIF_set_card_data() nötig? Wenn nur einer: Wie muss der aussehen?
Kann man die Werte in einer gemeinsamen csv-Datei haben und es werden sich je nach Import die tages-, Monats- oder Jahres-Werte herausgesucht?mit fragendem Gruß
Roger
Statt einer unterdrückten Fehlermeldung: könnte man die Überschriften nicht als Feldnamen interpretieren?
Ich wartete noch auf dein Feedback, weil ich mittlerweile so viele Änderungen vorgenommen habe, dass ich langsam einchecken wollte.
Zitaterror at: Datum; Gesamt-Bezug
Kann ich nicht unterdrücken, weil ich nicht weiß wer welche Datensätze liefert. Erwartet wird eine Liste von korrekten Datensätzen und wenn du die Überschrift lieferst, dann kann ich es nicht wissen. FileLog liefert dagegen keine Überschrift und da muss es genauso funktionieren.
Es gibt nur eine
DOIF_set_card_data-Funktion und die hat immer gleiche Parameter:
<card device>,<reading device>,<reading>,<col/bar specification>,<time offset>,<data list>
Die Beschreibung dazu steht ja im Wiki.
bei
<data list> wird eine kommagetrennte oder newline-getrennte Liste erwartet. Es ist egal, ob man sie direkt in Anführungszeichen angibt oder ob es sie andere Funktionen liefern.
ZitatDoIF_Strom_Statistik, PV_Einspeisung_s, Einspeisung, bar1month combination
bedeutet einfach, dass im DOIF-Device
DoIF_Strom_Statistik keine Angabe
[PV_Einspeisung_s:Einspeisung:bar1month] existiert und das stimmt bei di_counter_new auch, denn dort werden andere Readings definiert, aber das hatten wir schon.
Du musst für jede Definition [<Device>:<reading>:<collect type>] einen Daten-Import machen, denn für jede dieser Angaben werden vom DOIF-Device Daten gesammelt.
Sollten zwei identische Angaben [<Device>:<reading>:<collect type>] in einem DOIF-Device definiert worden sein, dann sind das die gleichen Daten und ein Import würde reichen - aber das macht innerhalb eines DOIF-Devices auch wenig Sinn.
Dann werde ich langsam die neue Version einchecken. Dort heißt die Funktion allerdings nicht
DOIF_getFileData sondern
DOIF_get_file_data. Ich habe die Namensgebung passend zu
DOIF_modify/set_card_data angepasst.
siehe: https://forum.fhem.de/index.php/topic,120088.msg1264859.html#msg1264859
Hi Damian,
Zitaterror at: Datum; Gesamt-Bezug
Kann ich nicht unterdrücken,
Damit kann ich gut leben. Daten werden ja trotzdem eingelesen. ;)
Zitatdas stimmt bei di_counter_new auch, denn dort werden andere Readings definiert, aber das hatten wir schon.
Danke. Der Hinweis (in fett) hat mir geholfen es zu verstehen. ::)
ZitatDu musst für jede Definition [<Device>:<reading>:<collect type>] einen Daten-Import machen, denn für jede dieser Angaben werden vom DOIF-Device Daten gesammelt.
Danke für die Erläuterung. So verstehe ich es und weiß Bescheid. :)
Also insgesamt: tolle Grafiken und Möglichkeiten. Ohne Dein Beispiel für die Statistiken für Zähler, hätte ich niemals so was hinbekommen. :'(
//Roger
Zitat von: Roger am 21 Februar 2023, 21:29:15
Hi Damian,
Damit kann ich gut leben. Daten werden ja trotzdem eingelesen. ;)
Danke. Der Hinweis (in fett) hat mir geholfen es zu verstehen. ::)
Danke für die Erläuterung. So verstehe ich es und weiß Bescheid. :)
Also insgesamt: tolle Grafiken und Möglichkeiten. Ohne Dein Beispiel für die Statistiken für Zähler, hätte ich niemals so was hinbekommen. :'(
//Roger
Vielleicht noch zur Info:
Wenn du einen Datensatz hast, der mit # beginnt, dann wird er ohne Meldungen überlesen. Das habe ich eingebaut, weil Filelog am Ende eine Infozeile beginnend mit # liefert.
Und wenn du eine falsche Datei in DOIF_get_file_data angibst, dann liefert die Funktion eine Fehlermeldung und auch diese muss ich als "fehlerhaften Datensatz" ausgeben, damit der User Bescheid weiß, daher "error at:".
Das Beispiel mit di_counter_new ist natürlich schon die Königsdisziplin und ich weiß nicht, ob es leichter oder eher schlechter ist an diesem Beispiel die Funktionsweise von card und dessen Parameter zu verstehen, weil es eine abstrakte Definition ist, bei der man die einzelnen card-Aufrufe nicht direkt sehen kann.
Und an dieser Stelle noch ein kleiner Ausblick. Es wird auch
barMinMax (fliegende Säulen, die die Min-Max-Spanne anzeigen) und
line für Linien in der gleichen Zeitdarstellung geben.
Ich möchte nämlich den Gasverbrauch (als Säulen) und die Temperatur (als Linie) in einem Diagramm gegenüberstellen.
Aber erstmal Programmierpause - es war schon etwas viel in den letzten Wochen :)
Hi Damian,
danke für die Info mit dem #
ZitatWenn du einen Datensatz hast, der mit # beginnt, dann wird er ohne Meldungen überlesen.
Habe meinen Export aus Excel entsprechend angepasst --> supi :)
Habe nun alle historischen Werte (Tagesverlauf, letzte 30 Tageswerte, Monatswerte und Jahreswerte) ins DOIF eingelesen. Die ersten beiden aus FHEM FileLog's, die Monats- & Jahreswerte aus Excel über csv --> sieht toll aus.
Nun muss ich noch die Farben anpassen.
ZitatDas Beispiel mit di_counter_new ist natürlich schon die Königsdisziplin und ich weiß nicht, ob es leichter oder eher schlechter ist an diesem Beispiel die Funktionsweise von card und dessen Parameter zu verstehen, weil es eine abstrakte Definition ist, bei der man die einzelnen card-Aufrufe nicht direkt sehen kann.
Mir hat die Funktionalität und die Grafik so gefallen, dass ich das unbedingt umsetzen wollte. Und Du hast hier etwas anspruchsvolles geschaffen. 8)
ZitatIch möchte nämlich den Gasverbrauch (als Säulen) und die Temperatur (als Linie) in einem Diagramm gegenüberstellen.
Das ist auch meine nächste Herausforderung. Will mal sehen, ob meine Bemühungen zur Einsparung erfolg hatten. Bei Heizung sollte man für den Vergleich mit
Gradtagzahlen arbeiten.
https://www.dwd.de/DE/leistungen/gtz_kostenfrei/gtz_kostenfrei.html (https://www.dwd.de/DE/leistungen/gtz_kostenfrei/gtz_kostenfrei.html)
Bin ja mal gespannt, was für eine Grafik Du hierfür erzeugst. ::)
ZitatAber erstmal Programmierpause - es war schon etwas viel in den letzten Wochen
Ja, es gibt ja noch anderes im Leben. ;)
//Roger
Zitat von: Damian am 21 Februar 2023, 13:07:27
Du musst am besten die vorherige Definition löschen.
Du hast es heute mit den Sonderzeichen :)
Nächster Kandidat: Das Minuszeichen
Es ist immer ungünstig Sonderzeichen zu nutzen, die in Perlbezeichnern (Außer Buchstaben und Zahlen ist nur _ erlaubt) nichts verloren haben.
Mit der aktuellen DOIF-Version funktionieren in der Beispieldefinition 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
nun auch Readings mit
Punkt,
Slash und
Minus im Namen :)
Hallo Damian,
ich habe einen Powerfox, der die Daten in Wh mit Punkt statt Komma und ohne Tausenderzeichen liefert.
Nach dem Thread:
https://forum.fhem.de/index.php/topic,132665.msg1267877.html#msg1267877 (https://forum.fhem.de/index.php/topic,132665.msg1267877.html#msg1267877)
habe ich auch userReadings erstellt, mit Tausenderpunkt und Komma und in kwh umgerechnet.
Diese Userreadings kann ich leider nicht so einfach in Dein Doif einsetzen, es nimmt die Daten nicht. Gibt es da einen Trick? Ich hätte gerne die Ausgabe im Doif als KWh und Punkt / Komma.
Dankeschön
Beste Grüße
Zitat von: FHEM-User22 am 13 März 2023, 10:29:19
Hallo Damian,
ich habe einen Powerfox, der die Daten in Wh mit Punkt statt Komma und ohne Tausenderzeichen liefert.
Nach dem Thread:
https://forum.fhem.de/index.php/topic,132665.msg1267877.html#msg1267877 (https://forum.fhem.de/index.php/topic,132665.msg1267877.html#msg1267877)
habe ich auch userReadings erstellt, mit Tausenderpunkt und Komma und in kwh umgerechnet.
Diese Userreadings kann ich leider nicht so einfach in Dein Doif einsetzen, es nimmt die Daten nicht. Gibt es da einen Trick? Ich hätte gerne die Ausgabe im Doif als KWh und Punkt / Komma.
Dankeschön
Beste Grüße
Das geht z. Zt. nicht. DOIF benötigt zum Rechnen Zahlen mit Punkt als Kommazeichen. Man kann als Formatierung nur die Anzahl der Nachkommastellen angeben.
Hallo Damian,
Dankeschön für die schnelle Antwort.
Beste Grüße aus Grimma
Hallo, wenn ich das Beispiel aus dem Wiki nehme, ,,di_counter_new" erhalte ich immer den Fehler ,,DOIF: Perlblck: no right bracket: {\"
die Klammern stimmen jedoch.
Kann da jemand helfen? Außerdem ist im WIKI mal nach dem set_Reading manchmal sofort eine Klammer und manchmal ein Leerzeichen. Da muss etwas mit der Formatierung schief gelaufen sein.
Ich habe die aktuelle Definition gerade bei mir mit copy und paste ohne Probleme definieren können.
Es handelt sich um eine RAW-Definition, daher muss die Definition über das Pluszeichen links neben der Kommandozeile erfolgen.