Generisches MQTT2 device, readings von json2namevalue umbenennen.

Begonnen von tomleitner, 18 Dezember 2018, 20:47:34

Vorheriges Thema - Nächstes Thema

tomleitner

Hallo,

Ich habe einen NEDAP Powerrouter als Wechselrichter für meine Photovoltaik Anlage. Dieser schickt jede Minute einen JSON String in die Cloud. Diesen habe ich nun per pfSense Firewall und tcpdump abgefangen und per mosquitto_pub nach MQTT2 transferriert und so ins FHEM gebracht. Das Problem ist: Die Werte im JSON string sind nicht wirklich aussagekräftig und ich muss noch die Zuordnung zwischen den JSON Variablen und den tatsächlichen Bedeutungen herausfinden.  Danach wird es notwendig sein die Readings die ja per json2namevalue erzeugt wurden entsprechend aussagekräftig umzubenennen.

Hier mein Device:
define Powerrouter MQTT2_DEVICE powerrouter
attr Powerrouter IODev MQTT2_Server
attr Powerrouter readingList powerrouter/state:.* { json2nameValue($EVENT, '') }
attr Powerrouter room MQTT,Powerrouter


Hier ein MQTT JSON Eintrag per mosquitto_sub mitgeschnitten:
powerrouter/state {"header":{"powerrouter_id":"99999999","time_send":"2018-12-18T21:40:06+00:00","version":3,"period":60},"module_statuses":[{"module_id":16,"status":24595,"version":1,"param_0":4999,"param_1":2255,"param_2":230,"param_3":4009,"param_4":1121000,"param_5":24810001},{"module_id":9,"status":1041,"version":1,"param_0":0,"param_1":0,"param_2":0,"param_3":7665221,"param_4":99803,"param_5":0,"param_6":0,"param_7":3635,"param_8":0,"param_9":0,"param_10":0},{"module_id":136,"status":88883457,"version":1,"param_0":0,"param_1":0,"param_2":0,"param_3":2492025,"param_4":3109228,"param_5":100,"param_6":0,"param_7":226,"param_8":254,"param_9":2720,"param_10":11700,"param_11":2200,"param_12":11635},{"module_id":12,"status":17,"version":1,"param_0":0,"param_1":0,"param_2":0,"param_3":4725739,"param_4":0,"param_5":0,"param_6":0,"param_7":0,"param_8":4935256,"param_9":0,"param_10":0,"param_11":9660995},{"module_id":11,"status":1811,"version":1,"param_0":2254,"param_1":719,"param_2":1575,"param_3":18662100,"param_4":2278,"param_5":438,"param_6":955,"param_7":14895300,"param_8":2247,"param_9":704,"param_10":1479,"param_11":26243900}]}


und im Screenshot im Anhang sieht man welche Readings daraus werden.

Frage also: Nachdem ich herausgefunden habe, welcher module_statuses_xxxxx genaue was bedeutet, wie kann ich die readings in dazugehörige vernünftige Namen umbenennen?  Beispiel: "power_total" oder "state_of_charge" etc.?

Danke....

Tom

Wuppi68

tacker mich mal hier an, weil ich ein ähnliches Problem habe ;-)
Jetzt auf nem I3 und primär Homematic - kein Support für cfg Editierer

Support heißt nicht wenn die Frau zu Ihrem Mann sagt: Geh mal bitte zum Frauenarzt, ich habe Bauchschmerzen

OdfFhem

Standardlösung wäre hier wohl https://wiki.fhem.de/wiki/UserReadings.

Angesichts der großen Zahl der erzeugten Readings bleibt es fraglich, ob es Sinn macht, das angelieferte JSON-Konstrukt automatisch aufsplitten zu lassen, um dann anschließend die erzeugten Readings durch "Umbenennen" zu verdoppeln.

Alternativ könnte man das JSON-Konstrukt als ein 1:1-Reading anlegen lassen und anschließend über eine myUtils-Routine selbst aufsplitten und ohne Verdopplung direkt in Readings mit den gewünschten Namen umwandeln ...

Auch möglich wäre die automatische Aufsplittung und eine myUtils-Sub, der ich einen geschönten Namen übergebe und die mir dann den dazu passenden Wert aus den unschönen Readings liefert - quasi ein ReadingsVal-Ersatz ...

Vielleicht hat aber auch jemand anders noch eine viel einfachere Lösung ...

Beta-User

Warum nicht dazu eine ReadingsGroup anlegen? Damit lassen sich entsprechende Label vergeben und auch Infos aus unterschiedlichen Quellen mischen (letzteres brauchst du hier nicht).

