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

Wzut

Zitat von: B.Stromberg am 08 November 2020, 18:00:50
Wenn du so etwas schon hast, würdest du mir den Code zur Verfügung stellen?
das steckt direkt in meinen Modulen und passt so nicht ganz als sub in der 99_myUtils, aber ich kann dir heute mal ein Beispiel posten.
Von der Ablauflogik kommt das Beispiel von rih schon einigermassen hin, allerdings hat der Aufruf nach Mitternacht und die Verwendung von $yday / $mday einen entscheidenden Nachteil : loggt man die Werte um daraus SVGs zu machen dann stellt das SVG den Januar als Februar da,
da der Zeitstempel im Log ja den 1. des Monats hat. IMHO ist es daher wichtig soetwas immer kurz vor Mitternacht zu machen, wie du das mit deinem at um 23:59 bereits gemacht hast.   
Maintainer der Module: MAX, MPD, UbiquitiMP, UbiquitiOut, SIP, BEOK, readingsWatcher

B.Stromberg

Moin in die Runde!

Also das mit dem Vortag funktioniert nun einwandfrei :)

Ich verstehe gar nicht, dass es so eine Funktion in FHEM nicht "out of the Box" gibt...

Es ist für einen Anfänger doch recht schwer zu begreifen, was nötig ist um "der Gerät" zu sagen, lies einen bestimmten Wert aus dem Logfile am Sonntag um 23:59h.
Wobei das wohl noch die einfachere Übung zu sein scheint und auch noch mit dem at Befehl zu realisieren scheint.
Schwierig wird es mit den Monaten denke ich!
31 Tage, 30 Tage und dann noch der Februar.

Eine Variable wie "get monthly" oder "get weekly" sowie "get daily" wäre ein Träumchen.



Wzut

Zitat von: B.Stromberg am 09 November 2020, 09:25:23
zu sagen, lies einen bestimmten Wert aus dem Logfile am Sonntag um 23:59h. dem at Befehl zu realisieren scheint.
<--snipp -->
31 Tage, 30 Tage und dann noch der Februar.

a. Denkfehler, es wird nichts aus einem Logfile gelesen. Im Gegenteil hier werden Events erzeugt die geloggt werden können.
b. völlig egal, denn der nächste Tag ist immer der 1. :)

Anbei wie ich es in der 99_myUtils lösen würde, egal mit welcher Device / Reading Kombi
Wichtig : die Funktion muss aufgerufen werden zwischen 23:51 und 23:59 damit sie den Anfang des neuen Tages erkennt.
Beim ersten Durchlauf wird noch kein Endwert berechnet da es ja noch keinen Startwert gibt. Behelfen kann sich etwas in dem man die Startwert Readings zuvor von Hand setzt ( sofern man noch plausible Werte hat, gerade für das Jahr schön)
Reading Namen sind immer Geschmacksache, also ggf ändern und die DEf der Logdatei anpassen damit die entsprechenden end_ Werte auch geloggt werden.
sub calc_Midnight {

my $name = shift // return 'missing device name'; # kein Name !
my $r = shift // return 'missing reading name'; # kein Reading !

my $val = ReadingsNum($name, $r, -1);
return "unknown reading $name:$r" if ($val == -1); # das Reading gibt es nicht

my $hash = (exists($defs{$name})) ? $defs{$name} : '';
return "unknown device $name" if (!$hash); # das Device gibt es nicht

my (undef, undef, undef, undef, undef, $year,  $weekday)  = localtime(time);
my (undef, undef, undef, $nday, undef, $nyear, $nweekday) = localtime(time+600);

my $newDay   = ( $nweekday != $weekday ) ? 1 : 0;
return 'call to early' if (!$newDay); # Ende, in 10 Minuten ist noch kein neuer Tag

my $newWeek  = ( $nweekday == 1 ) ? 1 : 0;
my $newMonth = ( $nday == 1 )     ? 1 : 0;
my $newYear  = ( $nyear != $year) ? 1 : 0;

my $lastday = ($val - ReadingsNum($name, 'startDay_'.$r ,0));
$lastday = 0 if ($lastday == $val);

my $lastweek = ($val - ReadingsNum($name, 'startWeek_'.$r ,0));
$lastweek = 0 if ($lastweek == $val);

my $lastmonth = ($val - ReadingsNum($name, 'startMonth_'.$r ,0));
$lastmonth = 0 if ($lastmonth == $val);

my $lastyear = ($val - ReadingsNum($name, 'startYear_'.$r ,0));
$lastyear = 0 if ($lastyear == $val);

readingsBeginUpdate($hash);
readingsBulkUpdate($hash,'startDay_'.$r,   $val);
readingsBulkUpdate($hash,'startWeek_'.$r,  $val) if ($newWeek);
readingsBulkUpdate($hash,'startMonth_'.$r, $val) if ($newMonth);
readingsBulkUpdate($hash,'startYear_'.$r,  $val) if ($newYear);
readingsEndUpdate($hash, 0); # die Zwischenwerte ohne Event

readingsBeginUpdate($hash);
readingsBulkUpdate($hash,'endDay_'.$r,   $lastday);
readingsBulkUpdate($hash,'endWeek_'.$r,  $lastweek)  if ($newWeek);
readingsBulkUpdate($hash,'endMonth_'.$r, $lastmonth) if ($newMonth);
readingsBulkUpdate($hash,'endYear_'.$r,  $lastyear)  if ($newYear);
readingsEndUpdate($hash, 1); # zum loggen mit Event

return;
}


