Autor Thema: customReadings mit JSON-Pointer?  (Gelesen 837 mal)

Offline Wuehler

  • Developer
  • Sr. Member
  • ****
  • Beiträge: 571
customReadings mit JSON-Pointer?
« am: 26 Juni 2019, 08:01:08 »
Hallo zusammen,

im Modul UnifiSwitch habe ich die Anforderung mehr Readings anzuzeigen als bisher. Vom Switch wird dabei das folgende (gekürzte) JSON empfangen. Dieses JSON sieht je nach Model des Switches unterschiedlich aus. Konkretes Beispiel: Manche Switche haben Temperatursensoren und liefern die Temperatur im JSON mit, der Switch unten (JSON-Beispiel) besitzt keinen solchen Sensor.

Jetzt könnte ich immer auf Anforderung einzelner User neue Readings hinzufügen. Das finde ich nicht so zielführend. Idee daher: ein Attribut mit dem man auf Basis des JSON dem User ermöglicht eigene Readings hinzuzufügen. Dazu könnte man im Attribut eine kommaseparierte Liste aus JSON-Pointern angeben.
attr customReadings /system-stats/cpu,/user-num_staDies würde dann neue Readings zur CPU-Load und den Usern erzeugen.

Meine Frage in die Runde: Es gibt solche Attribute bestimmt schon in anderen Modulen. Hat sich dafür vielleicht ein Standard in FHEM entwickelt, an den in mich halten kann?

