Hauptmenü

Json Array auswerten

Begonnen von thoweiss, 17 Juni 2013, 09:46:06

Vorheriges Thema - Nächstes Thema

thoweiss

Hallo zusammen,

ich komme mal wieder an meine Grenzen...

Ich habe einen Volkszähler aufgesetzt, der meine Stromverbrauchsdaten loggt.

Jetzt möchte ich den jeweils aktuellen Leistungswert auch in FHEM haben.

Dazu habe ich ein kleines Script angepasst (Quelle von hier: Link) das mir den Wert über die API des Volkszählers ausliest.

########################################################################
# Holt den letzten Messwert vom Volkszähler für eine bestimmte uuid
# Aufruf  : { vzGetReading("e620fbc0-d2b1-11e2-b313-db02177402aa") }

sub vzGetReading
{
my ($uuid) = @_;

Log(3,"Getting Data for uuid $uuid");
my $json = JSON->new->allow_nonref;

my  $r = get("http://xxxxserver-adressexxxx/middleware.php/data/$uuid.json?from=1%20seconds%20ago");
die "Couldn't get reading for uuid $uuid" unless defined $r;

my $report = $json->decode( $r );
$report = $report->{data}{tuples};
return $report;
#return $report->[1];
}


Der VZ gibt die Daten als Json zurück:
{"version":"0.2","data":{"uuid":"e620fbc0-d2b1-11e2-b313-db02177402aa","from":1371454853879,"to":1371454869490,"min":[1371454869490,-3231.333],"max":[1371454869490,-3231.333],"average":-3231.333,"consumption":-14.012,"rows":2,"tuples":[[1371454869490,-3231.333,1]]}}

Leider stecken die Daten in einem json Array (tuples), und meine Funktion gibt mir in FHEM folgendes zurück:

ARRAY(0xa4cc9f0)
Das scheint nur eine Referenz auf das Array zu sein - wie bekomme ich jetzt den Inhalt des Arrays?

Das dereferenzieren klappt irgendwie nicht...

Hat jemand da vielleicht eine Idee?


Danke und Gruß,
Thorsten

thoweiss

So, ich werde wohl die Auswertung auf den "average":-3231.333 Wert umstellen, dann muss ich nicht mit den Arrays rumprüddeln.

Ich schreibe wieder wenn es Funktioniert.

Gruß,
Thorsten

fritz

Zitat von: thoweiss schrieb am Mo, 17 Juni 2013 09:46Das dereferenzieren klappt irgendwie nicht...
Hat jemand da vielleicht eine Idee?
Man muss es einfach *richtig* machen :-)

Leider hast Du weder geschrieben, WIE denn Deine Struktur aktuell aussieht, noch WIE Du darauf zugreifst. Vielleicht weisst Du ja schon ersteres nicht, da hilft dann (selbst gerade angewendet :-)
use Data::Dumper;
...
my $result = decode_json $document;
print Dumper($result);

