[gelöst]Wie parse ich json?

Begonnen von supernova1963, 18 Juni 2017, 17:34:40

Vorheriges Thema - Nächstes Thema

supernova1963

Hallo lieber Leser,

da ich absoluter Perl - Neuling bin, und die Frage für die Profis unter euch sicher mehr als dumm ist, stelle ich sie hier.
Ich habe nachstehenden json - string, dessen Werte ich in Readings eines Dummies ablegen möchte?

$result:
[{"Address":"192.168.1.10","Family":"INET4","FirewallDetected":"true","Hostname":"","CustomName":"SERVER","ScanResult":"OK","HardwareAddress":"A8:20:66:00:00:00","Services":[{"Port":"22","Protocol":"TCP","Name":"ssh","Description":"SSH Secure Shell"},{"Port":"88","Protocol":"TCP","Name":"kerberos-sec","Description":"Kerberos (v5)"},{"Port":"445","Protocol":"TCP","Name":"microsoft-ds","Description":"SMB directly over IP"},{"Port":"464","Protocol":"TCP","Name":"kpasswd5","Description":"Kerberos (v5)"},{"Port":"548","Protocol":"TCP","Name":"afp","Description":"AFP over TCP"},{"Port":"625","Protocol":"TCP","Name":"apple-xsrvr-admin","Description":"Apple Mac Xserver admin"},{"Port":"749","Protocol":"TCP","Name":"kerberos-adm","Description":"Kerberos 5 admin/changepw"},{"Port":"1883","Protocol":"TCP","Name":"fhem-mqtt","Description":"FHEM Standard Mosquitto MQTT Port"},{"Port":"3306","Protocol":"TCP","Name":"mysql","Description":"mySQL"},{"Port":"3689","Protocol":"TCP","Name":"rendezvous","Description":"Rendezvous Zeroconf (used by Apple/iTunes)"},{"Port":"5900","Protocol":"TCP","Name":"vnc","Description":"Virtual Network Computer display 0"}]}]

Ich habe verschiedene Varianten ausprobiert, aber es will mir nicht gelingen, die Werte auszulesen. Trotz intensiver Suche und Lektüre zu json, komplexe Strukturen usw. habe ich den Schlüssel zum Erfolg noch nicht finden können.   
Kann mir einer von euch weiterhelfen?

Danke,

Gernot

Etwas übersichtlicher dargestellt mit:

use Data::Dumper;
...
my $decoded = decode_json($result);
print "Decoded Result: ".Dumper($decoded))

$VAR1 = [
          {
            'Address' => '192.168.1.10',
            'FirewallDetected' => 'true',
            'Services' => [
                            {
                              'Name' => 'ssh',
                              'Description' => 'SSH Secure Shell',
                              'Port' => '22',
                              'Protocol' => 'TCP'
                            },
                            {
                              'Name' => 'kerberos-sec',
                              'Port' => '88',
                              'Description' => 'Kerberos (v5)',
                              'Protocol' => 'TCP'
                            },
                            {
                              'Protocol' => 'TCP',
                              'Port' => '445',
                              'Description' => 'SMB directly over IP',
                              'Name' => 'microsoft-ds'
                            },
                            {
                              'Protocol' => 'TCP',
                              'Port' => '464',
                              'Description' => 'Kerberos (v5)',
                              'Name' => 'kpasswd5'
                            },
                            {
                              'Name' => 'afp',
                              'Description' => 'AFP over TCP',
                              'Port' => '548',
                              'Protocol' => 'TCP'
                            },
                            {
                              'Protocol' => 'TCP',
                              'Port' => '625',
                              'Description' => 'Apple Mac Xserver admin',
                              'Name' => 'apple-xsrvr-admin'
                            },
                            {
                              'Port' => '749',
                              'Description' => 'Kerberos 5 admin/changepw',
                              'Name' => 'kerberos-adm',
                              'Protocol' => 'TCP'
                            },
                            {
                              'Protocol' => 'TCP',
                              'Name' => 'fhem-mqtt',
                              'Description' => 'FHEM Standard Mosquitto MQTT Port',
                              'Port' => '1883'
                            },
                            {
                              'Protocol' => 'TCP',
                              'Name' => 'mysql',
                              'Description' => 'mySQL',
                              'Port' => '3306'
                            },
                            {
                              'Name' => 'rendezvous',
                              'Description' => 'Rendezvous Zeroconf (used by Apple/iTunes)',
                              'Port' => '3689',
                              'Protocol' => 'TCP'
                            },
                            {
                              'Protocol' => 'TCP',
                              'Name' => 'vnc',
                              'Port' => '5900',
                              'Description' => 'Virtual Network Computer display 0'
                            }
                          ],
            'ScanResult' => 'OK',
            'Family' => 'INET4',
            'HardwareAddress' => 'A8:20:66:00:00:00',
            'CustomName' => 'SERVER_RAUNET',
            'Hostname' => ''
          }
        ];




