Departure: Unterschied zwischen den Versionen
Krikan (Diskussion | Beiträge) K (Intrawiki-Links korrigiert) |
Sailor (Diskussion | Beiträge) Keine Bearbeitungszusammenfassung |
||
(9 dazwischenliegende Versionen von 6 Benutzern werden nicht angezeigt) | |||
Zeile 1: | Zeile 1: | ||
Departure ist ein Modul zur Anzeige der Abfahrtszeiten von Bahn, Bus, Zug und Fähre des öffentlichen Personennahverkehrs (ÖPNV). | Departure ist ein Modul zur Anzeige der Abfahrtszeiten von Bahn, Bus, Zug und Fähre des öffentlichen Personennahverkehrs (ÖPNV). | ||
Diese Seite basiert auf | Diese Seite basiert auf einem {{Link2Forum|Topic=48255.0|LinkText=Beitrag im Forum}} (von [https://forum.fhem.de/index.php?action=profile;u=5250 sbiermann]). Mittlerweile gibt es hierzu ein {{Link2Forum|Topic=60046.0|LinkText= noch inoffizielles Modul}} (von [https://forum.fhem.de/index.php?action=profile;u=14026 uniqueck]). | ||
Zusätzlich gibt es ein Widget für die FHEM Tablet UI (FTUI) https://forum.fhem.de/index.php? | |||
Diese Seite sollte angepasst/überarbeitet werden, wenn das Modul 98_departure offiziell eingecheckt ist. | Zusätzlich gibt es ein {{Link2Forum|Topic=48255.0|LinkText=Widget für die FHEM Tablet UI}} (FTUI) (von [https://forum.fhem.de/index.php?action=profile;u=7023 setstate]). | ||
{{Todo|Diese Seite sollte angepasst/überarbeitet werden, wenn das Modul 98_departure offiziell eingecheckt ist.}} | |||
__TOC__ | |||
== Vorbereitung == | == Vorbereitung == | ||
Zeile 9: | Zeile 13: | ||
<b>1. Ermitteln welche Provider gibt es und welcher ist für mich zuständig.</b> | <b>1. Ermitteln welche Provider gibt es und welcher ist für mich zuständig.</b> | ||
<pre> | <pre>https://transport.stefan-biermann.de/publictransportapi/rest/provider</pre> | ||
Dieses liefert als Antwort im JSON Format: | Dieses liefert als Antwort im JSON Format: | ||
Zeile 19: | Zeile 23: | ||
<b>2. Ermitteln der StationId für die Haltestelle deren Abfahrtszeiten ich gerne haben möchte. In diesem Beispiel die Haltstelle "SSB-Zentrum"</b> | <b>2. Ermitteln der StationId für die Haltestelle deren Abfahrtszeiten ich gerne haben möchte. In diesem Beispiel die Haltstelle "SSB-Zentrum"</b> | ||
<pre> | <pre> | ||
https://transport.stefan-biermann.de/publictransportapi/rest/station/suggest?q=SSB-Zentrum&provider=Vvs | |||
</pre> | </pre> | ||
Dieses liefert als Antwort im JSON Format: | Dieses liefert als Antwort im JSON Format: | ||
Zeile 29: | Zeile 33: | ||
<b>3. Abfrage der Departure Zeiten für die Haltestelle "SSB-Zentrum". Diese liefert die Daten im passenden Format für das zugehörige departure Widget für FTUI</b> | <b>3. Abfrage der Departure Zeiten für die Haltestelle "SSB-Zentrum". Diese liefert die Daten im passenden Format für das zugehörige departure Widget für FTUI</b> | ||
<pre> | <pre> | ||
https://transport.stefan-biermann.de/publictransportapi/rest/departure/FHEM?from=5000350&provider=Vvs | |||
</pre> | </pre> | ||
dieses liefert als Antwort im passenden Format: | dieses liefert als Antwort im passenden Format: | ||
Zeile 42: | Zeile 46: | ||
define myDeparture HTTPMOD none 0 | define myDeparture HTTPMOD none 0 | ||
attr myDeparture get01Name SSB-Zentrum | attr myDeparture get01Name SSB-Zentrum | ||
attr myDeparture get01URL | attr myDeparture get01URL https://transport.stefan-biermann.de/publictransportapi/rest/departure/FHEM?from=5000350&provider=Vvs | ||
attr myDeparture get01Regex (\[\[.*\]\]).* | attr myDeparture get01Regex (\[\[.*\]\]).* | ||
attr VAG timeout 30 | attr VAG timeout 30 | ||
Zeile 48: | Zeile 52: | ||
Es können mehrere Haltestellen in einem Device hinterlegt werden, hierzu einfach die drei Attribute get01Name, get01URL und get01Regex duplizieren und durchnummerieren. Dabei müssen natürlich Name und URL angepasst werden. | Es können mehrere Haltestellen in einem Device hinterlegt werden, hierzu einfach die drei Attribute get01Name, get01URL und get01Regex duplizieren und durchnummerieren. Dabei müssen natürlich Name und URL angepasst werden. | ||
Bei dieser Konfiguration erfolgt die Aktualisierung über das FTUI Widget! | Bei dieser Konfiguration erfolgt die Aktualisierung über das FTUI Widget! | ||
Alternativ wird im Forum erläutert, wie man mit HTTPMOD die Abfahrtszeiten erhalten kann. Erstmal auf der Bahn-Seite https://reiseauskunft.bahn.de/bin/bhftafel.exe/dox? den gewünschten Bahnhof raussuchen, es sind wie gesagt aber nicht nur Bahnhöfe drin sondern auch die meisten Haltestellen der regionalen Verkehrsverbünde. Einmal Abfahrt oder Ankunft wählen und dann "Später" drücken, erst dann ist oben in der URL der Parameter "si" mit der Bahnhofs-ID zu sehen. | |||
Eine URL für den Hauptbahnhof Hannover würde jetzt so aussehen: | |||
<pre> | |||
https://reiseauskunft.bahn.de/bin/bhftafel.exe/dox?si=8000152&bt=dep&p=1111111111&max=5&rt=1&use_realtime_filter=1&start=yes& | |||
</pre> | |||
in FHEM dann damit ein | |||
<pre> | |||
define bhf_HannoverHbf HTTPMOD https://reiseauskunft.bahn.de/bin/bhftafel.exe/dox?si=8000152&bt=dep&p=1111111111&max=5&rt=1&use_realtime_filter=1&start=yes& 0 | |||
</pre> | |||
In dem angelegtem Device auf Raw-Definition gehen und alles löschen und das eintragen | |||
<pre> | |||
defmod bhf_HannoverHbf HTTPMOD https://reiseauskunft.bahn.de/bin/bhftafel.exe/dox?si=8000152&bt=dep&p=1111111111&max=5&rt=1&use_realtime_filter=1&start=yes& 0 | |||
attr bhf_HannoverHbf userattr get1Name reading01-10Name reading01-11Name reading01-12Name reading01-13Name reading01-14Name reading01-15Name reading01-16Name reading01-17Name reading01-18Name reading01-19Name reading01-1Name reading01-20Name reading01-2Name reading01-3Name reading01-4Name reading01-5Name reading01-6Name reading01-7Name reading01-8Name reading01-9Name reading01Name reading01OExpr reading01RegOpt reading01Regex | |||
attr bhf_HannoverHbf get1Name Update | |||
attr bhf_HannoverHbf reading01-10Name departure_3_destination | |||
attr bhf_HannoverHbf reading01-11Name departure_3_time | |||
attr bhf_HannoverHbf reading01-12Name departure_3_delay | |||
attr bhf_HannoverHbf reading01-13Name departure_4_product | |||
attr bhf_HannoverHbf reading01-14Name departure_4_destination | |||
attr bhf_HannoverHbf reading01-15Name departure_4_time | |||
attr bhf_HannoverHbf reading01-16Name departure_4_delay | |||
attr bhf_HannoverHbf reading01-17Name departure_5_product | |||
attr bhf_HannoverHbf reading01-18Name departure_5_destination | |||
attr bhf_HannoverHbf reading01-19Name departure_5_time | |||
attr bhf_HannoverHbf reading01-1Name departure_1_product | |||
attr bhf_HannoverHbf reading01-20Name departure_5_delay | |||
attr bhf_HannoverHbf reading01-2Name departure_1_destination | |||
attr bhf_HannoverHbf reading01-3Name departure_1_time | |||
attr bhf_HannoverHbf reading01-4Name departure_1_delay | |||
attr bhf_HannoverHbf reading01-5Name departure_2_product | |||
attr bhf_HannoverHbf reading01-6Name departure_2_destination | |||
attr bhf_HannoverHbf reading01-7Name departure_2_time | |||
attr bhf_HannoverHbf reading01-8Name departure_2_delay | |||
attr bhf_HannoverHbf reading01-9Name departure_3_product | |||
attr bhf_HannoverHbf reading01Name reading | |||
attr bhf_HannoverHbf reading01OExpr {$val =~ s/<br\/><span class="delay.*">//g;; $val =~ s/<\/span>.*//g;; $val =~ s/.* ;.*//g;; $val =~ s/, <span.*//g;; $val =~ s/(;/(/g;; $val =~ s/);/)/g;; $val =~ s/ü;/ü/g;; $val =~ s/ö;/ö/g;; $val =~ s/ä;/ä/g;; $val =~ s/ß;/ß/g;; $val;;} | |||
attr bhf_HannoverHbf reading01RegOpt gm | |||
attr bhf_HannoverHbf reading01Regex <span class="bold">(.*)<\/span>\s<\/a>[\w\W]&[gl]t;;&[gl]t;;\s(.*)\s<br \/>[\w\W]<span class="bold">(\d\d:\d\d)<\/span>(.*)<\/div> | |||
attr bhf_HannoverHbf stateFormat departure_1_product departure_1_destination departure_1_time (departure_1_delay) | |||
</pre> | |||
Jetzt gibt es oben den Update Button oder "get bhf_HannoverHbf Update" in der FHEM Befehlzeile wählen, dann sollten ein paar Readings erscheinen: | |||
<pre> | |||
READINGS: | |||
2019-12-22 17:15:23 departure_1_delay 17:16 | |||
2019-12-22 17:15:23 departure_1_destination Hauptbahnhof/ZOB, Hannover | |||
2019-12-22 17:15:23 departure_1_product STB 10 | |||
2019-12-22 17:15:23 departure_1_time 17:14 | |||
2019-12-22 17:15:23 departure_2_delay 17:17 | |||
2019-12-22 17:15:23 departure_2_destination Sarstedt (Endpunkt GVH) | |||
2019-12-22 17:15:23 departure_2_product STB 1 | |||
2019-12-22 17:15:23 departure_2_time 17:14 | |||
2019-12-22 17:15:23 departure_3_delay 17:15 | |||
2019-12-22 17:15:23 departure_3_destination Haltenhoffstraße, Hannover | |||
2019-12-22 17:15:23 departure_3_product Bus 121 | |||
2019-12-22 17:15:23 departure_3_time 17:14 | |||
2019-12-22 17:15:23 departure_4_delay 17:15 | |||
2019-12-22 17:15:23 departure_4_destination Ahlem, Hannover | |||
2019-12-22 17:15:23 departure_4_product STB 10 | |||
2019-12-22 17:15:23 departure_4_time 17:15 | |||
2019-12-22 17:15:23 departure_5_delay | |||
2019-12-22 17:15:23 departure_5_destination Hauptbahnhof/ZOB, Hannover | |||
2019-12-22 17:15:23 departure_5_product Bussprin | |||
2019-12-22 17:15:23 departure_5_time 17:15 | |||
</pre> | |||
Man kann in der Bahnabfrage auch eine Linie auswählen, die Info muss dann im URL Parameter "tn" stehen. Wenn man eine bestimmte Richtung ausfiltern will geht das auch im Atrribut reading01Regex, da könnte man z.B. dort wo das jeweils zweite Reading erzeugt wird ....t;;\s(Leipzig.*)\s<br..... schreiben. | |||
Läuft bei jetzt seit ein paar Tagen ganz gut. Allerdings scheint nicht bei allen Verkehrsverbünden die Verspätungsanzeige schon zu funktionieren, da bleibt dann das Reading delay leer, bei mir im VBN geht es aber auch für lokale Bushaltestellen. | |||
Falls es nicht für alle Abfahrten Echtzeiten gibt kann man mit einem Userreading noch definieren, dass dann ein Planzeit angezeigt wird, z.B. so: | |||
departure_1_delay_time { ReadingsVal($NAME,"departure_1_delay",0) eq "" ? ReadingsVal($NAME,"departure_1_time",0) : ReadingsVal($NAME,"departure_1_delay",0);} | |||
oder wenn man z.B. eine Farbsteuerung bei Verspätungen benötigt ein Userreading was zwischen 0 und 1 umschaltet. | |||
departure_1_is_delay { ReadingsVal($NAME,"departure_1_delay",0) eq ReadingsVal($NAME,"departure_1_time",0) ? 0 : 1;} | |||
== Bekannte Probleme == | |||
=== UTC versus lokale Zeitzone === | |||
Die Uhrzeit unter departure_0_time und departure_0_time_human_readable wird in UTC und nicht in lokaler Zeit angezeigt. | |||
Hierfuer kann man sich ein User-Reading erstellen, welches die Zeitzonen-Differenz ermittelt und anschliessend auf die Abfahrtszeit in UTC vorzeichenrichtig drauf addiert. | |||
Das entsprechende Atrrribut "UserReading" lautet wie folgt: | |||
<pre> | |||
departure_0_only_time {my $oldtime = ReadingsVal($NAME,"departure_0_time",0);$oldtime =~ s/.*T//;$oldtime =~ s/\+.*//;my @lt = localtime(12*60*60);my @gt = gmtime(12*60*60);my $tz = $lt[2] - $gt[2];my @DepTimeSplit = split(":", $oldtime);my $newtime = $DepTimeSplit[0]+$tz . ":" . $DepTimeSplit[1];$newtime;}, | |||
departure_1_only_time {my $oldtime = ReadingsVal($NAME,"departure_1_time",0);$oldtime =~ s/.*T//;$oldtime =~ s/\+.*//;my @lt = localtime(12*60*60);my @gt = gmtime(12*60*60);my $tz = $lt[2] - $gt[2];my @DepTimeSplit = split(":", $oldtime);my $newtime = $DepTimeSplit[0]+$tz . ":" . $DepTimeSplit[1];$newtime;}, | |||
departure_2_only_time {my $oldtime = ReadingsVal($NAME,"departure_2_time",0);$oldtime =~ s/.*T//;$oldtime =~ s/\+.*//;my @lt = localtime(12*60*60);my @gt = gmtime(12*60*60);my $tz = $lt[2] - $gt[2];my @DepTimeSplit = split(":", $oldtime);my $newtime = $DepTimeSplit[0]+$tz . ":" . $DepTimeSplit[1];$newtime;}, | |||
departure_3_only_time {my $oldtime = ReadingsVal($NAME,"departure_3_time",0);$oldtime =~ s/.*T//;$oldtime =~ s/\+.*//;my @lt = localtime(12*60*60);my @gt = gmtime(12*60*60);my $tz = $lt[2] - $gt[2];my @DepTimeSplit = split(":", $oldtime);my $newtime = $DepTimeSplit[0]+$tz . ":" . $DepTimeSplit[1];$newtime;}, | |||
departure_4_only_time {my $oldtime = ReadingsVal($NAME,"departure_4_time",0);$oldtime =~ s/.*T//;$oldtime =~ s/\+.*//;my @lt = localtime(12*60*60);my @gt = gmtime(12*60*60);my $tz = $lt[2] - $gt[2];my @DepTimeSplit = split(":", $oldtime);my $newtime = $DepTimeSplit[0]+$tz . ":" . $DepTimeSplit[1];$newtime;}, | |||
departure_5_only_time {my $oldtime = ReadingsVal($NAME,"departure_5_time",0);$oldtime =~ s/.*T//;$oldtime =~ s/\+.*//;my @lt = localtime(12*60*60);my @gt = gmtime(12*60*60);my $tz = $lt[2] - $gt[2];my @DepTimeSplit = split(":", $oldtime);my $newtime = $DepTimeSplit[0]+$tz . ":" . $DepTimeSplit[1];$newtime;}, | |||
departure_6_only_time {my $oldtime = ReadingsVal($NAME,"departure_6_time",0);$oldtime =~ s/.*T//;$oldtime =~ s/\+.*//;my @lt = localtime(12*60*60);my @gt = gmtime(12*60*60);my $tz = $lt[2] - $gt[2];my @DepTimeSplit = split(":", $oldtime);my $newtime = $DepTimeSplit[0]+$tz . ":" . $DepTimeSplit[1];$newtime;}, | |||
departure_7_only_time {my $oldtime = ReadingsVal($NAME,"departure_7_time",0);$oldtime =~ s/.*T//;$oldtime =~ s/\+.*//;my @lt = localtime(12*60*60);my @gt = gmtime(12*60*60);my $tz = $lt[2] - $gt[2];my @DepTimeSplit = split(":", $oldtime);my $newtime = $DepTimeSplit[0]+$tz . ":" . $DepTimeSplit[1];$newtime;}, | |||
departure_8_only_time {my $oldtime = ReadingsVal($NAME,"departure_8_time",0);$oldtime =~ s/.*T//;$oldtime =~ s/\+.*//;my @lt = localtime(12*60*60);my @gt = gmtime(12*60*60);my $tz = $lt[2] - $gt[2];my @DepTimeSplit = split(":", $oldtime);my $newtime = $DepTimeSplit[0]+$tz . ":" . $DepTimeSplit[1];$newtime;}, | |||
departure_9_only_time {my $oldtime = ReadingsVal($NAME,"departure_9_time",0);$oldtime =~ s/.*T//;$oldtime =~ s/\+.*//;my @lt = localtime(12*60*60);my @gt = gmtime(12*60*60);my $tz = $lt[2] - $gt[2];my @DepTimeSplit = split(":", $oldtime);my $newtime = $DepTimeSplit[0]+$tz . ":" . $DepTimeSplit[1];$newtime;} | |||
</pre> | |||
Dieses schneidet auch gleich das Datum raus. | |||
== Links == | == Links == | ||
* | * {{Link2Forum|Topic=48255|LinkText=Forum: Neues FTUI Widget - Departure}} | ||
* [https://forum.fhem.de/index.php?topic=60046.0 Forum: Modul 98_Departure: Bereitstellung von Abfahrtszeiten an einem Bahnhof] | * [https://forum.fhem.de/index.php?topic=60046.0 Forum: Modul 98_Departure: Bereitstellung von Abfahrtszeiten an einem Bahnhof] | ||
* [[ | * [[FTUI Widget Departure|Wiki: FHEM Tablet UI - Departure Widget]] | ||
[[Kategorie:HOWTOS]] | [[Kategorie:HOWTOS]] | ||
[[Kategorie:Code Snippets]] | [[Kategorie:Code Snippets]] | ||
[[Kategorie:Modul (Inoffiziell)]] | [[Kategorie:Modul (Inoffiziell)]] |
Aktuelle Version vom 26. März 2024, 19:41 Uhr
Departure ist ein Modul zur Anzeige der Abfahrtszeiten von Bahn, Bus, Zug und Fähre des öffentlichen Personennahverkehrs (ÖPNV). Diese Seite basiert auf einem Beitrag im Forum (von sbiermann). Mittlerweile gibt es hierzu ein noch inoffizielles Modul (von uniqueck).
Zusätzlich gibt es ein Widget für die FHEM Tablet UI (FTUI) (von setstate).
Todo: Diese Seite sollte angepasst/überarbeitet werden, wenn das Modul 98_departure offiziell eingecheckt ist. |
Vorbereitung
Um die Abfahrtzeiten zu ermitteln wird der REST-Wrapper von sbiermann genutzt, der auf dem Dienst für die Android App "Öffi" basiert. Für die Spätere Abfrage wird der Provider und die ID der Haltestelle benötigt. Beides kann wie folgt ermittelt werden.
1. Ermitteln welche Provider gibt es und welcher ist für mich zuständig.
https://transport.stefan-biermann.de/publictransportapi/rest/provider
Dieses liefert als Antwort im JSON Format:
[{"name":"Sncb","aClass":"SncbProvider"},{"name":"Vbn","aClass":"VbnProvider"},{"name":"Wien","aClass":"WienProvider"},{"name":"Linz","aClass":"LinzProvider"},{"name":"Vrr","aClass":"VrrProvider"},{"name":"Oebb","aClass":"OebbProvider"},{"name":"Gvh","aClass":"GvhProvider"},{"name":"Ns","aClass":"NsProvider"},{"name":"Vao","aClass":"VaoProvider"},{"name":"Tfi","aClass":"TfiProvider"},{"name":"Vgn","aClass":"VgnProvider"},{"name":"Mvg","aClass":"MvgProvider"},{"name":"Pl","aClass":"PlProvider"},{"name":"Vgs","aClass":"VgsProvider"},{"name":"Nasa","aClass":"NasaProvider"},{"name":"Vbb","aClass":"VbbProvider"},{"name":"Ivb","aClass":"IvbProvider"},{"name":"Nvv","aClass":"NvvProvider"},{"name":"Mvv","aClass":"MvvProvider"},{"name":"Vagfr","aClass":"VagfrProvider"},{"name":"Vvv","aClass":"VvvProvider"},{"name":"Sf","aClass":"SfProvider"},{"name":"Vms","aClass":"VmsProvider"},{"name":"Sbb","aClass":"SbbProvider"},{"name":"Bsvag","aClass":"BsvagProvider"},{"name":"Jet","aClass":"JetProvider"},{"name":"Septa","aClass":"SeptaProvider"},{"name":"Bvb","aClass":"BvbProvider"},{"name":"Mersey","aClass":"MerseyProvider"},{"name":"Vvs","aClass":"VvsProvider"},{"name":"Nvbw","aClass":"NvbwProvider"},{"name":"Se","aClass":"SeProvider"},{"name":"Svv","aClass":"SvvProvider"},{"name":"Bahn","aClass":"BahnProvider"},{"name":"Vrs","aClass":"VrsProvider"},{"name":"Stockholm","aClass":"StockholmProvider"},{"name":"Vmv","aClass":"VmvProvider"},{"name":"Stv","aClass":"StvProvider"},{"name":"Sydney","aClass":"SydneyProvider"},{"name":"Paris","aClass":"ParisProvider"},{"name":"Dsb","aClass":"DsbProvider"},{"name":"Rt","aClass":"RtProvider"},{"name":"Dub","aClass":"DubProvider"},{"name":"Bvg","aClass":"BvgProvider"},{"name":"Paca","aClass":"PacaProvider"},{"name":"Vor","aClass":"VorProvider"},{"name":"FrenchSouthWest","aClass":"FrenchSouthWestProvider"},{"name":"Avv","aClass":"AvvProvider"},{"name":"Zvv","aClass":"ZvvProvider"},{"name":"Nri","aClass":"NriProvider"},{"name":"Invg","aClass":"InvgProvider"},{"name":"Eireann","aClass":"EireannProvider"},{"name":"Vbl","aClass":"VblProvider"},{"name":"Vvo","aClass":"VvoProvider"},{"name":"Sh","aClass":"ShProvider"},{"name":"Kvv","aClass":"KvvProvider"},{"name":"Bayern","aClass":"BayernProvider"},{"name":"Atc","aClass":"AtcProvider"},{"name":"Lu","aClass":"LuProvider"},{"name":"Italy","aClass":"ItalyProvider"},{"name":"Vvm","aClass":"VvmProvider"},{"name":"Met","aClass":"MetProvider"},{"name":"Ding","aClass":"DingProvider"},{"name":"Tlem","aClass":"TlemProvider"},{"name":"Vvt","aClass":"VvtProvider"},{"name":"Vrn","aClass":"VrnProvider"}]
Das was bei Name steht wird verwendet, der Wert aClass ist intern und braucht hier nicht weiter verwendet werden. Im Beispiel haben die Verkehrsbetriebe Stuttgart (VVS) den Namen "Vvs".
2. Ermitteln der StationId für die Haltestelle deren Abfahrtszeiten ich gerne haben möchte. In diesem Beispiel die Haltstelle "SSB-Zentrum"
https://transport.stefan-biermann.de/publictransportapi/rest/station/suggest?q=SSB-Zentrum&provider=Vvs
Dieses liefert als Antwort im JSON Format:
[{"type":"STATION","id":"5000350","lat":48726856,"lon":9129721,"place":"Stuttgart","name":"SSB-Zentrum","products":null,"lonAsDouble":9.129721,"latAsDouble":48.726856,"identified":true},{"type":"STATION","id":"5002601","lat":48722757,"lon":9129058,"place":"Stuttgart","name":"Industriestraße (SSB-Zentrum)","products":null,"lonAsDouble":9.129058,"latAsDouble":48.722757,"identified":true}]
Wie man sehen kann gibt es mehrere Treffer für SSB-Zentrum. Es wird aber nur der Typ "STATION" benötigt und somit lautet die StationId "5000350".
3. Abfrage der Departure Zeiten für die Haltestelle "SSB-Zentrum". Diese liefert die Daten im passenden Format für das zugehörige departure Widget für FTUI
https://transport.stefan-biermann.de/publictransportapi/rest/departure/FHEM?from=5000350&provider=Vvs
dieses liefert als Antwort im passenden Format:
[["U8","Vaihingen","3"],["U12","Dürrlewang","6"],["U8","Ostfildern","5"],["U3","Vaihingen","6"],["U12","Hallschlag","7"],["U3","Plieningen","9"],["U8","Vaihingen","12"],["U12","Dürrlewang","17"],["U8","Waldau","15"],["U3","Vaihingen","16"]]
Die Zeiten sind immer inklusive Verspätung angegeben, sofern der Provider diese Daten mit sendet.
Einbindung in FHEM
Wie in der Einleitung erwähnt gibt es aktuell zwei Wege, die Abfahrtszeiten einzubinden: über HTTPMOD oder über das noch inofizielle Modul 98_departure
define myDeparture HTTPMOD none 0 attr myDeparture get01Name SSB-Zentrum attr myDeparture get01URL https://transport.stefan-biermann.de/publictransportapi/rest/departure/FHEM?from=5000350&provider=Vvs attr myDeparture get01Regex (\[\[.*\]\]).* attr VAG timeout 30
Es können mehrere Haltestellen in einem Device hinterlegt werden, hierzu einfach die drei Attribute get01Name, get01URL und get01Regex duplizieren und durchnummerieren. Dabei müssen natürlich Name und URL angepasst werden. Bei dieser Konfiguration erfolgt die Aktualisierung über das FTUI Widget!
Alternativ wird im Forum erläutert, wie man mit HTTPMOD die Abfahrtszeiten erhalten kann. Erstmal auf der Bahn-Seite https://reiseauskunft.bahn.de/bin/bhftafel.exe/dox? den gewünschten Bahnhof raussuchen, es sind wie gesagt aber nicht nur Bahnhöfe drin sondern auch die meisten Haltestellen der regionalen Verkehrsverbünde. Einmal Abfahrt oder Ankunft wählen und dann "Später" drücken, erst dann ist oben in der URL der Parameter "si" mit der Bahnhofs-ID zu sehen.
Eine URL für den Hauptbahnhof Hannover würde jetzt so aussehen:
https://reiseauskunft.bahn.de/bin/bhftafel.exe/dox?si=8000152&bt=dep&p=1111111111&max=5&rt=1&use_realtime_filter=1&start=yes&
in FHEM dann damit ein
define bhf_HannoverHbf HTTPMOD https://reiseauskunft.bahn.de/bin/bhftafel.exe/dox?si=8000152&bt=dep&p=1111111111&max=5&rt=1&use_realtime_filter=1&start=yes& 0
In dem angelegtem Device auf Raw-Definition gehen und alles löschen und das eintragen
defmod bhf_HannoverHbf HTTPMOD https://reiseauskunft.bahn.de/bin/bhftafel.exe/dox?si=8000152&bt=dep&p=1111111111&max=5&rt=1&use_realtime_filter=1&start=yes& 0 attr bhf_HannoverHbf userattr get1Name reading01-10Name reading01-11Name reading01-12Name reading01-13Name reading01-14Name reading01-15Name reading01-16Name reading01-17Name reading01-18Name reading01-19Name reading01-1Name reading01-20Name reading01-2Name reading01-3Name reading01-4Name reading01-5Name reading01-6Name reading01-7Name reading01-8Name reading01-9Name reading01Name reading01OExpr reading01RegOpt reading01Regex attr bhf_HannoverHbf get1Name Update attr bhf_HannoverHbf reading01-10Name departure_3_destination attr bhf_HannoverHbf reading01-11Name departure_3_time attr bhf_HannoverHbf reading01-12Name departure_3_delay attr bhf_HannoverHbf reading01-13Name departure_4_product attr bhf_HannoverHbf reading01-14Name departure_4_destination attr bhf_HannoverHbf reading01-15Name departure_4_time attr bhf_HannoverHbf reading01-16Name departure_4_delay attr bhf_HannoverHbf reading01-17Name departure_5_product attr bhf_HannoverHbf reading01-18Name departure_5_destination attr bhf_HannoverHbf reading01-19Name departure_5_time attr bhf_HannoverHbf reading01-1Name departure_1_product attr bhf_HannoverHbf reading01-20Name departure_5_delay attr bhf_HannoverHbf reading01-2Name departure_1_destination attr bhf_HannoverHbf reading01-3Name departure_1_time attr bhf_HannoverHbf reading01-4Name departure_1_delay attr bhf_HannoverHbf reading01-5Name departure_2_product attr bhf_HannoverHbf reading01-6Name departure_2_destination attr bhf_HannoverHbf reading01-7Name departure_2_time attr bhf_HannoverHbf reading01-8Name departure_2_delay attr bhf_HannoverHbf reading01-9Name departure_3_product attr bhf_HannoverHbf reading01Name reading attr bhf_HannoverHbf reading01OExpr {$val =~ s/<br\/><span class="delay.*">//g;; $val =~ s/<\/span>.*//g;; $val =~ s/.* ;.*//g;; $val =~ s/, <span.*//g;; $val =~ s/(;/(/g;; $val =~ s/);/)/g;; $val =~ s/ü;/ü/g;; $val =~ s/ö;/ö/g;; $val =~ s/ä;/ä/g;; $val =~ s/ß;/ß/g;; $val;;} attr bhf_HannoverHbf reading01RegOpt gm attr bhf_HannoverHbf reading01Regex <span class="bold">(.*)<\/span>\s<\/a>[\w\W]&[gl]t;;&[gl]t;;\s(.*)\s<br \/>[\w\W]<span class="bold">(\d\d:\d\d)<\/span>(.*)<\/div> attr bhf_HannoverHbf stateFormat departure_1_product departure_1_destination departure_1_time (departure_1_delay)
Jetzt gibt es oben den Update Button oder "get bhf_HannoverHbf Update" in der FHEM Befehlzeile wählen, dann sollten ein paar Readings erscheinen:
READINGS: 2019-12-22 17:15:23 departure_1_delay 17:16 2019-12-22 17:15:23 departure_1_destination Hauptbahnhof/ZOB, Hannover 2019-12-22 17:15:23 departure_1_product STB 10 2019-12-22 17:15:23 departure_1_time 17:14 2019-12-22 17:15:23 departure_2_delay 17:17 2019-12-22 17:15:23 departure_2_destination Sarstedt (Endpunkt GVH) 2019-12-22 17:15:23 departure_2_product STB 1 2019-12-22 17:15:23 departure_2_time 17:14 2019-12-22 17:15:23 departure_3_delay 17:15 2019-12-22 17:15:23 departure_3_destination Haltenhoffstraße, Hannover 2019-12-22 17:15:23 departure_3_product Bus 121 2019-12-22 17:15:23 departure_3_time 17:14 2019-12-22 17:15:23 departure_4_delay 17:15 2019-12-22 17:15:23 departure_4_destination Ahlem, Hannover 2019-12-22 17:15:23 departure_4_product STB 10 2019-12-22 17:15:23 departure_4_time 17:15 2019-12-22 17:15:23 departure_5_delay 2019-12-22 17:15:23 departure_5_destination Hauptbahnhof/ZOB, Hannover 2019-12-22 17:15:23 departure_5_product Bussprin 2019-12-22 17:15:23 departure_5_time 17:15
Man kann in der Bahnabfrage auch eine Linie auswählen, die Info muss dann im URL Parameter "tn" stehen. Wenn man eine bestimmte Richtung ausfiltern will geht das auch im Atrribut reading01Regex, da könnte man z.B. dort wo das jeweils zweite Reading erzeugt wird ....t;;\s(Leipzig.*)\s<br..... schreiben.
Läuft bei jetzt seit ein paar Tagen ganz gut. Allerdings scheint nicht bei allen Verkehrsverbünden die Verspätungsanzeige schon zu funktionieren, da bleibt dann das Reading delay leer, bei mir im VBN geht es aber auch für lokale Bushaltestellen.
Falls es nicht für alle Abfahrten Echtzeiten gibt kann man mit einem Userreading noch definieren, dass dann ein Planzeit angezeigt wird, z.B. so:
departure_1_delay_time { ReadingsVal($NAME,"departure_1_delay",0) eq "" ? ReadingsVal($NAME,"departure_1_time",0) : ReadingsVal($NAME,"departure_1_delay",0);}
oder wenn man z.B. eine Farbsteuerung bei Verspätungen benötigt ein Userreading was zwischen 0 und 1 umschaltet.
departure_1_is_delay { ReadingsVal($NAME,"departure_1_delay",0) eq ReadingsVal($NAME,"departure_1_time",0) ? 0 : 1;}
Bekannte Probleme
UTC versus lokale Zeitzone
Die Uhrzeit unter departure_0_time und departure_0_time_human_readable wird in UTC und nicht in lokaler Zeit angezeigt. Hierfuer kann man sich ein User-Reading erstellen, welches die Zeitzonen-Differenz ermittelt und anschliessend auf die Abfahrtszeit in UTC vorzeichenrichtig drauf addiert. Das entsprechende Atrrribut "UserReading" lautet wie folgt:
departure_0_only_time {my $oldtime = ReadingsVal($NAME,"departure_0_time",0);$oldtime =~ s/.*T//;$oldtime =~ s/\+.*//;my @lt = localtime(12*60*60);my @gt = gmtime(12*60*60);my $tz = $lt[2] - $gt[2];my @DepTimeSplit = split(":", $oldtime);my $newtime = $DepTimeSplit[0]+$tz . ":" . $DepTimeSplit[1];$newtime;}, departure_1_only_time {my $oldtime = ReadingsVal($NAME,"departure_1_time",0);$oldtime =~ s/.*T//;$oldtime =~ s/\+.*//;my @lt = localtime(12*60*60);my @gt = gmtime(12*60*60);my $tz = $lt[2] - $gt[2];my @DepTimeSplit = split(":", $oldtime);my $newtime = $DepTimeSplit[0]+$tz . ":" . $DepTimeSplit[1];$newtime;}, departure_2_only_time {my $oldtime = ReadingsVal($NAME,"departure_2_time",0);$oldtime =~ s/.*T//;$oldtime =~ s/\+.*//;my @lt = localtime(12*60*60);my @gt = gmtime(12*60*60);my $tz = $lt[2] - $gt[2];my @DepTimeSplit = split(":", $oldtime);my $newtime = $DepTimeSplit[0]+$tz . ":" . $DepTimeSplit[1];$newtime;}, departure_3_only_time {my $oldtime = ReadingsVal($NAME,"departure_3_time",0);$oldtime =~ s/.*T//;$oldtime =~ s/\+.*//;my @lt = localtime(12*60*60);my @gt = gmtime(12*60*60);my $tz = $lt[2] - $gt[2];my @DepTimeSplit = split(":", $oldtime);my $newtime = $DepTimeSplit[0]+$tz . ":" . $DepTimeSplit[1];$newtime;}, departure_4_only_time {my $oldtime = ReadingsVal($NAME,"departure_4_time",0);$oldtime =~ s/.*T//;$oldtime =~ s/\+.*//;my @lt = localtime(12*60*60);my @gt = gmtime(12*60*60);my $tz = $lt[2] - $gt[2];my @DepTimeSplit = split(":", $oldtime);my $newtime = $DepTimeSplit[0]+$tz . ":" . $DepTimeSplit[1];$newtime;}, departure_5_only_time {my $oldtime = ReadingsVal($NAME,"departure_5_time",0);$oldtime =~ s/.*T//;$oldtime =~ s/\+.*//;my @lt = localtime(12*60*60);my @gt = gmtime(12*60*60);my $tz = $lt[2] - $gt[2];my @DepTimeSplit = split(":", $oldtime);my $newtime = $DepTimeSplit[0]+$tz . ":" . $DepTimeSplit[1];$newtime;}, departure_6_only_time {my $oldtime = ReadingsVal($NAME,"departure_6_time",0);$oldtime =~ s/.*T//;$oldtime =~ s/\+.*//;my @lt = localtime(12*60*60);my @gt = gmtime(12*60*60);my $tz = $lt[2] - $gt[2];my @DepTimeSplit = split(":", $oldtime);my $newtime = $DepTimeSplit[0]+$tz . ":" . $DepTimeSplit[1];$newtime;}, departure_7_only_time {my $oldtime = ReadingsVal($NAME,"departure_7_time",0);$oldtime =~ s/.*T//;$oldtime =~ s/\+.*//;my @lt = localtime(12*60*60);my @gt = gmtime(12*60*60);my $tz = $lt[2] - $gt[2];my @DepTimeSplit = split(":", $oldtime);my $newtime = $DepTimeSplit[0]+$tz . ":" . $DepTimeSplit[1];$newtime;}, departure_8_only_time {my $oldtime = ReadingsVal($NAME,"departure_8_time",0);$oldtime =~ s/.*T//;$oldtime =~ s/\+.*//;my @lt = localtime(12*60*60);my @gt = gmtime(12*60*60);my $tz = $lt[2] - $gt[2];my @DepTimeSplit = split(":", $oldtime);my $newtime = $DepTimeSplit[0]+$tz . ":" . $DepTimeSplit[1];$newtime;}, departure_9_only_time {my $oldtime = ReadingsVal($NAME,"departure_9_time",0);$oldtime =~ s/.*T//;$oldtime =~ s/\+.*//;my @lt = localtime(12*60*60);my @gt = gmtime(12*60*60);my $tz = $lt[2] - $gt[2];my @DepTimeSplit = split(":", $oldtime);my $newtime = $DepTimeSplit[0]+$tz . ":" . $DepTimeSplit[1];$newtime;}
Dieses schneidet auch gleich das Datum raus.