Aufruf im 23:5x at in deinem Fall mit {calc_Midnight('Strom','zaehler_jetzt')} wenn du unbedingt bei deinem Dummy bleiben willst.
Ich würde das Device nehmen das diesen zaehler_jetzt Wert tatsächlich erzeugt.

define at_lastDay at *23:58:00 {calc_Midnight('Strom','zaehler_jetzt')}
Maintainer der Module: MAX, MPD, UbiquitiMP, UbiquitiOut, SIP, BEOK, readingsWatcher

Wolle02

Moin zusammen,

ganz einfach und sozusagen "Out of the Box" wäre das eigentlich auch mir dem Modul "ElectricityCalculator" zu realisieren. Da werden dann automatisch Readings für Tag, letzter Tag, Monat, Jahr, spezieller Abrechnungszeitraum angelegt, die man dann loggen und daraus einen Plot machen kann.
Man kann auch gleich den Preis pro kWh angeben, so dass dann auch Readings für die Kosten für Tag, letzter Tag, usw. angelegt werden.

Alles was du dazu brauchst ist ein separates Zählerdevice, aber das hast du ja schon:
2020-11-01_00:00:40 Strom zaehler_jetzt: 255.728000000259

B.Stromberg

@Wzut
Vielen Dank!

Habe jetzt deinen Code in die 99_myUtils eingefügt und FHEM neu gestartet.
Dann das Define auch genauso von dir übernommen.

Ein execNow hat bisher keine Readings erzeugt, ging mir aber bei der anderen Geschichte weiter oben erst genauso.
Dauert also evtl. bis "Leben" in die Readings kommt.

Wenn ich das nun richtig verstehe wird über das Ganze der Wert zaehler_jetzt, welches ja der aktuelle Zählerstand ist mit den Perioden (Tag, Woche, Montat, Jahr) verglichen bzw. berechnet?

@Wolle02
Ja, das Modul hatte ich auch schon gefunden und mich daran probiert.
Allerdings hatte das bei mir irgendwie nicht funktioniert und war eigentlich auch schon zu umfangreich

Wzut

Zitat von: B.Stromberg am 09 November 2020, 18:00:00
Ein execNow hat bisher keine Readings erzeugt
warum schreibe ich wohl :
Wichtig : die Funktion muss aufgerufen werden zwischen 23:51 und 23:59 damit sie den Anfang des neuen Tages erkennt ?

edit : ich habe da gerade einen copy & paste Fehler gesehen. Die Reading Namen anfragen und speichern passen nicht zusammen.
im untere Abschnitt müsste
readingsBulkUpdate($hash,'startDay_'.$r,   $val) if ($newDay);
readingsBulkUpdate($hash,'startWeek_'.$r,  $val) if ($newWeek);
readingsBulkUpdate($hash,'startMonth_'.$r, $val) if ($newMonth);
readingsBulkUpdate($hash,'startYear_'.$r,  $val) if ($newYear);

