[gelöst] userReadings - Werte und Berechnung in diesen

Begonnen von Spook112, 18 März 2025, 12:37:53

Vorheriges Thema - Nächstes Thema

Spook112

Hi, ich habe ein Verständnisproblem bei Kalkulationen, die in userReadings bei mir stattfinden.

Problemstellung:
Ich habe eine Solaranlage mit 2 Panels laufen, die im FHEM mittels HTTPMOD eingebunden ist.
FHEM fragt zyklisch Werte von dem Inverter ab.
Übertragung und Anzeige in Form von userReadings finktioniert alles - scheinbar problemlos.

Bei der Anzeige der bis dato (am Tag) erzeugten Energie werden die userReadings e1 und e2 befüllt.
Sobald diese userReadings (e1 und e2) befüllt werden schreibe ich dieselben Werte noch in
zwei zusätzliche userReadings energy_Panel_1 und energy_Panel_2

Das erfolgt auf Grund der definition im Attribut userReadings:
energy_Panel_1:e.* monotonic { ReadingsNum($name, "e1", 0)},
energy_Panel_2:e.* monotonic { ReadingsNum($name, "e2", 0)},
Meine Erwartung wäre, das die Werte von e1 denen von energy_Panel_1 entsprechen müssten und
analog die Werte von e2 den werten von energy_Panel_2
Das ist aber nicht der Fall, wie auf dem Bild im Anhang zu sehen.
Woran liegt das ? Rührt das von der Verwendung von monotonic her ?

Was ich auch nicht verstehe:
Wenn ich den Trigger für das Befüllen des userReadings energy_Panel_2:e.* monoto... auf e1 oder e2 ändere wird das userReadings überhaupt nicht aktualisiert.
Nach meinem Verständnis müsste das doch aber.
Verständnisfrage: Warum geht das nicht und es muss eine "Wildcard" angegeben werden?


Raspberry PI / RaZberry ZWAVE Modul / RFXTRX433E / 13 Fibaro FGS-222-EN-A-v1.00 / 17 VISION ZD2102-5 / 10 Somfy RTS / 4 Greenwave GWRENS310-F / Gardena Sileno City / 3 Gardena Gartensteckdosen / 2 devolo Home Control Funkschalter / 8 FIBARO System FGSD002 Smoke Sensoren

betateilchen

Zitat von: Spook112 am 18 März 2025, 12:37:53Verständnisfrage: Warum geht das nicht und es muss eine "Wildcard" angegeben werden?

Es würde schon helfen, eine korrekte regexp im userReading anzugeben, damit "energy_Panel_2" wirklich nur dann aktualisiert wird, wenn "e2" sich ändert. Aktuell werden beide userReadings sowohl bei Änderungen an e1 e2 ... e(n) aktualisiert, weil "e.*" quasi ein Wildcard ist und in beiden userReadings verwendet wird.

Wozu brauchst Du monotonic, wenn Du ohnehin nur den gleichen Wert übertragen möchtest?

Vielleicht liefert ja das hier das Ergebnis, das Du erwartest?

energy_Panel_1:e1.* {ReadingsNum($name, "e1", 0)},
energy_Panel_2:e2.* {ReadingsNum($name, "e2", 0)},
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

Spook112

Danke für den Tipp.

Werde ich morgen ausprobieren, da im Moment keine Sonne scheint :-)

Trotzdem noch mal die Frage: Warum geht es mit e1 nicht sondern nur mit e.* oder e1.*  und analog mit e2 nicht sondern nur mit e2.* ?

e.*  sagt doch auch nichts anderes aus als e1 und e2 und e3 etc.

Und zu der Frage wozu ich monotonic benötige.
Aus mir unerklärlichen Gründen setzt FHEM den Wert für e1 und e2 auf 0 wenn keine Werte mehr geliefert werden, wenn die Sonne nicht mehr scheint.
Ich will aber auch abends noch sehen, was tagsüber an Energie produziert worden ist. Deshalb monotonic - da bleibt der letzte, höchste Wert dann stehen.
Raspberry PI / RaZberry ZWAVE Modul / RFXTRX433E / 13 Fibaro FGS-222-EN-A-v1.00 / 17 VISION ZD2102-5 / 10 Somfy RTS / 4 Greenwave GWRENS310-F / Gardena Sileno City / 3 Gardena Gartensteckdosen / 2 devolo Home Control Funkschalter / 8 FIBARO System FGSD002 Smoke Sensoren

betateilchen