{
  "rx_bytes": 47054900,
  "stat": {
    "sw": "78:8a:20:7f:bf:62",
    "duration": 556125000,
    "port_8-rx_bytes": 56100243,
    "rx_multicast": 429077,
    "port_3-rx_multicast": 8106,
    "port_3-tx_packets": 276794,
    "port_1-tx_multicast": 309890,
    "port_1-tx_broadcast": 20574,
    "port_8-tx_broadcast": 83412,
    "rx_crypts": 0,
    "port_3-tx_multicast": 239927,
    "tx_broadcast": 138921,
    "tx_packets": 2444735,
    "port_3-rx_packets": 10346,
    "rx_errors": 1,
    "rx_broadcast": 68773,
    "port_1-rx_broadcast": 65478,
    "port_3-tx_bytes": 41305896,
    "port_1-tx_bytes": 140293052,
    "port_3-rx_errors": 1,
    "port_1-tx_packets": 914795,
    "rx_frags": 0,
    "port_8-tx_multicast": 700483,
    "tx_dropped": 57,
    "port_3-tx_broadcast": 34935,
    "time": 1560970500000,
    "port_3-rx_broadcast": 417,
    "port_1-rx_bytes": 640521016,
    "tx_retries": 0,
    "rx_bytes": 698775704,
    "port_8-tx_bytes": 644641773,
    "site_id": "5834c627ccf28a23452c543f",
    "bytes": 1525016425,
    "rx_dropped": 0,
    "oid": "78:8a:20:7f:bf:62",
    "port_8-tx_packets": 1253146,
    "rx_packets": 1527256,
    "tx_errors": 0,
    "port_3-rx_bytes": 2154445,
    "port_1-rx_packets": 1100310,
    "port_1-tx_dropped": 57,
    "tx_multicast": 1250300,
    "datetime": "2019-06-19T18:55:00Z",
    "port_1-rx_multicast": 414762,
    "port_8-rx_broadcast": 2878,
    "port_8-rx_packets": 416600,
    "tx_bytes": 826240721,
    "port_8-rx_multicast": 6209,
    "o": "sw"
  },
  "system-stats": {
    "cpu": "56.1",
    "mem": "49.4",
    "uptime": "162053"
  },
  "user-num_sta": 7,
  "mac": "78:8b:20:3f:bf:62",
  "has_temperature": false,
  "inform_ip": "192.168.1.2",
  "_uptime": 162053,
  "connect_request_port": "46561",
  "required_version": "3.7.16",
  "downlink_table": [],
  "adoptable_when_upgraded": false,
  "has_fan": false,
  "ssh_session_table": [],
  "stp_priority": "32768",
  "port_overrides": [
    {
      "poe_mode": "off"
    },
    {
      "portconf_id": "5834c651ccf28a27852c5448",
      "poe_mode": "auto",
      "port_idx": "6"
    },
    {
      "portconf_id": "5834c651ccf28a27852c5448",
      "port_idx": "7",
      "poe_mode": "auto"
    }
  ],
  "guest-num_sta": 0,
  "led_override_color_brightness": 100,
  "num_sta": 7,
  "ethernet_table": [
    {
      "num_port": 8,
      "mac": "78:8b:20:3f:bf:62",
      "name": "eth0"
    },
    {
      "mac": "78:8b:20:3f:bf:63",
      "name": "srv0"
    }
  ],
  "switch_caps": {
    "max_aggregate_sessions": 4,
    "feature_caps": 1022,
    "max_mirror_sessions": 1
  },
  "type": "usw",
  "uptime": 162053,
  "stp_version": "rstp",
  "overheating": false,
  "sys_stats": {
    "mem_total": 262397952,
    "mem_buffer": 0,
    "loadavg_1": "1.44",
    "loadavg_15": "1.61",
    "loadavg_5": "1.62",
    "mem_used": 129560576
  },
  "fw_caps": 712229,
  "led_override_color": "#0000ff",
  "known_cfgversion": "e1257c2e03e4c126",
  "bytes": 310622376,
  "unsupported_reason": 0,
  "total_max_power": 50,
  "_id": "5ba172056921a11366ba9b21",
  "sys_error_caps": 0,
  "name": "switch-1",
  "adopted": true,
  "led_override": "default",
  "tx_bytes": 263567476,
  "uplink": {
    "netmask": "255.255.255.0",
    "up": true,
    "rx_errors": 0,
    "tx_errors": 0,
    "tx_packets": 340588,
    "max_speed": 1000,
    "rx_packets": 395060,
    "tx_bytes": 47054900,
    "type": "wire",
    "port_idx": 1,
    "name": "eth0",
    "media": "GE",
    "num_port": 8,
    "ip": "192.168.1.12",
    "mac": "18:3a:20:2f:bf:32",
    "tx_dropped": 0,
    "rx_bytes-r": 7710,
    "rx_dropped": 0,
    "tx_bytes-r": 1760,
    "full_duplex": true,
    "rx_multicast": 0,
    "speed": 100,
    "rx_bytes": 263567476
  },
  "outdoor_mode_override": "default",
  "jumboframe_enabled": false,
  "board_rev": 6,
  "inform_url": "http://192.168.1.2:8080/inform",
  "version": "4.0.42.10433",
  "model": "US8P60",
  "locating": false,
  "device_id": "5ba772056921a11366ba9b21",
  "connect_request_ip": "192.168.1.12",
  "license_state": "registered",
  "cfgversion": "e1257c2e03e4c126",
  "hw_caps": 0,
  "last_uplink": {
    "uplink_mac": "f2:9a:c2:32:1e:d2"
  },
  "last_seen": 1561526878,
  "ip": "192.168.1.12",
  "unsupported": false,
  "dot1x_portctrl_enabled": false,
  "port_table": [
    {
      "tx_bytes-r": 1760,
      "rx_dropped": 0,
      "lldp_table": [
        {
          "lldp_port_id": "eth1",
          "lldp_chassis_id": "F2:9A:C2:32:1E:D2",
          "lldp_system_name": "usg"
        }
      ],
      "aggregated_by": false,
      "rx_bytes": 263567476,
      "tx_dropped": 0,
      "jumbo": false,
      "port_poe": false,
      "tx_bytes": 47054900,
      "flowctrl_rx": false,
      "name": "Port 1",
      "port_idx": 1,
      "dot1x_status": "disabled",
      "bytes-r": 9471,
      "up": true,
      "tx_multicast": 91293,
      "tx_errors": 0,
      "rx_packets": 395060,
      "poe_caps": 0,
      "rx_bytes-r": 7710,
      "full_duplex": true,
      "stp_state": "forwarding",
      "rx_multicast": 123665,
      "autoneg": true,
      "speed": 100,
      "dot1x_mode": "unknown",
      "satisfaction": 100,
      "op_mode": "switch",
      "masked": false,
      "flowctrl_tx": false,
      "portconf_id": "5834c651ccf28a23452c5448",
      "stp_pathcost": 200000,
      "rx_broadcast": 19686,
      "media": "GE",
      "enable": true,
      "rx_errors": 0,
      "speed_caps": 1048623,
      "tx_broadcast": 5688,
      "tx_packets": 340588,
      "is_uplink": true
    },
    {
      "flowctrl_tx": false,
      "portconf_id": "5834c651ccf28a23452c5448",
      "enable": true,
      "rx_broadcast": 0,
      "media": "GE",
      "stp_pathcost": 0,
      "speed_caps": 1048623,
      "rx_errors": 0,
      "is_uplink": false,
      "tx_packets": 0,
      "tx_broadcast": 0,
      "full_duplex": false,
      "rx_bytes-r": 0,
      "poe_caps": 0,
      "speed": 0,
      "autoneg": true,
      "rx_multicast": 0,
      "stp_state": "disabled",
      "dot1x_mode": "unknown",
      "op_mode": "switch",
      "masked": false,
      "satisfaction": 100,
      "port_poe": false,
      "jumbo": false,
      "dot1x_status": "disabled",
      "port_idx": 2,
      "name": "Port 2",
      "tx_bytes": 0,
      "flowctrl_rx": false,
      "tx_multicast": 0,
      "up": false,
      "bytes-r": 0,
      "rx_packets": 0,
      "tx_errors": 0,
      "rx_dropped": 0,
      "tx_bytes-r": 0,
      "aggregated_by": false,
      "rx_bytes": 0,
      "lldp_table": [],
      "tx_dropped": 0
    },
  ],
  "state": 1,
  "dhcp_server_table": [],
  "upgradable": false,
  "uplink_depth": 1,
  "flowctrl_enabled": false,
  "y": 426.697322973217,
  "rollupgrade": false
}

