Shell-Command ausführen und JSON-Response in Readings anbieten?

Begonnen von bgewehr, 14 Januar 2018, 12:40:43

Vorheriges Thema - Nächstes Thema

bgewehr

Hallo,

habe ein python-Script, welches über CarNet mein Auto auslesen (und hoffentlich bald auch Befehle senden kann)!

Aufruf per CMDline und Antwort als JSON:


python vw_carnet_web.py retrieveCarNetInfo

/-/vehicle-info/get-vehicle-details
{"vehicleDetails":{"lastConnectionTimeStamp":["14.01.2018","11:05"],"distanceCovered":"8.657","range":"300","serviceInspectionData":"630 Tag(e) / 21.400 km","oilInspectionData":"630 Tag(e) / 21.400 km","showOil":true,"showService":true,"flightMode":false},"errorCode":"0"}



Welches fhem-Modul könnte ich dafür nehmen, um mein Auto auf diese Weise als device zu integrieren?
FritzBox 7590, Synology DS216+II mit Docker
Docker: FHEM mit hmlan, Homebridge, node-red, mosquitto, ems-collector für Buderus EMS mit AVR Net-IO
Gartenwasser über MQTT auf R/Pi A+
Volkszaehler.org auf R/Pi 2B mit Pi_Erweiterung
Raspberrymatic auf R/Pi 4B mit RPI-RF-MOD u. CUL868

KernSani

Schau dir mal HTTPMOD an. Du kannst aber auch mal im Forum suchen, da gibt es ein paar Beiträge zu CarNet.
RasPi: RFXTRX, HM, zigbee2mqtt, mySensors, JeeLink, miLight, squeezbox, Alexa, Siri, ...

bgewehr

httpmod ist ja an sich ganz gut, ich bräuchte aber shellCommandMod...

Mit

define on_testdummy_act testdummy.* {
my $result='python /home/bananapi/carnet/volkswagen-carnet-client/vw_carnet_web.py retrieveCarNetInfo';;
set testdummywert = $result;;
}


bekomme ich jedenfalls nicht das stdout des scriptaufrufes in testdummywert, sondern nichts.

Was mache ich falsch?
FritzBox 7590, Synology DS216+II mit Docker
Docker: FHEM mit hmlan, Homebridge, node-red, mosquitto, ems-collector für Buderus EMS mit AVR Net-IO
Gartenwasser über MQTT auf R/Pi A+
Volkszaehler.org auf R/Pi 2B mit Pi_Erweiterung
Raspberrymatic auf R/Pi 4B mit RPI-RF-MOD u. CUL868

CoolTux

https://perldoc.perl.org/functions/qx.html
http://www.perlmonks.org/?node_id=928192

Ausserdem geht der set Befehl auf Perlebene nicht. Du musst dazu die Funktion fhem() aufrufen und den gesamten Befehl, also Set bla bla als Wert übergeben.
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

bgewehr

Super, das hat nun geklappt:


testdummy.* {
my $result = qx "python /home/bananapi/carnet/volkswagen-carnet-client/vw_carnet_web.py retrieveCarNetInfo";;
fhem "set testdummywert = $result";;
}


Nun nur noch den JSON parsen...
FritzBox 7590, Synology DS216+II mit Docker
Docker: FHEM mit hmlan, Homebridge, node-red, mosquitto, ems-collector für Buderus EMS mit AVR Net-IO
Gartenwasser über MQTT auf R/Pi A+
Volkszaehler.org auf R/Pi 2B mit Pi_Erweiterung
Raspberrymatic auf R/Pi 4B mit RPI-RF-MOD u. CUL868

CoolTux

Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

bgewehr

Ich habe es jetzt mal nach einem fhem Update mit expandJSON versucht, dabei stürzt mir aber immer das ganze fhem so dermaßen ab, dass ich es nur mit einem kompletten reboot wiederbeleben kann.

sudo killall perl geht nicht, sudo systemctl stop fhem ebenfalls nicht, nur sudo reboot bringt was...