Markus Bloch

Hallo Gernot,

ich verstehe aus deinem Post gerade nicht wirklich dein konkretes Problem. Du schreibst, dass du bereits verschiedene Varianten erfolglos ausprobiert hast. Welche genau waren das denn?

Genauso (zumindest fast) wie Du es schreibst, funktioniert JSON in Perl. Du musst das Perl-Modul JSON einbinden (http://search.cpan.org/~ishigaki/JSON-2.94/lib/JSON.pm ; gibt es meist als fertiges Paket via APT/YUM/Zypper/...) und dann kannst du JSON-Strings mit einem Funktionsaufruf decoden:


use Data::Dumper;
use JSON;

...
my $decoded = decode_json($result);
print "Decoded Result: ".Dumper($decoded))


Das Ergebnis in $decoded ist in deinem Fall eine Array-Referenz mit einer Hash-Referenz der dein Scan-Result enthält.

Gruß
Markus
Developer für Module: YAMAHA_AVR, YAMAHA_BD, FB_CALLMONITOR, FB_CALLLIST, PRESENCE, Pushsafer, LGTV_IP12, version

aktives Mitglied des FHEM e.V. (Technik)

betateilchen

Hallo Markus,

Du hast zwar recht, aber ich glaube nicht, dass Deine Antwort einem Anfänger weiterhiflt ;)

Hier mal ein Beispiel, um an die IP Adresse 192.168.1.10 aus dem genannten String zu kommen.
(Das Beispiel habe ich in meine 99_myUtils.pm gebaut)


sub jsonTest {
my $s = '[{"Address":"192.168.1.10","Family":"INET4","FirewallDetected":"true","Hostname":"","CustomName":"SERVER","ScanResult":"OK","HardwareAddress":"A8:20:66:00:00:00","Services":[{"Port":"22","Protocol":"TCP","Name":"ssh","Description":"SSH Secure Shell"},{"Port":"88","Protocol":"TCP","Name":"kerberos-sec","Description":"Kerberos (v5)"},{"Port":"445","Protocol":"TCP","Name":"microsoft-ds","Description":"SMB directly over IP"},{"Port":"464","Protocol":"TCP","Name":"kpasswd5","Description":"Kerberos (v5)"},{"Port":"548","Protocol":"TCP","Name":"afp","Description":"AFP over TCP"},{"Port":"625","Protocol":"TCP","Name":"apple-xsrvr-admin","Description":"Apple Mac Xserver admin"},{"Port":"749","Protocol":"TCP","Name":"kerberos-adm","Description":"Kerberos 5 admin/changepw"},{"Port":"1883","Protocol":"TCP","Name":"fhem-mqtt","Description":"FHEM Standard Mosquitto MQTT Port"},{"Port":"3306","Protocol":"TCP","Name":"mysql","Description":"mySQL"},{"Port":"3689","Protocol":"TCP","Name":"rendezvous","Description":"Rendezvous Zeroconf (used by Apple/iTunes)"},{"Port":"5900","Protocol":"TCP","Name":"vnc","Description":"Virtual Network Computer display 0"}]}]';

my $decoded = decode_json($s);
my $address = $decoded->[0]->{'Address'};
Debug $address;
}



