FHEM Forum

FHEM - Hausautomations-Systeme => MQTT => Thema gestartet von: RalfP am 19 Februar 2025, 15:57:09

Titel: json2nameValue - array's
Beitrag von: RalfP am 19 Februar 2025, 15:57:09
Hallo,

innerhalb eines JSON strings kommen Daten, wie zum Beispiel
"packData":[{"power":311,"sn":"CO4HMDGME502856"},{"power":61,"sn":"CO4FHMGHM332446"}]Aufgeschlüsselt wird dies mit json2nameValue:
packData_1_sn = CO4HMDGME502856
packData_1_power = 311

packData_2_sn = CO4FHMGHM332446
packData_2_power = 61
Wenn das Array aber nur Anzahl 1 hat oder die Reihenfolge sich ändert, wird mir immer packData_1 überschrieben. Wie bekomme ich es hin, das ich immer eine eindeutige Zuordnung zur sn hätte? 
z.B.
packData_CO4HMDGME502856_sn = CO4HMDGME502856
packData_CO4HMDGME502856_power = 311

packData_CO4FHMGHM332446_sn = CO4FHMGHM332446
packData_CO4FHMGHM332446_power = 61
o.ä.

Bekommt man dies mit json2nameValue hin?

Vielen Dank für einen Tipp
Ralf
Titel: Aw: json2nameValue - array's
Beitrag von: betateilchen am 19 Februar 2025, 16:14:39
Sowas würde ich nicht mit json2nameValue() lösen, sondern mit einer simplen json-Auswertung in einem Stück perl code oder mit einem JsonMod-device.

Titel: Aw: json2nameValue - array's
Beitrag von: RalfP am 19 Februar 2025, 16:21:21
Das "packData_" muss nicht sein, auch die SN muss nicht nochmals als Wert vorhanden sein, ein reading "CO4HMDGME502856_power" zu bekommen, mit dem Wert 311, wäre ausreichend. Natürlich gib es noch ein paar andere Werte in dem hash. Die eindeutige Zuordnung ist mir wichtig.
Titel: Aw: json2nameValue - array's
Beitrag von: betateilchen am 19 Februar 2025, 16:30:50
Zitat von: betateilchen am 19 Februar 2025, 16:14:39oder mit einem JsonMod-device.

defmod test JsonMod file:///tmp/test.json
attr test readingList multi(jsonPath('$.packData.[*]'), concat('packData_',property('sn'),'_sn'), property('sn'));;\
multi(jsonPath('$.packData.[*]'), concat('packData_',property('sn'),'_power'), property('power'));;

erzeugt folgende readings:

setstate test 2025-02-19 16:28:34 packData_CO4FHMGHM332446_power 61
setstate test 2025-02-19 16:28:34 packData_CO4FHMGHM332446_sn CO4FHMGHM332446
setstate test 2025-02-19 16:28:34 packData_CO4HMDGME502856_power 311
setstate test 2025-02-19 16:28:34 packData_CO4HMDGME502856_sn CO4HMDGME502856

In /tmp/test.json steht Dein json-String (korrekt formatiert!):

{"packData":[{"power":311,"sn":"CO4HMDGME502856"},{"power":61,"sn":"CO4FHMGHM332446"}]}
Titel: Aw: json2nameValue - array's
Beitrag von: betateilchen am 19 Februar 2025, 16:33:23
Zitat von: RalfP am 19 Februar 2025, 16:21:21ein reading "CO4HMDGME502856_power" zu bekommen, mit dem Wert 311, wäre ausreichend.

Dann lass die erste multi() Zeile in readingList einfach weg und passe das concat() in der verbleibenden Zeile an.

multi(jsonPath('$.packData.[*]'), concat(property('sn'),'_power'), property('power'))

setstate test 2025-02-19 16:36:20 CO4FHMGHM332446_power 61
setstate test 2025-02-19 16:36:20 CO4HMDGME502856_power 311

