Werte aus einem Logfile auslesen für Vortag, Woche, Monat, Jahr....bloß wie?

Begonnen von B.Stromberg, 07 November 2020, 01:42:43

Vorheriges Thema - Nächstes Thema

B.Stromberg

Hallo!
Ich hatte vor einiger Zeit schon einmal ein Projekt gestartet, den Stromverbrauch meiner Wärmepumpe auszulesen.
Das klappt soweit auch alles sehr gut und genau.

Nun hätte ich sehr gern noch eine Anzeige für den Stromverbrauch des Vortags, Woche, Monat, Jahr.

Das Define für das Logfile sieht so aus:

define FileLog_Stromverbrauch FileLog ./log/Stromverbrauch-%Y-%m.log Strom:StromverbrauchStd:.*|Strom:StromverbrauchTag:.*|Strom:zaehler_jetzt:.*

Nun wird jeden Monat ein Logfile erzeugt.

Die Werte sehen dann so aus:

2020-11-01_00:00:00 Strom StromverbrauchTag: 0
2020-11-01_00:00:40 Strom StromverbrauchTag: 0.001
2020-11-01_00:00:40 Strom zaehler_jetzt: 255.728000000259


Jetzt müsste ja quasi nur ein Dummy erzeugt werden, der jeden Tag um 23:59h das Reading Vortag erzeugt.
Gleiches dann für Woche, Monat und Jahr.