liefert:



2017.06.18 18:11:26 1: DEBUG>192.168.1.10



Erklärung...

Durch die eckigen Klammern im String muss man beachten, dass es um eine array-Struktur geht, die genau aus einem Element besteht.
Deshalb muss man das mit angeben.



my $address = $decoded->[0]->{'Address'};



Nun muss man auch noch beachten, dass in $decoded->[0]->{'Services'} auch wieder ein Array steckt. Will man alle Elemente aus "Services" auswerten, muss man das gesamte Array auswerten.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

supernova1963

Vielen Dank betateilchen und Markus,

das ging ja super schnell. Mein 1. Versuch mit my $address = $decoded->[0]->{'Address'}; hat funktioniert:
2017.06.18 18:30:34 1: DEBUG>192.168.1.10

Wie sähe denn eine elegante Schleife für die Services aus (oder ist das jetzt unverschämt)?

Danke,

Gernot


betateilchen

#4
Unverschämt nicht, aber es würde Dir ja nichts helfen, wenn ich jetzt einfach eine copy&paste Lösung schreibe und Du nicht verstehst, warum es funktioniert.

Google mal nach "decode_json array" und lies ein bisschen in den ersten Ergebnissen der Suche.



my @services = @{$decoded->[0]->{'Services'}};



ergibt ein Array, in dem die Services wieder in hashes stehen.



Debug $services[0]->{'Port'};
Debug $services[0]->{'Description'};
Debug $services[0]->{'Name'};
Debug $services[0]->{'Protocol'};

liefert:

2017.06.18 18:49:56 1: DEBUG>22
2017.06.18 18:49:56 1: DEBUG>SSH Secure Shell
2017.06.18 18:49:56 1: DEBUG>ssh
2017.06.18 18:49:56 1: DEBUG>TCP


und wie man über ein Array loopt, findest Du jetzt bitte selbst raus.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

supernova1963

#5
Hab' ich mir gedacht, betrachten wir es als 'gültigen Versuch'.
Ich denke, dass eine solche Schleife, - auch für mich -, realisierbar ist.

Ich habe heute bereits soviel über "komplexe Strukturen in perl" gelesen, dass ich den 'Wald vor lauter Bäumen' nicht mehr sehe.
Danke noch einmal, betateilchen, auch für deine Erklärungen. So habe ich heute wieder einen kleinen Schritt nach vorn gemacht,

Gernot

P.S.: Die ersten Ergebnisse Deines Such-Tipps, waren bei mir alle als gelesen markiert.   

betateilchen

Ein array ist keine komplexe Struktur...
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

justme1968

noch eine wichtiger punkt: die json lib mag fehler im json code nicht und beendet sich dann komplett und damit dann auch fhem. um das zu verhindert muss man decode_json aus einem eval aufrufen:my $decoded = eval { decode_json($result) };

falls es beim dekodieren einen fehler gegeben hat kann man den z.b. so ausgeben:Log3 $name, 2, "$name: json error: $@ in $result" if( $@ );

gruss
  andre

ps: und noch etwas: das array zu dereferenzieren ist nicht nötig und sollte normalerweise auch vermieden werden. denn es ist gift für die performance wenn es mehrfach und mit grossen datenmengen passiert. mit referenzen zu arbeiten ist nicht weiter schwierig.
if( my $services = $decoded->[0]{'Services'} ) {
  Debug $services->[0]{'Port'};
}


hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

supernova1963

#8
Danke justme1968, für diese Hinweise.

Mögliche Fehler werde ich wie von Dir beschrieben mit eval abfangen.

Dein P.S. kann ich noch nicht richtig einordnen. Ich hatte es gerade schon wie folgt, - erfolgreich -, gelöst.
Ist das mit Deinem Vorschlag vergleichbar, oder ist es das, was ich vermeiden sollte?

Danke,

