FHEM Forum

FHEM => Anfängerfragen => Thema gestartet von: peewag am 16 Januar 2020, 20:44:58

Titel: (gelöst) Rechnen mit Timestamps
Beitrag von: peewag am 16 Januar 2020, 20:44:58
Hallo zusammen,

ich habe da anscheinend einen Knopf im Hirn, ich hoffe ihr könnt mir da weiter helfen.

Ich habe zwei Dummys:
1. PV_current_sensor --> MQTT Sensor --> liefert alle paar Sekunden einen neuen Stromwert
2. battery --> MQTT Sensor --> liefert auch alle paar Sekunden eine nee Spannung

Zusätzlich habe ich ein Notify:
calc_DC_PV_power:
PV_current_sensor.* {
my $power = ReadingsVal("PV_current_sensor","current",0) * ReadingsVal("battery","total_voltage",0);;
fhem("set PV_power $power");;
}


Dieses setzt bei einer Stromänderung den Wert eines dritten Dummys PV_power. Das funktioniert auch so weit.

Jetzt wollte ich gerne die Energie mit loggen, sprich: den vorigen Leistungs-Wert mit der vergangenen Zeit multiplizieren und aufsummieren. Aber ich schaffe es einfach nicht die Sekunden seit dem letzten Aufrufen des notifies heraus zu bekommen. OldTimestamp, OldReadingsAge oder ReadingAge liefern immer nur den aktuellen Timestamp oder gleich den Default-Wert egal ob ich sie auf eines der Dummys anwende oder auf das Notify.

Kann mir da bitte wer einen Tipp geben, wie ich da weiter komme?

vielen Dank schon mal,

lg Peter
Titel: Antw:Rechnen mit Timestamps
Beitrag von: MadMax-FHEM am 16 Januar 2020, 20:50:56
Ich würde ja im 3ten Dummy (wobei eh fraglich ist: braucht es 3 Dummy!? ;)  ) statt set ein:

setreading PV_power power $power
machen, dann kannst du doch da mittels:

ReadingsAge("PV_power","power",0)

Die Sekunden seit dem letzten Setzen abfragen!?

EDIT: evtl. würde ich auch das RegEx des notify etwas "enger" fassen. PV_current_sensor.* "hört" auf jeden Event des Devices... Interessant wäre aber ja nur "current"!?

EDIT2: evtl. auch statt ReadingsVal auf ReadingsNum "umstellen", da ist dann sichergestellt, dass nur "numerische" Werte zurückgeliefert werden (sollten [mal] Einheiten etc. dabei sein)...

Gruß, Joachim
Titel: Antw:Rechnen mit Timestamps
Beitrag von: KernSani am 16 Januar 2020, 20:55:03
Nur zur Sicherheit, Attribut oldteadings ist gesetzt?


Kurz, weil mobil
Titel: Antw:Rechnen mit Timestamps
Beitrag von: Otto123 am 16 Januar 2020, 21:25:58
Ich weiß nicht genau ob das trifft, ich hatte letztens mal sowas begonnen:
defmod n_Lueftung notify Fenster.*:(open|closed) setreading n_Lueftung time_$EVENT {(time)}
attr n_Lueftung userReadings Diff:time_closed.* {int(ReadingsNum($name,"time_closed",0) - ReadingsNum($name,"time_open",0))}

Bei jedem Aufruf des notify wird die Zeit zwischen open und closed gemessen und die Differenz ins userReadings geschrieben.

Gruß Otto
Titel: Antw:Rechnen mit Timestamps
Beitrag von: peewag am 16 Januar 2020, 21:46:29
Vielen Dank für die schnellen Antworten!

Erstes Problem war:
ZitatNur zur Sicherheit, Attribut oldteadings ist gesetzt?
hab ich natürlich übersehen  ::)

und das zweite Problem, dass es nur einen OldValue, bzw. ein Age gibt, wenn sich der Wert auch ändert! In der Nacht ist der PV-Strom hald immer 0A  ::) somit gibt es noch keine alten Werte.

Momentan sieht mein Notify so aus:
PV_current_sensor.* {
my $power = ReadingsVal("PV_current_sensor","current",0) * ReadingsVal("battery","total_voltage",0);;
my $duration = OldReadingsAge("PV_current_sensor","current",0);;
fhem("set PV_power $power");;
fhem ("setreading PV_power duration $duration");;
}


Vielen Dank für eure schnellen Antworten,

ich werde das morgen nochmals überarbeiten und dann von meinem Erfolg berichten!  8)
Titel: Antw:Rechnen mit Timestamps
Beitrag von: peewag am 19 Januar 2020, 21:38:26
So ich habe ja versprochen, ich Berichte von meinem Erfolg   8)


