Hier mal ein Beispiel für einen Wasserzähler mit Visualisierung:
Der Wasserzähler wurde über ESPEeasy eingebunden. Die Verbräuche können täglich, wöchentlich, monatlich und jährlich geloggt werden.
defmod Wasserzaehler DOIF { [00:02];;\
set_Reading("tagesverbrauch",get_Reading("heute"),1);;\
set_Reading("gesamt",get_Reading("heute")+get_Reading("gesamt"));;\
set_Reading("woche",get_Reading("heute")+get_Reading("woche"),$wday == 1 ? 1 : 0);;\
set_Reading("monat",get_Reading("heute")+get_Reading("monat"),$mday == 1 ? 1 : 0);;\
set_Reading("jahr",get_Reading("heute")+get_Reading("jahr"),$yday == 1 ? 1 : 0);;\
set_Reading("heute",0);;\
set_Reading("woche",0) if ($wday == 1);;\
set_Reading("monat",0) if ($mday == 1);;\
set_Reading("jahr",0) if ($yday == 1);;\
}\
reset {\
my $Wasseruhr=318334;;\
set_Reading ("gesamt",$Wasseruhr);;\
set_Reading ("heute",0);;\
#set_Reading ("woche",0);;\
#set_Reading ("monat",0);;\
#set_Reading ("jahr",0);;\
}\
\
{\
set_Reading("heute",get_Reading("heute")+([ESPEasy_ESP_Wasser_Wasserzaehler:Count]/2),0);;\
}\
attr Wasserzaehler group Aktuell
attr Wasserzaehler room Wasser,DOIF
attr Wasserzaehler uiTable {package ui_Table;;\
$TC{0..3}="style='padding-left: 3px;;padding-right: 3px'"\
}\
bar([$SELF:tagesverbrauch],0,600,"Vortag",120,0,"l",undef,80)|\
bar([$SELF:heute],0,600,"heute",120,0,"l",undef,80)|\
bar([$SELF:woche]/1000,0,4,"Woche",120,0,"m²",undef,80)|\
bar([$SELF:monat]/1000,0,15,"Monat",120,0,"m²",undef,80)|\
bar([$SELF:jahr]/1000,0,100,"Jahr",120,0,"m²",undef,80)
Moin,
sieht ja richtig gut aus. Aber müsste es nicht m3 heißen?
LG
Andreas
Zitat von: rischbiter123 am 17 Dezember 2020, 19:03:29
Moin,
sieht ja richtig gut aus. Aber müsste es nicht m3 heißen?
LG
Andreas
klar, ist mir noch gar nicht aufgefallen :)
Hallo Damian,
ich habe das natürlich auch gleich ausprobiert. Schaut toll aus. Danke.
Eine Frage hätte ich aber bitte zu Deinem Wasserzähler auf Basis ESPEasy.
Ich versuche mich auch damit, weiß aber nicht, welche Parameter ich dort für den Durchflussmesser eingeben muss.
https://forum.fhem.de/index.php/topic,114088.msg1083480.html#msg1083480 (https://forum.fhem.de/index.php/topic,114088.msg1083480.html#msg1083480)
Kannst Du mir da vielleicht helfen?
Ich komme da einfach nicht weiter.
Danke, lg, Gerhard
Bei mir ist das relativ primitiv mit einem Puls Counter gelöst. Daher muss ich bei mir gar nichts umrechnen, höchstens durch zwei teilen.
Ich habe jetzt mehr Vergleichsdaten der jeweiligen Vorgänger reingepackt und anders dargestellt:
defmod Wasserverbrauch DOIF { [00:02];;\
set_Reading("tagesverbrauch",get_Reading("heute"),1);;\
set_Reading("gesamt",get_Reading("heute")+get_Reading("gesamt"));;\
set_Reading("woche",get_Reading("heute")+get_Reading("woche"));;\
set_Reading("monat",get_Reading("heute")+get_Reading("monat"));;\
set_Reading("jahr",get_Reading("heute")+get_Reading("jahr"));;\
set_Reading("heute",0);;\
if ($wday == 1){\
set_Reading("wochenverbrauch",get_Reading("woche"),1);;\
set_Reading("woche",0);;\
}\
if ($mday == 1) {\
set_Reading("monatsverbrauch",get_Reading("monat"),1);;\
set_Reading("monat",0);;\
\
}\
if ($yday == 1) {\
set_Reading("jahresverbrauch",get_Reading("jahr"),1);;\
set_Reading("jahr",0);;\
}\
}\
reset {\
my $Wasseruhr=329325;;\
set_Reading ("gesamt",$Wasseruhr);;\
set_Reading ("heute",0);;\
set_Reading ("woche",0);;\
set_Reading ("monat",0);;\
set_Reading ("jahr",0);;\
}\
\
{\
set_Reading("heute",get_Reading("heute")+([ESPEasy_ESP_Wasser_Wasserzaehler:Count]/2),0);;\
}\
attr Wasserverbrauch group Aktuell
attr Wasserverbrauch room Wasser,DOIF
attr Wasserverbrauch uiTable {package ui_Table;;\
$TC{0..3}="style='padding-left: 3px;;padding-right: 3px'"\
}\
cylinder("Tag",0,600,"l",undef,undef,undef,1,[$SELF:tagesverbrauch],30,"letzter",[$SELF:heute],60,"aktuell")|\
cylinder("Woche",0,4,"m³",undef,undef,undef,1,[$SELF:wochenverbrauch]/1000,30,"letzte",[$SELF:woche]/1000,60,"aktuell")|\
cylinder("Monat",0,15,"m³",undef,undef,undef,1,[$SELF:monatsverbrauch]/1000,30,"letzter",[$SELF:monat]/1000,60,"aktuell")|\
cylinder("Jahr",0,150,"m³",undef,undef,undef,1,[$SELF:jahresverbrauch]/1000,30,"letztes",[$SELF:jahr]/1000,60,"aktuell")
Und so sieht es aus, wenn man noch den Durchschnittsverbrauch dazu nimmt.
Moin Damian,
nach welcher Anleitung hast Du den Counter gebaut? Würde den nämlich auch gerne bauen. Mit g..gle habe ich zwar verschiedene gefunden, würde aber natürlich gerne eine nehmen, von der ich sicher sein kann, daß sie auch mit Fhem funktioniert.
LG
Andreas
Zitat von: rischbiter123 am 19 Dezember 2020, 19:49:52
Moin Damian,
nach welcher Anleitung hast Du den Counter gebaut? Würde den nämlich auch gerne bauen. Mit g..gle habe ich zwar verschiedene gefunden, würde aber natürlich gerne eine nehmen, von der ich sicher sein kann, daß sie auch mit Fhem funktioniert.
LG
Andreas
Nach eigener Anleitung ;)
Ich habe den hier gekauft: TCRT5000
Wichtig ist noch: zwischen ,,D0" und ,,A0" einen 100kOhm Widerstand anlöten, sonst zählt er zu oft.
Hier noch der passende Code mit Durchschnittsberechnung (siehe https://forum.fhem.de/index.php/topic,116814.msg1112313.html#msg1112313):
defmod Wasserverbrauch DOIF { [00:02];;\
set_Reading("tagesverbrauch",get_Reading("heute"),1);;\
set_Reading("gesamt",get_Reading("heute")+get_Reading("gesamt"));;\
set_Reading("zaehler",get_Reading("heute")+get_Reading("zaehler"));;\
set_Reading("tage",1+get_Reading("tage"));;\
set_Reading("tagesdurchschnitt",get_Reading("gesamt")/get_Reading("tage"));;\
set_Reading("wochendurchschnitt",get_Reading("tagesdurchschnitt")*7/1000);;\
set_Reading("monatsdurchschnitt",get_Reading("tagesdurchschnitt")*30.5/1000);;\
set_Reading("jahresdurchschnitt",get_Reading("tagesdurchschnitt")*365/1000);;\
set_Reading("woche",get_Reading("heute")+get_Reading("woche"));;\
set_Reading("monat",get_Reading("heute")+get_Reading("monat"));;\
set_Reading("jahr",get_Reading("heute")+get_Reading("jahr"));;\
set_Reading("heute",0);;\
if ($wday == 1){\
set_Reading("wochenverbrauch",get_Reading("woche"),1);;\
set_Reading("woche",0);;\
}\
if ($mday == 1) {\
set_Reading("monatsverbrauch",get_Reading("monat"),1);;\
set_Reading("monat",0);;\
\
}\
if ($yday == 1) {\
set_Reading("jahresverbrauch",get_Reading("jahr"),1);;\
set_Reading("jahr",0);;\
}\
}\
reset {\
set_Reading ("zaehler",329325);;\
set_Reading ("gesamt",0);;\
set_Reading ("tage",0);;\
#set_Reading ("heute",0);;\
#set_Reading ("woche",0);;\
#set_Reading ("monat",0);;\
#set_Reading ("jahr",0);;\
}\
\
{\
set_Reading("heute",get_Reading("heute")+([ESPEasy_ESP_Wasser_Wasserzaehler:Count]/2),0);;\
}\
attr Wasserverbrauch group Aktuell
attr Wasserverbrauch room Wasser,DOIF
attr Wasserverbrauch uiTable {package ui_Table;;\
$TC{0..3}="style='padding-left: 3px;;padding-right: 3px'"\
}\
cylinder("Tag",0,600,"l",undef,undef,undef,1,[$SELF:tagesdurchschnitt],120,"Durchschnitt",[$SELF:tagesverbrauch],30,"letzter",[$SELF:heute],60,"aktuell")|\
cylinder("Woche",0,4,"m³",undef,undef,undef,1,[$SELF:wochendurchschnitt],120,"Durchschnitt",[$SELF:wochenverbrauch]/1000,30,"letzte",[$SELF:woche]/1000,60,"aktuell")|\
cylinder("Monat",0,15,"m³",undef,undef,undef,1,[$SELF:monatsdurchschnitt],120,"Durchschnitt",[$SELF:monatsverbrauch]/1000,30,"letzter",[$SELF:monat]/1000,60,"aktuell")|\
cylinder("Jahr",0,150,"m³",undef,undef,undef,1,[$SELF:jahresdurchschnitt],120,"Durchschnitt",[$SELF:jahresverbrauch]/1000,30,"letztes",[$SELF:jahr]/1000,60,"aktuell")
Hallo,
Leider sieht das mit dem Flex style so aus.
Ist nicht nutzbar, das habe ich auch schon bei dem Abfall doif festgestellt.
Liegt mit Sicherheit am Flex style, aber wo kann man hier ansetzen um das anzupassen?
Gruß
Carlos
Zitat von: carlos am 20 Dezember 2020, 13:45:03
Hallo,
Leider sieht das mit dem Flex style so aus.
Ist nicht nutzbar, das habe ich auch schon bei dem Abfall doif festgestellt.
Liegt mit Sicherheit am Flex style, aber wo kann man hier ansetzen um das anzupassen?
Gruß
Carlos
keine Ahnung, ich verwende die Standard-Styles (f18)
Wie wird denn das reset getriggert?
Irgendwie ist mir das DOIF-Perl nicht so ganz einleuchtend....
Zitat von: CQuadrat am 21 Dezember 2020, 09:53:57
Wie wird denn das reset getriggert?
Irgendwie ist mir das DOIF-Perl nicht so ganz einleuchtend....
reset ist ein Block, den man selbst per set nach Bedarf ausführen kann - es gibt hier keinen Trigger.
DOIF-Perl-Syntax ist hier beschrieben: https://fhem.de/commandref_DE.html#DOIF_Perl_Modus
Hier findet man Syntax für das uiTable-Attribut für die Visualisierung: https://wiki.fhem.de/wiki/DOIF/uiTable_Schnelleinstieg
Ich habe die Farben jetzt etwas wasserähnlicher genommen. Durchschnitt soll sich aber wegen der möglichen Überlappungen etwas abheben:
{package ui_Table;
$TC{0..3}="style='padding-left: 3px;padding-right: 3px'"
}
cylinder("Tag",0,600,"l",undef,undef,undef,1,[$SELF:tagesdurchschnitt],30,"Durchschnitt",[$SELF:tagesverbrauch],220,"letzter",[$SELF:heute],180,"aktuell")|
cylinder("Woche",0,4,"m³",undef,undef,undef,1,[$SELF:wochendurchschnitt],30,"Durchschnitt",[$SELF:wochenverbrauch]/1000,220,"letzte",[$SELF:woche]/1000,180,"aktuell")|
cylinder("Monat",0,15,"m³",undef,undef,undef,1,[$SELF:monatsdurchschnitt],30,"Durchschnitt",[$SELF:monatsverbrauch]/1000,220,"letzter",[$SELF:monat]/1000,180,"aktuell")|
cylinder("Jahr",0,150,"m³",undef,undef,undef,1,[$SELF:jahresdurchschnitt],30,"Durchschnitt",[$SELF:jahresverbrauch]/1000,220,"letztes",[$SELF:jahr]/1000,180,"aktuell")
Moin, Damian,
Dein Wasserzähler hat mich dazu gebracht, endlich eine Solar- und eine Ölverbrauchs-Graphik nach dem Schema zu versuchen. Grundlage sind die Statistiken, die ich mit dem Statistik-Modul und dem Hour-Counter-Modul erzeuge. Damit spare ich mir Rechnerei an etlichen Stellen.
Den Durchschnitt auf Tag/Woche/Monat/Jahr wollte ich dann mit den Perlzeitvariabelen fortlaufend und gleich in der UI-Table, in der Du ja auch rechnest ("/1000") errechnen in dieser Art:
cylinder("Tag",0,15,"Liter",undef,undef,undef,1,[CN.Test:appOpHoursPerDayTemp]*1.75/$hour,120,"Durchschnitt",[CN.Test:appOpHoursPerDay]*1.75,30,"gestern",[CN.Test:appOpHoursPerDayTemp]*1.75,60,"heute")|
Tja, Näse, da steigt das Plagiat aus. Ich habe etliche Notationen aus dem commandref versucht, aber immer wenn ich mit/ohne geschweiften/runden/eckigen Klammern da etwas zusammenbau, wird die entsprechende Säule gar nicht mehr gezeigt.
Was mache ich falsch?
Herzliche Grüße
Christian
Hast du package ui_Table im Attribut angegeben?
Poste sonst list von deiner Definition.
ui_Table habe ich eingebunden gemäß Deinem Muster. Bitte beachte beim folgenden Listing, dass ich noch im "werden" bin, daher ist der gesamte Rechenteil aus Deinem Muster buchstäblich "genullt". CN.Test ist ein houcounter, der lediglich die laufenden Durchschnitte nicht errechnet. Könnte ich dort über ein userreading. Bei Deinem uiTable wird aber nur gerechnet, wenn ich drauf schaue, und das ist ja im Normalfall einmal am Tag, also viel seltener als die statistischen Basisdaten erzeugt werden.
Internals:
.AttrList disable:0,1 loglevel:0,1,2,3,4,5,6 notexist checkReadingEvent:0,1 addStateEvent:1,0 weekdays setList:textField-long readingList DOIF_Readings:textField-long event_Readings:textField-long uiTable:textField-long event-aggregator event-min-interval event-on-change-reading event-on-update-reading oldreadings stateFormat:textField-long timestamp-on-change-reading
DEF {(0)
}
FUUID 5fe7b8c0-f33f-e1df-54ac-b2cb36eda50e7512
MODEL Perl
NAME DI_Oelverbrauch
NOTIFYDEV global,CN.Test
NR 3785
NTFY_ORDER 50-DI_Heizung
STATE initialized
TYPE DOIF
VERSION 23403 2020-12-22 15:43:36
.attraggr:
.attrminint:
READINGS:
2020-12-28 10:27:11 block_01 executed
2020-12-26 23:39:05 mode enabled
2020-12-26 23:39:05 state initialized
Regex:
accu:
uiTable:
CN.Test:
DI_Heizung_uiTable_c_0_0_0_0:
appOpHoursPerDay ^CN.Test$:^appOpHoursPerDay:
appOpHoursPerDayTemp ^CN.Test$:^appOpHoursPerDayTemp:
DI_Heizung_uiTable_c_0_1_0_0:
appOpHoursPerWeek ^CN.Test$:^appOpHoursPerWeek:
appOpHoursPerWeekTemp ^CN.Test$:^appOpHoursPerWeekTemp:
DI_Heizung_uiTable_c_0_2_0_0:
appOpHoursPerMonth ^CN.Test$:^appOpHoursPerMonth:
appOpHoursPerMonthTemp ^CN.Test$:^appOpHoursPerMonthTemp:
DI_Heizung_uiTable_c_0_3_0_0:
appOpHoursPerYear ^CN.Test$:^appOpHoursPerYear:
appOpHoursPerYearTemp ^CN.Test$:^appOpHoursPerYearTemp:
condition:
0 (0)
helper:
DEVFILTER ^global$|^CN.Test$
NOTIFYDEV global|CN.Test
globalinit 1
last_timer 0
sleeptimer -1
perlblock:
0 block_01
uiTable:
dev CN.Test
package package ui_Table;
reading appOpHoursPerYearTemp
table:
0:
0:
0:
0 'error Global symbol "$hour" requires explicit package name (did you forget to declare "my $hour"?) at (eval 258855) line 1.
in expression: cylinder("Tag",0,15,"Liter",undef,undef,undef,1,::ReadingValDoIf($hash,'CN.Test','appOpHoursPerDayTemp')*1.75/$hour,120,"Durchschnitt",::ReadingValDoIf($hash,'CN.Test','appOpHoursPerDay')*1.75,30,"gestern",::ReadingValDoIf($hash,'CN.Test','appOpHoursPerDayTemp')*1.75,60,"heute")'
1:
0:
0 package ui_Table;::DOIF_Widget($hash,$reg,'DI_Heizung_uiTable_c_0_1_0_0',cylinder("Woche",0,15,"Liter",undef,undef,undef,1,::ReadingValDoIf($hash,'CN.Test','appOpHoursPerWeekTemp')*1.75,120,"Durchschnitt",::ReadingValDoIf($hash,'CN.Test','appOpHoursPerWeek')*1.75,30,"vorige",::ReadingValDoIf($hash,'CN.Test','appOpHoursPerWeekTemp')*1.75,60,"diese"),"")
2:
0:
0 package ui_Table;::DOIF_Widget($hash,$reg,'DI_Heizung_uiTable_c_0_2_0_0',cylinder("Monat",0,15,"Liter",undef,undef,undef,1,::ReadingValDoIf($hash,'CN.Test','appOpHoursPerMonthTemp')*1.75,120,"Durchschnitt",::ReadingValDoIf($hash,'CN.Test','appOpHoursPerMonth')*1.75,30,"voriger",::ReadingValDoIf($hash,'CN.Test','appOpHoursPerMonthTemp')*1.75,60,"jetziger"),"")
3:
0:
0 package ui_Table;::DOIF_Widget($hash,$reg,'DI_Heizung_uiTable_c_0_3_0_0',cylinder("Jahr",0,15,"Liter",undef,undef,undef,1,::ReadingValDoIf($hash,'CN.Test','appOpHoursPerYearTemp')*1.75,120,"Durchschnitt",::ReadingValDoIf($hash,'CN.Test','appOpHoursPerYear')*1.75,30,"voriges",::ReadingValDoIf($hash,'CN.Test','appOpHoursPerYearTemp')*1.75,60,"dieses"),"")
tc:
0 style='padding-left: 3px;padding-right: 3px'
1 style='padding-left: 3px;padding-right: 3px'
2 style='padding-left: 3px;padding-right: 3px'
3 style='padding-left: 3px;padding-right: 3px'
td:
0:
tr:
Attributes:
room Test
uiTable {package ui_Table;
$TC{0..3}="style='padding-left: 3px;padding-right: 3px'"
}
cylinder("Tag",0,15,"Liter",undef,undef,undef,1,[CN.Test:appOpHoursPerDayTemp]*1.75/$hour,120,"Durchschnitt",[CN.Test:appOpHoursPerDay]*1.75,30,"gestern",[CN.Test:appOpHoursPerDayTemp]*1.75,60,"heute")|
cylinder("Woche",0,15,"Liter",undef,undef,undef,1,[CN.Test:appOpHoursPerWeekTemp]*1.75,120,"Durchschnitt",[CN.Test:appOpHoursPerWeek]*1.75,30,"vorige",[CN.Test:appOpHoursPerWeekTemp]*1.75,60,"diese")|
cylinder("Monat",0,15,"Liter",undef,undef,undef,1,[CN.Test:appOpHoursPerMonthTemp]*1.75,120,"Durchschnitt",[CN.Test:appOpHoursPerMonth]*1.75,30,"voriger",[CN.Test:appOpHoursPerMonthTemp]*1.75,60,"jetziger")|
cylinder("Jahr",0,15,"Liter",undef,undef,undef,1,[CN.Test:appOpHoursPerYearTemp]*1.75,120,"Durchschnitt",[CN.Test:appOpHoursPerYear]*1.75,30,"voriges",[CN.Test:appOpHoursPerYearTemp]*1.75,60,"dieses")|
Danke wiederum, dass Du überhaupt Dich des Themas annimmst.
Christian
OK.
$hour ist im uiTable-Attribut nicht bekannt (nur in Ereignis-Blöcken des DOIF).
Du kannst dir aber im uiTable-Attribut eine Perlfunktion definieren (wie z. B. ic-sub
hier https://wiki.fhem.de/wiki/DOIF/uiTable_Schnelleinstieg#Anzahl_der_Tage_bis_zur_Abfall-Entsorgung), die mit
my ($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = localtime($seconds);
die entsprechenden Variablen zunächst bestimmt, dann die Division durchführt und das Ergebnis zurückliefert.
Die kannst du dann beim cylinder angeben:
cylinder("Tag",0,15,"Liter",undef,undef,undef,1,durchschnitt([CN.Test:appOpHoursPerDayTemp]),120,"Durchschnitt",...
PS
Am besten die neuste DOIF-Version vom 26.12.2020 nehmen. Ich habe einige Optimierungen an der Cylinder-Funktion vorgenommen.
Ah, danke, subs hatte ich als Möglichkeit übersehen, weil ich zu sehr darauf fixiert war, es mit den Perl-Variabelen (die ja im Ausführungsteil gute Dienste leisten) auch in UI-Tables nutzen zu können.
Allerdings werde ich gleich wieder an meine Grenzen geführt:
DI_Oelverbrauch: error: Global symbol "$seconds" requires explicit package name (did you forget to declare "my $seconds"?) at (eval 267101) line 4.
in uiTable: no warnings 'redefine';package ui_Table;
Auf die Verbesserungen der Cylinder-Funktion war ich heute Morgen auch schon gestoßen, hatte aber sicherheitshalber erstmal nicht geupdatet.
Christian
{package ui_Table;
$TC{0..3}="style='padding-left: 3px;padding-right: 3px'"
sub durchschnitt
{
my ($param)=@_;
my ($seconds, $microseconds) = ::gettimeofday();
my ($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = localtime($seconds);
return($param*1.75/$hour);
}
}
Und es klappt bestens, vielen Dank für diesen Erweiterung der Möglichkeiten und eine bewundernswerte Hilfsbereitschaft!
Christian
Ich glaube, es muss im define
$yday == 0
heißen, um den ersten Tag des Jahres zu erwischen.
Siehe auch:
https://forum.fhem.de/index.php?topic=95162.0 (https://forum.fhem.de/index.php?topic=95162.0)