Gernot


    my $decoded = decode_json($result);
    readingsBeginUpdate($hash);
        readingsBulkUpdateIfChanged($hash, "IP", $decoded->[0]->{'Address'}, 1);
        readingsBulkUpdateIfChanged($hash, "FirewallDetected", $decoded->[0]->{'FirewallDetected'}, 1);
        readingsBulkUpdateIfChanged($hash, "ScanResult", $decoded->[0]->{'ScanResult'}, 1);
        readingsBulkUpdateIfChanged($hash, "Family", $decoded->[0]->{'Family'}, 1);
        readingsBulkUpdateIfChanged($hash, "HardwareAddress", $decoded->[0]->{'HardwareAddress'}, 1);
        readingsBulkUpdateIfChanged($hash, "CustomName", $decoded->[0]->{'CustomName'}, 1);
        readingsBulkUpdateIfChanged($hash, "Hostname", $decoded->[0]->{'Hostname'}, 1);
    readingsEndUpdate($hash, 0);
    my $i = 0;
    my $Port = "";
    my $Protocol = "";
    my $Description = "";
    my $Name = "";
    my $ServiceID = "";
    while ($decoded->[0]->{'Services'}->[$i]) {
        $Port = $decoded->[0]->{'Services'}->[$i]->{'Port'};
        $Protocol = $decoded->[0]->{'Services'}->[$i]->{'Protocol'};
        $Description = $decoded->[0]->{'Services'}->[$i]->{'Description'};
        $Name = $decoded->[0]->{'Services'}->[$i]->{'Name'};
        $ServiceID = $Protocol.substr("00000".$Port, -5, 5);
        readingsBeginUpdate($hash);
            readingsBulkUpdateIfChanged($hash, $ServiceID."_Port", $Port);
            readingsBulkUpdateIfChanged($hash, $ServiceID."_Protocol", $Protocol);
            readingsBulkUpdateIfChanged($hash, $ServiceID."_Description", $Description);
            readingsBulkUpdateIfChanged($hash, $ServiceID."_Name", $Name);
            readingsBulkUpdateIfChanged($hash, $ServiceID."_Service", $Port."/".$Protocol." ".$Name.": ".$Description);
        readingsEndUpdate($hash, 0);
        $i = $i+1
    }


