HTTPMOD - readings namen aus dem Inhalt rauslesen (luftdaten.info)

Begonnen von bartpl, 04 Februar 2020, 13:04:43

Vorheriges Thema - Nächstes Thema

bartpl

Hi,

Ich habe einen Luftsensor von luftdaten.info. Will da direkt die Daten daraus lesen, diese sind über JSON REST Aufruf verfügbar.
Habe dafür bereits diverses mit HTTPMOD ausprobiert, ich komme leider nich zu dem gewünschten Stand:

das Gerät kann über eine lokale IP angesprochen werden und liefert folgenden JSON:
{
    "software_version": "NRZ-2018-123B",
    "age": "47",
    "sensordatavalues": [
        {
            "value_type": "SDS_P1",
            "value": "8.55"
        },
        {
            "value_type": "SDS_P2",
            "value": "3.60"
        },
        {
            "value_type": "BME280_temperature",
            "value": "23.74"
        },
        {
            "value_type": "BME280_humidity",
            "value": "53.09"
        },
        {
            "value_type": "BME280_pressure",
            "value": "96407.30"
        },
        {
            "value_type": "HECA_temperature",
            "value": "23.87"
        },
        {
            "value_type": "HECA_humidity",
            "value": "39.66"
        },
        {
            "value_type": "samples",
            "value": "3211110"
        },
        {
            "value_type": "min_micro",
            "value": "105"
        },
        {
            "value_type": "max_micro",
            "value": "64476"
        },
        {
            "value_type": "signal",
            "value": "-58"
        }
    ]
}


Das Problem ist - jedes Wert ist eine separate Liste in einer Array, das aus value_type und value besteht.

Was ich gerne erreichen würde, wäre: für jedes Eintrag in der sensordatavalues soll ein Reading gestellt werden, dessen Name den value_type entspricht, und wert den value. Wie kann ich das am einfachsten auf die Reihe kriegen?

habe versucht mit extractAllJSON und extractAllJSONFilter versucht aber die Namen kriege ich nicht aus dem Inhalt rausgelesen...

KölnSolar

