Hallo,
ich brauche mal Hilfe bitte, wie ich weiterkommen kann:
Ich hole mit HTTPMOD Daten im Json Format und schreibe diese in bestimmte Readings. Dies habe ich Dank der guten Hilfe jetzt hinbekommen.
Nun habe ich in diesen Daten noch ein Segment in Listform, und habe bisher nicht raus bekommen, wie ich hieraus auch ein Reading bilden kann!
Beispiel:
Rohdaten
{"status":true,"server":{"name":"Toller Name","version":4711,"Liste":[{"name":"Franz","Wert":333},{"name":"Fritz","Wert":88888}]}}
HTTPMOD Dev "'TEST_JSON": https://url.de/json 60
attr TEST_JSON get01Name Name
attr TEST_JSON get01JSON server_name
gibt mir "Toller Name" zurück
Wie komme ich aber an z.B. den Wert 333 von "Franz" aus dem Objekt "Liste" ran.
Könnte Ihr mir einen Schubs geben?!
Danke Holger
PS: "Fritz" + "Franz" sind nicht immer in dieser Reihenfolge, diese ist zufällig, ich könnte also nicht immer den 1, Wert nehmen
ohne json mit regex würde ich folgendes probieren
attr TEST_JSON get01Regex Franz","Wert":(\d+)
Ohne json Modul kannst du folgenden Code einbauen.
Er wandelt mit einigen geschickten Ersetzungen per regulärem Ausdruck aus einem json String einen Perlstring, der mit eval in ein hash verwandelt wird. Dann kannst du bequem auf die Elemente zugreifen(letzte drei Zeilen) - läuft schon seit Wochen in Twilight, könnte man noch bequem in ein Unterprogramm verwandeln.:
if (defined($result)) {
# ersetze in result(json) ": durch "=>
# dadurch entsteht ein Perausdruck, der direkt geparst werden kann
my $perlAusdruck = $result;
$perlAusdruck =~ s/("[\w ]+")(\s*)(:)/$1=>/g;
$perlAusdruck =~ s/null/undef/g;
$perlAusdruck =~ s/true/1/g;
$perlAusdruck =~ s/false/0/g;
$perlAusdruck = '$resHash = ' .$perlAusdruck;
my $resHash;
eval $perlAusdruck;
Log3 $hash, 3, "[$hash->{NAME}] error $@ parsing $result" if($@);
$cond_code = $resHash->{query}{results}{channel}{item}{condition}{code};
$cond_txt = $resHash->{query}{results}{channel}{item}{condition}{text};
$temperatur = $resHash->{query}{results}{channel}{item}{condition}{temp};
}
bei dir müsste der Zugriff so aussehen:
my $listeNutzer = $resHash->{server}{Liste};
Die Liste dann zu Fuß abklappern - wie bei einem Array üblich. Eventuell mit dem Dumper dumpen.
Wenn du Pech hast muss an den regulärden Ausdrücken noch geschraubt werden.
Bitte melden wenn es nicht klappt.
Habe mal schnell ausprobiert ob es funktioniert. Und es klappt.
Habe auch gleich eine kleine Funktion gebaut - kannst du in die 99_utis einbauen und dann aufrufen:
#!/usr/local/bin/perl
use strict;
use Data::Dumper;
my $json =
'{"status":true,"server":{"name":"Toller Name","version":4711,"Liste":[{"name":"Franz","Wert":333},{"name":"Fritz","Wert":88888}]}}'
;
my $resHash = jsonAsPerlHash($json);
print "jsonAsPerl". Dumper $resHash;
foreach my $hash (@{$resHash->{server}{Liste}}) {
print "$hash->{name} -> $hash->{name}\n";
}
###################################################
###################################################
###################################################
sub jsonAsPerlHash ($) {
my ($json) = @_;
my $perlAusdruck = $json;
$perlAusdruck =~ s/("[\w-: ]+")(\s*)(:)/$1=>/g;
$perlAusdruck =~ s/null/undef/g;
$perlAusdruck =~ s/true/1/g;
$perlAusdruck =~ s/false/0/g;
$perlAusdruck = '$resHash = ' .$perlAusdruck;
my $resHash;
eval $perlAusdruck;
print "[json] error $@ parsing $json\n" if($@);
return $resHash;
}
jsonAsPerl$VAR1 = {
'server' => {
'name' => 'Toller Name',
'Liste' => [
{
'name' => 'Franz',
'Wert' => 333
},
{
'name' => 'Fritz',
'Wert' => 88888
}
],
'version' => 4711
},
'status' => 1
};
Franz -> Franz
Fritz -> Fritz
Danke Dietmar,
ich werde mal mein Glück versuchen das bei mir umzusetzen!
VG Holger
HTTPMOD wurde so erweitert, dass es mit
attr test extractAllJSON 1
JSON komplett in Readings einliest. Dann musst du dir Dein Attribut heraussuchen - Wahrscheinlich ist das einfacher für dich.