jüngsten Wert aus filelog auslesen, um ihn zu inkrementieren *gelöst*

Begonnen von lynckmeister, 26 Januar 2023, 09:37:01

Vorheriges Thema - Nächstes Thema

lynckmeister

Moin zusammen, ich habe ein Shelly im Einsatz, dass mir den Energieverbrauch misst. Allerdings resettet sich der Zähler bei einem Stromverlust.
Daher speichere ich den Zähler in einem Logfile.
Ich möchte nun einen Gesamtverbrauch "sammeln" und dazu die Tagesverbrauchswerte inkrementieren. Da ich auch meinen Fhem gelegentlich resette muss ich den Vor-Wert aus dem Filelog auslesen.
Ich kann mit Get in einem AT bereits Werte erhalten. Allerdings komm ich nicht dahinter wie ich den letzten der im Filelog vorhandenen Werte finde. Wenn ich einen Zeitstempel from und to angebe könnte es ja sein, dass in dieser letzten Minute des Tages keiner oder mehrere geschrieben wurden. Gibt es eine Möglichkeit definitv den letzten Wert aus meiner RegEx zu finden egal wann er geschrieben wurde?

Hier mal mein Beispielcode. Der findet nun mehrere Einträge mit Tagesverbrauch in diesem Intervall.
Wieso werden eigentlich die Werte alle ins Fhem log ausgegeben !? Als ich das intervall noch größer hatte wurde es mit der Ausgabe aus dem Get überflutet, wie kann ich das abstellen?


+*00:00:10 {
my $test = fhem ("get FileLog_Shelly - - 2023-01-01_00:00 2023-01-01_00:00 4:energy.*");

}


frank

ZitatDa ich auch meinen Fhem gelegentlich resette
das habe ich ja noch nie gehört. was machst du da genau?
FHEM: 6.0(SVN) => Pi3(buster)
IO: CUL433|CUL868|HMLAN|HMUSB2|HMUART
CUL_HM: CC-TC|CC-VD|SEC-SD|SEC-SC|SEC-RHS|Sw1PBU-FM|Sw1-FM|Dim1TPBU-FM|Dim1T-FM|ES-PMSw1-Pl
IT: ITZ500|ITT1500|ITR1500|GRR3500
WebUI [HMdeviceTools.js (hm.js)]: https://forum.fhem.de/index.php/topic,106959.0.html

lynckmeister

so ? du verlässt dich auf deine Zählwerte im flüchten RAM deines Fhem-Rechners?

Otto123

#3
Zitat von: lynckmeister am 26 Januar 2023, 09:37:01
Wieso werden eigentlich die Werte alle ins Fhem log ausgegeben !? Als ich das intervall noch größer hatte wurde es mit der Ausgabe aus dem Get überflutet, wie kann ich das abstellen?
Moin,

Üblicherweise in dem Du ein 1 anhängst ;) https://fhem.de/commandref_DE.html#perl
fhem ("get FileLog_Shelly - - 2023-01-01_00:00 2023-01-01_00:00 4:energy.*",1)

ZitatHier mal mein Beispielcode. Der findet nun mehrere Einträge mit Tagesverbrauch in diesem Intervall.
Ich habe die Aufgabe noch nicht ganz verstanden, aber wäre die Lösung der höchste Wert in diesem Intervall?
Viele Grüße aus Leipzig
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

lynckmeister

ja davon kann man ausgehen... die Werte werden ja immer höher... also wird der letzte auch immer der höchste sein;)

Aufgabe ist einfach den letzten Verbrauchsstand aus dem Log zu nehmen, um mit dem Dailyverbrauch den Gesamtverbrauch seit beginn zb der Aufzeichnung zu errechnen... Also Gedamtverbrauch der Klimaanlage...

lynckmeister

hmm komisch obwohl ich jetzt ,1 hin dran hängen habe, werden immer noch zahlreiche Werte ins log geschrieben ...

Otto123

