externe Datei *.json auswerten

Begonnen von curt, 17 November 2018, 06:12:46

Vorheriges Thema - Nächstes Thema

curt

Hallo allerseits,

externer WebServer liefert auf Port 80 bzw. 443 (und ausschließlich das, das folgende ist die komplette Datei):


{
  "timestamp": "2018-11-17T05:45:00+01:00",
  "value": 106.0,
  "trend": 1,
  "stateMnwMhw": "low",
  "stateNswHsw": "unknown"
}


Ich weiß was ich will - aber nicht, wie man das macht. Also RegEx ist klar (und für mich anstrengend: Das Alter, Genossen!). Aber vielleicht gibt es etwas viel schlaueres: Wie kann man diese fünf Objekteigenschaften eines Objekts elegant in FHEM importieren? 
RPI 4 - Jeelink HomeMatic Z-Wave

CoolTux

Wieso Regex? Ich würde da encode_json nehmen.
use JSON;
Nicht vergessen. Wie Holst Du denn die Daten? Wieso Datei wenn ein Webserver ausliefert?
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

OdfFhem

Ich nutze für Webserver-Abfragen:https://wiki.fhem.de/wiki/HTTPMOD.

Unter Parsing JSON mit extractAllJSON (bzw. JSON Lists) solltest Du was Passendes finden ...

Folgendes (ungetestet) könnte/sollte ausreichen

defmod <devicename> HTTPMOD <webserver-adresse> 86400
attr <devicename> extractAllJSON 1

dev0

Eine andere Möglichkeit wäre den Befehl getURL von hier zu benutzen:
geturl http://foobar.de [dev:json] --define --json

Danach hast Du einen Dummy mit dem Namen dev incl. der Readings aus dem JSON String.

rudolfkoenig

Alternative ohne die externe JSON Bibliothek: json2reading($defs{devicename}, $json)

curt

#5
Guten Morgen allerseits.

