Reading Splitten und Zeitstempel setzen.

Begonnen von Manley, 04 Mai 2024, 07:34:14

Vorheriges Thema - Nächstes Thema

Manley

Hi Leuts.

Da meine Frau und ich scheinbar einen Drang dazu haben (mittlerweile 4 mal passiert) Licht am Auto (Innen wie Aussen) brennen zu lassen und uns damit den nächsten morgen zu versauen (leere Batterie) habe ich ein kleines Bastelprojekt daraus gemacht. Ein ESP8266 sitzt jetzt in der nähe der Autobatterie und überträgt fleissig die Batteriespannung via MQTT ins FHEM. Meldungen bei zu niedriger Spannung gehen dann via Telegram an meine Frau und mich. Projekt erfolgreich.
Mein Bastellaune war aber noch nicht ganz gestillt. Warum nur die Spannungswerte haben, wenn das Auto in der Nähe des WLANs ist. Jetzt speichert der ESP die Daten und schickt sie dann ins FHEM wenn er wieder im WLAN ist.
Jetzt zu meinem Problem. (Ich hoffe ich war bis hier hin nicht zu ausschweifend ;) )
Die gespeicherten Daten, die er ins FHEM schickt, kommen in ein Reading namens data. Das sieht wie folgt aus:
2024-05-03 14:028:01|12.72
Jetzt möchte ich via notify ein setreading absetzen was mir das eigentliche Reading "Spannung" mit Zeitstempel sozusagen rückwirkend setzt. Sprich "setreading Auto_Batterie 2024-05-03 14:028:01 Spannung 12.72".
Also habe ich versucht mittels Perl das Reading beim | zu splitten und in den Befehl zu drücken. Aber es scheitert bei mir an der Perl-Syntax. Irgendwie möchte Perl nicht in meinen Kopf.
Und da erbitte ich nun eure Hilfe.
Ich hoffe der Text ist nicht zu lang geworden.

Grüße.

New:
Ich habe gerade etwas damit gespielt, und festgestellt, dass ich wahrscheinlich auf dem falschen Weg bin. Ich bin davon ausgegangen, dass ein Reading welches mit setreading einen veränderten Zeitstempel bekommt auch unter diesem in die Log-Datei geschrieben wird. Leider passiert das wohl nicht. Vielleicht brauch einen neuen Ansatz um die Daten ins FHEM zu bekommen. Vielleicht hat ja noch jemand eine andere Idee, wie ich die gespeicherten Daten ins Log bekomme.

Grüße.
Wir essen jetzt Opa!
Satzzeichen können Leben retten.

betateilchen

Du bist komplett auf dem richtigen Weg. Hättest Du in Deinem setreading oben einen korrekten Zeitstempel angegeben, würde es funktionieren.

Aber Du hast bei der Zeitangabe einen Fehler:

setreading Auto_Batterie 2024-05-03 14:028:01 Spannung 12.72
                                       ^^^

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

Manley

Leider ist es das nicht. Habe den Zeitstempel von Hand geschrieben, und einfach einen Fehler gemacht. Ich kann manuell mit setreading Auto_Batterie 2024-05-04 11:00:00 Spannung 13.00 das Reading erfolgreich setzen. Auch der Zeitstempel wird übernommen. Nur leider nicht ins LogFile geschrieben. Wenn das Reading normal via MQTT aktualliesiert wird schreibt er es ins Log.
Wir essen jetzt Opa!
Satzzeichen können Leben retten.

Nobbynews

#3
Aus der commandref zu setreading:
ZitatAchtung: setreading generiert kein Event für ein Gerät X, falls es aus einem notify für Gerät X aufgerufen wurde. In so einem Fall könnte man auf "sleep 0.1; setreading X Y Z" ausweichen

Ohne Event gibt es keinen Log-Eintrag.

Manley

Hahaa, das funktioniert :) Hab mir euch einen Perl-Schnipsel zusammengebastelt der scheinbar funktioniert.
Auto_Batterie:data.* {my $data = ReadingsVal("Auto_Batterie","data",0); my ($time, $spannung) = split /,/, $data; fhem("sleep 0.1; setreading Auto_Batterie $time Spannung $spannung");}Ein Problem war noch |. Das habe ich jetzt gegen ein , ersetzt. Leider kann ich es im Moment nicht testen. Der ESP ist zum Einkaufen XD. Ich gebe gern noch Rückmeldung ob alles funktioniert hat. Sollte sich jmd das ganze Nachbauen wollen, steh ich gern Rede und Antwort :)
Wir essen jetzt Opa!
Satzzeichen können Leben retten.