#6
So als Ansatz vom Perl NOOB - nur für die FHEM Kommandozeile zum testen. Du hast die Zahlen in einem Array und sortierst das. Dann ist der erste die kleinste und der letzte die größte Zahl.
{my @arr=qw(2 3 8 9 6 7 10 0 3 2);; my @arr1= sort {$a<=>$b} @arr;; return $arr1[-1]}

Zum anderen Problem, Dein Code liefert ja die Zahlen als return Wert (letzte Variable) Du hast jetzt den get Befehl verhindert. Wenn Du den Wert im Log verhindern willst: hänge als letztes in Deine Perlcode {... ; return undef} ich dachte ja das war nur ein Codefragment?
Viele Grüße aus Leipzig
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

lynckmeister

ok das mit dem Array schau ich mir gleich an , aktuell kämpfe ich mit der Ausgabe , hier mal die gesamte Funktion aus DEF:


+*00:00:10 {
my $test = fhem ("get FileLog_Shelly - - 2023-01-01_00:00 2023-01-01_00:00 4:energy:0:");
{Log 1," >>>>>>>>> Filelog get $test"};
return undef
}



Im Log taucht jetzt folgendes auf :

2023.01.26 12:28:29 1:  >>>>>>>>> Filelog get 2023-01-01_00:00:24 1.2
2023-01-01_00:00:24 1.2
2023-01-01_00:00:24 1.2
2023-01-01_00:00:24 1.2
2023-01-01_00:00:24 1.2
2023-01-01_00:00:24 1.2
#4:energy:0:




Otto123

#8
Naja jetzt schreibst Du den Inhalt Variable $test direkt mit der Log Ausgabe ins Log :)
Zitat{Log 1," >>>>>>>>> Filelog get $test"}

Ich habe noch keine richtige Idee wie Du die Zahlen der Ausgabe vernünftig in ein Array bekommst  :-X da kennen die FHEM Spezies bestimmt was ganz einfaches. Ich würde mich mit split & co mühen...  :'(

Schau Dir das doch direkt in der Kommandozeile an:
{my $test = fhem ("get FileLog_Shelly - - 2023-01-01_00:00 2023-01-01_00:00 4:energy:0:")}
{my $test = fhem ("get FileLog_Shelly - - 2023-01-01_00:00 2023-01-01_00:00 4:energy:0:");;return willi}
{my $test = fhem ("get FileLog_Shelly - - 2023-01-01_00:00 2023-01-01_00:00 4:energy:0:");;return " >>>>>>>>> Filelog get $test"}
Die erste Zeile entspricht: return $test
Viele Grüße aus Leipzig
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

betateilchen

Zitat von: lynckmeister am 26 Januar 2023, 09:37:01
Allerdings komm ich nicht dahinter wie ich den letzten der im Filelog vorhandenen Werte finde.

Stell um auf DbLog, da gibt es genau für Deine Anforderung den Befehl "get ... ReadingsVal <device> <reading>" der den neuesten Wert dieser Kombination zurückliefert.
-----------------------
Mach es möglichst simpel und mach es richtig,
dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

lynckmeister

@Otto, danke für deine Hilfe,
aber ich verstehe nicht so ganz den Gedanken....

ja ich logge eine Zeile ins Log, die will ich da auch lesen - also einmal den Inhalt meiner Testvariablen.

Aber es werden halt auch die Ausgaben vom GET mitgeloggt...
Wenn ich deine drei Statements in der cmdline laufen lasse dann sieht das Ergebnis in
Ich habe alle drei Statements in der CMD Line laufen lassen wie folgt:

1.

2023-01-01_00:00:24 1.2
2023-01-01_00:00:24 1.2
2023-01-01_00:00:24 1.2
2023-01-01_00:00:24 1.2
2023-01-01_00:00:24 1.2
2023-01-01_00:00:24 1.2
#4:energy:0:

Genau diese Zeilen stehen ja auch in meinem Log, wo ich sie nicht haben will ;)
2.
Gleiche Ausgabe ( wenn ich return willi durch return $test ersetze

3. Läuft nur, wenn ich alles ab ;;return weglasse:

{my $test = fhem ("get FileLog_Shelly - - 2023-01-01_00:00 2023-01-01_00:00 4:energy:0:")}

Was ja klar ist, weil du die Perl } ja ab dieser Stelle geschlossen hast ...
Also das mehrer Ereignisse gefunden werden und ich mit einem Array ( du hast dazu ja bereits früher infos gegeben ) weiter versarbeiten kann etc ist soweit klar. Nur wenn ich bei dem Call immer diese Aushgabe habe die auch ins Filelog geht, stimmt doch irgendwas nicht.. und ,1 krieg ich nicht zum laufen ..

@betateilchen: Ja dblog kann ich auch machen, ich dachte nicht, dass das hier aufwendig wird ;)


Otto123

#11
sorry bei 3. hatte ich einen copy Fehler eingebaut, die } muss natürlich am Ende. habe es oben korrigiert.

Aber nochmal
1. entspricht deinem at - wenn Du das so machst hast Du die Ausgabe unabhängig von ,1 immer im Log!
2. verhindert die Ausgabe und schreibt statt dessen willi ins Log, wenn Du willi durch '' oder undef ersetzt steht nichts mehr im Log
3. war leider falsch, aber das ist genau das was Du in deinem letzen at gemacht hast. Du hast die Ausgabe verhindert, aber wieder rein geholt.

Um bei dem get Aufruf das Log zu verhindern, muss an den fhem Aufruf eine 1 angehängt werden: {fhem("get bla bla",1)} oder ohne evaluation {fhem('get bla bla',1)}.

Aber wie gesagt: Du schreibst mMn noch dein Ergebnis ins Log. So habe ich zumindest diese Aussage verstanden:
Zitathmm komisch obwohl ich jetzt ,1 hin dran hängen habe, werden immer noch zahlreiche Werte ins log geschrieben ...
Du musst deine Variable $text "verarbeiten" und am Ende solltest Du nichts an den Aufrufer (dein at ) zurückgeben.
Viele Grüße aus Leipzig
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

lynckmeister

#12
ok vielen Dank für die ausführliche Erklärung, ich glaub jetzt hab ich was verstanden  :)
Also wichtig ist: Es wird nur dann nicht ins log ausgegeben, wenn man in den Fhem call ein ,1 anschliesst UND ein return nondev oder eben "willi" macht.... bei nur ,1 oder nur return nondev wird trotzdem ins log geballert...
So siehts aus :

my @test = fhem ("get FileLog_Shelly - - 2023-01-01_00:00 2023-01-01_00:00 4:energy:0:",1);

return undef


so jetzt gehts an diese Array Sache.. Dieser Get befehl schreibt kein Array sondern ein String mit Zeilenumbruch (CR bzw \n) ....
Also muss man 1. Die Ausgabe am Zeilenumbruch in ein Array schreiben und 2. die Daten die immer vorne mit anstehen rausschneiden...
das ganze sieht dann so aus :


my @test = split("\n",fhem ("get FileLog_Shlly - - 2023-01-01_00:00 2023-01-05_00:00 4:energy:0:",1));
@test = map { s/^.* //; $_ } @test; # hier schneide ich alles ab dem ersten Leerzeichen ab , ginge sicher auch mit Substr ($str,20)
pop @test; # in der letzten Stelle schreibt der Get befehl nochmal nach was ich gesucht habe- könnte man ja vergessen haben - also weg damit!
@test= sort {$a<=>$b} @test; # die Ottogedächtniszeile .. das Array wird sortiert. .. Perl ist echt BrainF*** ----
{Log 1," >>>>>>>>> Filelog get $test[-1] "}; # der höchste Wert steht an der letzten Stelle meines Arrays und jetzt kann ich damit machen was ich will ;)))



BOA WAS EIN AKT... vielen lieben Dank Otto !!

... und jetzt stell ich um auf dblog ;)))))