stehen
Maintainer der Module: MAX, MPD, UbiquitiMP, UbiquitiOut, SIP, BEOK, readingsWatcher

B.Stromberg

Zitat von: Wzut am 09 November 2020, 18:35:48
warum schreibe ich wohl :
Wichtig : die Funktion muss aufgerufen werden zwischen 23:51 und 23:59 damit sie den Anfang des neuen Tages erkennt ?

edit : ich habe da gerade einen copy & paste Fehler gesehen. Die Reading Namen anfragen und speichern passen nicht zusammen.
im untere Abschnitt müsste
readingsBulkUpdate($hash,'startDay_'.$r,   $val) if ($newDay);
readingsBulkUpdate($hash,'startWeek_'.$r,  $val) if ($newWeek);
readingsBulkUpdate($hash,'startMonth_'.$r, $val) if ($newMonth);
readingsBulkUpdate($hash,'startYear_'.$r,  $val) if ($newYear);

stehen



Ok sorry, dachte das execNow würde das "vorverlegen"
Denkfehler....

diese sind dann richtig?

readingsBulkUpdate($hash,'end_Day'.$r,   $lastday);
readingsBulkUpdate($hash,'end_Week'.$r,  $lastweek)  if ($newWeek);
readingsBulkUpdate($hash,'end_Month'.$r, $lastmonth) if ($newMonth);
readingsBulkUpdate($hash,'end_Year'.$r,  $lastyear)  if ($newYear);


weil die Auflösung vorn ist ja auch anders
wäre dann da nicht endDay_ logisch? (nach Schema startDay_)

Das werden für mich wohl immer Bömische Dörfer bleiben...


Wzut

Zitat von: B.Stromberg am 09 November 2020, 19:15:23
wäre dann da nicht endDay_ logisch? (nach Schema startDay_)
wenn du das schöner findest tue dir keinen Zwang an, ich schrieb ja auch das diese Namen eine reine Geschmacksfrage sind.
Maintainer der Module: MAX, MPD, UbiquitiMP, UbiquitiOut, SIP, BEOK, readingsWatcher

B.Stromberg

Zitat von: Wzut am 09 November 2020, 19:30:08
wenn du das schöner findest tue dir keinen Zwang an, ich schrieb ja auch das diese Namen eine reine Geschmacksfrage sind.

Nö, nö.... Die Namen sind mir wurscht wenns funktioniert.
Tut es aber nicht, bekomme keine Readings, auch nicht nach 23:58h

Woran kann es liegen?

Internals:
   COMMAND    {calc_Midnight('Strom','zaehler_jetzt')}
   DEF        *23:58:00 {calc_Midnight('Strom','zaehler_jetzt')}
   FUUID      5fa9716d-f33f-0855-2dd0-047eeac8cd36ef8b
   NAME       at_lastDay
   NR         292
   PERIODIC   yes
   RELATIVE   no
   REP        -1
   STATE      Next: 23:58:00
   TIMESPEC   23:58:00
   TRIGGERTIME 1605049080
   TRIGGERTIME_FMT 2020-11-10 23:58:00
   TYPE       at
   READINGS:
     2020-11-09 23:58:00   state           Next: 23:58:00
Attributes:
   room       Stromverbrauch


Evtl. noch einmal zum Verständnis:

zaehler_jetzt haut den aktuellen Zählerstand raus und ist ein Userreading.

zaehler_jetzt:StromverbrauchTag.* monotonic {ReadingsVal($name,'StromverbrauchTag',0)}

Der Stromverbrauch wird an einer S0 Schnittstelle vom Stromzähler mit einem Wemos D1 Mini ausgelesen.

Hier noch einmal mein gesamter Code:

define PulsStrom MQTT_DEVICE
setuuid PulsStrom 5ed317f0-f33f-0855-3a48-bca25ab19e05593f
attr PulsStrom IODev myBroker
attr PulsStrom room Stromverbrauch
attr PulsStrom stateFormat transmission-state
attr PulsStrom subscribeReading_Count Stromcount/Watt/Count
attr PulsStrom subscribeReading_Time Stromcount/Watt/Time
attr PulsStrom subscribeReading_Total Stromcount/Watt/Total
attr PulsStrom userReadings StromAktuell {sprintf("%.2f",(3600/(ReadingsVal($name,"Time",0))*1000))}