To much input :(
Ich bin doch bei solchen Punkten ein alter Mann.

Wenn ich auf Port 80 bzw 443 die URL anfrage, kommt *exakt* die oben genannte Antwort plaintext.

Klar kann ich eure Suchbegriffe durchhecheln. Schaffe ich. Aber dann ist Weihnachten.
Mir würde wirklich ein Beispielcode helfen - wie ich diese fünf Objektparameter in die Objekteigenschaften schubse.

Das Objekt selbst bestimmt sich über die URL. Alternativ über mich, dann ist die URL eine Objekteigenschaft. Letzteres wäre die bessere Variante.


RPI 4 - Jeelink HomeMatic Z-Wave

curt

Zitat von: rudolfkoenig am 17 November 2018, 07:09:28
Alternative ohne die externe JSON Bibliothek: json2reading($defs{devicename}, $json)

"Ohne" klingt grundsätzlich genial.

Wo kann ich weiterlesen?

Und wo finde ich ein grundsätzlich ähnliches Beispiel für FHEM?

RPI 4 - Jeelink HomeMatic Z-Wave

CoolTux

Zitat von: OdfFhem am 17 November 2018, 06:59:21
Ich nutze für Webserver-Abfragen:https://wiki.fhem.de/wiki/HTTPMOD.

Unter Parsing JSON mit extractAllJSON (bzw. JSON Lists) solltest Du was Passendes finden ...

Folgendes (ungetestet) könnte/sollte ausreichen

defmod <devicename> HTTPMOD <webserver-adresse> 86400
attr <devicename> extractAllJSON 1


Das hier ist Beispielcode und kannst Du ganz einfach testen. Ich würde das empfehlen.
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

betateilchen

Erklärt es doch mal einem Anfänger!

Also... es gibt in FHEM ein Modul, das genau das tun kann, was Du letztendlich haben möchtest. Das Modul heißt HTTPMOD.

Was tut HTTPMOD? Es liest das Ergebnis einer Webserverabfrage und verarbeitet die zurückgelieferten Daten.

Was brauchst Du, um das zu nutzen? Du definierst Dir in FHEM einfach ein device vom Typ HTTPMOD und verwendest die URL Deines Webservers als Parameter

define myDevice HTTPMOD <hier kommt die URL Deines Webservers hin> 3600

Danach musst Du dem neu angelegten device sagen, dass alles, was als JSON im Ergebnis ankommt, auch als JSON ausgewertet werden soll.

attr myDevice extractAllJSON 1

und speicherst das Ganze ab.

save

Die drei genannten Code-Blöcke gibst Du alle in der FHEM Befehlszeile ganz oben im Frontend ein.

Was bedeutet die 3600 am Ende des define? Das ist der Abstand in Sekunden (Intervall) in dem die Abfragen auf dem Webserver erfolgen sollen, um die Daten zu aktualisieren.

Was ist das Ergebnis? Du hast ein FHEM device mit dem Namen myDevice, bei dem die JSON Werte alle in einzelnen readings stehen. Das device kannst Du natürlich auch anders benennen, "myDevice" ist nur ein Beispielname.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

CoolTux

Ich bin dafür die Erklärung ins Wiki zu schreiben  ;D
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

betateilchen

Letztendlich musst Du aber noch wissen, ob die Daten als HTML Antwort kommen oder ob dabei eine Datei vom Server heruntergeladen wird. Wenn es sich um eine Datei handelt, ist die Vorgehensweise ein bisschen anders. Aber das geht aus der Fragestellung noch nicht eindeutig hervor.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

betateilchen

Zitat von: CoolTux am 17 November 2018, 12:45:24
Ich bin dafür die Erklärung ins Wiki zu schreiben  ;D

Suchst Du Streit?
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

CoolTux

Zitat von: betateilchen am 17 November 2018, 12:46:45
Suchst Du Streit?

Nein. Aber kann es sein das Du unentspannt bist lieber Udo?
Ich finde die Erklärung OK. Bin nur gespannt ob die die Musse hast es den nächsten 6 Leuten auch zu erklären. Denn HTTPMODE ist ein schwieriges Thema wie ich finde.
Oder man schreibt es nieder was Du gut geschrieben hast.
Mir egal, mach wie Du willst, alter Grummelbär.
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

betateilchen

Zitat von: CoolTux am 17 November 2018, 12:59:23
Nein. Aber kann es sein das Du unentspannt bist

Überhaupt nicht. Aber meine Meinung zum Wiki sollte hinlänglich bekannt sein.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

CoolTux

Naja hat ja keiner gesagt das Du das machen sollst. Aber gerade HTTPMODE ist so eine unendliche Geschichte was die Bedienbarkeit an geht.
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

curt

Ach Jungs (und Mädels) - nicht streiten. [KRACH] [BUMS] [Bierkasten auf dem Tisch] Bier ist für alle da, bitte bedient euch!

Also das mit dem Wiki kann gern ich machen. Ich halte das Wiki für wichtig: Ich selbst lerne am besten an Beispielen. Blöderweise gibt es selten welche. Und wenn man im Forum wider Erwarten Beispiele findet, sind die nicht selten veraltet.

Zitat von: betateilchen am 17 November 2018, 12:43:15
Erklärt es doch mal einem Anfänger!

Mit HTTPMOD mache ich schon einiges. Das selbst ist gar nicht das Problem.

attr myDevice extractAllJSON 1

Das wusste ich nicht. Dieser erste Schritt funktioniert auch fein: Alle Daten werden zu Readings umgewandelt:


stateMnwMhw normal 2018-11-18 22:17:48
stateNswHsw unknown 2018-11-18 22:17:48
timestamp 2018-11-18T22:15:00+01:00 2018-11-18 22:17:48
trend 1 2018-11-18 22:17:48
value 106 2018-11-18 22:17:48


Also "value" wäre das, was ich brauche, bislang (dazu unten) hieß das bei mir "Pegel". Und das neue "trend" grinst mich so schön an, das würde ich natürlich auch gern nutzen. Ich weiß nur nicht, wie man das macht.  Da bitte ich um Hilfe.

Hintergrund (die Kurzversion):
Ich greife seit einigen Monaten einige Flußpegel vermittels HTTPMOD ab und pople mir mit regex den jeweiligen Pegel heraus. Das wird in der Ganglinie vergleichend dargestellt. Als ich nun einen Artikel (noch unklar ob für Codeschnipsel oder Wiki) schreiben wollte -also ich wollte da schon auch etwas fachlichen Hintergrund einfließen lassen- fiel mir auf, dass es gar keine Navigation zu den sicher 20 Jahre statisch vorhandenen Seiten gibt. Also das Bundesamt angeschrieben. Die reagierten schnell und antworteten freundlich: Haben wir als REST-API mit JSON. - Hmmm, ok, ich kenn' da ja Leute ...

Ok, der alte Stand, Pegel Elbe Schöna (funktioniert fein, über das event-on-change-reading könnte man streiten):


define ElbePegelSchoena HTTPMOD http://www.bafg.de/php/SCHOENAELBEW.htm 3600
attr ElbePegelSchoena userattr reading01Name reading01Regex
attr ElbePegelSchoena alias Pegel Schoena
attr ElbePegelSchoena enableControlSet 1
attr ElbePegelSchoena event-on-change-reading Pegel
attr ElbePegelSchoena group Flusspegel
attr ElbePegelSchoena reading01Name Pegel
attr ElbePegelSchoena reading01Regex Letzter gemessener Wert \:[^0-9]+([0-9.]+)
attr ElbePegelSchoena room 51 Flusspegel
attr ElbePegelSchoena sortby 2
attr ElbePegelSchoena stateFormat {sprintf("%.0f",ReadingsVal("ElbePegelSchoena","Pegel",0))}
attr ElbePegelSchoena timeout 5
#attr ElbePegelSchoena icon keinname

define FileLog_ElbePegelSchoena FileLog ./log/ElbePegelSchoena-%Y.log ElbePegelSchoena
attr FileLog_ElbePegelSchoena logtype text
attr FileLog_ElbePegelSchoena room Alle_Logs

define SVG_FileLog_ElbePegelSchoena SVG FileLog_ElbePegelSchoena:SVG_FileLog_ElbePegelSchoena:CURRENT
attr SVG_FileLog_ElbePegelSchoena room 51 Flusspegel
attr SVG_FileLog_ElbePegelSchoena sortby 2


Und das ist der neue Stand:


define ElbePegelSchoena1 HTTPMOD https://www.pegelonline.wsv.de/webservices/rest-api/v2/stations/SCH%C3%96NA/W/currentmeasurement.json 600
attr ElbePegelSchoena1 extractAllJSON 1
attr ElbePegelSchoena1 room 51 Flusspegel

define FileLog_ElbePegelSchoena1 FileLog ./log/ElbePegelSchoena-%Y.log ElbePegelSchoena
attr FileLog_ElbePegelSchoena1 logtype text
attr FileLog_ElbePegelSchoena1 room Alle_Logs


Der wirft wie gesagt Readings aus:


stateMnwMhw normal 2018-11-18 22:17:48
stateNswHsw unknown 2018-11-18 22:17:48
timestamp 2018-11-18T22:15:00+01:00 2018-11-18 22:17:48
trend 1 2018-11-18 22:17:48
value 106 2018-11-18 22:17:48


"value" müsste ich nun wohl dazu prügeln, dass er "Pegel" heißt. Und "trend" würde ich auch gern nutzen - nur (Stichworte: Wiki, nachlesen) wie geht das?

Seid bitte gnädig zu einem alten Mann, der was lernen will ...
RPI 4 - Jeelink HomeMatic Z-Wave

curt

Hmm, das war sicher eine zu triviale Frage. Im Forum wurde diese Frage auch mehrmals gestellt, eine Antwort fand ich nur leider nicht.

Es geht darum, dass ein vorhandenes Reading "value" umzubenennen sei in "Pegel". Ich fand userReadings, das könnte etwas ähnliches machen.

attr ElbePegelSchoena1 userReadings Pegel { ReadingsVal("ElbePegelSchoena1","value.*",0) }


Das funktioniert leider nicht wie gewünscht. Es gibt dann zwar ein neues Reading "Pegel", das hat dann aber den Wert "0". Was tun?
RPI 4 - Jeelink HomeMatic Z-Wave

OdfFhem

vermutlich reicht es aus, "value" statt "value.*" zu verwenden

attr ElbePegelSchoena1 userReadings Pegel { ReadingsVal("ElbePegelSchoena1","value",0) }


Noch eine Anmerkung:
Wenn ich Deinen alten Stand betrachte und bislang damit zufrieden gewesen wäre, würde ich wahrscheinlich nur den http-Link sowie reading01Regex anpassen ... und noch reading02-Attribute für Trend ergänzen ...

curt

#18
@OdfFhem
Mein treuer Freund! Wenn gar nichts mehr geht und ich leise weinend in der Ecke sitze, dann kommst Du um die Ecke.

Zitat von: OdfFhem am 20 November 2018, 02:28:29
vermutlich reicht es aus, "value" statt "value.*" zu verwenden

attr ElbePegelSchoena1 userReadings Pegel { ReadingsVal("ElbePegelSchoena1","value",0) }

Wow, das geht!
Da wäre ich im Traum nicht darauf gekommen. Und warum nicht? Ich zeige es Dir:

In https://wiki.fhem.de/wiki/UserReadings ist so ein schöner gelber Kasten. Da steht "nur mit ".*". Und in den dort verlinkten Kasten kommt http://forum.fhem.de/index.php/topic,52165.0.html - da unterhalten sich die Stars von FHEM (übrigens genau die, die mir oben noch antworteten!) darüber, dass es ohne ".*" nun mal gar nicht geht. Das habe ich so einfach als Wahrheit genommen, blöd wie ich bin.

BTW: Mein ganz simples Beispiel muss eigentlich auch in https://wiki.fhem.de/wiki/UserReadings rein ...

Zitat von: OdfFhem am 20 November 2018, 02:28:29
Noch eine Anmerkung:
Wenn ich Deinen alten Stand betrachte und bislang damit zufrieden gewesen wäre, würde ich wahrscheinlich nur den http-Link sowie reading01Regex anpassen ... und noch reading02-Attribute für Trend ergänzen ...

Das geht nicht.
Zwar ist die Datenquelle (einen konkreten Flußpegel gibt es ja nur einmal) identisch. Aber leider sind zwei Bundesämter im Spiel. Die eine Version kommt vom BAFG, die neuere json-Version kommt von der WSV.

Meine alte FHEM-Version setzt mit HTTPMOD und regex auf BAFG (stinknormale html-Seite ohne Budenzauber) auf: Deren Pegelseiten sind seit gut 20 Jahren statisch, also der Nachhaltigkeitspunkt geht wirklich an die. - Problem ist: Man kann das nicht neu aufsetzen. Die haben keine Verlinkungen auf die einzelnen Pegel mehr. Nur aus diesen Grunde habe ich ...

Die JSON-Version von der WSV muss ihre Nachhaltigkeit erstmal beweisen. Andererseits kommt da mehr, da kommt noch ein Trend mit, sowas mag man als FHEM/FTUI-Nutzer natürlich.

BTW: Offen gesagt war ich drauf und dran, das Problem mit der Brechstange zu lösen: sed über alle fraglichen Logs, Pegel durch value ersetzen ...

Und es gibt noch einen Seiteneffekt:
Nicht nur, dass Du um die Ecke kommst, wenn ich so gar nicht mehr weiter weiß. Sondern auch, dass ich wieder etwas gelernt habe: Wie so eine JSON-Datei ausseiht, wie sie aufgebaut ist.

Denn
das löst noch ein ganz anderes Problem: Vor einem halben Jahr fing ich an, mir Sorgen um meine vielen kleinen Server zu machen. Ich hatte gar nicht vor, da minutenweise den Puls und die Temperatur zu fühlen, alle diesbezüglichen Lösungen sind aus meiner Sicht Quatsch - wir sind doch kein Hochverfügbarkeitsrechenzentrum im Keller neben den Kartoffeln. Sondern ich will lediglich wissen, ob Updates einzuspielen sind. Also das als Reading einer automatisch erzeugten Device (kommt ins Netz - bekommt eine Device). Den ersten Teil (lokal auf den Servern) habe ich vor Monaten gelöst, das steht. Der zweite Teil fehlt. Ich halte nichts von automatisierten ssh-Orgien, das sind aus meiner Sicht Sicherheitsrisiken.

Oh, ich habe mich verplauscht.

Ich danke Dir!

P.S. Beispiel in https://wiki.fhem.de/wiki/UserReadings eingefügt.
RPI 4 - Jeelink HomeMatic Z-Wave

CoolTux

Zitat von: curt am 20 November 2018, 03:09:18
@OdfFhem
Mein treuer Freund! Wenn gar nichts mehr geht und ich leise weinend in der Ecke sitze, dann kommst Du um die Ecke.

Wow, das geht!
Da wäre ich im Traum nicht darauf gekommen. Und warum nicht? Ich zeige es Dir:

In https://wiki.fhem.de/wiki/UserReadings ist so ein schöner gelber Kasten. Da steht "nur mit ".*". Und in den dort verlinkten Kasten kommt http://forum.fhem.de/index.php/topic,52165.0.html - da unterhalten sich die Stars von FHEM (übrigens genau die, die mir oben noch antworteten!) darüber, dass es ohne ".*" nun mal gar nicht geht. Das habe ich so einfach als Wahrheit genommen, blöd wie ich bin.

Da bringst Du jetzt aber Trigger RegEx und Parameterübergabe an eine Funktion durcheinander.


ReadingsVal("ElbePegelSchoena1","value.*",0)

Das hier ist ein Funktionsaufruf und "value.*" der Parameter welcher an die Funktion übergeben werden soll. Und das ist halt Unsinn.
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

curt

RPI 4 - Jeelink HomeMatic Z-Wave

StefanStrobel

Statt einem userReading kann man auch HTTPMOD sagen, wie er aus einem JSON-Objekt ein Reading benennen soll:

attr EP reading100JSON value
attr EP reading100Name Pegel
attr EP reading104JSON trend
attr EP reading104Name Trend


oder wenn man viele Readings umbenennen möchte und sich die Tipparbeit erleichtern will:

attr EP enableControlSet 1
attr EP extractAllJSON 2

nach dem nächsten Lesen bewirkt extractAllJSON 2 dass die ganzen Attribute für alle JSON-Objekte einmal angelegt werden und das extractAllJSON Attribut wieder gelöscht wird. Dann kann man bequem die unnötigen Attribute löschen und andere Umbenennen.

Gruss
   Stefan