Danke schon mal und viele Grüße,
Dirk
Zustimmung Zustimmung x 1 Liste anzeigen

Offline Beta-User

  • Developer
  • Hero Member
  • ****
  • Beiträge: 7591
  • eigentlich eher user wie "developer"
Antw:customReadings mit JSON-Pointer?
« Antwort #1 am: 26 Juni 2019, 15:06:15 »
Hmm, bin nicht sicher, ob es das ist, was du suchst, aber "json2nameValue()" kennt drei Argumente. Das letzte dient dazu, ggf. Readings zu mappen (oder eben auch ausdrücklich nicht zu mappen).

Findet gelegentlich bei MQTT2_DEVICE Anwendung, aber firm bin ich da leider nicht so wirklich...
Server: HP-T620@Debian 10, aktuelles FHEM + ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN
svn:MySensors, WeekdayTimer, AttrTemplate => {mqtt2, mysensors, httpmod}

Offline Wuehler

  • Developer
  • Sr. Member
  • ****
  • Beiträge: 571
Antw:customReadings mit JSON-Pointer?
« Antwort #2 am: 27 Juni 2019, 09:51:05 »
Hallo Beta-User,

json2nameValue() könnte zumindest das Mittel der Wahl sein, um auf JSON::Pointer als zusätzliche Abhängigkeit zu verzichten, daher auf jeden Fall schon mal Danke für den Hinweis darauf.

Mir ging es vor allem um die Sicht der Anwender in der Verwendung eines Attributes, dass aus internen Daten bei Bedarf Readings erzeugt. Aus Usersicht wäre es meiner Meinung nach nicht so schön, je Modul andere Logiken zu nutzen.
ZB einmal RegExp, beim anderen Modul dann JsonPointer-Syntax, mal mit Komma separiert, mal mit Semikolon oder Leerzeichen.
Hat sich da evtl. schon etwas als quasi-Standard durchgesetzt?

VG,
Dirk

Offline Beta-User

  • Developer
  • Hero Member
  • ****
  • Beiträge: 7591
  • eigentlich eher user wie "developer"
Antw:customReadings mit JSON-Pointer?
« Antwort #3 am: 27 Juni 2019, 10:43:22 »
Moin Dirk,

an sich habe ich zu wenig Erfahrung, um das mit dem "Standard" beantworten zu können.

Nach meiner Kenntnis ist MQTT2_DEVICE bislang das einzige Modul, das json2valueName() voll nutzt, von daher neige ich zur Empfehlung, das im Wesentlichen so zu machen wie bei MQTT2_DEVICE, einschließlich der Attribut-Benennung.

Dort gibt es ein Attribut "jsonMap":
Zitat
jsonMap oldReading1:newReading1 oldReading2:newReading2...
 space or newline separated list of oldReading:newReading pairs.
 Used in the automatically generated readingList json2nameValue function to map the generated reading name to a better one. E.g.
  • attr m2d jsonMap SENSOR_AM2301_Humidity:Humidity
     attr m2d readingList tele/sonoff/SENSOR:.* { json2nameValue($EVENT, 'SENSOR_', $JSONMAP) }
