Von MQTT empfangenen JSON String in Einzelwerte zerlegen

Begonnen von 4eversr, 04 März 2021, 13:55:51

Vorheriges Thema - Nächstes Thema

4eversr

Hallo,

ich habe einen ESP an meinem S0-Stromzähler, der mir alle 20 Sekunden per MQTT einen JSON-String schickt, der so aufgebaut ist: {"S0":380950,"Ver":3}

Der erste Wert S0 ist der Zählerstand in Wattstunden, also 380950 Wh = 380,95 kWh
Der zweite Wert "Ver" ist der aktuelle Verbrauch in Watt, hier also 3 Watt.

Ich würde jetzt natürlich gerne diesen JSON String so zerlegen, dass ich mir den S0 Wert und auch den Verbrauchswert als reine Zahl in ein userreading des Gerätes abspeichere.
Im Idealfall würde ich den Zählerstand dann noch als "monotonic" anlegen, so dass wenn der ESP nach Stromausfall wieder bei 0 als Zählerstand anfängt er trotzdem weiter hochzählt.
Ich selbst habe schon versucht über regexr.com und regex101.com mir passende Regex-Kommandos zum extrahieren der Werte zu bauen, aber ich glaube das Userreading selbst kommt mit Klammersetzung gar nicht klar !?
Ich bin jedenfalls komplett aufgeschmissen, da ich bei diesem ganzen Stringzerlegen gar nicht durchblicke. Ich hatte mir auch schonmal etwas zum Modul "jsonexpand" im FHEM Handbuch durchgelesen, aber auch das ist schonzu hoch für mich. ;)

Hier der aktuelle Programmcode und im Anhang ein Screenshot vom Istzustand.

define s0zaehler MQTT_DEVICE
attr s0zaehler IODev Mosquitto
attr s0zaehler subscribeReading_s0zaehler EG/IPs-S0-WiFi
attr s0zaehler userReadings Zaehlerstand { my $val = (ReadingsVal("$name", "s0zaehler", 0));;$val =~/s ":"d+/g;; return $val;;}




   


Beta-User

Falls du erst in das Thema MQTT einsteigst, solltest du ggf. mal einen Blick auf MQTT2_DEVICE werfen, das macht JSON-Extraktion einfacher und könnte mit etwas Aufwand vermutlich auch recht einfach gleich die Umrechnung (+monotonic) machen...

(Ansonsten: MQTT_GENRERIC_BRIDGE unterstützt auch json2nameValue(). Damit könntest du den Wert über eine eigene Routine laufen lassen und ebenfalls gleich umgerechnet+addiert z.B. in einen dummy schreiben).
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: ZigBee2mqtt, MiLight@ESP-GW, BT@OpenMQTTGw | ZWave | SIGNALduino | MapleCUN | RHASSPY
svn: u.a Weekday-&RandomTimer, Twilight,  div. attrTemplate-files, MySensors

4eversr

#2
Hallo,

ich benutze MQTT schon länger, aber bisher immer nur zum publishen von Werten auf Displays, Tablets und OLEDs.
Da ich schon so viele Client-Geräte habe und die alle wunderbar mit dem bisherigen alten MQTT laufen, würde ich eher ungern zu MQTT2 wechseln ;)

Ich hab mein userreading jetzt mal angepasst und json2nameValue ergänzt, aber funktionieren tut das so natürlich nicht.

Zaehlerstand { my $data= (ReadingsVal("$name", "s0zaehler", 0));my $dataJSon = json2nameValue($data);toJSON($dataJSon);}

Dadurch hat sich mein Ausgabestring jetzt tatsächlich verändert, von ursprünglich {"S0":380950,"Ver":3} auf jetzt {"S0":"380950","Ver":"3"}
Ich habe jetzt also mehr Anführungszeichen, aber noch keine Einzelwerte :)

Oder muss ich am Ende des Befehles jetzt nur noch sowas schreiben wie "return S0" und schon gibt er mir den Zählerstand aus ?

-------------------------------------------------------

EDIT:
Getreu dem Motto "I have no idea what i am doing" habe ich es jetzt nach viel Try & Error hinbekommen:

Zaehlerstand { my $data= (ReadingsVal("$name", "s0zaehler", 0));my $dataJSon = json2nameValue($data);toJSON($dataJSon);return $dataJSon->{S0}},
Verbrauch { my $data= (ReadingsVal("$name", "s0zaehler", 0));my $dataJSon = json2nameValue($data);toJSON($dataJSon);return $dataJSon->{Ver}}


Liefert mir ganz sauber ein Feld Zaehlerstand und ein Feld Verbrauch mit den richtigen Werten. Sogar ein Teilen durch 1000 um Kilowattstunden zu erhalten, hat funktioniert (siehe unten)

Kann ich in dieses Userreading jetzt beim Zaehlerstand auch noch "monotonic" einbauen, oder geht das auf diese Weise nicht ?

Dieser Versuch hier mit Monotonic hat leider nicht funktioniert / danach wurden die Werte gar nicht mehr aktualisiert.
Zaehlerstand monotonic{ my $data= (ReadingsVal("$name", "s0zaehler", 0));my $dataJSon = json2nameValue($data);toJSON($dataJSon);return ($dataJSon->{S0})/1000}

Beta-User

Ungetestet:
Zaehlerstand:s0zaehler.* monotonic { my $data= (ReadingsVal("$name", "s0zaehler", 0));my $dataJSon = json2nameValue($data);toJSON($dataJSon);return ($dataJSon->{S0})/1000}
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: ZigBee2mqtt, MiLight@ESP-GW, BT@OpenMQTTGw | ZWave | SIGNALduino | MapleCUN | RHASSPY
svn: u.a Weekday-&RandomTimer, Twilight,  div. attrTemplate-files, MySensors