Ergebnis:
Internals:
   CFGFN
   DEF        A8:20:66:00:00:00
   MAC        A8:20:66:00:00:00
   NAME       nc_A8_20_66_00_00_00
   NR         48
   STATE      <table width=100%% style="table-layout:fixed"><tr>
            <td style='text-align: left'>192.168.1.10</td>
            <td style='width: 30px'><img src="./fhem/images/default/10px-kreis-gruen.png" alt="up"></td>
            <td align=Left style='white-space: nowrap'>Apple,</td>
            <td style='text-align: right'>2017-06-18 19:39:02</td></tr></table>
   TYPE       netClient
   Helper:
     Dblog:
       Fingname:
         Logdb:
           TIME       1497807542.84255
           VALUE      SERVER_RAUNET
       Hostname:
         Logdb:
           TIME       1497807542.84255
           VALUE      n/a
       Ip:
         Logdb:
           TIME       1497807542.84255
           VALUE      192.168.1.10
       Nr:
         Logdb:
           TIME       1497807542.84255
           VALUE      010
       Vendor:
         Logdb:
           TIME       1497807542.84255
           VALUE      Apple,
       State:
         Logdb:
           TIME       1497807542.84255
           VALUE      up
   Readings:
     2017-06-18 19:39:21   CustomName      SERVER_RAUNET
     2017-06-18 19:39:02   FINGNAME        SERVER_RAUNET
     2017-06-18 19:39:21   Family          INET4
     2017-06-18 19:39:21   FirewallDetected true
     2017-06-18 19:39:02   HOSTNAME        n/a
     2017-06-18 19:39:21   HardwareAddress A8:20:66:00:00:00
     2017-06-18 19:39:02   IP              192.168.1.10
     2017-06-18 19:39:02   NR              010
     2017-06-18 19:39:21   ScanResult      OK
     2017-06-18 19:39:21   TCP00022_Description SSH Secure Shell
     2017-06-18 19:39:21   TCP00022_Name   ssh
     2017-06-18 19:39:21   TCP00022_Port   22
     2017-06-18 19:39:21   TCP00022_Protocol TCP
     2017-06-18 19:39:21   TCP00022_Service 22/TCP ssh: SSH Secure Shell
     2017-06-18 19:39:21   TCP00088_Description Kerberos (v5)
     2017-06-18 19:39:21   TCP00088_Name   kerberos-sec
     2017-06-18 19:39:21   TCP00088_Port   88
     2017-06-18 19:39:21   TCP00088_Protocol TCP
     2017-06-18 19:39:21   TCP00088_Service 88/TCP kerberos-sec: Kerberos (v5)
     2017-06-18 19:39:21   TCP00445_Description SMB directly over IP
     2017-06-18 19:39:21   TCP00445_Name   microsoft-ds
     2017-06-18 19:39:21   TCP00445_Port   445
     2017-06-18 19:39:21   TCP00445_Protocol TCP
     2017-06-18 19:39:21   TCP00445_Service 445/TCP microsoft-ds: SMB directly over IP
     2017-06-18 19:39:21   TCP00464_Description Kerberos (v5)
     2017-06-18 19:39:21   TCP00464_Name   kpasswd5
     2017-06-18 19:39:21   TCP00464_Port   464
     2017-06-18 19:39:21   TCP00464_Protocol TCP
     2017-06-18 19:39:21   TCP00464_Service 464/TCP kpasswd5: Kerberos (v5)
     2017-06-18 19:39:21   TCP00548_Description AFP over TCP
     2017-06-18 19:39:21   TCP00548_Name   afp
     2017-06-18 19:39:21   TCP00548_Port   548
     2017-06-18 19:39:21   TCP00548_Protocol TCP
     2017-06-18 19:39:21   TCP00548_Service 548/TCP afp: AFP over TCP
     2017-06-18 19:39:21   TCP00625_Description Apple Mac Xserver admin
     2017-06-18 19:39:21   TCP00625_Name   apple-xsrvr-admin
     2017-06-18 19:39:21   TCP00625_Port   625
     2017-06-18 19:39:21   TCP00625_Protocol TCP
     2017-06-18 19:39:21   TCP00625_Service 625/TCP apple-xsrvr-admin: Apple Mac Xserver admin
     2017-06-18 19:39:21   TCP00749_Description Kerberos 5 admin/changepw
     2017-06-18 19:39:21   TCP00749_Name   kerberos-adm
     2017-06-18 19:39:21   TCP00749_Port   749
     2017-06-18 19:39:21   TCP00749_Protocol TCP
     2017-06-18 19:39:21   TCP00749_Service 749/TCP kerberos-adm: Kerberos 5 admin/changepw
     2017-06-18 19:39:21   TCP01883_Description FHEM Standard Mosquitto MQTT Port
     2017-06-18 19:39:21   TCP01883_Name   fhem-mqtt
     2017-06-18 19:39:21   TCP01883_Port   1883
     2017-06-18 19:39:21   TCP01883_Protocol TCP
     2017-06-18 19:39:21   TCP01883_Service 1883/TCP fhem-mqtt: FHEM Standard Mosquitto MQTT Port
     2017-06-18 19:39:21   TCP03306_Description mySQL
     2017-06-18 19:39:21   TCP03306_Name   mysql
     2017-06-18 19:39:21   TCP03306_Port   3306
     2017-06-18 19:39:21   TCP03306_Protocol TCP
     2017-06-18 19:39:21   TCP03306_Service 3306/TCP mysql: mySQL
     2017-06-18 19:39:21   TCP03689_Description Rendezvous Zeroconf (used by Apple/iTunes)
     2017-06-18 19:39:21   TCP03689_Name   rendezvous
     2017-06-18 19:39:21   TCP03689_Port   3689
     2017-06-18 19:39:21   TCP03689_Protocol TCP
     2017-06-18 19:39:21   TCP03689_Service 3689/TCP rendezvous: Rendezvous Zeroconf (used by Apple/iTunes)
     2017-06-18 19:39:21   TCP05900_Description Virtual Network Computer display 0
     2017-06-18 19:39:21   TCP05900_Name   vnc
     2017-06-18 19:39:21   TCP05900_Port   5900
     2017-06-18 19:39:21   TCP05900_Protocol TCP
     2017-06-18 19:39:21   TCP05900_Service 5900/TCP vnc: Virtual Network Computer display 0
     2017-06-18 19:39:02   VENDOR          Apple,
     2017-06-18 19:39:02   state           up
   Helper:
Attributes:
   ScanInterval 86400
   ScanMode   quick
   alias      SERVER_RAUNET
   group      NetClients
   room       Netz
   sortby     010
   stateFormat {
        if (ReadingsVal("nc_A8_20_66_00_00_00","state","") eq "up"){
            return "<table width=100%% style=\"table-layout:fixed\"><tr>
            <td style='text-align: left'>".ReadingsVal("nc_A8_20_66_00_00_00","IP","")."</td>
            <td style='width: 30px'><img src=\"./fhem/images/default/10px-kreis-gruen.png\" alt=\"up\"></td>
            <td align=Left style='white-space: nowrap'>".ReadingsVal("nc_A8_20_66_00_00_00","VENDOR","")."</td>
            <td style='text-align: right'>".ReadingsTimestamp("nc_A8_20_66_00_00_00","state","")."</td></tr></table>"
        }
        elsif (ReadingsVal("nc_A8_20_66_00_00_00","state","") eq "down") {
            return "<table width=100%% style=\"table-layout:fixed\"><tr>
            <td style='text-align: left'>".ReadingsVal("nc_A8_20_66_00_00_00","IP","")."</td>
            <td style='width: 30px'><img src=\"./fhem/images/default/10px-kreis-rot.png\" alt=\"up\"></td>
            <td align=Left style='white-space: nowrap'>".ReadingsVal("nc_A8_20_66_55_58_AC","VENDOR","")."</td>
            <td style='text-align: right'>".ReadingsTimestamp("nc_A8_20_66_00_00_00","state","")."</td></tr></table>"
        }
        else {
            return "<table width=100%% style=\"table-layout:fixed\"><tr>
            <td style='text-align: left'>".ReadingsVal("nc_A8_20_66_00_00_00","IP","")."</td>
            <td style='width: 30px'><img src=\"./fhem/images/default/10px-kreis-gelb.png\" alt=\"up\"></td>
            <td align=Left style='white-space: nowrap'>".ReadingsVal("nc_A8_20_66_55_58_AC","VENDOR","")."</td>
            <td style='text-align: right'>".ReadingsTimestamp("nc_A8_20_66_00_00_00","state","")."</td></tr></table>"
        } }

Markus Bloch

Zitat von: betateilchen am 18 Juni 2017, 18:18:42
Du hast zwar recht, aber ich glaube nicht, dass Deine Antwort einem Anfänger weiterhiflt ;)

Oha, da war ich ja auf dem völlig falschen Dampfer :-/
Developer für Module: YAMAHA_AVR, YAMAHA_BD, FB_CALLMONITOR, FB_CALLLIST, PRESENCE, Pushsafer, LGTV_IP12, version

aktives Mitglied des FHEM e.V. (Technik)

justme1968

das was du machst ist im prinzip das gleiche. direkt auf der referenz zu arbeiten.

du solltest aber jeweils vorher prüfen ob es den knoten auf den du zugreifst auch tatsächlich gibt.

wenn es $decoded->[0]->{'Services'} nicht gibt fliegst du sonst raus wenn du auf $decoded->[0]->{'Services'}->[$i] zugreifst.

du kannst noch überlegen wie in meinem beispie dinge die mehrfach verwendet werden einer eigenen variable zuzuweisen. also z.b. das $decoded->[0]->{'Services'}das ist auf dauer übersichtlicher, änderungsfreundlicher und auch effizienter.
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

supernova1963

Hallo justme1968,

die Bereitschaft dein enormes Wissen hier im Forum zu teilen, ohne nur den geringsten Anflug von Überheblichkeit, ist vorbildlich!