Zitat von: Spook112 am 19 März 2025, 00:53:07Trotzdem noch mal die Frage: Warum geht es mit e1 nicht sondern nur mit e.* oder e1.*  und analog mit e2 nicht sondern nur mit e2.* ?

Es geht nicht darum, dass es mit e.* NICHT geht, sondern dass es ZU OFT geht. Du überschreibst mit e.* immer alle userReadings und nicht nur das eine, bei dem sich der Wert gerade geändert hat.

Und e1 ist etwas anderes als e1.* weil die Angabe e1 als regex von FHEM als ^e1$ verwendet wird. Deshalb passt diese regexp nicht, wenn nach e1 noch etwas weiteres im Event steht (der Zahlenwert...)

Zitat von: Spook112 am 19 März 2025, 00:53:07e.*  sagt doch auch nichts anderes aus als e1 und e2 und e3 etc.

Doch, es sagt schon was anderes aus. Ich hoffe, das wurde jetzt durch meine Erklärungen verständlich.

Zitat von: Spook112 am 19 März 2025, 00:53:07Und zu der Frage wozu ich monotonic benötige.
Aus mir unerklärlichen Gründen setzt FHEM den Wert für e1 und e2 auf 0 wenn keine Werte mehr geliefert werden, wenn die Sonne nicht mehr scheint.

Was ist denn daran unerklärlich? Was steht denn auf der mit HTTPMOD gelesenen Seite, wenn keine Werte mehr geliefert werden?

Zitat von: Spook112 am 19 März 2025, 00:53:07Ich will aber auch abends noch sehen, was tagsüber an Energie produziert worden ist. Deshalb monotonic - da bleibt der letzte, höchste Wert dann stehen.

Das kannst Du auch einfach dadurch lösen, dass Du im userReading den Wert nur dann schreibst, wenn er auch wirklich sinnvoll ist. Das kann man z.B. so machen:

energy_Panel_1:e1.* {ReadingsNum($name, "e1", 0) ? ReadingsNum($name, "e1", 0) : undef},
Bei einem Rückgabewert "undef" wird ein userReading nicht verändert.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

Spook112

Danke sehr schön erklärt.
Das mit den regEx habe ich verstanden.

ZitatWas ist denn daran unerklärlich? Was steht denn auf der mit HTTPMOD gelesenen Seite, wenn keine Werte mehr geliefert werden?
Muss ich heute Abend mal ausprobieren.
Ich meine dann wird gar nichts geliefert, da der Inverter dann nicht mehr erreichbar ist.

Zu dem Codebeispiel - das geht m.E. nicht so einfach, da die userReadings e1 und e2 (und andere) über Attribute definiert werden.

Nachdem ich blauäugig da einfach :undef hinten angefügt habe ist nun ein neues userReading e1:undef entstanden, was ich bis jetzt auch nicht löschen konnte.
Fehlermeldung: Bad older-than-seconds format undef

Hast Du einen Vorschlag wie ich das :undef in diesem Falle richtig nutzen/einbauen/verwenden kann ?

Im Anhang mal ein Screenshot was jetzt bei Sonnenschein zurückgeliefert wird.
Raspberry PI / RaZberry ZWAVE Modul / RFXTRX433E / 13 Fibaro FGS-222-EN-A-v1.00 / 17 VISION ZD2102-5 / 10 Somfy RTS / 4 Greenwave GWRENS310-F / Gardena Sileno City / 3 Gardena Gartensteckdosen / 2 devolo Home Control Funkschalter / 8 FIBARO System FGSD002 Smoke Sensoren

betateilchen

Es geht nicht darum, einfach ":undef" irgendwo anzuhängen, sondern darum, die von mir vorgegebene Syntax in dem perl-Konstrukt für das userReading zu beachten und zu verwenden.

-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

Spook112

Da hast Du natürlich recht.
Es war ein, zugegebenermaßen nicht sehr aussichtsreicher, Versuch.

Zurück zu Deiner Frage  - Was steht denn auf der mit HTTPMOD gelesenen Seite, wenn keine Werte mehr geliefert werden?

The connection has timed out
The server at nnn.nnn.nnn.nnn is taking too long to respond.
Hatte ich schon vermutet, denn der Inverter schaltet sich ab, wenn kein Sonnenlicht mehr Strom erzeugt.