TomLee

ZitatEin Problem war noch |. Das habe ich jetzt gegen ein , ersetzt.

Hallo,

eine Frage. Wenn Du die Möglichkeit hast das Pipe-Zeichen durch Komma zu ersetzen, kannst dann doch gleich " Spannung " nehmen, oder geht das nicht ? Damit würdest Dir das splitten mit Variablenzuordnung sparen und das ReadingsVal könntest direkt verwenden !?

Kommt der Wert (2024-05-03 14:028:01|12.72) über einen großen Json mit anderen Name/Wert Paaren oder nur das eine Paar über einen eigenen Topic ?

Gruß

Thomas

Manley

Zitat von: TomLee link=msg=1312515 date1714828951Wenn Du die Möglichkeit hast das Pipe-Zeichen durch Komma zu ersetzen, kannst dann doch gleich " Spannung " nehmen, oder geht das nicht ? Damit würdest Dir das splitten mit Variablenzuordnung sparen und das ReadingsVal könntest direkt verwenden !?
Den Teil verstehe ich nicht. Ich habe den Code für das MQTT-Publish selbst geschrieben. Es kommen nur timestamp und der wert für die Spannung.
Wir essen jetzt Opa!
Satzzeichen können Leben retten.

TomLee

Du schreibst du hast das Pipe-Zeichen durch Komma ersetzt, das verstehe ich so das jetzt in dem data-Reading das hier ankommt:
2024-05-03 14:28:01,12.72Wenn du das gleich so sendest:
2024-05-03 14:28:01 Spannung 12.72hast du doch gleich die richtige Syntax für setreading. Oder lieg ich damit so falsch ?



ZitatEs kommen nur timestamp und der wert für die Spannung.
Nutzt Du MQTT2, kann man mal ein List von dem Device sehen ? Vermutlich hätte ich einen Vorschlag es ohne notify umzusetzen.

TomLee

2024-05-03 14:28:01
Diese Zeit ist das die der letzten Messung (und genau diesen Zeitstempel möchtest du in FHEM) oder die des publish-Zeitpunkt ?

Manley

#9
Manchmal ist man einfach blind. Klar kann ich das einfach komplett senden. Mit Spannung.  :o
Habs jetzt geändert. Jetzt funktioniert mein Perl-Schnipsel nicht mehr. Ist aber nicht schlimm, der hat eh Fehler geworfen.

Internals:
   CFGFN     
   CID        Auto_Batterie
   DEF        Auto_Batterie
   FUUID      663665ff-f33f-64c2-889f-3db67959bb9a0cb2
   IODev      mqtt2_server
   LASTInputDev mqtt2_server
   MSGCNT     139
   NAME       Auto_Batterie
   NR         271
   STATE      12.86 V -76 dBm (online)
   TYPE       MQTT2_DEVICE
   eventCount 148
   mqtt2_server_CONN mqtt2_server_192.168.1.110_63033
   mqtt2_server_MSGCNT 139
   mqtt2_server_TIME 2024-05-04 19:11:54
   .DT:
     DEVICETOPIC Auto_Batterie
   .attraggr:
   .attrminint:
   READINGS:
     2024-05-04 18:44:47   IODev           mqtt2_server
     2024-05-04 19:11:54   IP-Adresse      192.168.1.110
     2024-05-04 19:11:54   Max-Spannung    12.86
     2024-05-04 18:57:53   Min-Spannung    12.78
     2024-05-04 19:11:54   Spannung        12.86
     2024-05-04 18:57:12   data            2024-05-04 18:56:39 Spannung 12.78
     2024-05-04 19:11:54   freeHeap        37072 Bytes
     2024-05-04 19:11:54   rssi            -76 dBm
     2024-05-04 18:57:07   status          online
     2024-05-04 19:11:54   uptime          0 Tage, 0 Stunden, 15 Minuten
Attributes:
   group      Allgemeines
   readingList Auto_Batterie:status:.* status