Beispiel für eine Tabelle mit drei Spalten:
defmod rgTemperaturen_Heizung readingsGroup <%temp_temperature>,<Vorlauf>,<Rücklauf> MYSENSOR_96:,<Hauptleitung>,temperature24,temperature23 \
MYSENSOR_98:,<Altbau_allg.>,temperature27,temperature28 \
MYSENSOR_98:,<Neubau_allg.>,temperature23,temperature22 \
MYSENSOR_98:,<Bodenkonvektor>,temperature23,temperature24\
MYSENSOR_98:,<Bad>,temperature25,temperature26 \
MYSENSOR_96:,<Schlafzimmer>,temperature27,temperature26 \
MYSENSOR_98:,<WZ_Ost>,temperature29,temperature30 \
MYSENSOR_98:,<WZ_West>,temperature27,temperature31

Gruß, Beta-User
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

tomleitner

Danke für Eure Antworten. Die Idee mit der readingsGroup hatte ich auch schon .... ist es damit möglich aber auch, gleich wie bei einem normalen Device, Plots zu machen, Events auszulösen etc?

Einen andere Idee hatte ich soeben: Ich könnte die JSON Daten ja in meinem Bash Script schon parsen und als einzelne Werte, die im Bash ja viel leichter umzubenennen sind, ins MQTT2 schreiben. Dazu gibts für die CMD Line folgende Software:

https://stedolan.github.io/jq/

die das ermöglichen sollte.. allerdings noch nicht ausprobiert obs auch geht. Aber in Perl gibt es sicher auch einfache Lösungen. Und wenn ich die Readings mal als Liste im Bash habe ist eine Umbenennung von Variablen sehr leicht.


tomleitner

Hier eine Lösung mit Python um den JSON String "grep" freundlich zu machen und einzelne Variablen ins MQTT2 zu schreiben:

pi@fhem ~ $ cat test.dat
{"header":{"powerrouter_id":"99999999","time_send":"2018-12-18T21:40:06+00:00","version":3,"period":60},"module_statuses":[{"module_id":16,"status":24595,"version":1,"param_0":4999,"param_1":2255,"param_2":230,"param_3":4009,"param_4":1121000,"param_5":24810001},{"module_id":9,"status":1041,"version":1,"param_0":0,"param_1":0,"param_2":0,"param_3":7665221,"param_4":99803,"param_5":0,"param_6":0,"param_7":3635,"param_8":0,"param_9":0,"param_10":0},{"module_id":136,"status":88883457,"version":1,"param_0":0,"param_1":0,"param_2":0,"param_3":2492025,"param_4":3109228,"param_5":100,"param_6":0,"param_7":226,"param_8":254,"param_9":2720,"param_10":11700,"param_11":2200,"param_12":11635},{"module_id":12,"status":17,"version":1,"param_0":0,"param_1":0,"param_2":0,"param_3":4725739,"param_4":0,"param_5":0,"param_6":0,"param_7":0,"param_8":4935256,"param_9":0,"param_10":0,"param_11":9660995},{"module_id":11,"status":1811,"version":1,"param_0":2254,"param_1":719,"param_2":1575,"param_3":18662100,"param_4":2278,"param_5":438,"param_6":955,"param_7":14895300,"param_8":2247,"param_9":704,"param_10":1479,"param_11":26243900}]}
pi@fhem ~ $ python -mjson.tool <test.dat
{
    "header": {
        "period": 60,
        "powerrouter_id": "99999999",
        "time_send": "2018-12-18T21:40:06+00:00",
        "version": 3
    },
    "module_statuses": [
        {
            "module_id": 16,
            "param_0": 4999,
            "param_1": 2255,
            "param_2": 230,
            "param_3": 4009,
            "param_4": 1121000,
            "param_5": 24810001,
            "status": 24595,
            "version": 1
        },
....
....


Ich werde wohl das benutzen und etwas Bash scripten ...

rudolfkoenig

Ich habe json2nameValue mit einem optionalen map Parameter erweitert, damit man die generierten Namen einfacher umbenennen kann.
Weiterhin habe ich MQTT2_DEVICE mit einem jsonMap Attribut erweitert, wo man dieses map fuellen kann.

Der commandref Eintrag:

ZitatjsonMap 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.

tomleitner

.... na das ist ja genial!!! :) Vielen Dank. Werde es gleich  ausprobieren!!!

Danke und schöne Grüße // Tom

tomleitner

.... leider gibts nun ein Problem:

2018.12.20 11:02:00 1: ERROR evaluating my $NAME='TPSW2';my $EVTPART8='8';my $EVTPART7='7';my $EVTPART6='6';my $DEVICETOPIC='TPSW2';my $EVTPART3='3';my $EVTPART5='5';my $EVENT='0 1 2 3 4 5 6 7 8 9';my $EVTPART4='4';my $EVTPART9='9';my $TOPIC='1';my $EVTPART1='1';my $EVTPART0='0';my $EVTPART2='2';my $JSONMAP='';{return undef; { json2nameValue($EVENT, 'UPTIME_', $JSONMAP) }}: Too many arguments for main::json2nameValue at (eval 3750) line 1, near "$JSONMAP) "

2018.12.20 11:02:00 3: Too many arguments for main::json2nameValue at (eval 3750) line 1, near "$JSONMAP) "

2018.12.20 11:13:37 1: PERL WARNING: Deep recursion on subroutine "main::eObj" at fhem.pl line 5000.
2018.12.20 11:13:37 3: eval: my $EVTPART0='{"header":{"powerrouter_id":"9561773H426B8716","time_send":"2018-12-20T12:12:06+00:00","version":3,"period":60},"module_statuses":[{"module_id":16,"status":26899,"version":1,"param_0":5000,"param_1":2279,"param_2":240,"param_3":525,"param_4":1121000,"param_5":24900916},{"module_id":9,"status":7955,"version":1,"param_0":5001,"param_1":2291,"param_2":47,"param_3":7666135,"param_4":99874,"param_5":2256,"param_6":0,"param_7":3635,"param_8":39983,"param_9":46,"param_10":315},{"module_id":136,"status":116540227,"version":1,"param_0":2544,"param_1":0,"param_2":0,"param_3":2492026,"param_4":3110362,"param_5":99,"param_6":3000,"param_7":220,"param_8":494,"param_9":2880,"param_10":11700,"param_11":2200,"param_12":11647},{"module_id":12,"status":49219,"version":1,"param_0":19646,"param_1":9,"param_2":18,"param_3":4726980,"param_4":410,"param_5":15707,"param_6":11,"param_7":17,"param_8":4936707,"param_9":290,"param_10":36,"param_11":9663687},{"module_id":11,"status":1811,"version":1,"param_0":2283,"param_1":95,"param_2":193,"param_3":18687100,"param_4":2287,"param_5":121,"param_6":174,"param_7":14912000,"param_8":2273,"param_9":103,"param_10":158,"param_11":26293300}';my $TOPIC='powerrouter/state';my $NAME='Powerrouter';my $JSONMAP='$defs{Powerrouter}{JSONMAP}';my $EVENT='{"header":{"powerrouter_id":"9561773H426B8716","time_send":"2018-12-20T12:12:06+00:00","version":3,"period":60},"module_statuses":[{"module_id":16,"status":26899,"version":1,"param_0":5000,"param_1":2279,"param_2":240,"param_3":525,"param_4":1121000,"param_5":24900916},{"module_id":9,"status":7955,"version":1,"param_0":5001,"param_1":2291,"param_2":47,"param_3":7666135,"param_4":99874,"param_5":2256,"param_6":0,"param_7":3635,"param_8":39983,"param_9":46,"param_10":315},{"module_id":136,"status":116540227,"version":1,"param_0":2544,"param_1":0,"param_2":0,"param_3":2492026,"param_4":3110362,"param_5":99,"param_6":3000,"param_7":220,"param_8":494,"param_9":2880,"param_10":11700,"param_11":2200,"param_12":11647},{"module_id":12,"status":49219,"version":1,"param_0":19646,"param_1":9,"param_2":18,"param_3":4726980,"param_4":410,"param_5":15707,"param_6":11,"param_7":17,"param_8":4936707,"param_9":290,"param_10":36,"param_11":9663687},{"module_id":11,"status":1811,"version":1,"param_0":2283,"param_1":95,"param_2":193,"param_3":18687100,"param_4":2287,"param_5":121,"param_6":174,"param_7":14912000,"param_8":2273,"param_9":103,"param_10":158,"param_11":26293300}';my $DEVICETOPIC='Powerrouter';{ json2nameValue($EVENT) }


das war gestern noch nicht?

rudolfkoenig

Zitat2018.12.20 11:02:00 3: Too many arguments for main::json2nameValue at (eval 3750) line 1, near "$JSONMAP) "
Dein fhem.pl ist nicht aktuell

Zitat2018.12.20 11:13:37 1: PERL WARNING: Deep recursion on subroutine "main::eObj" at fhem.pl line 5000.
Die input-Daten sind kaputt (abgeschnitten, das Array wird nie zugemacht).
Das habe ich jetzt gefixt: Es wird nichts zurueckgeliefert, und auf "attr global verbose 4" ein Fehler gemeldet.
Mit diesem Input hat man die Endlosschleife auch vor den gestrigen Aenderungen bekommen.

tomleitner

Alles,klar. Danke.
Fehler ist nun weg nach einem Update.
Schöne Grüße....