Zitat von: RalfP am 19 Februar 2025, 16:21:21Natürlich gib es noch ein paar andere Werte in dem hash. Die eindeutige Zuordnung ist mir wichtig.

Für weitere Werte wäre das Vorgehen identisch, solange die Werte im Array im gleichen Element stehen.

(Und ein hash ist was völlig anderes)
Titel: Aw: json2nameValue - array's
Beitrag von: rudolfkoenig am 19 Februar 2025, 17:04:36
Fuer aehnliche Zwecke gibt es ein hashKeyRename in fhem.pl:
{ my $in='{"packData":[{"power":311,"sn":"CO4HMDGME502856"},{"power":61,"sn":"CO4FHMGHM332446"}]}';;\
  my $h=json2nameValue($in);;\
  $h = hashKeyRename($h, "packData_(.*)_sn:(.*)", "packData_(.*)_power");;\
  join("\n", map {"$_=$h->{$_}" } keys %{$h}) }
erzeugt:
CO4FHMGHM332446=61
CO4HMDGME502856=311

Falls man das letzte Argument fuer hashKeyRename als "(\\d+)" schreibt, dann kriegt man
packData_CO4FHMGHM332446_power=61
packData_CO4HMDGME502856_power=311
packData_CO4FHMGHM332446_sn=CO4FHMGHM332446
packData_CO4HMDGME502856_sn=CO4HMDGME502856
Das ist problematisch, falls mehrere Arrays im JSON vorkommen.
Titel: Aw: json2nameValue - array's
Beitrag von: RalfP am 19 Februar 2025, 19:38:03
Also, ich würde sagen, es erfüllt seinen Zweck. Das readingList im MQTT2-Device sieht jetzt so aus:
.*/xxxxxx/xxxxxx/properties/report:.* { json2nameValue($EVENT, '', $JSONMAP, undef, 'packData') }
.*/xxxxxx/xxxxxx/properties/report:.* { my $h = json2nameValue($EVENT, undef, undef, 'packData', undef); $h = hashKeyRename($h,'packData_(.*)_sn:(.*)','(\\d+)'); return $h; }
Damit habe ich alle Daten und die "packData" werden gesondert behandelt. Die Readings werden so erzeugt (z.B):
packData_CO4FHMGHM332446_power
packData_CO4FHMGHM332446_socLevel
...
packData_CO4HMDGME502856_power
packData_CO4HMDGME502856_socLevel
Das join musste ich weglassen, da eine Warnung entstand: PERL WARNING: Useless use of join or string in void context at...

Ich gestehe, so 100%'ig verstehe ich es noch nicht, aber das Ergebnis spricht für sich. Ich kann mich nur bedanken.

Einen schönen Abend wünsche ich Euch.
Ralf
Titel: Aw: json2nameValue - array's
Beitrag von: rudolfkoenig am 19 Februar 2025, 20:48:41
.*/xxxxxx/xxxxxx/properties/report:.* { my $h = json2nameValue($EVENT, undef, undef, 'packData', undef); $h = hashKeyRename($h,'packData_(.*)_sn:(.*)','(\\d+)'); return $h; }

Das duerfte Equivalent sein mit

.*/xxxxxx/xxxxxx/properties/report:.* { hashKeyRename(json2nameValue($EVENT,undef,undef,'packData'),'packData_(.*)_sn:(.*)','(\\d+)') }
Titel: Aw: json2nameValue - array's
Beitrag von: RalfP am 19 Februar 2025, 22:08:19
...sieht gut aus, funktioniert. Vielen Dank
Ralf
Titel: Aw: json2nameValue - array's
Beitrag von: FHEMAN am 20 Februar 2025, 02:25:48
Ich notiere hier mal Zendure dran, damit man das auch über die Suche findet. Danke für die Lösung!
Titel: Aw: json2nameValue - array's
Beitrag von: RalfP am 21 Februar 2025, 08:10:05
Hab es jetzt auch in meinem Projekt https://github.com/RP-Develop/Zendure (https://github.com/RP-Develop/Zendure) mit eigepflegt.

Grüße
Ralf