Das Modul wirkt eigentlich super, aber vielleicht scheitert es auch an der Struktur meines JSON:


{"vehicleDetails":{"lastConnectionTimeStamp":["14.01.2018","16:56"],"distanceCovered":"8.677","range":"250","serviceInspectionData":"629 Tag(e) / 21.400 km","oilInspectionData":"629 Tag(e) / 21.400 km","showOil":true,"showService":true,"flightMode":false},"errorCode":"0"}
FritzBox 7590, Synology DS216+II mit Docker
Docker: FHEM mit hmlan, Homebridge, node-red, mosquitto, ems-collector für Buderus EMS mit AVR Net-IO
Gartenwasser über MQTT auf R/Pi A+
Volkszaehler.org auf R/Pi 2B mit Pi_Erweiterung
Raspberrymatic auf R/Pi 4B mit RPI-RF-MOD u. CUL868

CoolTux

Warum machst du es nicht mit encode_json? Ruf es innerhalb eines evals auf dann stürzt auch FHEM nicht ab.
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

dev0

@bgewehr:
Ich hab es mit Deinem JSON String getestet und kein Problem:

define d dummy

define j expandJSON d:json:.*

setreading d json {"vehicleDetails":{"lastConnectionTimeStamp":["14.01.2018","16:56"],"distanceCovered":"8.677","range":"250","serviceInspectionData":"629 Tag(e) / 21.400 km","oilInspectionData":"629 Tag(e) / 21.400 km","showOil":true,"showService":true,"flightMode":false},"errorCode":"0"}

list d
Internals:
   CFGFN     
   NAME       d
   NR         749
   STATE      ???
   TYPE       dummy
   READINGS:
     2018-01-16 17:44:49   errorCode       0
     2018-01-16 17:44:49   json            {"vehicleDetails":{"lastConnectionTimeStamp":["14.01.2018","16:56"],"distanceCovered":"8.677","range":"250","serviceInspectionData":"629 Tag(e) / 21.400 km","oilInspectionData":"629 Tag(e) / 21.400 km","showOil":true,"showService":true,"flightMode":false},"errorCode":"0"}
     2018-01-16 17:44:49   vehicleDetails_distanceCovered 8.677
     2018-01-16 17:44:49   vehicleDetails_oilInspectionData 629 Tag(e) / 21.400 km
     2018-01-16 17:44:49   vehicleDetails_range 250
     2018-01-16 17:44:49   vehicleDetails_serviceInspectionData 629 Tag(e) / 21.400 km



Es werden allerdings nur die JSON Objekte und nicht die Arrays dekodiert. Arrays habe ich noch nicht implementiert, wenn dann würde ich vermutlich auch nur den vollständigen Array-String in das jeweilige Reading schreiben. Sonst müßte das Modul raten, in welcher Reihenfolge...

@CoolTux: expandJSON ruft decode_json in einem eval auf.

bgewehr

Hab Perl 5.20 und JSON per cpan installiert. Muss ich sonst noch was berücksichtigen?
FritzBox 7590, Synology DS216+II mit Docker
Docker: FHEM mit hmlan, Homebridge, node-red, mosquitto, ems-collector für Buderus EMS mit AVR Net-IO
Gartenwasser über MQTT auf R/Pi A+
Volkszaehler.org auf R/Pi 2B mit Pi_Erweiterung
Raspberrymatic auf R/Pi 4B mit RPI-RF-MOD u. CUL868

dev0

Nein, nicht das ich wüsste. Es sind die gleichen Voraussetzungen wie bei Dienem 70_JSONREADINGS.pm Modul. Die Core-Routine beruht ja auch auf Deinem toReadings(), wenn auch etwas angepasst...

bgewehr

Mit Verbose 5 become ich folgendes Ergebnis kurz vor dem endgültigen Absturz (oder einer Schleife, das Ding ist nur mit Neustart wiederzubeleben):


