[gelöst] Wieder mal JSON String (Tasmota) zerlegen

Begonnen von Nighthawk, 10 April 2024, 19:11:27

Vorheriges Thema - Nächstes Thema

Nighthawk

Hallo zusammen,

wieder mal versuche ich einen JSON String den Tasmota per MQTT übermittelt zu zerlegen und in definierte Readings abzulegen, leider gelingt es mir nur zum Teil und auch alles andere als elegant..

Folgendermaßen sieht der String aus:
{"Time":"2024-04-10T19:00:21","DS18B20":{"Id":"FDDB770E64FF","Temperature":21.19},"VEML6070":{"UvLevel":5,"UvIndex":0.01,"UvIndexText":"Niedrig","UvPower":0.000},"SHT3X":{"Temperature":23.19,"Humidity":39.6,"DewPoint":8.67},"MAX44009":{"Illuminance":  110.2},"TempUnit":"C"}
nun möchte ich die Werte in standardreadings ablegen, bisher bin ich nur auf folgendes gekommen:

tele/$DEVICETOPIC/SENSOR:.* { my %ret1; while ($EVENT =~ /.SHT3X....Temperature..([\d]+\.[\d]+)..Humidity..([\d]+\.[\d]+)..DewPoint..([\d]+\.[\d]+)./g) { $ret1{"temperature"}=$1; }; return \%ret1; }
tele/$DEVICETOPIC/SENSOR:.* { my %ret1; while ($EVENT =~ /.SHT3X....Temperature..([\d]+\.[\d]+)..Humidity..([\d]+\.[\d]+)..DewPoint..([\d]+\.[\d]+)./g) { $ret1{"humidity"}=$2; }; return \%ret1; }
tele/$DEVICETOPIC/SENSOR:.* { my %ret1; while ($EVENT =~ /.SHT3X....Temperature..([\d]+\.[\d]+)..Humidity..([\d]+\.[\d]+)..DewPoint..([\d]+\.[\d]+)./g) { $ret1{"dewpoint"}=$3; }; return \%ret1; }
tele/$DEVICETOPIC/SENSOR:.* { my %ret2; while ($EVENT =~ /.MAX44009....Illuminance....([\d]+\.[\d]+)./g) { $ret2{"brightness"}=$1; }; return \%ret2; }
tele/$DEVICETOPIC/SENSOR:.* { my %ret3; while ($EVENT =~ /.VEML6070....UvLevel..([\d]+)..UvIndex..([\d]+\.[\d]+)..UvIndexText...(\w+)...UvPower..([\d]+\.[\d]+)./g) { $ret3{"UvLevel"}=$1; }; return \%ret3; }
tele/$DEVICETOPIC/SENSOR:.* { my %ret3; while ($EVENT =~ /.VEML6070....UvLevel..([\d]+)..UvIndex..([\d]+\.[\d]+)..UvIndexText...(\w+)...UvPower..([\d]+\.[\d]+)./g) { $ret3{"UvIndex"}=$2; }; return \%ret3; }
tele/$DEVICETOPIC/SENSOR:.* { my %ret3; while ($EVENT =~ /.VEML6070....UvLevel..([\d]+)..UvIndex..([\d]+\.[\d]+)..UvIndexText...(\w+)...UvPower..([\d]+\.[\d]+)./g) { $ret3{"UvIndexText"}=$3; }; return \%ret3; }
tele/$DEVICETOPIC/SENSOR:.* { my %ret3; while ($EVENT =~ /.VEML6070....UvLevel..([\d]+)..UvIndex..([\d]+\.[\d]+)..UvIndexText...(\w+)...UvPower..([\d]+\.[\d]+)./g) { $ret3{"UvPower"}=$4; }; return \%ret3; }

damit bekomme ich das Groß eingefangen und entsprechend zugewiesen, nur schön und auch variabel ist anders..
Problematisch sind hier auch die Werte vom Max4409, da habe ich keine Regexp gefunden die mir bei dem Wert sicher hilft, denn scheinbar hält Tasmota hier Stellen für größere Werte als Leerzeichen frei, diese können also mal leer sein und mal mit Dezimalzahl gefüllt..

Gibt es einen Weg das ganze eleganter zu gestalten und wie bekommt man die Platzhalter des MAX4409 eingefangen?


Gruß
Alex

TomLee

Hallo,

im richtigen Forumbereich wäre bestimmt schon wer auf dein Anliegen eingegangen ...

Weshalb nutzt Du nicht einfach das Attribut jsonMap um die Readingnamen zu mappen und die nicht erwünschten Readings gar nicht erst anlegen zu lassen ?

Gruß

Thomas

betateilchen

Das sind doch insgesamt nur 12 readings.
Warum lässt Du die nicht einfach automatisch von json2nameValue anlegen und verwendest die dann vorgegebenen Namen?
Ob da jetzt ein reading mit angelegt wird, das Du nicht benötigst, ist doch eigentlich völlig egal, das tut niemandem weh.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

Nighthawk

Zitat von: TomLee am 10 April 2024, 22:05:56Hallo,

im richtigen Forumbereich wäre bestimmt schon wer auf dein Anliegen eingegangen ...

Weshalb nutzt Du nicht einfach das Attribut jsonMap um die Readingnamen zu mappen und die nicht erwünschten Readings gar nicht erst anlegen zu lassen ?

Gruß

Thomas

Hallo zusammen,

Thomas, danke für den Wink mit dem Zaunpfahl, das war ja super einfach und ich habe genau das was ich brauche.
Nur der Vollständigkeitshalber, hier meine Lösung:

tele/$DEVICETOPIC/SENSOR:.* { json2nameValue($EVENT,"",{"SHT3X_Temperature"=>"temperature", "SHT3X_Humidity"=>"humidity", "SHT3X_DewPoint"=>"dewpoint", "MAX44009_Illuminance"=>"brightness", "VEML6070_UvIndex"=>"UvIndex", "VEML6070_UvIndexText"=>"UvIndexText", "VEML6070_UvLevel"=>"UvLevel", "VEML6070_UvPower"=>"UvPower"}, ".*(temperature|humidity|dewpoint|brightness|UvIndex|UvIndexText|UvLevel|UvPower).*");; }
@Betateilchen
Ntürlich tut es nicht weh wenn da unnötige Readings angelegt werden, denn mit Event-on-change... kann und muss man es ja eh eingrenzen was Events erzeugt, mir geht es an dieser Stelle rein um Ästhetik, ich halte gern die Readings möglichst einheitlich, also temperature bei Temperatur etc, in diesem Fall würde das Reading aber SHT3X_Temperature heißen.
Klar kann mach auch das umbiegen, aber die Lösung oben ist doch einfach und absolut universell...

Gruß
Alex