define Strom dummy
setuuid Strom 5edc1980-f33f-0855-fa44-917ad2b8c36a379e
attr Strom event-on-change-reading StromverbrauchStd,StromverbrauchTag,zaehler_jetzt
attr Strom readingList StromverbrauchStd StromverbrauchTag zaehler_vortag zaehler_jetzt
attr Strom room Stromverbrauch
attr Strom userReadings zaehler_jetzt:StromverbrauchTag.* monotonic {ReadingsVal($name,'StromverbrauchTag',0)}


define FileLog_Stromverbrauch FileLog ./log/Stromverbrauch-%Y-%m.log Strom:StromverbrauchStd:.*|Strom:StromverbrauchTag:.*|Strom:zaehler_jetzt:.*
setuuid FileLog_Stromverbrauch 5ed317f0-f33f-0855-7a59-e6d543aacb7e4a88
attr FileLog_Stromverbrauch room Stromverbrauch

define Stromverbrauch readingsGroup Strom:zaehler_jetzt Strom:StromverbrauchStd
setuuid Stromverbrauch 5ed317f0-f33f-0855-a676-a7a01522f2ce841a
attr Stromverbrauch mapping {"zaehler_jetzt" => "Zaehlerstand", "StromverbrauchStd" => "Momentanverbrauch"}
attr Stromverbrauch nameStyle style="font-weight:bold"
attr Stromverbrauch notime 1
attr Stromverbrauch room Stromverbrauch
attr Stromverbrauch style style="font-size:20px"
attr Stromverbrauch valueFormat {zaehler_jetzt => "%.3f KW/h", StromverbrauchStd => "%.3f KW/h"}
attr Stromverbrauch valueStyle style="text-align:right"

define ESP_reboot at *00:00:00 { system "wget -O /dev/null -q 192.168.2.70/tools?cmd=ResetPulseCounter";; }
setuuid ESP_reboot 5ed596c6-f33f-0855-e761-a6eacc6aab728ccc
attr ESP_reboot room Stromverbrauch
define StromverbrNoti notify PulsStrom {\
my $StromUmlaufzeit = ReadingsVal("PulsStrom","Time","0") / 1000;;\
my $StromProStd=3.6/$StromUmlaufzeit;;\
my $StromProStdRounded=int(1000 * $StromProStd + 0.5) / 1000;;\
my $StromProTag = ReadingsVal("PulsStrom","Total","0") / 1000;;\
fhem("set Strom StromverbrauchStd $StromProStdRounded");;;;\
fhem("set Strom StromverbrauchTag $StromProTag");;;;\
}
setuuid StromverbrNoti 5edc3eb5-f33f-0855-03df-1afa1c1e5549b7b2
attr StromverbrNoti room Stromverbrauch




Wzut

es hat schon seinen Grund warum wir immer lists sehen wollen und keine DEF / RAW Zeilen oder Screenshots.
Anyway, zumindest sieht man das du dir in meinen Augen ein unnötig komplexes Konstrukt aus MQTT- > notify -> dummy + at zusammen gebaut hast, nicht ganz einfach zu lesen und halt noch schwerer ais Aussenstehnder nachzuvollziehen. Ganz gar unklar ist mir dieses Reboot at um Mitternacht.
Wäre es mir würden zuerst das notify und der blöde dummy in die ewigen Jagdgründe gehen. Das was dann noch übrig bleibt bekäme seinen Platz in einem userReading des MQTT Device. Aber das ist eine ganz andere Baustelle und hier OT.

Ok, ich habe heute morgen mein Posting mit dem Code der sub editiert. Lösche deine und nimm die neue Version.
Geändert habe ich die nackten return am Anfang so das nun direkte Rückmeldungen kommen wenn etwas nicht passt.
Du kannst dir zum testen das Leben etwas leichter machen wenn du localtime(time+600) änderst in localtime(time+86400), dann kannst du den ganzen Tag testen und musst nicht immer kurz vor Mitternacht am PC sitzen und 24 Stunden auf den nächsten Versuch warten.

Bitte denke auch noch daran  dein FileLog_Stromverbrauch auf die neuen Events anpassen.
Maintainer der Module: MAX, MPD, UbiquitiMP, UbiquitiOut, SIP, BEOK, readingsWatcher