RPi3/2 buster/stretch-SamsungAV_E/N-RFXTRX-IT-RSL-NC5462-Oregon-CUL433-GT-TMBBQ-01e-CUL868-FS20-EMGZ-1W(GPIO)-DS18B20-CO2-USBRS232-USBRS422-Betty_Boop-EchoDot-OBIS(Easymeter-Q3/EMH-KW8)-PCA301(S'duino)-Deebot(mqtt2)-zigbee2mqtt

bartpl

Ich will direkt aus dem Sensor die Daten bekommen, sollte das Netz nicht verfügbar sein...
Die Frage ist aber denke ich allgemein wichtig - wie kann ich Namen und Werte für dynamisch erstellte Readings aus einer unsorteierten Liste extrahieren?
in Perl würde ich eine foreach schleife machen, und ein setreading machen wo ich Name aus einen Parameter nehme und Wert aus anderen. Leider hier finde ich keinen eleganten Weg das zu schaffen ohne ins Perl einzutauchen und eigene Module zu schreiben.
Das wird besonders kompliziert, wenn die Reihenfolge zufällig ist...

Ein ähnliches Beispiel hatte ich erlebt als ich versucht habe die Daten aus MQTT output von Domoticz rauszuparsen. Es shickt immer ein Array das Parameter Name und dessen Wert beinhaltet. Und nur diesen einzelnen Array. Wenn ein neues aktualisiert wird, dann schickt domoticz nur den anderen... Habe versucht das so ins multiple readings zu zerlegen, habe aber geschaltert. Inwzischen habe ich domoticz komplett mit fhem abgelößt und das Problem habe ich nicht mehr. Aber als Use Case denke ich es wäre gut dafür eine Lösung zu haben. Vielleicht ist einfach mein fhem voodoo zu klein um das schön und elegant zu lösen, wie z.B. mit extractAllJSON...

yersinia

Mal doof gefragt: sollte nicht extractAllJSON gehen?
ZitatIf you don't care about the naming of your readings, you can simply extract all JSON data with
    attr test2 extractAllJSON 1
viele Grüße, yersinia
----
FHEM 6.4 (SVN) on RPi 4B with RasPi OS Bookworm (perl 5.36.0) | FTUI
nanoCUL->2x868(1x ser2net)@tsculfw, 1x433@Sduino | MQTT2 | Tasmota | ESPEasy
VCCU->14xSEC-SCo, 7xCC-RT-DN, 5xLC-Bl1PBU-FM, 3xTC-IT-WM-W-EU, 1xPB-2-WM55, 1xLC-Sw1PBU-FM, 1xES-PMSw1-Pl

bartpl

es funktioniert, leider die Namen sind generisch und nicht einzuordnen:
Internals:
   BUSY       0
   CFGFN     
   DEF        http://192.168.3.3/data.json 600
   FUUID      5e396414-f33f-8de5-5505-70f96364fa5f43da
   Interval   600
   JSONEnabled 1
   LASTSEND   1580819503.58799
   MainURL    http://192.168.3.3/data.json
   ModuleVersion 3.5.21 - 27.12.2019
   NAME       SmogMelder
   NOTIFYDEV  global
   NR         24175
   NTFY_ORDER 50-SmogMelder
   STATE      ???
   TRIGGERTIME 1580820078.84346
   TRIGGERTIME_FMT 2020-02-04 13:41:18
   TYPE       HTTPMOD
   addr       http://192.168.3.3:80
   auth       0
   buf       
   code       200
   compress   1
   conn       
   data       
   displayurl http://192.168.3.3/data.json
   header     
   host       192.168.3.3
   httpheader HTTP/1.1 200 OK
Server: nginx
Date: Tue, 04 Feb 2020 12:31:43 GMT
Content-Type: application/json
Content-Length: 1092
Connection: close
Vary: Accept-Encoding
Last-Modified: Tue, 04 Feb 2020 09:44:22 GMT
ETag: "5e393cf6-444"
Accept-Ranges: bytes
   httpversion 1.0
   hu_blocking 0
   hu_filecount 2
   hu_port    80
   hu_portSfx
   ignoreredirects 1
   loglevel   4
   path       /data.json
   protocol   http
   redirects  0
   timeout    2
   url        http://192.168.3.3/data.json
   value      0
   QUEUE:
   READINGS:
     2020-02-04 13:31:43   age             47
     2020-02-04 13:31:43   sensordatavalues_01_value 8.55
     2020-02-04 13:31:43   sensordatavalues_01_value_type SDS_P1
     2020-02-04 13:31:43   sensordatavalues_02_value 3.60
     2020-02-04 13:31:43   sensordatavalues_02_value_type SDS_P2
     2020-02-04 13:31:43   sensordatavalues_03_value 23.74
     2020-02-04 13:31:43   sensordatavalues_03_value_type BME280_temperature
     2020-02-04 13:31:43   sensordatavalues_04_value 53.09
     2020-02-04 13:31:43   sensordatavalues_04_value_type BME280_humidity
     2020-02-04 13:31:43   sensordatavalues_05_value 96407.30
     2020-02-04 13:31:43   sensordatavalues_05_value_type BME280_pressure
     2020-02-04 13:31:43   sensordatavalues_06_value 23.87
     2020-02-04 13:31:43   sensordatavalues_06_value_type HECA_temperature
     2020-02-04 13:31:43   sensordatavalues_07_value 39.66
     2020-02-04 13:31:43   sensordatavalues_07_value_type HECA_humidity
     2020-02-04 13:31:43   sensordatavalues_08_value 3211110
     2020-02-04 13:31:43   sensordatavalues_08_value_type samples
     2020-02-04 13:31:43   sensordatavalues_09_value 105
     2020-02-04 13:31:43   sensordatavalues_09_value_type min_micro
     2020-02-04 13:31:43   sensordatavalues_10_value 64476
     2020-02-04 13:31:43   sensordatavalues_10_value_type max_micro
     2020-02-04 13:31:43   sensordatavalues_11_value -58
     2020-02-04 13:31:43   sensordatavalues_11_value_type signal
     2020-02-04 13:31:43   software_version NRZ-2018-123B
   REQUEST:
     data       
     header     
     ignoreredirects 0
     retryCount 0
     type       update
     url        http://192.168.3.3/data.json
     value      0
   defptr:
     readingBase:
       age        reading
       sensordatavalues_01_value reading
       sensordatavalues_01_value_type reading
       sensordatavalues_02_value reading
       sensordatavalues_02_value_type reading
       sensordatavalues_03_value reading
       sensordatavalues_03_value_type reading
       sensordatavalues_04_value reading
       sensordatavalues_04_value_type reading
       sensordatavalues_05_value reading
       sensordatavalues_05_value_type reading
       sensordatavalues_06_value reading
       sensordatavalues_06_value_type reading
       sensordatavalues_07_value reading
       sensordatavalues_07_value_type reading
       sensordatavalues_08_value reading
       sensordatavalues_08_value_type reading
       sensordatavalues_09_value reading
       sensordatavalues_09_value_type reading
       sensordatavalues_10_value reading
       sensordatavalues_10_value_type reading
       sensordatavalues_11_value reading
       sensordatavalues_11_value_type reading
       software_version reading
     readingNum:
       age       
       sensordatavalues_01_value
       sensordatavalues_01_value_type
       sensordatavalues_02_value
       sensordatavalues_02_value_type
       sensordatavalues_03_value
       sensordatavalues_03_value_type
       sensordatavalues_04_value
       sensordatavalues_04_value_type
       sensordatavalues_05_value
       sensordatavalues_05_value_type
       sensordatavalues_06_value
       sensordatavalues_06_value_type
       sensordatavalues_07_value
       sensordatavalues_07_value_type
       sensordatavalues_08_value
       sensordatavalues_08_value_type
       sensordatavalues_09_value
       sensordatavalues_09_value_type
       sensordatavalues_10_value
       sensordatavalues_10_value_type
       sensordatavalues_11_value
       sensordatavalues_11_value_type
       software_version
     readingOutdated:
     requestReadings:
       update:
         age        reading
         sensordatavalues_01_value reading
         sensordatavalues_01_value_type reading
         sensordatavalues_02_value reading
         sensordatavalues_02_value_type reading
         sensordatavalues_03_value reading
         sensordatavalues_03_value_type reading
         sensordatavalues_04_value reading
         sensordatavalues_04_value_type reading
         sensordatavalues_05_value reading
         sensordatavalues_05_value_type reading
         sensordatavalues_06_value reading
         sensordatavalues_06_value_type reading
         sensordatavalues_07_value reading
         sensordatavalues_07_value_type reading
         sensordatavalues_08_value reading
         sensordatavalues_08_value_type reading
         sensordatavalues_09_value reading
         sensordatavalues_09_value_type reading
         sensordatavalues_10_value reading
         sensordatavalues_10_value_type reading
         sensordatavalues_11_value reading
         sensordatavalues_11_value_type reading
         software_version reading
   sslargs:
Attributes:
   enforceGoodReadingNames 1
   extractAllJSON 1


Was ich gerne hätte wäre für alles unter sensordatavalues das es analog zu age oder software_version aussieht.
Dafür müsste es aber für jedne Eintrag der JSON Tabelle die Name des readings aus value_type ziehen, und den Inhalt aus value.

Ich hätte mal gerne so etwas:
   READINGS:
     2020-02-04 13:31:43   age 47
     2020-02-04 13:31:43   SDS_P1 8.55
     2020-02-04 13:31:43   SDS_P2 3.60
     2020-02-04 13:31:43   BME280_temperature 23.74
     2020-02-04 13:31:43   BME280_humidity 53.09
     2020-02-04 13:31:43   BME280_pressure 96407.30
...

Das schaffe ich leider nicht generisch zu schaffen.

KölnSolar

ZitatIch will direkt aus dem Sensor die Daten bekommen, sollte das Netz nicht verfügbar sein...
Ägypten ?
Du meinst das Inet und nicht WLAN mit Netz ?
Dann mach das doch mit define Deindevicename LuftdatenInfo local IPdesSensors  ???
RPi3/2 buster/stretch-SamsungAV_E/N-RFXTRX-IT-RSL-NC5462-Oregon-CUL433-GT-TMBBQ-01e-CUL868-FS20-EMGZ-1W(GPIO)-DS18B20-CO2-USBRS232-USBRS422-Betty_Boop-EchoDot-OBIS(Easymeter-Q3/EMH-KW8)-PCA301(S'duino)-Deebot(mqtt2)-zigbee2mqtt

bartpl

Hmm - darauf bin ich nicht gekommen :) Danke! Das ist noch eleganter :)

