Bus-Abfahrtszeiten über HTTP-Binding/JSON einlesen

Einrichtung der openHAB Umgebung und allgemeine Konfigurationsthemen.

Moderatoren: seppy, udo1toni

Antworten
Zacki
Beiträge: 43
Registriert: 26. Jan 2019 13:27
Answers: 0

Bus-Abfahrtszeiten über HTTP-Binding/JSON einlesen

Beitrag von Zacki »

Hallo

Ich brauche bitte eure Hilfe.
Ich würde gerne die Abfahrtszeiten des Busses in meiner Nähe in Openhab anzeigen.
Die Daten bekomme ich über eine JSON-Abfrage die wie folgt aussieht:

{"data":{"monitors":[{"locationStop":{"type":"Feature","geometry":{"type":"Point","coordinates":[16.4216256018884,48.2617457797284]},"properties":{"name":"60201398","title":"Töllergasse","municipality":"Wien","municipalityId":90001,"type":"stop","coordName":"WGS84","attributes":{"rbl":1115}}},"lines":[{"name":"28A","towards":"Floridsdorf S U","direction":"R","richtungsId":"2","barrierFree":true,"realtimeSupported":true,"trafficjam":false,"departures":{"departure":[{"departureTime":{"timePlanned":"2019-02-01T18:17:00.000+0100","timeReal":"2019-02-01T18:16:41.000+0100","countdown":1}},{"departureTime":{"timePlanned":"2019-02-01T18:32:00.000+0100","timeReal":"2019-02-01T18:32:00.000+0100","countdown":17}},{"departureTime":{"timePlanned":"2019-02-01T18:47:00.000+0100","timeReal":"2019-02-01T18:47:00.000+0100","countdown":32}},{"departureTime":{"timePlanned":"2019-02-01T19:01:00.000+0100","timeReal":"2019-02-01T19:01:30.000+0100","countdown":46}},{"departureTime":{"timePlanned":"2019-02-01T19:16:00.000+0100","countdown":61},"vehicle":{"name":"28A","towards":"Floridsdorf","direction":"R","richtungsId":"2","barrierFree":true,"realtimeSupported":true,"trafficjam":false,"type":"ptBusCity","attributes":{}}}]},"type":"ptBusCity","lineId":428}]},{"locationStop":{"type":"Feature","geometry":{"type":"Point","coordinates":[16.4216256018884,48.2617457797284]},"properties":{"name":"60201398","title":"Töllergasse","municipality":"Wien","municipalityId":90001,"type":"stop","coordName":"WGS84","attributes":{"rbl":1115}}},"lines":[{"name":"29A","towards":"Floridsdorf S U","direction":"R","richtungsId":"2","barrierFree":true,"realtimeSupported":true,"trafficjam":false,"departures":{"departure":[{"departureTime":{"timePlanned":"2019-02-01T18:20:00.000+0100","timeReal":"2019-02-01T18:21:05.000+0100","countdown":6}},{"departureTime":{"timePlanned":"2019-02-01T18:28:00.000+0100","timeReal":"2019-02-01T18:27:18.000+0100","countdown":12}},{"departureTime":{"timePlanned":"2019-02-01T18:36:00.000+0100","timeReal":"2019-02-01T18:36:00.000+0100","countdown":21}},{"departureTime":{"timePlanned":"2019-02-01T18:43:00.000+0100","timeReal":"2019-02-01T18:43:30.000+0100","countdown":28}},{"departureTime":{"timePlanned":"2019-02-01T18:51:00.000+0100","timeReal":"2019-02-01T18:51:00.000+0100","countdown":36}},{"departureTime":{"timePlanned":"2019-02-01T18:59:00.000+0100","timeReal":"2019-02-01T18:59:30.000+0100","countdown":44}},{"departureTime":{"timePlanned":"2019-02-01T19:06:00.000+0100","timeReal":"2019-02-01T19:06:00.000+0100","countdown":51}},{"departureTime":{"timePlanned":"2019-02-01T19:13:00.000+0100","countdown":58}},{"departureTime":{"timePlanned":"2019-02-01T19:21:00.000+0100","countdown":66},"vehicle":{"name":"29A","towards":"Floridsdorf","direction":"R","richtungsId":"2","barrierFree":true,"realtimeSupported":true,"trafficjam":false,"type":"ptBusCity","attributes":{}}}]},"type":"ptBusCity","lineId":429}]}]},"message":{"value":"OK","messageCode":1,"serverTime":"2019-02-01T18:14:41.518+0100"}}

dazu würde ich gerne die fett markierten Daten auslesen:
28A - 1 & 17min
29A - 6 & 12min

Ich habe nur keine Ahnung wie ich dies nun umsetzen kann.
Das HTTP-Binding habe ich nun mal installiert.
.) Nun muss das http.cfg file befüllt werden oder? Was muss ich hier tun?
.) Dann muss noch eine getValue.js Datei erstellt werden? Was muss ich hier reinschreiben?
.) und wie sieht dann mein Item aus?