The special newReading value of 0 will prevent creating a reading for oldReading.

So wie ich das verstanden habe, kannst du das nur nicht ganz so verwenden, weil du ja eine Art "Standardsatz" an JSON-Inhalten hast, der immer ausgewertet werden soll und der User hier die Option erhalten soll, das im Sinne einer Positivliste zu verwenden (und alles andere dann weiter ignorieren).

(Sorry, bin kein Perl-Experte, versuche aber mal meine unfertigen Gedanken dazu auszubreiten...)
json2nameValue() sollte hier an sich funktionieren, aber etwas anders als bei MQTT2_DEVICE verwendet werden, nämlich ohne die "0"-Option. Allerdings brauchst du dann vermutlich einen weiteren Durchlauf über den Rückgabewert von json2nameValue(), der nur die zusätzlich gesetzten newReading-keys in dem hash läßt und alles andere rauslöscht bzw. nur die in den Reading-Update-Prozess übergibt?
Server: HP-T620@Debian 10, aktuelles FHEM + ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN
svn:MySensors, WeekdayTimer, AttrTemplate => {mqtt2, mysensors, httpmod}

Offline Wuehler

  • Developer
  • Sr. Member
  • ****
  • Beiträge: 571
Antw:customReadings mit JSON-Pointer?
« Antwort #4 am: 27 Juni 2019, 17:00:14 »
Hi,

Zitat
attr m2d readingList tele/sonoff/SENSOR:.* { json2nameValue($EVENT, 'SENSOR_', $JSONMAP) }
Könntest du dazu ein beispielhaftes JSON posten, und welches Ergebnis am Ende rauskommt?
Ich habe zwar eine Idee, bin aber unsicher, ob die Idee durch Hoffnung nicht in meine Denkrichtung beeinflusst wurde  ;)

VG,
Dirk

Offline Beta-User

  • Developer
  • Hero Member
  • ****
  • Beiträge: 7591
  • eigentlich eher user wie "developer"
Antw:customReadings mit JSON-Pointer?
« Antwort #5 am: 27 Juni 2019, 17:21:07 »
Boah, schwierig...

Der tatsächlich einzige Typ Hardware, wo das derzeit zum Einsatz kommt, ist meines Wissens der ebusd.

In diesem Beitrag https://forum.fhem.de/index.php/topic,97989.msg913625.html#msg913625 ist auch ein Beispiel, allerdings ohne passendes Attribut für $JSONMAP, das ist da nicht gesetzt (es werden allso die sich aus dem JSON ergebenden Reading-Namensteile genommen). Es gibt auch irgendwo (link müßte über den ebus-mqtt-Teil im Wiki zu finden sein) ein template-File von TomLee (?), wo das effektiv gemacht wird (ich bekomme da leider keine weitere Zuarbeit, hab's mehrfach erfolglos versucht, aber auf die Festlegung von Readingnamen wollte keiner Einsteigen ;D ...)

Was ich verstanden habe: das erste Argument ist der eigentliche JSON, das zweite ein Präfix (kann auch leer bleiben), mit dem dann jeder Readingname beginnt und hinten ist dann das mapping (Format wie in cref beim Attribut? Bitte ggf. in den MQTT2_DEVICE-Code schauen oder Rudi bitten, das zu erläutern; $JSONMAP muß ja irgendwo gefüllt werden, und zwar pro Device...).

Ich würde empfehlen, da einfach (ggf. mit einem MQTT2_DEVICE und MQTT2_SERVER auf einem Testsystem) etwas rumprobieren (publish dann z.B. mit mosquitto_pub, da kannst du die JSON-Blobs dann recht einfach reinwerfen und auch mehrere MQTT2_DEVICEs auf denselben Topic lauschen lassen...), damit du ein Gefühl dafür bekommst (so habe ich das auch versucht); der Mechanismus an sich ist nicht besonders schwer zu verstehen.
Server: HP-T620@Debian 10, aktuelles FHEM + ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN
svn:MySensors, WeekdayTimer, AttrTemplate => {mqtt2, mysensors, httpmod}

Offline rudolfkoenig

  • Administrator
  • Hero Member
  • *****
  • Beiträge: 20886