018.01.17 18:14:31 5: expandJSON testdummyexpand: Yield decode: HASH(0x3010ad0) | testdummywert | json | {"vehicleDetails":{"lastConnectionTimeStamp":["17.01.2018","18:06"],"distanceCovered":"9.013","range":"890","serviceInspectionData":"626 Tag(e) / 21.000 km","oilInspectionData":"626 Tag(e) / 21.000 km","showOil":true,"showService":true,"flightMode":false},"errorCode":"0"}
FritzBox 7590, Synology DS216+II mit Docker
Docker: FHEM mit hmlan, Homebridge, node-red, mosquitto, ems-collector für Buderus EMS mit AVR Net-IO
Gartenwasser über MQTT auf R/Pi A+
Volkszaehler.org auf R/Pi 2B mit Pi_Erweiterung
Raspberrymatic auf R/Pi 4B mit RPI-RF-MOD u. CUL868

bgewehr

#12
Also: das expandJSON funktioniert, aber nicht dann wenn zuvor ein notify den JSON-Wert an das Dummy-Device geliefert hat. Löse ich durch Modifikation des State readings per set dummy 1 schon das notify aus, welches vom expandJSON erzeugt wird? Dann jedenfalls wird der String sauber in Readings zerlegt.

Also ist mein Problem mit knallhartem, blockierenden Absturz von FHEM eine Kombination aus meinem setreading im Notify und dem Notify im expandJSON. Beide Komponenten für sich arbeiten einwandfrei, in der Kombination dann der Absturz.

Irgendwelche Ideen?
FritzBox 7590, Synology DS216+II mit Docker
Docker: FHEM mit hmlan, Homebridge, node-red, mosquitto, ems-collector für Buderus EMS mit AVR Net-IO
Gartenwasser über MQTT auf R/Pi A+
Volkszaehler.org auf R/Pi 2B mit Pi_Erweiterung
Raspberrymatic auf R/Pi 4B mit RPI-RF-MOD u. CUL868

dev0

Kann ich nicht nachstellen:

define d dummy
define t dummy
define j expandJSON d:json:.*
define n notify t setreading d json {"vehicleDetails":{"lastConnectionTimeStamp":["17.01.2018","18:06"],"distanceCovered":"9.013","range":"890","serviceInspectionData":"626 Tag(e) / 21.000 km","oilInspectionData":"626 Tag(e) / 21.000 km","showOil":true,"showService":true,"flightMode":false},"errorCode":"0"}
trigger t on

list d
...
   READINGS:
     2018-01-18 08:20:00   errorCode       0
     2018-01-18 08:20:00   json            {"vehicleDetails":{"lastConnectionTimeStamp":["17.01.2018","18:06"],"distanceCovered":"9.013","range":"890","serviceInspectionData":"626 Tag(e) / 21.000 km","oilInspectionData":"626 Tag(e) / 21.000 km","showOil":true,"showService":true,"flightMode":false},"errorCode":"0"}
     2018-01-18 08:20:00   vehicleDetails_distanceCovered 9.013
     2018-01-18 08:20:00   vehicleDetails_oilInspectionData 626 Tag(e) / 21.000 km
     2018-01-18 08:20:00   vehicleDetails_range 890
     2018-01-18 08:20:00   vehicleDetails_serviceInspectionData 626 Tag(e) / 21.000 km


Funktioniert das Beispiel bei Dir?
Falls das gezeigte Beispiel nicht dem entspricht was Du meintest, dann bitte etwas Nachstellbares (mit Dummies) posten, damit ich es untersuchen kann.

ZitatLöse ich durch Modifikation des State readings per set dummy 1 schon das notify aus, welches vom expandJSON erzeugt wird?
Das hängt von der regex des expandJSON Device ab. Wenn Du wie in meinem Beispiel nur das Reading "json" angibst, dann nicht.

Sind Deine fhem.pl / 91_notify.pm halbwegs aktuell?

bgewehr