Auto_Batterie:data:.* data
Auto_Batterie:Spannung:.* Spannung
Auto_Batterie:Max-Spannung:.* Max-Spannung
Auto_Batterie:Min-Spannung:.* Min-Spannung
Auto_Batterie:rssi:.* rssi
Auto_Batterie:IP-Adresse:.* IP-Adresse
Auto_Batterie:freeHeap:.* freeHeap
Auto_Batterie:uptime:.* uptime
   room       1.10_Aussen,XXXNeueGeräteXXX
   stateFormat Spannung V rssi (status)

Der ESP speichert den Zeitpunkt der Messung. Und es wäre natürlich schön, wenn der Trennt später zeitlich korrekt wäre. Deswegen das setreading mit dem extra Zeitstempel.
Übrigens, danke für die schnellen Antworten.
Wir essen jetzt Opa!
Satzzeichen können Leben retten.

TomLee

Ok, vlt. gibts jetzt auch was an meinem Vorschlag zu meckern, ab er es tut so und Du sparst Dir das notify.
Ersetze in der MQTT2_DEVICE-Definition mal diesen Eintrag:
Auto_Batterie:data:.* datamit diesem:
Auto_Batterie:data:.* {my $e=decode_json($EVENT);fhem("setreading $NAME $e->{data}")}

Manley

#11
Leider führt es zu dieser ewig langen Fehlermeldung:
2024.05.04 19:57:43 1: ERROR evaluating my $CID=   $evalSpecials->{'%CID'};my $DEVICETOPIC=   $evalSpecials->{'%DEVICETOPIC'};my $EVENT=   $evalSpecials->{'%EVENT'};my $EVTPART0=   $evalSpecials->{'%EVTPART0'};my $EVTPART1=   $evalSpecials->{'%EVTPART1'};my $EVTPART2=   $evalSpecials->{'%EVTPART2'};my $EVTPART3=   $evalSpecials->{'%EVTPART3'};my $JSONMAP=   $evalSpecials->{'%JSONMAP'};my $NAME=   $evalSpecials->{'%NAME'};my $TOPIC=   $evalSpecials->{'%TOPIC'};{my $e=decode_json($EVENT);;fhem("setreading $NAME $e->{data}")}: garbage after JSON object, at character offset 4 (before "-05-04 19:47:02 Span...") at (eval 30418) line 1.
Ich finde aber die Idee gut, das direkt in der Definition zu machen. Könnte man jetzt nicht auch mit readingsVal arbeiten? Ich teste das mal.
Wir essen jetzt Opa!
Satzzeichen können Leben retten.

TomLee

Bin ich als Laie erstmal überfordert und ohne List kann ich es noch nicht mal nachvollziehen ob du es genauso übernommen hast wie ich gezeigt habe.

Werd mich mit beschäftigen dauert jetzt aber etwas.

Manley

Auszug aus dem list:
Attributes:
   group      Allgemeines
   readingList Auto_Batterie:status:.* status
Auto_Batterie:data:.* {my $e=decode_json($EVENT);fhem("setreading $NAME $e->{data}")}
Auto_Batterie:Spannung:.* Spannung
Auto_Batterie:Max-Spannung:.* Max-Spannung
Auto_Batterie:Min-Spannung:.* Min-Spannung
Auto_Batterie:rssi:.* rssi
Auto_Batterie:IP-Adresse:.* IP-Adresse
Auto_Batterie:freeHeap:.* freeHeap
Auto_Batterie:uptime:.* uptime
   room       1.10_Aussen,XXXNeueGeräteXXX
   stateFormat Spannung V rssi (status)
Wir essen jetzt Opa!
Satzzeichen können Leben retten.

TomLee

ZitatKönnte man jetzt nicht auch mit readingsVal arbeiten?

Nee, du schickst ja einen Json und das Reading data gäbs ja nicht mehr mit meinem vorgeschlagenen readingList-Eintrag.

Wenn du einfach nur einen String
2024-05-04 18:56:39 Spannung 12.78 statt Json senden würdest, kann ich mir vorstellen das du einfach nur $EVENT übergeben könntest und das rumfuchteln in dem Json würde man sich sparen.

Ungetestet, kann jetzt nicht am PC testen:

Auto_Batterie:data:.* {fhem("setreading $NAME $EVENT")}