Antw:customReadings mit JSON-Pointer?
« Antwort #6 am: 27 Juni 2019, 19:18:26 »
Zitat
Boah, schwierig...

Stimmt gar nicht :)
defmod m2test MQTT2_DEVICE
attr m2test IODev m2s
attr m2test readingList tele/sonoff/SENSOR:.* { Log 1, $EVENT;; json2nameValue($EVENT, 'SENSOR_', $JSONMAP) }

setstate m2test 2019-06-27 19:15:15 SENSOR_AM2301_Humidity 31.1
setstate m2test 2019-06-27 19:15:15 SENSOR_AM2301_Temperature 6.7
setstate m2test 2019-06-27 19:15:15 SENSOR_TempUnit C
setstate m2test 2019-06-27 19:15:15 SENSOR_Time 2019-06-27T18:15:15
Log:
Zitat
2019.06.27 19:15:15.990 1: {"Time":"2019-06-27T18:15:15","AM2301":{"Temperature":6.7,"Humidity":31.1},"TempUnit":"C"}

Offline Wuehler

  • Developer
  • Sr. Member
  • ****
  • Beiträge: 571
Antw:customReadings mit JSON-Pointer?
« Antwort #7 am: 28 Juni 2019, 08:47:01 »
Vielen Dank. Hatte geblendet durch Hoffnung tatsächlich etwas anderes verstanden, da ich mqtt bisher nicht nutze. Habe den ersten Teil (tele/sonoff/SENSOR) nicht als Topic erkannt, sondern dachte, dass es eine Einschränkung auf einen bestimmten json-Zweig ist.

In meinem Fall habe ich ein sehr umfangreiches JSON. Im ersten Post habe ich schon gekürzt, wenn man einen 48 Port- Switch zu Hause hat, kämen nur für die Ports knapp 2000 Readings zusammen.

Wenn ich den Code in json2nameValue() richtig verstanden habe könnte man durch weglassen von newReadingName in JsonMap Readings ausschließen. Diese Negativliste wäre dann vermutlich immer sehr umfangreich.
Könnte man die JsonMap auch als Positivliste verwenden, dann sollte ich das Recht ähnlich umsetzen können.

Gab es nicht auch schon mal eine Diskussion darüber, dass man per $defs($name)) per userreadings theoretisch alles zu einem Reading machen könnte, was im hash gespeichert ist? Dass das aber eigentlich nicht gern gesehen wird?
Wie wäre es, dazu Standardattribute zu haben: Der Modulautor kann im Hash definieren, welche internen Daten per readingList-Attribut erlaubt sind und der Anwender kann das jsonMap-Attribut verwenden, um nur ausgewählte zu bekommen.

Offline Beta-User

  • Developer
  • Hero Member
  • ****
  • Beiträge: 7591
  • eigentlich eher user wie "developer"
Antw:customReadings mit JSON-Pointer?
« Antwort #8 am: 28 Juni 2019, 09:14:23 »
Moin Dirk,

komme nochmal zurück auf das hier:
(Sorry, bin kein Perl-Experte, versuche aber mal meine unfertigen Gedanken dazu auszubreiten...)
json2nameValue() sollte hier an sich funktionieren, aber etwas anders als bei MQTT2_DEVICE verwendet werden, nämlich ohne die "0"-Option. Allerdings brauchst du dann vermutlich einen weiteren Durchlauf über den Rückgabewert von json2nameValue(), der nur die zusätzlich gesetzten newReading-keys in dem hash läßt und alles andere rauslöscht bzw. nur die in den Reading-Update-Prozess übergibt?
Soweit ich das für MQTT2_DEVICE verstanden hatte, füllt json2nameValue() nicht direkt die Readings (das passiert erst duch den jeweiligen Modulcode), sondern liefert einen Hash (?) mit key=>value-Paaren zurück. Den solltest du Nachbearbeiten/auf gewünschte Werte filtern können, ganz ähnlich wie bei anderen from-JSON-Mechanismen auch.

(@Rudi: Danke für die Klarstellung, ich hatte die Frage zunächst irgendwie mißverstanden und gedacht, Dirk sucht ein "isoliertes" Beispiel ohne MQTT2_DEVICE; mit ist es in der Tat sehr easy...)
Server: HP-T620@Debian 10, aktuelles FHEM + ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN
svn:MySensors, WeekdayTimer, AttrTemplate => {mqtt2, mysensors, httpmod}

