FHEM Forum

FHEM => Anfängerfragen => Thema gestartet von: bgewehr am 14 Januar 2018, 12:40:43

Titel: Shell-Command ausführen und JSON-Response in Readings anbieten?
Beitrag von: bgewehr am 14 Januar 2018, 12:40:43
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?
Titel: Shell-Command ausführen und JSON-Response in Readings anbieten?
Beitrag von: KernSani am 14 Januar 2018, 12:45:35
Schau dir mal HTTPMOD an. Du kannst aber auch mal im Forum suchen, da gibt es ein paar Beiträge zu CarNet.
Titel: Antw:Shell-Command ausführen und JSON-Response in Readings anbieten?
Beitrag von: bgewehr am 14 Januar 2018, 16:41:09
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?
Titel: Antw:Shell-Command ausführen und JSON-Response in Readings anbieten?
Beitrag von: CoolTux am 14 Januar 2018, 16:47:28
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.
Titel: Antw:Shell-Command ausführen und JSON-Response in Readings anbieten?
Beitrag von: bgewehr am 14 Januar 2018, 17:01:33
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...
Titel: Antw:Shell-Command ausführen und JSON-Response in Readings anbieten?
Beitrag von: CoolTux am 14 Januar 2018, 17:49:20
https://www.tutorialspoint.com/json/json_perl_example.htm
Titel: Antw:Shell-Command ausführen und JSON-Response in Readings anbieten?
Beitrag von: bgewehr am 14 Januar 2018, 21:22:37
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"}
Titel: Antw:Shell-Command ausführen und JSON-Response in Readings anbieten?
Beitrag von: CoolTux am 14 Januar 2018, 23:15:47
Warum machst du es nicht mit encode_json? Ruf es innerhalb eines evals auf dann stürzt auch FHEM nicht ab.
Titel: Antw:Shell-Command ausführen und JSON-Response in Readings anbieten?
Beitrag von: dev0 am 16 Januar 2018, 17:46:03
@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.
Titel: Antw:Shell-Command ausführen und JSON-Response in Readings anbieten?
Beitrag von: bgewehr am 16 Januar 2018, 18:30:23
Hab Perl 5.20 und JSON per cpan installiert. Muss ich sonst noch was berücksichtigen?
Titel: Antw:Shell-Command ausführen und JSON-Response in Readings anbieten?
Beitrag von: dev0 am 16 Januar 2018, 18:52:20
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...
Titel: Antw:Shell-Command ausführen und JSON-Response in Readings anbieten?
Beitrag von: bgewehr am 17 Januar 2018, 18:17:19
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"}
Titel: Shell-Command ausführen und JSON-Response in Readings anbieten?
Beitrag von: bgewehr am 17 Januar 2018, 22:21:23
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?
Titel: Antw:Shell-Command ausführen und JSON-Response in Readings anbieten?
Beitrag von: dev0 am 18 Januar 2018, 08:46:19
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?
Titel: Antw:Shell-Command ausführen und JSON-Response in Readings anbieten?
Beitrag von: bgewehr am 18 Januar 2018, 08:53:41
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.
Titel: Antw:Shell-Command ausführen und JSON-Response in Readings anbieten?
Beitrag von: dev0 am 18 Januar 2018, 14:05:05
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...
Titel: Antw:Shell-Command ausführen und JSON-Response in Readings anbieten?
Beitrag von: bgewehr am 18 Januar 2018, 20:21:24
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.
Titel: Antw:Shell-Command ausführen und JSON-Response in Readings anbieten?
Beitrag von: bgewehr am 20 Januar 2018, 12:38:25
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!
Titel: Antw:Shell-Command ausführen und JSON-Response in Readings anbieten?
Beitrag von: bgewehr am 28 Januar 2018, 18:01:35
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?
Titel: Antw:Shell-Command ausführen und JSON-Response in Readings anbieten?
Beitrag von: CoolTux am 28 Januar 2018, 18:23:54
Es kann sein das true und false als 0 und 1 gewandelt werden bei decode_json()
Titel: Antw:Shell-Command ausführen und JSON-Response in Readings anbieten?
Beitrag 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.
Titel: Antw:Shell-Command ausführen und JSON-Response in Readings anbieten?
Beitrag von: bgewehr am 29 Januar 2018, 21:22:10
Auf alle Fälle hier mal ein Zwischenstand.

Lesehilfe:


Titel: Antw:Shell-Command ausführen und JSON-Response in Readings anbieten?
Beitrag von: dev0 am 30 Januar 2018, 17:24:36
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?
Titel: Antw:Shell-Command ausführen und JSON-Response in Readings anbieten?
Beitrag von: dev0 am 01 Februar 2018, 09:12:33
@bgewehr: Teste bitte mal die angehängte Version, die sollte true/false als 1/0 in das entsprechende Reading schreiben.
Titel: Antw:Shell-Command ausführen und JSON-Response in Readings anbieten?
Beitrag von: bgewehr am 02 Februar 2018, 07:16:07
Perfekt - funktioniert.

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

Vielen Dank!
Titel: Antw:Shell-Command ausführen und JSON-Response in Readings anbieten?
Beitrag von: bgewehr am 02 Februar 2018, 07:20:43
Noch ein letzter Gedanke:

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


Höherweg 85 Düsseldorf 40233
Titel: Antw:Shell-Command ausführen und JSON-Response in Readings anbieten?
Beitrag von: CoolTux am 02 Februar 2018, 08:56:59
Denke mal


encode_utf8();
Titel: Antw:Shell-Command ausführen und JSON-Response in Readings anbieten?
Beitrag von: dev0 am 02 Februar 2018, 16:42:29
@bgewehr: Magst Du das mal testen und berichten?

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

statt der jetzigen decode_json Zeile (~178)
Titel: Antw:Shell-Command ausführen und JSON-Response in Readings anbieten?
Beitrag von: bgewehr am 02 Februar 2018, 16:51:37
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.
Titel: Antw:Shell-Command ausführen und JSON-Response in Readings anbieten?
Beitrag von: dev0 am 02 Februar 2018, 17:06:19
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
Titel: Antw:Shell-Command ausführen und JSON-Response in Readings anbieten?
Beitrag von: bgewehr am 02 Februar 2018, 18:19:10
Inzwischen schlägt das throttling immer häufiger zu - und sperrt mich aus bis zur nächsten Fahrt:
Titel: Antw:Shell-Command ausführen und JSON-Response in Readings anbieten?
Beitrag von: dev0 am 08 Februar 2018, 09:22:59
Ich habe die Änderungen ins svn eingecheckt.
Titel: Antw:Shell-Command ausführen und JSON-Response in Readings anbieten?
Beitrag von: Morgennebel am 12 April 2019, 20:33:16
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
Titel: Antw:Shell-Command ausführen und JSON-Response in Readings anbieten?
Beitrag von: dev0 am 22 April 2019, 09:11:30
Nein.