PV_current_sensor.* {
my $power = ReadingsNum("PV_current_sensor","current",0) * ReadingsNum("battery","total_voltage",0);;
my $duration = OldReadingsAge("PV_current_sensor","current",0);;
my $energy = ReadingsNum("PV_power", "energy",0);;
if ($power >= 2.0 && $duration < 120)
{
$energy = $energy + ($power * $duration / 3600.0);;
}
fhem("set PV_power $power");;
fhem ("setreading PV_power duration $duration");;
fhem ("setreading PV_power energy $energy");;
}


Kurze Erlärung:
Jedes mal wenn ein neuer Stromwert per MQTT rein kommt, wird diese Funktion aufgerufen.
Dann wird die aktuelle Leistung berechnet und in die Variable power gespeichert.
Außerderm wird das alter des letzten Stromwertes abgefragt und unter der Variable duration gespeichert.
Und die bereits aufsummierte Energie wird auch ausgelesen und unter energy abgespeichert.
Jetzt wir überprüft, ob die aktuelle Leistung über 2 W ist und ob der letzte Stromwert eh nicht älter als 120 Sekunden ist.
Trifft das zu, wird in die Variable energy ihr eigener Wert plus die aktuelle Leistung mal den vergangenen Stunden (Sekunden/3600) gespeichert.
Auschließend wird die aktuelle Leistung, die Dauer und die aufsummierte Energie abgespeichert.

Die Abfrage mit 120s habe ich eingefügt, um bei Fehlern (z.B.: wenn der Stromsensor länger keinen Wert sendet und somit der "alte" einfriert und dieser dann für eine lange Zeit gewertet wird) nichts aufzuaddieren. Leistungen unter 2W werden auch ignoriert.

Es gibt dann noch ein Notify, welches um genau 00:00:00 das Reading energy auf 0Wh setzt.

Ich hoffe es kann wer was damit anfangen  ::)
Titel: Antw:(gelöst) Rechnen mit Timestamps
Beitrag von: peewag am 24 Januar 2020, 13:20:50
So, jetzt stehe ich natürlich schon vor dem nächsten Problem!

Das Age eines Readings gibt immer an, wann sich der Wert das letzte mal geändert hat, und nicht, wann er das letzte mal upgedatet wurde.

Das heißt:

Uhrzeit    Wert    Age    Ergebnis    erwünschtes Ergebnis 
00:00:00    3    1    3    3 
00:00:01    4    1    4    4 
00:00:02    3    1    3    3 
00:00:03    3    2    6    3 
00:00:04    3    3    9    3 
00:00:05    3    4    12    3 
00:00:06    2    1    2    2 

Wenn nun, wie in der Tabelle ersichtlich, sich der Wert von 3 auf 4 ändert, steht als Age 1 - was auch erwartet wird.
Wenn nun aber, der Wert gleich bleibt (weil z.B.: der gleiche Strom als zuvor gemessen wurde), dann erhöht sich age um die Zeitdifferenz.

Das Problem ist nun aber, dass beim regelmäßigen aufaddieren, dass der Wert mit der Zeit multipliziert wird und das in jeder Zeile. Bleibt nun der Wert gleich, so wird dieser mit einer größeren Zeitdifferenz multipliziert obwohl seit dem letzten mal Multiplizieren wieder nur eine Sekunde vergangen ist.

Gibt es eine Möglichkeit nicht OldReadingsAge() und somit die Zeitdifferenz seit der letzten Änderung des Wertes zu bekommen, ich möchte lieber die Zeitdifferenz, wenn der Wert das letzte mal upgedatet wurde!?

Ich werd mal ein bisschen weiter stöbern, dafür wirds doch eine Lösung geben  :)
Titel: Antw:(gelöst) Rechnen mit Timestamps
Beitrag von: Otto123 am 24 Januar 2020, 15:43:56
Zitat von: peewag am 24 Januar 2020, 13:20:50
wann sich der Wert das letzte mal geändert hat, und nicht, wann er das letzte mal upgedatet wurde.
Hast Du event-on-change-reading gesetzt?

Gruß Otto
Titel: Antw:(gelöst) Rechnen mit Timestamps
Beitrag von: peewag am 08 Februar 2020, 10:04:06
ja das wars, ich habe jetzt beim PV_current_sensor das Attribut event-on-change-reading auf current gesetzt und jetzt funktioniert es wunderbar.

Titel: Antw:(gelöst) Rechnen mit Timestamps
Beitrag von: crusader am 08 Februar 2020, 10:47:04
Wäre auch einfacher gegangen mit dem für diese Aufgabe vorgesehenen Zauberwort:


attr userReadings energy integral {ReadingsVal($name,"power",0)/3600}