JSON und 3 Arrays im String

Begonnen von CoolTux, 02 Juni 2017, 13:42:24

Vorheriges Thema - Nächstes Thema

CoolTux

Hallo,

Ich habe einen JSON String mit 3 Arrays. Habe ihn mal versucht übersichtlich zu machen


{"serial":"smartpi160812345","name":"House","lat":52.3667,"lng":9.7167,"time":"2017-05-30 19:52:11","softwareversion":"","ipaddress":"169.254.3.10",
   
   
    "datasets":[{"time":"2017-05-30 19:52:08","phases":[
   
    {"phase":1,"name":"phase 1","values":[
{"type":"current","unity":"A","info":"","data":0.24830514},{"type":"voltage","unity":"V","info":"","data":230},{"type":"power","unity":"W","info":"","data":57.110184},{"type":"cosphi","unity":"","info":"","data":0.70275474},{"type":"frequency","unity":"Hz","info":"","data":120.413925}]},
   
    {"phase":2,"name":"phase 2","values":[
{"type":"current","unity":"A","info":"","data":0.86874366},{"type":"voltage","unity":"V","info":"","data":230},{"type":"power","unity":"W","info":"","data":199.81104},{"type":"cosphi","unity":"","info":"","data":0.99155134},{"type":"frequency","unity":"Hz","info":"","data":386.1237}]},
   
    {"phase":3,"name":"phase 3","values":[
{"type":"current","unity":"A","info":"","data":1.3195294},{"type":"voltage","unity":"V","info":"","data":230},{"type":"power","unity":"W","info":"","data":303.49176},{"type":"cosphi","unity":"","info":"","data":-0.25960922},{"type":"frequency","unity":"Hz","info":"","data":153.38525}]},
   
    {"phase":4,"name":"phase 4","values":[
{"type":"current","unity":"A","info":"","data":1.0668689}]}]}]}


Muss ich da jetzt tatsächlich Schleifen durch alle Arrays machen die dann auch noch verschachtelt sind?


if( ref($decode_json->{datasets}) eq "ARRAY" and scalar(@{$decode_json->{datasets}}) > 0 {
   
        foreach $datasets (@{$decode_json->{datasets}}) {
       
            readingsBulkUpdateIfChanged($hash,'datasetsTime',$datasets->{time},1);
           
           if( ref($datasets->{phases}) eq "ARRAY" and scalar(@{$datasets->{phases}}) > 0 {

                foreach $phases (@{$decode_json->{datasets}}) {
                                ........
                                ........
                }
       
        }
   
    }




Grüße
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

zap

Dieser Anwendungsfall scheint mir prädestiniert für eine rekursive Funktion zu sein.
2xCCU3, Fenster, Rollläden, Themostate, Stromzähler, Steckdosen ...)
Entwicklung: FHEM auf AMD NUC (Ubuntu)
Produktiv inzwischen auf Home Assistant gewechselt.
Maintainer: FULLY, Meteohub, HMCCU, AndroidDB

CoolTux

Siehst Du die vielen Fragezeichen über meinen Kopf  ;D

Muss ich in dieser Funktion nicht das selbe machen? Oder wie ist das gemeint?
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

zap

#3
Möglicherweise habe ich Deine Anforderungen falsch interpretiert. JSON verwende ich selten bis gar nicht. In meinem Modul habe ich z.B. die Anforderung, eine beliebig verschachtelte Struktur von Arrays und Hashes als String auszugeben. Heißt: Ein Array kann Hashreferenzen enthalten, die wiederum Arrays oder Hashes enthalten können usw.

Die folgende Funktion löst so einen Verhau auf. Dabei ruft sich die Funktion immer wieder selbst auf. Die Rekursion endet, sobald sie auf ein Skalar stößt. Ich habe ein paar Codezeilen weg gelassen, damit das Prinzip klarer wird. Vielleicht kannst Du das vom Prinzip her gebrauchen. Falls nicht, sorry für die Verwirrung  :-[


sub HMCCU_RefToString ($)
{
my ($r) = @_;

my $result = '';

if (ref ($r) eq 'ARRAY') {
foreach my $e (@$r) {
# Rekursiver Aufruf
$result .= HMCCU_RefToString ($e);
}
}
elsif (ref ($r) eq 'HASH') {
foreach my $k (sort keys %$r) {
# Rekursiver Aufruf
$result .= "$k=".HMCCU_RefToString ($r->{$k});
}
}
elsif (ref ($r) eq 'SCALAR') {
$result .= $$r;
}
else {
$result .= $r;
}

return $result;
}
2xCCU3, Fenster, Rollläden, Themostate, Stromzähler, Steckdosen ...)
Entwicklung: FHEM auf AMD NUC (Ubuntu)
Produktiv inzwischen auf Home Assistant gewechselt.
Maintainer: FULLY, Meteohub, HMCCU, AndroidDB

CoolTux

Denke das ich das für meine aktuelle Anforderung nicht gebrauchen kann. Aber es wird ganz sicher mal eine kommen.
Ich habe das jetzt in der Tat so gemacht das ich durch alle Arrays gehe. Wobei ein Array auch eine Hash Referenze haben kann die ich brauche.

Vielleicht kennt jemand noch eine elegantere Lösung
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net