Offline rudolfkoenig

  • Administrator
  • Hero Member
  • *****
  • Beiträge: 20886
Antw:customReadings mit JSON-Pointer?
« Antwort #9 am: 28 Juni 2019, 09:28:18 »
Zitat
Gab es nicht auch schon mal eine Diskussion darüber, dass man per $defs($name)) per userreadings theoretisch alles zu einem Reading machen könnte, was im hash gespeichert ist?
Das habe ich verpasst oder verdraengt.
Eine funktionierende Realisierung ist mAn weder einfach, noch performant (oder ich uebersehe etwas).
Weiterhin fehlt mir noch der (sinnvoll begruendete) Bedarf.

Zitat
Wie wäre es, dazu Standardattribute zu haben: Der Modulautor kann im Hash definieren, welche internen Daten per readingList-Attribut erlaubt sind und der Anwender kann das jsonMap-Attribut verwenden, um nur ausgewählte zu bekommen.
Kannst du das bitte mit anderen Worten formulieren: bei meinen Ratereien kommt nur fuer mich Unverstaendliches raus.

Zitat
Soweit ich das für MQTT2_DEVICE verstanden hatte, füllt json2nameValue() nicht direkt die Readings
Auf Wunsch von betateilchen gibt es eine json2reading Funktion, was json2nameValue + readingsBulkUpdate macht.
Wenn mehrere Module die Positivliste haben wollen, dann baue ich das ein.

Offline Beta-User

  • Developer
  • Hero Member
  • ****
  • Beiträge: 7591
  • eigentlich eher user wie "developer"
Antw:customReadings mit JSON-Pointer?
« Antwort #10 am: 28 Juni 2019, 10:32:02 »
Auf Wunsch von betateilchen gibt es eine json2reading Funktion, was json2nameValue + readingsBulkUpdate macht.
Wenn mehrere Module die Positivliste haben wollen, dann baue ich das ein.
Soll keine direkte Antwort sein, noch eine Aufforderung, da am Verhalten was zu ändern, aber eine Anmerkung zum "gefühlten" Verhalten von MQTT2_DEVICE:
Ich fand es schon immer irgenwie verwirrend, dass bei complex zwar dieser Parameter $JSONMAP auftaucht, aber dann das entsprechende Attribut nicht gefüllt wird. Da es dazu dann noch praktisch keine Beispiele gibt, findet das dann auch wenig Anwendung... (klar, die cref ist eigentlich eindeutig, und mit etwas Rumspielen wird es auch schnell klar und einfach).

Logischer hätte ich gefunden, wenn das entsprechende Attribut dann angelegt worden wäre, wenn es nicht vorhanden ist. Und zwar mit an sich "doofen/unnötigen" readingname1:readingname1-usw.-Mappings. Der user hätte es dann in der Hand, durch schlichtes Löschen die Readings rauszuwerfen, die er nicht braucht.
Es ist schon klar, dass das gravierende anderen Nachteile hätte, aber entweder will der user was mappen (und nutzt complex), oder der einfache Mechanismus reicht (simple). Denkweise dabei: Will der Anwender was mappen, weiß er (hoffentlich) auch, was er da tut.
MQTT2_DEVICE ist da sicher speziell, weil man da tendenziell alles "verwerten" will, aber z.B. bei HTTPMOD muß man auch angeben, was man haben will (das könnte man evtl. durch so eine Positiv-Listen-Denke auch einfacher zu konfigurieren machen, aber bitte: das ist von sehr weit weg geschossen und kann auch ganz falsch sein...)
Server: HP-T620@Debian 10, aktuelles FHEM + ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN
svn:MySensors, WeekdayTimer, AttrTemplate => {mqtt2, mysensors, httpmod}

Offline betateilchen

  • Developer
  • Hero Member
  • ****
  • Beiträge: 16063
  • s/fhem\.cfg/configDB/g
Antw:customReadings mit JSON-Pointer?
« Antwort #11 am: 28 Juni 2019, 14:04:33 »
Auf Wunsch von betateilchen gibt es eine json2reading Funktion, was json2nameValue + readingsBulkUpdate macht.

wofür ich nach wie vor sehr dankbar bin :)
-----------------------
Unaufgeforderte Anfragen per email werden von mir nicht beantwortet. Dafür ist das Forum da.
-----------------------
Nächster Hamburg Stammtisch am 20.09.2019

Offline Wuehler

  • Developer
  • Sr. Member
  • ****
  • Beiträge: 571