In meinem Fall (eine stündliche Wettervorhersage für 10 Tage) beginnt die Ausgabe (#eigene Kommentare) mit:
$VAR1 = {                        # Hash-Referenz
   'alerts' => [],               # Referenz auf leeres Array
   'hourly_forecast' => [        # Referenz auf Array von Hash-Referenzen
                         {       # erste Hash-Referenz
        'wspd' => {              # Wert (wieder als Hash-Referenz
            'metric' => '12',    # primitiver Wert :-)
            'english' => '8'     # noch einer :-)
            },
        'icon' => 'clear',
...
        'FCTTIME' => {           # wieder eine Hashreferenz
            'hour' => '15',
...
            'pretty' => '3:00 PM CEST on June 18, 2013',
...
            },
...
      'condition' => 'Heiter'
     },                          # Ende des ersten Array-Elementes
     {                           # Beginn des zweiten Elementes
...                              # u.s.w. für 10 Tage a 24 Stunden :-)

Das Codestück, was mir nun ein paar Werte ausliest, sieht so aus:
foreach my $day (@{$result->{'hourly_forecast'}}) {
    print $day->{'FCTTIME'}->{'pretty'} . ": " .
          $day->{condition} . "\n";
}

und liefert (wie gewünscht):
3:00 PM CEST on June 18, 2013: Heiter
4:00 PM CEST on June 18, 2013: Heiter
und so weiter


Fazit: Schau Dir Deine Struktur an, und dann folge ihr einfach :-)
Viel Erfolg

<F>

P.S.: Ich gestehe, manches muss ich auch mehrmals probieren bis es klappt, aber wenn man den Zugriff mal fertig hat, sieht man auch gleich, warum das nur so und nicht anders sein muss.

thoweiss

Danke für deine Antwort,
ich werde das gleich mal testen (wenn ich wieder zuhause bin).

Ich gebe dann rückmeldung - wenn es klappt, oder auch nicht ;-)

Danke und gruß,
Thorsten

thoweiss

So, ich mache es jetzt folgendermaßen:


sub vzGetReading
{
my ($uuid) = @_;

Log(3,"Getting Data for uuid $uuid");
my $json = JSON->new->allow_nonref;

my  $r = get("http://misterhouse/volkszaehler.org/htdocs/middleware.php/data/$uuid.json?from=1%20seconds%20ago");
die "Couldn't get reading for uuid $uuid" unless defined $r;

my $report = $json->decode($r);
$report = $report->{data}{average};

return $report;
}



Anstelle das  Array aufzudröseln, hole ich mir einfach den Durchschnittswert der Leistung.

Da ich in der Anfrage nur die Werte der letzten Sekunde hole, entspricht der Durchschnitt dem Aktuellen Wert der Leistungsaufnahme.

Jetzt muss ich mir noch ein at anlegen was mir die Leistung einmal pro Minute abholt.

Das *richtige* dereferenzieren werde ich aber noch üben, heute isses mir nur zu heiss dazu...


Puschel74

Hallo,

define <hol_die_Werte> at +00:01:00 <woher_kommen_die_Werte>

holt dir jede Minute die Werte ab.

<hol_die_Werte> ist ein frei erfundener Name - bitte anpassen
<woher_kommen_die_Werte> sorry, ich hab nicht den gesamten Beitrag überfolgen aber das müsste dein Aufruf der *.pm sein
Die Parameter noch übergeben nicht vergessen ;-)

Grüße
Zotac BI323 als Server mit DBLog
CUNO für FHT80B, 3 HM-Lan per vCCU, RasPi mit CUL433 für Somfy-Rollo (F2F), RasPi mit I2C(LM75) (F2F), RasPi für Panstamp+Vegetronix +SONOS(F2F)
Ich beantworte keine Supportanfragen per PM! Bitte im Forum suchen oder einen Beitrag erstellen.

thoweiss

Also so

+*00:00:30 { fhem "set du.power.strom.180 vzGetReading("e620fbc0-d2b1-11e2-b313-db02177402aa")" }


Funzt es jedenfalls nicht...


Sieht dann im Webinterface so aus : du.power.strom.180 vzGetReading("e620fbc0-d2b1-11e2-b313-db02177402aa")

Wie rufe ich denn eine Funktion mit Rückgabewert als set auf?

Ich komme mit der FHEM-Syntax noch nicht besonders gut klar...

Sorry für die blöden Fragen

fritz

Zeichenkettenverknüpfung in Perl:"set irgendwas " . myfunctioncall($param)könnte helfen.

<F>

thoweiss

Hallo Fritz,

ich will ja nicht verketten, ich will dem dummy den Rückgabewert der Funktion als state zuweisen...

fritz

...indem Du fhem die Zeichenkette "set du.power.strom.180 12345" sendest (falls vzGetReading("e620fbc0-d2b1-11e2-b313-db02177402aa") gerade 12345 zurückgibt). Und die baust Du Dir am einfachsten mit Zeichenkettenverknüpfung zusammen: "set du.power.strom.180 " . vzGetReading("e620fbc0-d2b1-11e2-b313-db02177402aa") (Achte auf das mind. eine Leerzeichen am Ende der Startzeichenkette, sonst hängen Device-Name und Sollwert syntaktisch falsch zusammen!

<F>

P.S.: Edit - ich dachte, da wäre ein Fehler im Text... war aber doch alles richtig

thoweiss

Jetzt habe ich es geschnallt ;-)

Ich habe das Leerzeichen übersehen,
da hat er mir den String natürlich komplett zusammengeführt.

Mittlerweile habe ich auch gesehen, das es sogar schon ein fertiges Modul für den Volkszähler gibt.

Aber macht nichts- jetzt hab ich wieder etwas gelernt!


Danke euch und gruß,
Thorsten..