Hallo,
ich habe mal eine Frage, was die Module und ElectricityCalculator und DbLog betrifft.
Vorher habe ich die Werte aus dem ElectricityCalculator mit DbLog in die DB geschrieben und die Graphen (Balkendiagramme) mir mit Grafana anzeigen lassen. In Grafana kann Timestamp Manipulation machen, so das ich den Wert für den Monatsverbrauch, der einen Timestamp von 2019-09-01 00:00:01 hat, auf den Monat August "shiften" kann, damit im Diagramm der Balken auch richtigen Monat erscheint.
Jetzt baue ich grade mir eine Visu mit SmartVisu und nutze das dort enthaltene plot.period mit einem angepassten Fronthem https://forum.fhem.de/index.php/topic,86584.0.html (https://forum.fhem.de/index.php/topic,86584.0.html), um den Graphen mit anzeigen zu lassen. Leider gibt es weder in Smartvisu noch im Converter eine Möglichkeit, manipulativ auf den Timestamp einzugreifen.
Eine Möglichkeit wäre, dass der Maintainer von ElectricityCalculator die Erstellung der Readings um Zeit x nach vorne setzt, wobei ich nicht weiß, ob es da vielleicht andere Probleme ergibt. Kann ich da mit DbLog/DbRep irgendwie in den Prozess beim schreiben in die DB eingreifen?
Wie könnte man das noch lösen? Bin um Tipps dankbar.
LG
Kai
Hallo Kai,
ja du kannst im DbLog mit dem Attribut valueFn oder im Device selbst mit dem Attr DbLogValueFn in den Schreibprozess eingreifen und den Timestamp über die Variable $TIMESTAMP verändern.
Schau dir das mal an.
Grüße,
Heiko
Zitat von: DS_Starter am 01 Oktober 2019, 00:42:38
Hallo Kai,
ja du kannst im DbLog mit dem Attribut valueFn oder im Device selbst mit dem Attr DbLogValueFn in den Schreibprozess eingreifen und den Timestamp über die Variable $TIMESTAMP verändern.
Schau dir das mal an.
Grüße,
Heiko
Guten Morgen Heiko,
vielen Dank für den Tipp - hatte zwar nach sowas gesucht im commandref, aber irgendwie ist mir der Befehl durch die Lappen gegangen. 8)
Ich vermute, das das müsste in etwas so aussehen dann, wenn ich 10 Sekunden vom Timestamp abziehen will?
{
if ($READING eq "Stromzaehler_total_consumption_EnergyCostDayLast")
$NEWTIMESTAMP=time_str2num($TIMESTAMP) - 10
$TIMESTAMP=$NEWTIMESTAMP;
}
Also Umrechnung von Fhem-Timestamp nach Sekunden, davon dann 10 abziehen. Nur wie komm von Sekunden wieder auf den Fhem Timestamp.
Da werde ich auch mit https://wiki.fhem.de/wiki/Zeitangaben,_rechnen_mit nicht schlauer.
Moin Kai,
ZitatNur wie komm von Sekunden wieder auf den Fhem Timestamp.
So:
$NEWTIMESTAMP= FmtDateTime($NEWTIMESTAMP);
Steht im Wiki an anderer Stelle: https://wiki.fhem.de/wiki/DevelopmentModuleAPI#FmtDateTime
In Summe also so, Klammern waren nicht richtig:
{
if ($READING eq "Stromzaehler_total_consumption_EnergyCostDayLast") {
my $NEWTIMESTAMP=time_str2num($TIMESTAMP) - 10;
$NEWTIMESTAMP= FmtDateTime($NEWTIMESTAMP);
$TIMESTAMP=$NEWTIMESTAMP;
}
}
Bisschen einkürzen geht noch mit:
my $NEWTIMESTAMP= FmtDateTime(time_str2num($TIMESTAMP) - 10);
EDIT: my hat gefehlt.
Grüße,
Heiko
Ja cool - vielen Dank Heiko. Werde ich gleich mal testen
Moin Heiko 8)
so, hab es mal getestet, aber leider scheint es keinen Unterschied in der DB zu geben ???
Eingetragen hatte ich im Device "myElectricityCalculator" das Attribut DbLogValueFn mit folgenden Inhalt
{
if ($READING eq "Stromzaehler_total_consumption_EnergyCostDayLast") {
my $NEWTIMESTAMP= FmtDateTime(time_str2num($TIMESTAMP) - 10);
$TIMESTAMP=$NEWTIMESTAMP;
}
- es scheint aber keinen Unterscheid zum Vortag zu geben.
Vor der Änderung:
"2019-10-01 00:00:00" "myElectricityCalculator" "ELECTRICITYCALCULATOR" "Stromzaehler_total_consumption_EnergyDayLast: 10.673" "Stromzaehler_total_consumption_EnergyDayLast" "10.673" "kWh"
Nach der Änderung:
"2019-10-02 00:00:00" "myElectricityCalculator" "ELECTRICITYCALCULATOR" "Stromzaehler_total_consumption_EnergyDayLast: 8.153" "Stromzaehler_total_consumption_EnergyDayLast" "8.153" "kWh"
Ich hätte jetzt beim zweiten DB Eintrag einen Timestamp von 2019-10-01 23:59:50 erwartet
Moin Kai,
das Reading heißt ja auch Stromzaehler_total_consumption_EnergyDayLast. In deiner if-Bedingung
hast du Stromzaehler_total_consumption_EnergyCostDayLast angegeben ?
LG,
Heiko
Zitat von: DS_Starter am 02 Oktober 2019, 08:05:41
Moin Kai,
das Reading heißt ja auch Stromzaehler_total_consumption_EnergyDayLast. In deiner if-Bedingung
hast du Stromzaehler_total_consumption_EnergyCostDayLast angegeben ?
LG,
Heiko
Ok, das ist jetzt aber peinlich - ich hab das nicht gesehen, obwohl ich es mir mehrmals angeschaut habe. Typisches Copy/Paste Phänomen :-) Ja, dann macht das Sinn, das es nicht geklappt hat
Jo, sowas kenn ich zur Genüge. Starre stundenlang auf einen Code und finde nichts ;D
Zitat von: DS_Starter am 02 Oktober 2019, 08:17:07
Jo, sowas kenn ich zur Genüge. Starre stundenlang auf einen Code und finde nichts ;D
Ich mach bei sowas immer eine Pause - wenn ich bei einer Sache nicht weiterkomme, versuche ich 30 Minuten Abstand vom Problem zu nehmen, und dann noch mal frisch dran zu gehen. Hat mir schon oft Nerven und Zeit gespart - oder einfach nicht Müde wichtige Sachen machen. Es gibt einen Zeitpunkt, da baut man nur noch scheisse :-)
Moin und nen schönen Feiertag 8)
Hatte den Fehler gestern berichtigt, trotzdem hat er am Timestamp nix geändert :o :o
{
if ($READING eq "Stromzaehler_total_consumption_EnergyDayLast") {
my $NEWTIMESTAMP= FmtDateTime(time_str2num($TIMESTAMP) - 10);
$TIMESTAMP=$NEWTIMESTAMP;
}
2019-10-03 00:00:00 myElectricityCalculator ELECTRICITYCALCULATOR Stromzaehler_total_consumption_EnergyDayLast: 12.609 Stromzaehler_total_consumption_EnergyDayLast 12.609 kWh
Hallo Kai,
naja, ich habe einen Check im DbLog der die Rückgabe von $TIMESTAMP kontrolliert. Dieser Check war nicht gut.
Ich habe es ihn geändert und getestet.
Zieh dir die neue DbLog Version aus meinem contrib. Zum Download in der FHEMWEB Kommandozeile inklusive der Ausführungszeichen angeben:
"wget -qO ./FHEM/93_DbLog.pm https://svn.fhem.de/fhem/trunk/fhem/contrib/DS_Starter/93_DbLog.pm"
Btw ... In deinem Ausschitt fehlt unter wieder eine "}" oder ist nur nicht mit gepostet.
Dir auch einen schönen Feiertag,
LG,
Heiko
Zitat von: DS_Starter am 03 Oktober 2019, 13:59:14
Btw ... In deinem Ausschitt fehlt unter wieder eine "}" oder ist nur nicht mit gepostet.
Dir auch einen schönen Feiertag,
LG,
Heiko
Hey,
Ich teste das mal und gebe dir morgen eine Rückmeldung. Die } war das, hatte sie nur vergessen zu kopieren ;D
Guten Morgen,
wollte nur kurz Bescheid geben, das es jetzt geklappt hat. Vielen Dank noch mal dafür.
"2019-10-03 23:59:50" "myElectricityCalculator" "ELECTRICITYCALCULATOR" "Stromzaehler_total_consumption_EnergyDayLast: 12.646" "Stromzaehler_total_consumption_EnergyDayLast" "12.646" "kWh"
Vielleicht kannst Du mir bei einem SQL Befehl helfen, um die bisher vorhandenen Timestamp Einträge um 10 Sekunden zu verringern?
Mein Select zum testen ist
SELECT * from history where Device = 'myElectricityCalculator' and READING like '%EnergyDayLast' and Timestamp like '%2019-10-02%'
Morgen Kai,
na das sieht doch gut aus. :)
Dann checke ich den jetzigen Stand von DbLog ein. Hat sich ja schon ein bisschen was verändert.
Dein Statement kann so aussehen:
UPDATE history SET TIMESTAMP=DATE_SUB(TIMESTAMP, INTERVAL 10 SECOND) where Device = 'myElectricityCalculator' AND READING LIKE '%EnergyDayLast' AND TIMESTAMP >= '2019-10-04 00:00:00' AND TIMESTAMP < '2019-10-05 00:00:00';
Aus Performance Sicht ist LIKE nicht so gut. Wenn du auch das Reading bestimmen kannst, benutze besser READING=''.
Wenn es nicht anders geht, dann eben tut es auch LIKE.
Grüße,
Heiko
Zitat von: DS_Starter am 04 Oktober 2019, 09:10:42
Morgen Kai,
na das sieht doch gut aus. :)
Dann checke ich den jetzigen Stand von DbLog ein. Hat sich ja schon ein bisschen was verändert.
Dein Statement kann so aussehen:
UPDATE history SET TIMESTAMP=DATE_SUB(TIMESTAMP, INTERVAL 10 SECOND) where Device = 'myElectricityCalculator' AND READING LIKE '%EnergyDayLast' AND TIMESTAMP >= '2019-10-04 00:00:00' AND TIMESTAMP < '2019-10-05 00:00:00';
Aus Performance Sicht ist LIKE nicht so gut. Wenn du auch das Reading bestimmen kannst, benutze besser READING=''.
Wenn es nicht anders geht, dann eben tut es auch LIKE.
Grüße,
Heiko
Vielen dank - hat geklappt - jetzt stimmt auch der Timestamp der historischen Daten. Ging auch mit =, da war es tatsächlich erheblich schneller
Vielen Dank
mir fällt grad auf beim commandref eintrag zu DbLogValueFn Beispiel. Dort fehlt wohl ein "}"
Example
attr SMA_Energymeter DbLogValueFn
{
if ($READING eq "Bezug_WirkP_Kosten_Diff"){
$UNIT="Diff-W";
}
if ($READING =~ /Einspeisung_Wirkleistung_Zaehler/ && $VALUE < 2){
$IGNORE=1;
}
Jepp, hast du recht. Danke, ändere ich gleich mit.
:D
Zitat von: DS_Starter am 04 Oktober 2019, 09:45:27
Jepp, hast du recht. Danke, ändere ich gleich mit.
:D
Gerne 8)
Moin,
ich hatte valueFn noch mal um ein Reading erweitert, aber leider ist es beim Schreiben wieder nicht gelaufen. Ist da irgendwo ein Fehler drin? Klammern müssten doch richtig sein, oder?
{
if ($READING eq "Stromzaehler_total_consumption_EnergyDayLast") {
my $NEWTIMESTAMP= FmtDateTime(time_str2num($TIMESTAMP) - 10);
$TIMESTAMP=$NEWTIMESTAMP;
}
if ($READING eq "Stromzaehler_total_consumption_EnergyMonthLast") {
my $NEWTIMESTAMP= FmtDateTime(time_str2num($TIMESTAMP) - 10);
$TIMESTAMP=$NEWTIMESTAMP;
}
}
Moin Kai,
da gibt es ein paar Fragen ...
1. was ging nicht ? Timestamp eines der beiden Readings oder beide nicht verändert ?
2. DbLogValueFn oder valueFn ?
3. gibts es Fehler im Log ? wenn mit dem Timestamp etwas nicht stimmt wird nun mit verbose 2 ausgeschrieben:
... TIMESTAMP got from DbLogValueFn in <device> is invalid: <TIMESTAMP>
4. sicher dass es nicht funktioniert hat ? ;)
Die Klammern sind richtig, ja. Wobei man dann "my $NEWTIMESTAMP;" nur einmal vor em ersten if initialisiert. Aber das ist nur eine Schönheitssache, hat nichts mit dem Prob zu tun.
Probiere es doch mal mit Readings die öfter kommen. Sonst muss man immer einen Tag warten.
Hey
Zitat von: DS_Starter am 05 Oktober 2019, 10:08:51
Moin Kai,
da gibt es ein paar Fragen ...
1. was ging nicht ? Timestamp eines der beiden Readings oder beide nicht verändert ?
2. DbLogValueFn oder valueFn ?
3. gibts es Fehler im Log ? wenn mit dem Timestamp etwas nicht stimmt wird nun mit verbose 2 ausgeschrieben:
... TIMESTAMP got from DbLogValueFn in <device> is invalid: <TIMESTAMP>
4. sicher dass es nicht funktioniert hat ? ;)
Die Klammern sind richtig, ja. Wobei man dann "my $NEWTIMESTAMP;" nur einmal vor em ersten if initialisiert. Aber das ist nur eine Schönheitssache, hat nichts mit dem Prob zu tun.
Probiere es doch mal mit Readings die öfter kommen. Sonst muss man immer einen Tag warten.
1. Stromzaehler_total_consumption_EnergyDayLast ging nicht - tags zuvor ging es noch - hatte nur das zweite if eingefügt - das Readings dazu wird nur einmal im Monat aktualisiert.
2. DbLogValueFn beim Device
3. Verbose 2 bei welchem Device? Im DbLog Device ist Verbose 2, es wurde aber beim Update des Readings nichts geloggt
4. das Select sagte jedenfalls
2019-10-05 00:00:00 myElectricityCalculator ELECTRICITYCALCULATOR Stromzaehler_total_consumption_EnergyDayLast: 10.674 Stromzaehler_total_consumption_EnergyDayLast 10.674 kWh
bin mir fast sicher, das es nicht gelaufen ist :o
verbose 2 im dblog device.
passt also wenn ich es richtig sehe. heisst aber auch es wurde kein Fehler bei der timestamp veränderung festgestellt.
hmm ...
Moin Kai,
ich habe jetzt mal die Zeit gefunden dein Szenario bei mir nachzustellen.
Dazu habe ich DbLogValueFn im Device SMA_Energymeter ganz bewußt auf die gleiche Weise wie du gesetzt:
{
if ($READING eq "L2_Spannung") {
my $NEWTIMESTAMP= FmtDateTime(time_str2num($TIMESTAMP) - 10);
$TIMESTAMP=$NEWTIMESTAMP;
}
if ($READING eq "L1_Spannung") {
my $NEWTIMESTAMP= FmtDateTime(time_str2num($TIMESTAMP) - 10);
$TIMESTAMP=$NEWTIMESTAMP;
}
}
Im cache von DbLog sieht man die beiden veränderten Timestamps von L1_Spannung, L2_Spannung gegenüber den anderen.
Zitat
50932 => 2019-10-06 07:42:57|SMA_Energymeter|SMAEM|Einspeisung_WirkP_Verguet_Diff: 0.0000|Einspeisung_WirkP_Verguet_Diff|0.0000|
50933 => 2019-10-06 07:42:57|SMA_Energymeter|SMAEM|state: -212.2|state|-212.2|
50934 => 2019-10-06 07:42:57|SMA_Energymeter|SMAEM|Saldo_Wirkleistung: -212.2|Saldo_Wirkleistung|-212.2|W
50935 => 2019-10-06 07:42:57|SMA_Energymeter|SMAEM|Bezug_Wirkleistung_Zaehler: 9261.7989|Bezug_Wirkleistung_Zaehler|9261.7989|kWh
50936 => 2019-10-06 07:42:57|SMA_Energymeter|SMAEM|Einspeisung_Wirkleistung: 0.0|Einspeisung_Wirkleistung|0.0|W
50937 => 2019-10-06 07:42:57|SMA_Energymeter|SMAEM|Einspeisung_Wirkleistung_Zaehler: 14677.5471|Einspeisung_Wirkleistung_Zaehler|14677.5471|kWh
50938 => 2019-10-06 07:42:47|SMA_Energymeter|SMAEM|L1_Spannung: 233.9|L1_Spannung|233.9|V
50939 => 2019-10-06 07:42:47|SMA_Energymeter|SMAEM|L2_Spannung: 234.0|L2_Spannung|234.0|V
50940 => 2019-10-06 07:42:57|SMA_Energymeter|SMAEM|L3_Spannung: 235.2|L3_Spannung|235.2|V
Ich wüßte nicht warum das bei dir nicht funktionionieren sollte. Die Ursache verbirgt sich dann wahrscheinlich irgendwo anders.
Nebenbei, man kann die Funktion auch so schreiben:
{
if ($READING =~ /^L1_Spannung$|^L2_Spannung$/) {
my $NEWTIMESTAMP= FmtDateTime(time_str2num($TIMESTAMP) - 10);
$TIMESTAMP=$NEWTIMESTAMP;
}
}
LG,
Heiko
Zitat von: DS_Starter am 06 Oktober 2019, 07:58:12
Im cache von DbLog sieht man die beiden veränderten Timestamps von L1_Spannung, L2_Spannung gegenüber den anderen.
Ich wüßte nicht warum das bei dir nicht funktionionieren sollte. Die Ursache verbirgt sich dann wahrscheinlich irgendwo anders.
Deine Vermutung ist richtig - es hatte ja mal funktioniert und ich habe ein Rollback auf die funktionierende Version gemacht. Was soll ich sagen, geht auch nicht mehr - im fhemlog sind auch keine Einträge um die Uhrzeit, DB Eintrag wird aber unverändert geschrieben. Hmmm
Zitat von: DS_Starter am 06 Oktober 2019, 07:58:12
Nebenbei, man kann die Funktion auch so schreiben:
{
if ($READING =~ /^L1_Spannung$|^L2_Spannung$/) {
my $NEWTIMESTAMP= FmtDateTime(time_str2num($TIMESTAMP) - 10);
$TIMESTAMP=$NEWTIMESTAMP;
}
}
LG,
Heiko
Ah cool - ein or geht also auch . mal testen. Hatte ich noch gar nicht dran gedacht
Nur zur Info, falls es wen noch interessiert.
Ich hab das jetzt so gelöst und funktioniert wie erwartet:
{
if ($READING =~ /.*_EnergyDayLast$|.*_EnergyMonthLast$/) {
my $NEWTIMESTAMP= FmtDateTime(time_str2num($TIMESTAMP) - 10);
$TIMESTAMP=$NEWTIMESTAMP;
}
}