Wie HTTPMOD mit dem Ergebnis des Aufrufs der URL http://nnn.nnn.nnn.nnn:8050/getOutputData dann bzw. generell im Detail umgeht weiss ich leider auch nicht.
Die aufzurufenden URLs und die zu befüllenden userReadings sind wie schon geschrieben über Attribute definiert.:
Attributes
alias                        Solaranlage auf dem Gartenhaus               deleteattr
event-on-change-reading      .*                                           deleteattr
get1JSON                     data_maxPower                                deleteattr
get1Name                     MaxPower                                     deleteattr
get1Poll                     1                                            deleteattr
get1URL                      http://nnn.nnn.nnn.nnn:8050/getMaxPower      deleteattr
get2Name                     OutputData                                   deleteattr
get2Poll                     1                                            deleteattr
get2URL                      http://nnn.nnn.nnn.nnn:8050/getOutputData    deleteattr
get3Name                     Alarm                                        deleteattr
get3Poll                     1                                            deleteattr
get3URL                      http://nnn.nnn.nnn.nnn:8050/getAlarm         deleteattr
get4Name                     Disabled                                     deleteattr
get4Poll                     1                                            deleteattr
get4URL                      http://nnn.nnn.nnn.nnn:8050/getOnOff         deleteattr
get5Name                     DeviceInfo                                   deleteattr
get5Poll                     1                                            deleteattr
get5PollDelay                3600                                         deleteattr
get5URL                      http://nnn.nnn.nnn.nnn:8050/getDeviceInfo    deleteattr
group                        Solaranlage                                  deleteattr
icon                         measure_photovoltaic_inst                    deleteattr
oldreadings                  total_power                                  deleteattr
reading101JSON               data_maxPower                                deleteattr
reading101Name               MaxPower                                     deleteattr
reading201JSON               data_e1                                      deleteattr
reading201Name               e1                                           deleteattr
reading202JSON               data_e2                                      deleteattr
reading202Name               e2                                           deleteattr
reading203JSON               data_te1                                     deleteattr
reading203Name               te1                                          deleteattr
reading204JSON               data_te2                                     deleteattr
reading204Name               te2                                          deleteattr
reading205JSON               data_p1                                      deleteattr
reading205Name               Panel_1                                      deleteattr
reading206JSON               data_p2                                      deleteattr
reading206Name               Panel_2                                      deleteattr
Die get Befehle hohlen mit den dort angegebenen URLs die jeweiligen JSON Dateien, in denen dann die benötigten Informationen stehen.
Wie FHEM dann "im Hintergrund" diese Informationen in die weiter unten definierten userReadings schreibt und wo auf dem Weg der richtige Ansatzpunkt wäre das :undef einzubauen weiss ich aber beim besten Willen nicht.

Hast Du/jemand dazu Ideen?
Raspberry PI / RaZberry ZWAVE Modul / RFXTRX433E / 13 Fibaro FGS-222-EN-A-v1.00 / 17 VISION ZD2102-5 / 10 Somfy RTS / 4 Greenwave GWRENS310-F / Gardena Sileno City / 3 Gardena Gartensteckdosen / 2 devolo Home Control Funkschalter / 8 FIBARO System FGSD002 Smoke Sensoren

betateilchen

Zitat von: Spook112 am 19 März 2025, 23:26:55Die get Befehle hohlen mit den dort angegebenen URLs die jeweiligen JSON Dateien, in denen dann die benötigten Informationen stehen.
Wie FHEM dann "im Hintergrund" diese Informationen in die weiter unten definierten userReadings schreibt und wo auf dem Weg der richtige Ansatzpunkt wäre das :undef einzubauen weiss ich aber beim besten Willen nicht.

Das undef kommt doch nicht in die Attribute der originären readings, sondern müssen im Attribut userReadings angegeben werden.

Und nochmal ganz klar gesagt: es geht nicht um :undef! Der Doppelpunkt ist Teil der verwendeten Syntax im perl Code, der für die userReadings verwendet wird.

Das hier:

energy_Panel_1:e1.* {ReadingsNum($name, "e1", 0) ? ReadingsNum($name, "e1", 0) : undef},
muss in das Attribut userReadings, um beispielsweise das reading energy_Panel_1 zu erzeugen.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

Spook112