fhem.pl und der Rest sind von einem Update von Vorgestern.

Ich glaube, die Sache mit dem Python Script macht den Unterschied:


define on_testdummy_act testdummy.* {
my $result = qx "python /home/bananapi/carnet/volkswagen-carnet-client/vw_carnet_web.py retrieveCarNetInfo";;
fhem "set testdummywert = $result";;
}


Ich baue mal einen weiteren dummy "data_changed" dazwischen und triggere davon den expandJSON.
FritzBox 7590, Synology DS216+II mit Docker
Docker: FHEM mit hmlan, Homebridge, node-red, mosquitto, ems-collector für Buderus EMS mit AVR Net-IO
Gartenwasser über MQTT auf R/Pi A+
Volkszaehler.org auf R/Pi 2B mit Pi_Erweiterung
Raspberrymatic auf R/Pi 4B mit RPI-RF-MOD u. CUL868

dev0

ZitatFunktioniert das Beispiel bei Dir?
Die Antwort steht noch aus.

Zitatdefine on_testdummy_act testdummy.* {
Da fehlt zumindest der Modulname im define.

Zitatfhem "set testdummywert = $result";;
Das "=" Zeichen würde dazu führen, dass das expandJSON Modul überhaupt nicht auf den Wert triggern würde.

Deine Angaben (lists, logs) sind zu ungenau bzw. nicht vorhanden, dass ich das ohne weitere exakte Angaben etwas analysieren kann...

bgewehr

Sorry für die schlechten inputs, ich versuche es oft unterwegs vom iPhone - mit mäßigem Ergebnis.

Das Beispiel von Dir funktioniert wie angegeben.

Zitat
define on_testdummy_act testdummy.* {
Da fehlt zumindest der Modulname im define.
Das war ein Kopierfehler von mir:


define act_on_testdummy notify testdummy.* {
my $result = qx "python /home/bananapi/carnet/volkswagen-carnet-client/vw_carnet_web.py getVehicleDetails";;
fhem "setreading testdummywert json $result";;
}

So ist der notify definiert.

Der epandJSON triggert NICHT, wenn ich set testdummy 1 ausführe, was ja auch richtig ist.
Hole ich aber den wert für json aus dem python Script, dann verklemmt sich fhem irgendwo so sehr, dass nur noch ein Neustart oder hartnäckiges sudo killall perl hilft.
FritzBox 7590, Synology DS216+II mit Docker
Docker: FHEM mit hmlan, Homebridge, node-red, mosquitto, ems-collector für Buderus EMS mit AVR Net-IO
Gartenwasser über MQTT auf R/Pi A+
Volkszaehler.org auf R/Pi 2B mit Pi_Erweiterung
Raspberrymatic auf R/Pi 4B mit RPI-RF-MOD u. CUL868

bgewehr

Ich habe das python script nun umgeschrieben und erhalte die carnet-Infos jetzt per MQTT alle 10 Minuten.

Dafür ist das expandJSON EIN HAMMER! es bildet mir aus den ca. 20 JSONs von Carnet so um die 200 Readings - ein Traum!

Danke, dev0!
FritzBox 7590, Synology DS216+II mit Docker
Docker: FHEM mit hmlan, Homebridge, node-red, mosquitto, ems-collector für Buderus EMS mit AVR Net-IO
Gartenwasser über MQTT auf R/Pi A+
Volkszaehler.org auf R/Pi 2B mit Pi_Erweiterung
Raspberrymatic auf R/Pi 4B mit RPI-RF-MOD u. CUL868

bgewehr

Hmmm.

Mein JSON ist brav nach key:value aufgeteilt, aber dennoch kommen values, die z.B. false sind, nicht korrekt durch:


{"errorCode":"0","timerCount":3,"remoteAuxiliaryHeating":
{"status":{"active":false,"operationMode":"HEATING","outdoorTemp":"9,5 °C","remainingTime":30},
"timers":[
{"timerId":1,"active":false,"weekDay":7,"time":{"hours":6,"minutes":40},"nextActivationDate":"29.01.2018"},
{"timerId":2,"active":false,"weekDay":1,"time":{"hours":6,"minutes":40},"nextActivationDate":"29.01.2018"},
{"timerId":3,"active":false,"weekDay":6,"time":{"hours":0,"minutes":0},"nextActivationDate":"03.02.2018"}
]}
}


"active":false,

wird ignoriert und weggelassen, obwohl es gültig ist.

Muss ich mal im Modul expandJSON nachschauen, warum. @Dev0, hilfst Du mir?
FritzBox 7590, Synology DS216+II mit Docker
Docker: FHEM mit hmlan, Homebridge, node-red, mosquitto, ems-collector für Buderus EMS mit AVR Net-IO
Gartenwasser über MQTT auf R/Pi A+
Volkszaehler.org auf R/Pi 2B mit Pi_Erweiterung
Raspberrymatic auf R/Pi 4B mit RPI-RF-MOD u. CUL868

CoolTux

Es kann sein das true und false als 0 und 1 gewandelt werden bei decode_json()
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

bgewehr

Ich fürchte, es ist schlimmer:

https://stackoverflow.com/questions/6792173/in-perl-checking-a-json-decoded-boolean-value


Part of the confusion probably comes from Perl itself - Perl does not have boolean types in the language. It only has truthiness.
FritzBox 7590, Synology DS216+II mit Docker
Docker: FHEM mit hmlan, Homebridge, node-red, mosquitto, ems-collector für Buderus EMS mit AVR Net-IO
Gartenwasser über MQTT auf R/Pi A+
Volkszaehler.org auf R/Pi 2B mit Pi_Erweiterung
Raspberrymatic auf R/Pi 4B mit RPI-RF-MOD u. CUL868

bgewehr

#21
Auf alle Fälle hier mal ein Zwischenstand.

Lesehilfe:


  • Die aktuelle Außentemperatur ist 12 Grad am Auto
  • Die Zieltemperatur ist immer 10, unwichtig
  • Der Modus der Standheizung ist HEATING, sie ist aber nicht aktiv ({"active":false} das ist ja mein aktuelles Problem)
  • Ich  kann noch 85 km mit dieser Tankfüllung fahren
  • Der Kilometerstand ist 10.203 km
  • in 614 Tagen oder 19.800 km ist Wartung angesagt
  • Es ist ein Arteon Elegance

FritzBox 7590, Synology DS216+II mit Docker
Docker: FHEM mit hmlan, Homebridge, node-red, mosquitto, ems-collector für Buderus EMS mit AVR Net-IO
Gartenwasser über MQTT auf R/Pi A+
Volkszaehler.org auf R/Pi 2B mit Pi_Erweiterung
Raspberrymatic auf R/Pi 4B mit RPI-RF-MOD u. CUL868

dev0

Zitat von: bgewehr am 29 Januar 2018, 21:18:55
Ich fürchte, es ist schlimmer:
https://stackoverflow.com/questions/6792173/in-perl-checking-a-json-decoded-boolean-value
Part of the confusion probably comes from Perl itself - Perl does not have boolean types in the language. It only has truthiness.
Ich komme im Moment nicht dazu mich dort einzuarbeiten. Artikel in dieser Art und auch die Doku zu JSON und JSON::XS haben mich nicht wirklich weiter gebracht um Dir ad hoc eine Lösung/Erweiterung zu bieten. Vielleicht verstehe ich die Formulierungen einfach auch nur nicht...

Kennt jemand anderes vielleicht die Lösung, wie man ein true/false als Text dekodieren lassen kann?

dev0

@bgewehr: Teste bitte mal die angehängte Version, die sollte true/false als 1/0 in das entsprechende Reading schreiben.

bgewehr

Perfekt - funktioniert.

Ich habe wieder 35 neue Readings, alle brav in 0 und 1.

Vielen Dank!
FritzBox 7590, Synology DS216+II mit Docker
Docker: FHEM mit hmlan, Homebridge, node-red, mosquitto, ems-collector für Buderus EMS mit AVR Net-IO
Gartenwasser über MQTT auf R/Pi A+
Volkszaehler.org auf R/Pi 2B mit Pi_Erweiterung
Raspberrymatic auf R/Pi 4B mit RPI-RF-MOD u. CUL868

bgewehr

Noch ein letzter Gedanke:

würde hier ein encode() der Ergebnisse helfen?


Höherweg 85 Düsseldorf 40233
FritzBox 7590, Synology DS216+II mit Docker
Docker: FHEM mit hmlan, Homebridge, node-red, mosquitto, ems-collector für Buderus EMS mit AVR Net-IO
Gartenwasser über MQTT auf R/Pi A+
Volkszaehler.org auf R/Pi 2B mit Pi_Erweiterung
Raspberrymatic auf R/Pi 4B mit RPI-RF-MOD u. CUL868

CoolTux

Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

dev0

@bgewehr: Magst Du das mal testen und berichten?

  eval { $h = decode_json(encode_utf8($dvalue)); 1; };

statt der jetzigen decode_json Zeile (~178)

bgewehr

Sieht gut aus:


Wir möchten Sie darüber informieren, dass Ihr Fahrzeug Bernd's Arteon am 02.02.2018 um 08:43 in das Gebiet das Dorf eingefahren ist.
FritzBox 7590, Synology DS216+II mit Docker
Docker: FHEM mit hmlan, Homebridge, node-red, mosquitto, ems-collector für Buderus EMS mit AVR Net-IO
Gartenwasser über MQTT auf R/Pi A+
Volkszaehler.org auf R/Pi 2B mit Pi_Erweiterung
Raspberrymatic auf R/Pi 4B mit RPI-RF-MOD u. CUL868

dev0

Kann ich dann so bei Gelegenheit einchecken? Ich hab's selbst nicht getestet.

Anbei das angepasste Modul. Vielleicht findest sich noch jemand der es auch testen mag.

Edit: angehängtes Modul entfernt

bgewehr

Inzwischen schlägt das throttling immer häufiger zu - und sperrt mich aus bis zur nächsten Fahrt:
FritzBox 7590, Synology DS216+II mit Docker
Docker: FHEM mit hmlan, Homebridge, node-red, mosquitto, ems-collector für Buderus EMS mit AVR Net-IO
Gartenwasser über MQTT auf R/Pi A+
Volkszaehler.org auf R/Pi 2B mit Pi_Erweiterung
Raspberrymatic auf R/Pi 4B mit RPI-RF-MOD u. CUL868

dev0


Morgennebel

Moin,


ich möchte diesen alten Thread wieder hervorkramen, da ich gerade damit meinen Speedport Hybrid eingebunden habe.

Jedoch bin ich noch nicht ganz glücklich: die JSON-Daten haben als Key sehr kurze, nichtssagende Schlüssel und expandJSON übernimmt diese 1:1. Irgendwo zwischen der Abfrage des Speedports mit einem Script und expandJSON würde ich gerne die Schlüssel umbenennen.

Dazu habe ich testweise ein $resultat =~ s/OldKey/NewKeyName/ integriert - das führt jedoch leider dazu, daß in der Abfrage zunächst die alten Schlüssel stehen und expandJSON die neuen dazupackt.

Gibt es bei expandJSON eine Möglichkeit der Schlüsselumbenennung "on-the-fly"?

Danke, -MN
Einziger Spender an FHEM e.V. mit Dauerauftrag seit >= 24 Monaten

FHEM: MacMini/ESXi, 2-3 FHEM Instanzen produktiv
In-Use: STELLMOTOR, VALVES, PWM-PWMR, Xiaomi, Allergy, Proplanta, UWZ, MQTT,  Homematic, Luftsensor.info, ESP8266, ESERA

dev0