Anzumerken ist, dass nicht immer beide Buslinien zur Verfügung stehen. Zum Wochenende zB fährt nur der 29A
und es stehen auch nicht immer beide Zeiten zur Verfügung. Gerade zu Betriebsende. Wie geht man hier vor?

Könnt ihr mir bitte helfen dieses "Projekt" umzusetzen?

Vielen Dank

Benutzeravatar
udo1toni
Beiträge: 15246
Registriert: 11. Apr 2018 18:05
Answers: 242
Wohnort: Darmstadt

Re: Bus-Abfahrtszeiten über HTTP-Binding/JSON einlesen

Beitrag von udo1toni »

Der absolute JSON Pfad zu den Angaben sieht so aus:

Code: Alles auswählen

$.data.monitors[0].lines[0].name
$.data.monitors[0].lines[0].departures.departure[0].departureTime.countdown
$.data.monitors[0].lines[0].departures.departure[1].departureTime.countdown
$.data.monitors[1].lines[0].name
$.data.monitors[1].lines[0].departures.departure[0].departureTime.countdown
$.data.monitors[1].lines[0].departures.departure[1].departureTime.countdown
Die Schwierigkeit besteht darin, dass diese Daten nicht zwingend so vorliegen müssen. Konkret muss also die Angabe im monitors-Feld den Namen abfragen:

Code: Alles auswählen

$.data.monitors[?(@.lines[0].name=='28A')].lines[0].departures.departure[0].departureTime.countdown
$.data.monitors[?(@.lines[0].name=='28A')].lines[0].departures.departure[1].departureTime.countdown
Diese beiden jsonpath statements geben die ersten beiden Countdown-Zeiten der Linie 28A zurück.
in der http.cfg kannst Du einen http cache definieren, um die Zugriffe zu minimieren:

Code: Alles auswählen

busauskunft.url=http://www.... #(die Adresse zur json Datei)
busauskunft.updateInterval=60000  #Abfrageinterval in Millisekunden
Das definiert ein http cache mit dem Namen busauskunft. Darauf greifst Du über die Items zu:

Code: Alles auswählen

String Linie28A1 "28A 1 [%s min]" {http="<[busauskunft:30000:JSONPATH($.data.monitors[?(@.lines[0].name=='28A')].lines[0].departures.departure[0].departureTime.countdown)]"}
String Linie28A2 "28A 2 [%s min]" {http="<[busauskunft:30000:JSONPATH($.data.monitors[?(@.lines[0].name=='28A')].lines[0].departures.departure[1].departureTime.countdown)]"}
String Linie29A1 "29A 1 [%s min]" {http="<[busauskunft:30000:JSONPATH($.data.monitors[?(@.lines[0].name=='29A')].lines[0].departures.departure[0].departureTime.countdown)]"}
String Linie29A2 "29A 2 [%s min]" {http="<[busauskunft:30000:JSONPATH($.data.monitors[?(@.lines[0].name=='29A')].lines[0].departures.departure[1].departureTime.countdown)]"}
Die vier Items enthalten nun jeweils den Abstand zur (geplanten) Abfahrt.
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet

Zacki
Beiträge: 43
Registriert: 26. Jan 2019 13:27
Answers: 0

Re: Bus-Abfahrtszeiten über HTTP-Binding/JSON einlesen

Beitrag von Zacki »

Vielen Dank, ich werde das spätestens zum We gleich mal testen.
Melde mich wieder
Vielen Dank!!!!!!

Zacki
Beiträge: 43
Registriert: 26. Jan 2019 13:27
Answers: 0

Re: Bus-Abfahrtszeiten über HTTP-Binding/JSON einlesen

Beitrag von Zacki »

Vielen Vielen Vielen Dank, es funktioniert! Wie geil ist das denn!!!! :-D Danke

Eine kurze "kosmetische" Frage noch:
Es ist bestimmt möglich nach Betriebsschluss einer Linie nicht den Wert "NULL min" anzuzeigen,
sondern hier irgendwo eine Wenn-Formel zu hinterlegen:
Wenn String "Linie28A 1" = "NULL"; Dann "Betriebsschluss"

bzw kann man die beiden Items zu einem zusammenfassen?
28A 5min und 15min
29A 1min und 11min

bzw wenn Betriebsschluss, dass dann nur mehr
28A 3min (2. Zeit wird gar nicht mehr angezeigt)
29A 2min und 12min

bzw
28A Betriebsschluss
29A 3min und 13min

mein nächste Plan wäre dann nämlich Openhab mit Alexa zu verknüpfen, um dann auch die Möglichkeit zu haben, die Zeiten abzufragen.

Vielen Dank noch einmal für deine Hilfe!

Benutzeravatar
udo1toni
Beiträge: 15246
Registriert: 11. Apr 2018 18:05
Answers: 242
Wohnort: Darmstadt

Re: Bus-Abfahrtszeiten über HTTP-Binding/JSON einlesen

Beitrag von udo1toni »

Ja, das geht sicher. Vermutlich ist es dann aber einfacher, die Auswertung der Zeiten in einer Rule erledigen zu lassen. Diese schreibt dann einen String in ein Item, welches angezeigt wird.

Für den konkreten Code müsste man etwas Hirnschmalz investieren :)
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet

Antworten