Antw:customReadings mit JSON-Pointer?
« Antwort #12 am: 01 Juli 2019, 21:46:12 »
Danke für die Diskussion bis hierher. War gerade in Urlaubsvorbereitung, bald gehts los, daher die späte Antwort.

Fasse für mich folgendes zusammen:
- readingsList ist ein spezielles Attribut aus mqtt2, mit dem das JSON aus einem Topic in Readings gewandelt werden kann
- json2nameValue() klopft das Json-Format platt, Unterstrukturen werden mit _ verbunden
- jsonMap wird als Attribut verwendet, um den aus JSON generierten Readings besser Namen zu verpassen und kann als Negativliste bei weglassen des newReadingName verwendet werden

Ich brauche:
- jsonFilter als Attribut, damit nicht aus jedem json-Feld ein Reading erstellt wird, sondern der User sich die Werte gezielt aussuchen kann.
- nicht performat, aber möglich wäre: json2nameValue() nutzen, um eine Map zu bekommen mit potentiellen Readings. Darauf jsonFilter anwenden, um nur die gewollten durchzulassen

Nicht ganz glücklich bin ich mit der Verwendung des Unterstrich zur Konkatenation und der damit verbundenen etwas unleserlichen Addressierung eines bestimmten Feldes im JSON. Ich würde da den JSON::Pointer irgendwie vorziehen. Da könnte man in der Doku auch drauf verweisen. Wenn es dagegen eure Meinung ist, den Unterstrich besser zu nutzen, um Ähnlichkeit in FHEM zu bekommen mache ich das auch gerne.

Viele Grüße,
Dirk

Offline Beta-User

  • Developer
  • Hero Member
  • ****
  • Beiträge: 7591
  • eigentlich eher user wie "developer"
Antw:customReadings mit JSON-Pointer?
« Antwort #13 am: 02 Juli 2019, 07:25:25 »
Im Prinzip m.E. eine gute Zusammenfassung. Zwei Anmerkungen:
- Als Negativliste dient $JSONMAP nur dann, wenn value im key:value-Paar "0" ist. Weglassen des newReadingName dürfte nicht diesen Effekt haben (kann aber sein, dass die Vorbehandlung der Daten aus dem Attribut doch zu diesem Ergebnis führt, und das MQTT2_DEVICE-spezifisch ist; das habe ich mir im Code nocht angesehen).

- M.E. ist das mit dem Unterstrich beim Auspacken von Unterstrukturen zwar häufig nicht erforderlich, aber der sichere Weg, eindeutige Readingnamen zu haben. Da aber der Mechanismus immer derselbe ist, könntest du in der Nachbearbeitung ja nach "desiredReading" _und_ ".+_desiredReading" filtern (und im letzteren Fall nochmal umpacken). Dann braucht es den User nicht zu kümmern, aus welcher Ebene das gewünschte Reading stammt. Und da er in dieser Positivlisten-Denke sowieso nie den "Unterstrichnamen" zu sehen bekommt, kann er nehmen, was er im JSON sieht (oder es drauf anlegen, wenn er weiß, wie der Mechanismus funktioniert...).

Aber wie bisher auch: kann auch falsch sein, was ich dazu schreibe.

Jedenfalls schönnen Urlaub.
Server: HP-T620@Debian 10, aktuelles FHEM + ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN
svn:MySensors, WeekdayTimer, AttrTemplate => {mqtt2, mysensors, httpmod}

Offline Wuehler

  • Developer
  • Sr. Member
  • ****
  • Beiträge: 571
Antw:customReadings mit JSON-Pointer?
« Antwort #14 am: 02 Juli 2019, 08:42:19 »
Vermutlich mache ich mir zu viele Gedanken über die Tiefe von Json-Strukturen. In der Regel sind es maximal zwei Ebenen, manchmal auch drei. In meinem konkreten Fall würde im Extremfall folgendes Reading herauskommen:
port_table_lldp_table_lldp_system_name
Und da glaube ich nicht, dass das jemand als Reading braucht.

Dann muss ich mir noch mal ansehen wie json2nameValue() mit Arrays umgeht. Nicht dass es immer nur für den letzten Port eines Switches Readings gibt.

Zitat
Jedenfalls schönnen Urlaub
Danke. Morgen gehts los. Daher ruht dieser Thread für mich die nächste Zeit.

 

decade-submarginal