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.
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...
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.
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.
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 :)
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
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.
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.72
Wenn du das gleich so sendest:
2024-05-03 14:28:01 Spannung 12.72
hast 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.
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 ?
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.
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:.* data
mit diesem:
Auto_Batterie:data:.* {my $e=decode_json($EVENT);fhem("setreading $NAME $e->{data}")}
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.
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.
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)
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")}
Hatte nie behauptet einen Jason zu schicken.
Ich hatte mich vielleicht missverständlich ausgedrück als ich sagte:
ZitatManchmal ist man einfach blind. Klar kann ich das einfach komplett senden. Mit Spannung. :o
Habs jetzt geändert.
Da hatte ich die Formatierung der Daten schon angepasst. Das er direkt im ESP schon "Zeitstempel Spannung Wert" speichert.
Auto_Batterie:data:.* {fhem("setreading $NAME $EVENT")}
Damit klappt es jetzt super.
Ich danke dir für deine Mühe und Geduld.
ZitatHatte nie behauptet einen Jason zu schicken.
Sry, war mein Denkfehler.
Wenn da in dem automatisch erstellten readinglist-Eintrag hinten nach :.* das letzte Verzeichnis des Topic-Pfad ergänzt wird, ist klar das nur ein String übertragen wird, das hab ich bis jetzt gekonnt nicht registriert ::) , obwohl ich es weiß.
ZitatAuto_Batterie:data:.* data
Jetzt ist mir klar das du nur einen String schickst, das erklärt auch die Fehlermeldung mit dem "Müll nach JSON-Objekt", mit dem vorigen Vorschlag und das
{fhem("setreading $NAME $EVENT")}
jetzt auf Anhieb ohne Änderung am Sketch klappt.
Sooo. Wollte mich nur kurz bedanken. Hab das Ding jetzt endlich am Laufen. Wenn einer Interesse hat, stehe ich gerne Rede und Antwort.
MfG
Manley