Guten Morgen,
ich beziehe mich auf die Auffälligkeit aus https://forum.fhem.de/index.php?topic=137753. (https://forum.fhem.de/index.php?topic=137753.). Ich möchte gerne hier klären, wie wir das lösen.
Ich habe TimeSeries.pm und fhem.pl mit Debug-Zeilen versehen und beigefügt, um eine schnelle Nachverfolgung zu ermöglichen. Zeilennummern beziehen sich auf beigefügtes fhem.pl mit Debug-Zeilen.
Viele Grüße
Boris
Situation
In readingsBulkUpdate() erfolgt die Behandlung von event-aggregator ab Zeile 5134. Erhält ein Reading, für das event-aggregator genutzt wird, den ersten Wert, dann wird ein TimeSeries-Objekt angelegt und im Hash des Readings gespeichert. Die statistischen Werte sind am Beispiel von mean auslesbar mit { $defs{"testdummy"}{READINGS}{"testreading"}{".ts"}{mean} }.
Problem
Existiert das Reading noch nicht, für das ein Wert per readingsBulkUpdate() geschrieben werden soll, funktioniert die Programmlogik von Zeile 5134 bis 5166 nicht. Ich bin mir nicht sicher, aber ich meine, dass in setReadingsVal() das TimeSeries-Objekt wieder verloren geht. Erst beim zweiten eingehenden Wert wird es (wieder) angelegt und steht dann zur Verfügung.
Testfall
Anhänge einspielen und Log beobachten.
defmod testdummy dummy
attr testdummy event-aggregator testreading::const:mean:86400
setreading testdummy testreading 1
setreading testdummy testreading 2
setreading testdummy testreading 3
Anmerkung:
Zitat von: Dr. Boris Neubert am 04 April 2024, 08:25:08Das Problem ist eine Spezialität von dem Dummy. Bei Devices, wo die Readings bereits bei Definition feststehen, taucht es nicht auf.
Es gibt aber viele weitere device-Types, bei denen bei der Definition die readings noch nicht feststehen.
Spontan fallen mir HTTPMOD, JsonMod und auch die ganzen MQTT2_DEVICES ein.
$readings in Zeile 5143 und ff. ist nur ein "fake entry", falls das Reading noch nich existiert (siehe Zeile 5060).
Vorschlag: setReadingsVal vor dem TimeSeries Block verschieben, und danach $reading erneut holen.
Off-Topic: mein perl 5.38 beschwert sich: Smartmatch is deprecated at FHEM/TimeSeries.pm line 113.
Zitat von: rudolfkoenig am 04 April 2024, 23:37:17$readings in Zeile 5143 und ff. ist nur ein "fake entry", falls das Reading noch nich existiert (siehe Zeile 5060).
Vorschlag: setReadingsVal vor dem TimeSeries Block verschieben, und danach $reading erneut holen.
Ich habe mich heute morgen lange mit dem Abschnitt herumgeschlagen.
Meiner Auffassung nach darf
setReadingsVal() nicht aufgerufen werden, solange ich keinen Wert für das Reading habe. Bei der Verwendung von Zeitreihen (event-aggregator) kann es sein, dass erst zwei oder drei Werte nach
readingsBulkUpdate() gefüttert werden müssen, bevor die Zeitreihe einen Wert liefert.
Wir brauchen aber
$hash->{READINGS}{$reading}{".ts"} schon beim ersten gefütterten Wert. Wie lege ich denn
$hash->{READINGS}{$reading}{".ts"} an, ohne dass ein späteres
setReadingsVal() das wieder kaputtmacht und ohne einen VAL zu setzen?
Der Schluss von
if(@v) { ... } ist auch gruselig, aber das glaube ich schon gelöst zu haben (Code zum Review folgt).
Ich bin mir nicht sicher, ob aktuell jemand über meinen Beitrag und den darin geäußerten Bedarf nachdenkt oder ob ich nicht klar gemacht habe, dass ich von Euch Input suche, ob und wie wir in fhem.pl eine Funktion einbauen, die ein Reading ohne VAL und TIME anlegt - analog zu setReadingsVal(), was ein nicht existentes Reading anlegt aber mit Werten versieht.
ZitatWie lege ich denn $hash->{READINGS}{$reading}{".ts"} an, ohne dass ein späteres setReadingsVal() das wieder kaputtmacht und ohne einen VAL zu setzen?
So:
$hash->{READINGS}{$reading}{".ts"} = 42;
Zitat[...] ob und wie wir in fhem.pl eine Funktion einbauen, die ein Reading ohne VAL und TIME anlegt
Diese Aufgabe ist mAn zu speziell, insb. da es nur in fhem.pl benoetigt wird.
Zitat von: rudolfkoenig am 13 April 2024, 12:39:09ZitatWie lege ich denn $hash->{READINGS}{$reading}{".ts"} an, ohne dass ein späteres setReadingsVal() das wieder kaputtmacht und ohne einen VAL zu setzen?
$hash->{READINGS}{$reading}{".ts"} = 42;
So ist es aber doch im Moment (fhem.pl Zeilen 5054 und 5159 im aktuellen SVN) und meinem Verständnis nach bügelt das darauffolgende setReadingsVal() in Zeile 5183 den halbgaren Eintrag weg. Oder bin ich hier auf der falschen Spur?
ZitatSo ist es aber doch im Moment (fhem.pl Zeilen 5054 und 5159 im aktuellen SVN) und meinem Verständnis nach bügelt das darauffolgende setReadingsVal() in Zeile 5183 den halbgaren Eintrag weg. Oder bin ich hier auf der falschen Spur?
Nicht wirklich, Zeile 5061 erzeugt bei Bedarf ein Fake $reading, was nicht wieder in $hash->{READINGS} eingetragen wird.
Zeile 5150 sollte meiner Meinung nach statt
$readings->{".ts"}= $ts;
die "unkekuerzte" Version
$hash->{READINGS}{$reading}{".ts"} = $ts;
verwenden.
Da ich TimeSeries nicht wirklich kenne, sollte das jemand ueberpruefen.
P.S.:Sorry, habe die Antwort lange uebersehen, auch weil SMF mir keine Nachricht geschickt hat.