Christoph Morrison

Zitat von: KölnSolar am 04 Februar 2020, 13:40:10
Dann mach das doch mit define Deindevicename LuftdatenInfo local IPdesSensors  ???

Um das kurz zu konkretisieren:
LuftdatenInfo hat drei Betriebsmodi. Im remote-Modus holt das Modul die Daten aus dem Interwebs, im local-Modus holt es die Daten direkt von deinem Sensor. Hast du mehrere Sensoren angeschlossen, gibt es noch den slave-Modus, bei dem für jeden Sensor (bzw. für jeden Datenpunkt eines Sensors) ein eigenes Device erstellt werden kann. So habe ich zum Beispiel einen modifizierten Sensor mit dem SDS011, einem BME680 und einem DHT22 (teilweise redundant, aber nicht tragisch) im Betrieb. Es gibt bei mir dann vier Devices: Ein Device im local-Modus und drei Devices im slave-Modus. Ich übertrage gar keine Daten an Dritte.

bartpl

Vielen Dank an alle! Ich denke dieses Thema kann zugemacht werden.

KölnSolar

Das kannst Du selbst mit dem Button links unten. Muss aber nicht sein. Wichtiger wäre in Deinem 1. Post den Betreff mit einem [gelöst] zu ergänzen.
RPi3/2 buster/stretch-SamsungAV_E/N-RFXTRX-IT-RSL-NC5462-Oregon-CUL433-GT-TMBBQ-01e-CUL868-FS20-EMGZ-1W(GPIO)-DS18B20-CO2-USBRS232-USBRS422-Betty_Boop-EchoDot-OBIS(Easymeter-Q3/EMH-KW8)-PCA301(S'duino)-Deebot(mqtt2)-zigbee2mqtt

clumsy

#10
Hallo zusammen

Ich habe ein ähnliches Problem, an dem ich mir seit Tagen die Zähne ausbeisse. Ich lese mit HTTPMOD meine Wärmepumpe aus, dies mit mehreren get[0-9]+URL's. Leider kommt in der JSON Antwort das Resultat immer in einem Array namens "object_result" zurück. Das führt bei mehreren URL's dazu dass die Resultate (zufällig) nummeriert werden (jeweils mit "object_result-[0-9]+" als Reading Name. Dazu kommt, dass einige der Werte in einem Code/Value Paar daherkommen. (Beispiele unten).

Nun meine Fragen/Ideen:
- Gibt es eine Möglichkeit bei ExtractALLJSON den get[0-9]+Name voranzustellen, so dass die verschiedenen readings aus den get's eineindeutig werden?
- Gibt es eine Möglichkeit automatisiert aus Code/Value Paaren ein Reading mit Code als Name und Wert Value zu generieren?

Vielen Dank und Grüsse aus der CH

STefan

get01 liefert:
Body: {
  "error_code" : "0",
  "error_msg" : "Success",
  "error_msg_code" : "",
  "object_result" : {
    "is_fault" : true,
    "status" : "ONLINE"
  },
  "is_reuslt_suc" : true
}



get02 liefert:
Body: {
  "error_code" : "0",
  "error_msg" : "Success",
  "error_msg_code" : "",
  "object_result" : [ {
    "code" : "Power",
    "value" : "0"
  }, {
    "code" : "Mode",
    "value" : "1"
  }, {
    "code" : "Manual-mute",
    "value" : "1"
  }, {
    "code" : "T02",
    "value" : "8.0"
  }, {
    "code" : "2074",
    "value" : "0000001000000000"
  }, {
    "code" : "2075",
    "value" : "0000000000001000"
  }, {
    "code" : "2076",
    "value" : "0000000000000000"
  }, {
    "code" : "2077",
    "value" : "0000000000000000"
  }, {
    "code" : "H03",
    "value" : "0"
  }, {
    "code" : "Set_Temp",
    "value" : "33.0"
  }, {
    "code" : "R08",
    "value" : "8.0"
  }, {
    "code" : "R09",
    "value" : "35.0"
  }, {
    "code" : "R10",
    "value" : "15.0"
  }, {
    "code" : "R11",
    "value" : "35.0"
  }, {
    "code" : "R01",
    "value" : "27.0"
  }, {
    "code" : "R02",
    "value" : "33.0"
  }, {
    "code" : "R03",
    "value" : "27.0"
  }, {
    "code" : "T01",
    "value" : "8.5"
  }, {
    "code" : "T02",
    "value" : "8.0"
  }, {
    "code" : "T03",
    "value" : "9.0"
  }, {
    "code" : "1158",
    "value" : "0"
  }, {
    "code" : "1159",
    "value" : "0"
  }, {
    "code" : "F17",
    "value" : "1"
  }, {
    "code" : "H02",
    "value" : "1"
  } ],
  "is_reuslt_suc" : true
}

amenomade

ZitatGibt es eine Möglichkeit bei ExtractALLJSON den get[0-9]+Name voranzustellen, so dass die verschiedenen readings aus den get's eineindeutig werden?
Bei extractAllJSON kann man nichts beeinflüssen. Dafür musst Du einzelne Readings erstellen (mit (get|reading)XXJSON, und die wie gewünscht benennen
ZitatGibt es eine Möglichkeit automatisiert aus Code/Value Paaren ein Reading mit Code als Name und Wert Value zu generieren?
Nein, zumindest nicht ohne Nacharbeit über userReadings oder so.
Aber wenn die immer in der gleichen Reihenfolge kommen, kennst Du schon die Namen anhand der Position. Wenn die Reihenfolge zufällig ist, ist es einfacher über readingXXRegex zu gehen.
Pi 3B, Alexa, CUL868+Selbstbau 1/2λ-Dipol-Antenne, USB Optolink / Vitotronic, Debmatic und HM / HmIP Komponenten, Rademacher Duofern Jalousien, Fritz!Dect Thermostaten, Proteus

clumsy

Danke für die prompte Antwort!!

Dann komm ich wohl nicht drum herum das per einzeln Hand zu definieren..

Evtl. als Anregung für eine zukünftige Version, dass man bei ExtractAllJSON so eine Art "Prefix" angeben kann. (z.b. als Attribut), das dann bei allen readings vorangestellt wird, so könnte man es bei mehreren get's relativ einfach eineindeutig machen...

Nochmals Danke und guten Start in die Woche!

STefan

amenomade

Zitat von: clumsy am 12 Oktober 2020, 07:42:12
Danke für die prompte Antwort!!

Dann komm ich wohl nicht drum herum das per einzeln Hand zu definieren..

Evtl. als Anregung für eine zukünftige Version, dass man bei ExtractAllJSON so eine Art "Prefix" angeben kann. (z.b. als Attribut), das dann bei allen readings vorangestellt wird, so könnte man es bei mehreren get's relativ einfach eineindeutig machen...

Nochmals Danke und guten Start in die Woche!

STefan
Naja... man muss nicht unbedingt alles einzeln definieren: man kann auch extractAllJSON auf 2 setzen, und er erstellt selbst die einzelne Readings. Dann kann man löschen was man nicht braucht
Man kann auch in set|get|readingXXJSON Regex benutzen, z.B.reading01JSON object_result_[0-9]+_value Somit extrahiert er object_result_01_code, object_result_02_code, object_result_03_code, object_result_04_code usw
Und dann macht man ein reading01-1Name power
reading01-2Name mode
reading01-3Name manual-mute
...
um die umzubenennen. Das ist was ich mit "wenn die immer in der gleichen Reihenfolge kommen, kennst Du schon die Namen anhand der Position." meinte
Pi 3B, Alexa, CUL868+Selbstbau 1/2λ-Dipol-Antenne, USB Optolink / Vitotronic, Debmatic und HM / HmIP Komponenten, Rademacher Duofern Jalousien, Fritz!Dect Thermostaten, Proteus

clumsy

Das wäre tatsächlich eine Zwischenvariante die einigermassen machbar ist vom Aufwand. Mein Problem ist, dass ich in 6 get's jeweils zwischen 5 und 20 "object_result" erhalte, welche aber nicht zwingend in der Reihenfolge reproduzierbar sind. Abgesehen davon erhalte ich auch noch zusätzliche Infos ausserhalb vom "object_result".

Auf jeden Fall Danke für die Detaillierung und Hilfe, ich werd nochmals den Kopf rauchen lassen, welchen Weg ich gehe ;)

Grüsse aus der CH!

STefan