Erneut danke für die Erklärungen.
Dort, im Attribut userReadungs habe ich es eingetragen und es funktioniert wie gewünscht.
Zugegebenermaßen habe ich den Perl-Ausdruck trotzdem noch nicht richtig verstanden:
energy_Panel_1:e1.* {ReadingsNum($name, "e1", 0) ? ReadingsNum($name, "e1", 0) : undef},Was klar ist: - energy_Panel_1 ist der Name des userReadings, welches befüllt werden soll
              - :e1.*  nach dem Doppelpunkt kommt der Trigger/das Event, der/das das Auswerten oder Lesen der Daten veranlasst, die in das userReadings geschrieben werden sollen
              - in den {} kommt das eigentliche Perl Statement, ReadingsNum liest einen numerischen Wert aus dem Reading e1 in diesem Device und wenn es keinen Wert findet wird defaultmäßig der Wert 0 genommen

Und dann kommt die spannende Frage: was bewirkt das ? und der Teil ReadingsNum($name, "e1", 0) : undef danach?
Ich bin kein Perl Programmierer, aber was ich meine verstanden zu haben ist, dass der Teil vor dem ? mit dem Teil hinter dem Fragezeichen verglichen wird.
Was dann der : und das dahinter stehende undef (vermutlich gleichbedeutend mit nicht definiert) bewirken habe ich noch nicht verstanden.

Sorry an die Spezialisten und Programmierer für die vermutlich für Euch einfache Frage :-)

 
Raspberry PI / RaZberry ZWAVE Modul / RFXTRX433E / 13 Fibaro FGS-222-EN-A-v1.00 / 17 VISION ZD2102-5 / 10 Somfy RTS / 4 Greenwave GWRENS310-F / Gardena Sileno City / 3 Gardena Gartensteckdosen / 2 devolo Home Control Funkschalter / 8 FIBARO System FGSD002 Smoke Sensoren

betateilchen

Der Vergleich steht vor dem Fragezeichen, nach dem ? ist der Teil, der gilt, wenn der Vergleich "true" ergibt, nach dem Doppelpunkt kommt der Teil, der bei "false" ausgeführt wird.

Es ist eine Kurzform für

if ReadingsNum($name, "e1", 0) {
  return ReadingsNum($name, "e1", 0);
} else {
  return undef;
}

Und ich weiß genau, welche Frage als Nächstes kommt 🙃
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

betateilchen

#10
Zitat von: betateilchen am 20 März 2025, 21:26:54Und ich weiß genau, welche Frage als Nächstes kommt

ZitatWo ist denn da ein Vergleich?

Wenn ReadingsNum() das Ergebnis 0 liefert, entspricht das automatisch "false", jedes andere numerische Ergebnis entspricht "true".

Deshalb kann man sich den expliziten Vergleich

if (ReadingsNum(...) != 0) {...}
einfach ersparen.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

Spook112

Coole Lösung - vielen Dank für die Erklänrung.

Nur um zu checken, ob ich es tatsächlich verstanden habe.

- Wenn also das userReadings "e1" den Wert "0" liefert ist das Ergebnis des Vergleichs "false" und es greift das elsif "undef" --> soll heissen tue gar nichts, was zur Folge hat, dass das im userReadings "energy_Panel_1" drin stehen bleibt was schon vorher drin stand
- wenn das userReadings "e1" überhaupt keinen Wert liefert greift der Defaultwert "0" mit dem Ergebnis wie oben
- wenn das userReadings "e1" einen anderen Wert als "0" liefert wird das userReadings "energy_Panel_1" mit dem Wert von "e1" befüllt

Trifft es das ?
Raspberry PI / RaZberry ZWAVE Modul / RFXTRX433E / 13 Fibaro FGS-222-EN-A-v1.00 / 17 VISION ZD2102-5 / 10 Somfy RTS / 4 Greenwave GWRENS310-F / Gardena Sileno City / 3 Gardena Gartensteckdosen / 2 devolo Home Control Funkschalter / 8 FIBARO System FGSD002 Smoke Sensoren

betateilchen

-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

Spook112

Perfekt - danke nochmal für die geduldigen Erläuterungen.

Das ursprüngliche Problem, dass die Werte von e1/e2 und energy_Panel_1/energy_Panel_2 voneinander abgewichen sind tritt nicht mehr auf.
Bzgl. Perl Abfragen/Vergleichen habe ich einiges gelernt :-)
Raspberry PI / RaZberry ZWAVE Modul / RFXTRX433E / 13 Fibaro FGS-222-EN-A-v1.00 / 17 VISION ZD2102-5 / 10 Somfy RTS / 4 Greenwave GWRENS310-F / Gardena Sileno City / 3 Gardena Gartensteckdosen / 2 devolo Home Control Funkschalter / 8 FIBARO System FGSD002 Smoke Sensoren