B.Stromberg

Zitat von: Wzut am 10 November 2020, 17:17:22
es hat schon seinen Grund warum wir immer lists sehen wollen und keine DEF / RAW Zeilen oder Screenshots.
Anyway, zumindest sieht man das du dir in meinen Augen ein unnötig komplexes Konstrukt aus MQTT- > notify -> dummy + at zusammen gebaut hast

Nun ja, also ein Großteil dieses Konstruktes hat Otto mir hier zusammengeklöppelt, somit prallt die Kritik voll bei mir ab  ;D

Aber Spaß beiseite...

Leider gleicher Effekt wie gestern:

Internals:
   CFGFN     
   COMMAND    {calc_Midnight('Strom','zaehler_jetzt')}
   DEF        *23:58:00 {calc_Midnight('Strom','zaehler_jetzt')}
   FUUID      5faadbb8-f33f-0855-f193-60ba67d7c428eab5
   NAME       at_lastDay
   NR         426
   PERIODIC   yes
   RELATIVE   no
   REP        -1
   STATE      Next: 23:58:00
   TIMESPEC   23:58:00
   TRIGGERTIME 1605135480
   TRIGGERTIME_FMT 2020-11-11 23:58:00
   TYPE       at
   READINGS:
     2020-11-10 23:58:00   state           Next: 23:58:00
Attributes:
   room       Stromverbrauch


Es kommen keine Readings

Wzut

Nicht im Strom dummy und ohne Meldung im Log ?
Hast es denn mal von Hand versucht mit execNow ? auch da landen Fehler im Log.
Maintainer der Module: MAX, MPD, UbiquitiMP, UbiquitiOut, SIP, BEOK, readingsWatcher

B.Stromberg

Zitat von: Wzut am 11 November 2020, 06:28:54
Nicht im Strom dummy und ohne Meldung im Log ?
Hast es denn mal von Hand versucht mit execNow ? auch da landen Fehler im Log.

Achsoooooooo
Die Readings landen im Strom Dummy. Sorry, das war für mich nicht so ersichtlich, dachte das müsste alles im at_lastDay landen.

Das Modul liest also "nur" die Zählerstände um 23:58h.
Eine weitere Auswertung findet nicht statt?

Internals:
   FUUID      5edc1980-f33f-0855-fa44-917ad2b8c36a379e
   NAME       Strom
   NR         278
   STATE      0
   TYPE       dummy
   READINGS:
     2020-11-11 12:33:00   StromverbrauchStd 0.048
     2020-11-11 12:33:00   StromverbrauchTag 3.015
     [b]2020-11-10 23:58:00   endDay_zaehler_jetzt 0[/b]
     [b]2020-11-10 23:58:00   startDay_zaehler_jetzt 306.156000000099[/b]
     2020-05-30 23:17:16   state           0
     [b]2020-11-11 12:32:20   zaehler_jetzt   309.172000000086[/b]
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)}


Müsste bei endDay_zaehler_jetzt nicht ein Wert stehen, nämlich der vom Vortag?
Die anderen Werte von Woche, Monat und Jahr erscheinen erst nach den jeweiligen Abläufen?


Wzut

Du könntest mir einen riesen Gefallen tun : Wenn ich mir schon die Mühe mache so viel zu schreiben dann mach du dir bitte auch die Mühe es zu lesen ...

Zitat von: Wzut am 09 November 2020, 17:22:33
Beim ersten Durchlauf wird noch kein Endwert berechnet da es ja noch keinen Startwert gibt. Behelfen kann sich etwas in dem man die Startwert Readings zuvor von Hand setzt ( sofern man noch plausible Werte hat, gerade für das Jahr schön)
Bedeutet : dein erstes Tagesreading bekommst du heute Abend da es nun für heute einen Startwert gibt.
Maintainer der Module: MAX, MPD, UbiquitiMP, UbiquitiOut, SIP, BEOK, readingsWatcher

B.Stromberg

Naja, das Modul läuft ja bereits seit 2 Tagen. Hatte auch mit der Uhrzeit gespielt.
Aber OK, dann warte ich noch.

Eine Frage bleibt allerdings.

Werden die Daten bei jedem FHEM Start wieder zurückgesetzt?