Tja und warum bin ich nun im Anfängerforum?
Weil ich leider Null Plan habe wie ich das machen kann :(

Kann mir jemand bitte unter die Arme greifen?

amenomade

Mit einem at, der ein
setreading Strom lastDay [Strom:StromverbrauchTag]macht, brauchst Du kein zusätzliches Dummy
Pi 3B, Alexa, CUL868+Selbstbau 1/2λ-Dipol-Antenne, USB Optolink / Vitotronic, Debmatic und HM / HmIP Komponenten, Rademacher Duofern Jalousien, Fritz!Dect Thermostaten, Proteus

B.Stromberg

Zitat von: amenomade am 07 November 2020, 01:59:06
Mit einem at, der ein
setreading Strom lastDay [Strom:StromverbrauchTag]macht, brauchst Du kein zusätzliches Dummy

..kannst du mir da bitte etwas mehr auf die Sprünge helfen?

EDIT:

so?
define lastDay at *23:59:00 [Strom:StromverbrauchTag]

Allerdings kriege ich so kein Reading....


amenomade

Nein, genau wie geschrieben: ein at, der setreading macht.
define lastDay at *23:59:00 setreading Strom lastDay [Strom:StromverbrauchTag]
Pi 3B, Alexa, CUL868+Selbstbau 1/2λ-Dipol-Antenne, USB Optolink / Vitotronic, Debmatic und HM / HmIP Komponenten, Rademacher Duofern Jalousien, Fritz!Dect Thermostaten, Proteus

B.Stromberg

Zitat von: amenomade am 07 November 2020, 08:57:14
Nein, genau wie geschrieben: ein at, der setreading macht.
define lastDay at *23:59:00 setreading Strom lastDay [Strom:StromverbrauchTag]

Danke für deine Hilfe.

Habe das jetzt mal aktuell ausprobiert.
Bekomme aber kein Reading :(

Internals:
   CFGFN     
   COMMAND    setreading Strom lastDay [Strom:StromverbrauchTag]
   DEF        *12:40:00 setreading Strom lastDay [Strom:StromverbrauchTag]
   FUUID      5fa6876a-f33f-0855-1fc0-b7111c34616982f2
   NAME       lastDay
   NR         29790
   PERIODIC   yes
   RELATIVE   no
   REP        -1
   STATE      Next: 12:40:00
   TIMESPEC   12:40:00
   TRIGGERTIME 1604835600
   TRIGGERTIME_FMT 2020-11-08 12:40:00
   TYPE       at
   READINGS:
     2020-11-07 12:40:00   state           Next: 12:40:00
Attributes:

amenomade

Zeig bitte das Ergebnis von "list Strom", nachdem Du auf dem at ein set execNow gemacht hast.

Pi 3B, Alexa, CUL868+Selbstbau 1/2λ-Dipol-Antenne, USB Optolink / Vitotronic, Debmatic und HM / HmIP Komponenten, Rademacher Duofern Jalousien, Fritz!Dect Thermostaten, Proteus

B.Stromberg

Zitat von: amenomade am 07 November 2020, 16:28:58
Zeig bitte das Ergebnis von "list Strom", nachdem Du auf dem at ein set execNow gemacht hast.


Internals:
   FUUID      5edc1980-f33f-0855-fa44-917ad2b8c36a379e
   NAME       Strom
   NR         278
   STATE      0
   TYPE       dummy
   READINGS:
     2020-11-08 02:56:40   StromverbrauchStd 0.047
     2020-11-08 02:56:40   StromverbrauchTag 0.586
     2020-11-08 02:56:45   lastDay         0.586
     2020-05-30 23:17:16   state           0
     2020-11-08 02:56:30   zaehler_jetzt   287.353000000142
Attributes:
   event-on-change-reading StromverbrauchStd,StromverbrauchTag,zaehler_jetzt
   readingList StromverbrauchStd StromverbrauchTag zaehler_vortag zaehler_jetzt
   room       Stromverbrauch
   userReadings zaehler_jetzt:StromverbrauchTag.* monotonic {ReadingsVal($name,'StromverbrauchTag',0)}

Nobbynews

Zitat von: B.Stromberg am 08 November 2020, 02:57:39

Internals:
   READINGS:
     2020-11-08 02:56:40   StromverbrauchStd 0.047
     2020-11-08 02:56:40   StromverbrauchTag 0.586
     2020-11-08 02:56:45   lastDay         0.586
     2020-05-30 23:17:16   state           0
     2020-11-08 02:56:30   zaehler_jetzt   287.353000000142
Attributes:
   event-on-change-reading StromverbrauchStd,StromverbrauchTag,zaehler_jetzt

Also das reading lastDay ist doch vorhanden. Von Hand gesetzt?
Oder ist ein fehlender Log-Eintrag gemeint?
Im Wiki steht dazu:
ZitatSind bei einem Device weder event-on-change-reading noch event-on-update-reading spezifiziert, werden für alle Readings sowohl bei Änderung als auch bei der Aktualisierung (mit dem gleichen Wert) Events erzeugt. Sobald jedoch eines der beiden Attribute gesetzt ist, müssen alle Readings, die protokolliert werden sollen bei (mindestens) einem der Attribute berücksichtigt sein.
Somit dürfte also das Reading lastDay in der Auflistung fehlen und damit kein Event und deshalb kein Log-Eintrag erzeugt werden.

B.Stromberg

soooo..........das Reading ist nun da.
Bin heute Nacht gespannt ob das dann auch so geht (wovon ich jetzt mal ausgehe)

Somit wäre Vortag erledigt.

Wie geht das Ganze nun mit Woche, Monat und Jahr?


B.Stromberg

Zitat von: amenomade am 07 November 2020, 16:28:58
Zeig bitte das Ergebnis von "list Strom", nachdem Du auf dem at ein set execNow gemacht hast.

Das scheint soweit zu klappen.

Kannst du mir bitte auch bei wöchentlich, monatlich und jährlich weiterhelfen?

Wzut

Woche , Monat Jahr läuft bei mir nach dem gleichen Muster :
at nahe Miternacht um die aktuellen Ist Werte zu retten und die neuen berechnen. Da macht es allerdings schon Sinn auf eine eigene Funktion in der 99_myUtils auszuweichen , die muss beim Aufruf zuerst prüfen :
Ist der nächste Tag ein Montag ? wenn ja dann rette den aktuellen Wert als Wochenende und berechne aus dem Wert von letzet Woche den aktuellen Verbrauch dieser Woche.
Dann prüfen ob der nächste Tag der erste eines Monats ist , wenn ja : gleiches Spiel wie bei der Woche.
zum Schluss dann prüfen ob morgen der 1. januar ist (oder heute der 31.12) , wenn ja : Jahr berechnen.
Das ergibt zwar eine Batterie von Readings, aber so bekommt man schön den Überblick.
Ich würde bei der Gelgenheit auch gleich den Dummy entsorgen und direkt die Readings in dem Device setzen das auch die Ausgangswerte bereitstellt.
Maintainer der Module: MAX, MPD, UbiquitiMP, UbiquitiOut, SIP, BEOK, readingsWatcher

amenomade

Du hast aber kein Reading, das den Verbrauch für Woche, Monat oder Jahr erfasst.
Schau mal nach Modul "statistics". Für Woche macht es nicht, aber Du hättest schon Monat und Jahr.

Sonst kannst Du auch mit einem at arbeiten: bei Tageswechsel:
- wenn $wday==1, zaehler_jetzt als zaehler_Anfang_Woche speichern
- wenn $mday==1, zaehler_jetzt als zaehler_Anfang_Monat speichern
- wenn $yday==1, zaehler_jetzt als zaehler_Anfang_Jahr speichern

Dann mit userReadings oder noch im at selbst die gewünschte Differenzen kalkulieren.
Pi 3B, Alexa, CUL868+Selbstbau 1/2λ-Dipol-Antenne, USB Optolink / Vitotronic, Debmatic und HM / HmIP Komponenten, Rademacher Duofern Jalousien, Fritz!Dect Thermostaten, Proteus

B.Stromberg

Zitat von: Wzut am 08 November 2020, 17:48:03
Woche , Monat Jahr läuft bei mir nach dem gleichen Muster :
at nahe Miternacht um die aktuellen Ist Werte zu retten und die neuen berechnen. Da macht es allerdings schon Sinn auf eine eigene Funktion in der 99_myUtils auszuweichen , die muss beim Aufruf zuerst prüfen :
Ist der nächste Tag ein Montag ? wenn ja dann rette den aktuellen Wert als Wochenende und berechne aus dem Wert von letzet Woche den aktuellen Verbrauch dieser Woche.
Dann prüfen ob der nächste Tag der erste eines Monats ist , wenn ja : gleiches Spiel wie bei der Woche.
zum Schluss dann prüfen ob morgen der 1. januar ist (oder heute der 31.12) , wenn ja : Jahr berechnen.
Das ergibt zwar eine Batterie von Readings, aber so bekommt man schön den Überblick.
Ich würde bei der Gelgenheit auch gleich den Dummy entsorgen und direkt die Readings in dem Device setzen das auch die Ausgangswerte bereitstellt.

Das übersteigt leider meine Fähigkeiten bei weitem....
Wenn du so etwas schon hast, würdest du mir den Code zur Verfügung stellen?

jkriegl

Hier ein Code-Beispiel für Wetterwerte am Monatsendedefmod month_end at *23:59:00 {if ((strftime "%d",localtime time+86400) eq "01") {\
my $Erg=sprintf("Durchs %.1f max %.1f min %.1f", ReadingsVal("muc","temperature_avg_month",0), \
ReadingsVal("muc","temperature_max_month",0),\
ReadingsVal("muc","temperature_min_month",0));;\
fhem("setreading muc month_end $Erg");;;; }\
}

das reading:
month_end Durchs 10.3 max 22.2 min 3.4 2020-10-31 23:59:00
Rpi 3/4, buster, Fhem, Cul 868, HM-CC-RT-DN, HM-Sec-Sco, HM-ES-PMSw1-Pl, ebus (Vaillant), ECMD, Telegram, HTTPMOD, Xiaomi, Shelly

rih

@B.Stromberg:
Möchte Dir beispielhaft meine Lösung vorstellen (vermutlich ähnlich wie die von Wzut). Ist vielleicht nicht profihaft programmiert, dafür aber leicht verständlich und leicht um die Wochenwerte erweiterbar.

Zunächst brauchst Du 3 bzw. in Deinem Fall 4 Dummys, welche die Werte des Tages/Vortages, Woche/Vorwoche, Monat/Vormonat und Jahr/Vorjahr speichern. Natürlich könntest Du auch alle Werte in nur einem Dummy speichern.

Dann brauchst Du den nachfolgenden Code, den Du in die 99_myUtils.pm einfügst. Die Variablen- und Readingsnamen musst Du nach Deinen Wünschen anpassen:
sub PV_Rechner {
my ($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = localtime;
my $Total_neu = (ReadingsVal("S0_PV","Total",0));
my $Total_alt = (ReadingsVal("S0_PV","Total_alt",0));
my $ErtragVorTag = (ReadingsVal("PV_Ertrag_Tag","Ertrag_VorTag",0));
my $ErtragVorMonat = (ReadingsVal("PV_Ertrag_Monat","Ertrag_VorMonat",0));
my $ErtragVorJahr = (ReadingsVal("PV_Ertrag_Jahr","Ertrag_VorJahr",0));
my $ErtragTag = (ReadingsVal("PV_Ertrag_Tag","Ertrag_Tag",0));
my $ErtragMonat = (ReadingsVal("PV_Ertrag_Monat","Ertrag_Monat",0));
my $ErtragJahr = (ReadingsVal("PV_Ertrag_Jahr","Ertrag_Jahr",0));
my $Diff = $Total_neu - $Total_alt;
my $ErtragTag_neu = $ErtragTag + $Diff;
my $ErtragMonat_neu = $ErtragMonat + $Diff;
my $ErtragJahr_neu = $ErtragJahr + $Diff;
fhem("setreading S0_PV Total_alt $Total_neu");
fhem("setreading PV_Ertrag_Tag Ertrag_Tag $ErtragTag_neu");
fhem("setreading PV_Ertrag_Monat Ertrag_Monat $ErtragMonat_neu");
fhem("setreading PV_Ertrag_Jahr Ertrag_Jahr $ErtragJahr_neu");
if(($hour==0) && ($min==0)){
  my $neuerVortagesErtrag = $ErtragTag;
  fhem("setreading PV_Ertrag_Tag Ertrag_VorTag $neuerVortagesErtrag ");
  fhem("setreading PV_Ertrag_Tag Ertrag_Tag 0")
}
if(($hour==0) && ($min==0) && ($mday==1)){
  my $neuerVormonatsErtrag = $ErtragMonat;
  fhem("setreading PV_Ertrag_Monat Ertrag_VorMonat $neuerVormonatsErtrag ");
  fhem("setreading PV_Ertrag_Monat Ertrag_Monat 0")
}
if(($hour==0) && ($min==0) && ($yday==1)){
  my $neuerVorjahresErtrag = $ErtragJahr;
  fhem("setreading PV_Ertrag_Jahr Ertrag_VorJahr $neuerVorjahresErtrag ");
  fhem("setreading PV_Ertrag_Jahr Ertrag_Jahr 0")
}
}


Nun legst Du ein at an, welches minütlich die Routine in der 99_myUtils.pm startet:
define PV_Ertrag at +*00:01:00 {PV_Rechner]

Die Zählerwerte Total_alt/Total_neu werden direkt im Zähler-Device (hier S0-Zähler) gebildet bzw. gespeichert. Alle Readings in den Dummys solltest Du vor dem ersten Aufruf der Routine mit
setreading "Dummyname" "Readingname" "Readingwert"
aus der Kommandzeile anlegen.
Falls der minütliche Aufruf des at nicht gewüscht ist (z.B. nur jede Stunde), dann müsstest Du die "if's" in der Routine anpassen.
Vielleicht hilft Dir das weiter.

Nachtrag: Die Werte werden dann in einer Readingsgroup erfasst und mit mittels den Attributen valueStyle und valueFormat zu einer gefälligen Anzeige gebracht.