Danke für Alles und hier im Speziellen für weitere wertvolle konkrete Hinweise,

Gernot

Ich hab's bis jetzt so gemacht:


#######################################################################################
# netClient_QuickScanDone() Blocking Sub-Routine wurde abgeschlossen
sub netClient_QuickScanDone($)
{
    my ($string) = @_;
    my ($name, $result) = split("\\|", $string);
    my $hash = $defs{$name};
    # json Format - Korrektur (',}' und ',]' sowie ' durch " ersetzten
    $result = fingJsonKorrektur($result);
    # json Fehler abfangen
    my $decoded = eval { decode_json($result) };
    if($@) {
        Log3 $name, 2, "$name: json error: $@ in $result";
        return "json error!";
    }
    # fing ScanResult ist nicht OK abfangen
    if ($decoded->[0]->{"ScanResult"} ne 'OK') {
        readingsSingleUpdate($hash,"state","Down", 1);
        Log3 $name, 3, "$name: fing error: ".$decoded->[0]->{"ScanResult"};
        return "fing error!";
    }
   
    readingsBeginUpdate($hash);
        readingsBulkUpdateIfChanged($hash, "IP", $decoded->[0]->{"Address"}, 1);
        readingsBulkUpdateIfChanged($hash, "FirewallDetected", $decoded->[0]->{"FirewallDetected"}, 1);
        readingsBulkUpdateIfChanged($hash, "ScanResult", $decoded->[0]->{"FirewallDetected"}, 1);
        readingsBulkUpdateIfChanged($hash, "state", "up", 1);
        readingsBulkUpdateIfChanged($hash, "Family", $decoded->[0]->{"Family"}, 1);
        readingsBulkUpdateIfChanged($hash, "HardwareAddress", $decoded->[0]->{"HardwareAddress"}, 1);
        readingsBulkUpdateIfChanged($hash, "CustomName", $decoded->[0]->{"CustomName"}, 1);
        readingsBulkUpdateIfChanged($hash, "Hostname", $decoded->[0]->{"Hostname"}, 1);
    readingsEndUpdate($hash, 0);
    if (!defined($decoded->[0]->{"Services"}) {
        Log3 $name, 2, "$name: no defined services in $result";
        return "no service";
    }
    my $i = 0;
    my $Port = "";
    my $Protocol = "";
    my $Description = "";
    my $Name = "";
    my $ServiceID = "";
    while ($decoded->[0]->{"Services"}->[$i]) {
        $Port = $decoded->[0]->{"Services"}->[$i]->{"Port"};
        $Protocol = $decoded->[0]->{"Services"}->[$i]->{"Protocol"};
        $Description = $decoded->[0]->{"Services"}->[$i]->{"Description"};
        $Name = $decoded->[0]->{"Services"}->[$i]->{"Name"};
        $ServiceID = $Protocol.substr("00000".$Port, -5, 5);
        readingsBeginUpdate($hash);
            readingsBulkUpdateIfChanged($hash, $ServiceID."_Port", $Port);
            readingsBulkUpdateIfChanged($hash, $ServiceID."_Protocol", $Protocol);
            readingsBulkUpdateIfChanged($hash, $ServiceID."_Description", $Description);
            readingsBulkUpdateIfChanged($hash, $ServiceID."_Name", $Name);
            readingsBulkUpdateIfChanged($hash, $ServiceID."_Service", $Port."/".$Protocol." ".$Name.": ".$Description);
        readingsEndUpdate($hash, 0);
        $i = $i+1
    }
    Log3 $name, 3, "$name: QuickScan hat $i Services bei Veränderung hinzugefügt/aktualisiert!";
    # zum Abschluss wird die "RUNNING_PID des helpers des devices gelöscht
    delete($hash->{helper}{SCANRUNNING_PID});
    # Aufruf der Sub-Routine zum setzten des Timers für die nächste Ausführung
    netClient_SetNextTimer($hash);
    # Abschluss der Sub-Routine ohne Rückgabewert
}
#######################################################################################