Nextride: Unterschied zwischen den Versionen
KKeine Bearbeitungszusammenfassung |
Keine Bearbeitungszusammenfassung |
||
| (Eine dazwischenliegende Version von einem anderen Benutzer wird nicht angezeigt) | |||
| Zeile 1: | Zeile 1: | ||
{{ | == Wann fährt die nächste Bahn? == | ||
[[ | |||
* [http://haltestellenmonitor.vrr.de/monitor/5c1a5bf76de06ea27630edc685232626 Mobiel/VRR Abfahrzeiten Ziegelstraße] | |||
== Nextride 2.0? == | |||
Im alten Space an der Sudbrackstraße hatten wir ein Display der nächsten Nahverkehr-Abfahrzeiten (s.u.), an der Blomestraße fehlt so etwas leider bisher. Der Link oben wurde mit dem [https://haltestellenmonitor.vrr.de/vu/mobiel#/index VRR-Haltestellenmonitor] erstellt. | |||
Der eigentliche API-Endpunkt hinter dem Haltestellenmonitor ist '''"https://haltestellenmonitor.vrr.de/backend/api/stations/table''', darauf aufbauend könnte ein neues '''nextride''' entstehen. | |||
Als neue Anzeigemöglichkeit könnte ich mir zB. -- energiesparend :) -- einen Arduino mit eInk-Display vorstellen? | |||
=== VRR API === | |||
Dokumentation zu diesem API habe ich beim VRR auf die Schnelle nicht gefunden, es gibt dort zwar einen "Open Data" Bereich, aber dort scheinen nur Download-Datensätze angeboten zu werden, aber keine Live-Daten. Daher ist alles was hier folgt Ergebnis von Reverse Engineering. | |||
==== Suche von Stationen ==== | |||
[https://haltestellenmonitor.vrr.de/backend/api/stations/search?query=blomestr] | |||
==== Request ==== | |||
Der Haltestellenmonitor schickt die Haltestellendaten als POST-Request, und die POST-Parameter für eine Haltestelle sind konstant, zB. für die Stadtbahn-Haltestelle Ziegelstraße: | |||
<nowiki> | |||
table%5Bdeparture%5D%5BstationId%5D=23005614&table%5Bdeparture%5D%5BstationName%5D=Bielefeld+Ziegelstra%C3%9Fe&table%5Bdeparture%5D%5BplatformVisibility%5D=1&table%5Bdeparture%5D%5Btransport%5D=0%2C1%2C2%2C3%2C4%2C15%2C6&table%5Bdeparture%5D%5BuseAllLines%5D=1&table%5Bdeparture%5D%5BlinesFilter%5D=&table%5Bdeparture%5D%5BoptimizedForStation%5D=0&table%5Bdeparture%5D%5BrowCount%5D=6&table%5Bdeparture%5D%5BrefreshInterval%5D=60&table%5Bdeparture%5D%5Bdistance%5D=0&table%5Bdeparture%5D%5Bmarquee%5D=-1&table%5BsortBy%5D=0 | |||
</nowiki> | |||
oder netter formatiert: | |||
<nowiki> | |||
table[departure][stationId] "23005614" | |||
table[departure][stationName] "Bielefeld+Ziegelstraße" | |||
table[departure][platformVisibility] "1" | |||
table[departure][transport] "0,1,2,3,4,15,6" | |||
table[departure][useAllLines] "1" | |||
table[departure][linesFilter] "" | |||
table[departure][optimizedForStation] "0" | |||
table[departure][rowCount] "6" | |||
table[departure][refreshInterval] "60" | |||
table[departure][distance] "0" | |||
table[departure][marquee] "-1" | |||
table[sortBy] "0" | |||
</nowiki> | |||
===== Feldwerte ===== | |||
* table[departure][transport] | |||
{| class="wikitable" | |||
|+ Werte | |||
|- | |||
| 0 || ICE/IC/EC | |||
|- | |||
| 1 || Zug | |||
|- | |||
| 2 || S-Bahn | |||
|- | |||
| 3 || U-Bahn | |||
|- | |||
| 4 || Straßenbahn | |||
|- | |||
| 5 || Bus | |||
|- | |||
| 6 || Schwebebahn | |||
|} | |||
==== Response ==== | |||
Die Antwort kommt als JSON-Dokument zurück, damit lässt sich gut weiterarbeiten: | |||
<nowiki> | |||
{ | |||
"departureData":[ | |||
{ | |||
"name":"2", | |||
"lineNumber":"2", | |||
"lineCode":"31002", | |||
"subname":"Stadtbahn", | |||
"direction":"Bielefeld, Altenhagen", | |||
"directionCode":"H", | |||
"route":"Bielefeld, Altenhagen", | |||
"type":4, | |||
"day":"23", | |||
"month":"4", | |||
"year":"2023", | |||
"hour":"9", | |||
"minute":"03", | |||
"orgDay":"23", | |||
"orgHour":"9", | |||
"orgMinute":"00", | |||
"countdown":"4", | |||
"platform":"", | |||
"delay":"3", | |||
"isRealTime":true, | |||
"isDateOverflow":false, | |||
"lineInfo":{ | |||
"lineInfo":{ | |||
"messages":[ | |||
], | |||
"text":"", | |||
"priority":0 | |||
}, | |||
"lineBlocking":{ | |||
"messages":[ | |||
], | |||
"text":"", | |||
"priority":0 | |||
} | |||
}, | |||
"fullTime":"1682233380", | |||
"orgFullTime":"1682233200", | |||
"supplement":"", | |||
"key":"231" | |||
}, | |||
{ | |||
"name":"2", | |||
"lineNumber":"2", | |||
"lineCode":"31002", | |||
"subname":"Stadtbahn", | |||
"direction":"Bielefeld, Sieker", | |||
"directionCode":"R", | |||
"route":"Bielefeld, Sieker", | |||
"type":4, | |||
"day":"23", | |||
"month":"4", | |||
"year":"2023", | |||
"hour":"9", | |||
"minute":"04", | |||
"orgDay":"23", | |||
"orgHour":"9", | |||
"orgMinute":"04", | |||
"countdown":"5", | |||
"platform":"", | |||
"delay":"0", | |||
"isRealTime":true, | |||
"isDateOverflow":false, | |||
"lineInfo":{ | |||
"lineInfo":{ | |||
"messages":[ | |||
], | |||
"text":"", | |||
"priority":0 | |||
}, | |||
"lineBlocking":{ | |||
"messages":[ | |||
], | |||
"text":"", | |||
"priority":0 | |||
} | |||
}, | |||
"fullTime":"1682233440", | |||
"orgFullTime":"1682233440", | |||
"supplement":"", | |||
"key":"38" | |||
}, | |||
{ | |||
"name":"2", | |||
"lineNumber":"2", | |||
"lineCode":"31002", | |||
"subname":"Stadtbahn", | |||
"direction":"Bielefeld, Altenhagen", | |||
"directionCode":"H", | |||
"route":"Bielefeld, Altenhagen", | |||
"type":4, | |||
"day":"23", | |||
"month":"4", | |||
"year":"2023", | |||
"hour":"9", | |||
"minute":"15", | |||
"orgDay":"23", | |||
"orgHour":"9", | |||
"orgMinute":"15", | |||
"countdown":"16", | |||
"platform":"", | |||
"delay":"0", | |||
"isRealTime":true, | |||
"isDateOverflow":false, | |||
"lineInfo":{ | |||
"lineInfo":{ | |||
"messages":[ | |||
], | |||
"text":"", | |||
"priority":0 | |||
}, | |||
"lineBlocking":{ | |||
"messages":[ | |||
], | |||
"text":"", | |||
"priority":0 | |||
} | |||
}, | |||
"fullTime":"1682234100", | |||
"orgFullTime":"1682234100", | |||
"supplement":"", | |||
"key":"234" | |||
}, | |||
{ | |||
"name":"2", | |||
"lineNumber":"2", | |||
"lineCode":"31002", | |||
"subname":"Stadtbahn", | |||
"direction":"Bielefeld, Sieker", | |||
"directionCode":"R", | |||
"route":"Bielefeld, Sieker", | |||
"type":4, | |||
"day":"23", | |||
"month":"4", | |||
"year":"2023", | |||
"hour":"9", | |||
"minute":"19", | |||
"orgDay":"23", | |||
"orgHour":"9", | |||
"orgMinute":"19", | |||
"countdown":"20", | |||
"platform":"", | |||
"delay":"0", | |||
"isRealTime":true, | |||
"isDateOverflow":false, | |||
"lineInfo":{ | |||
"lineInfo":{ | |||
"messages":[ | |||
], | |||
"text":"", | |||
"priority":0 | |||
}, | |||
"lineBlocking":{ | |||
"messages":[ | |||
], | |||
"text":"", | |||
"priority":0 | |||
} | |||
}, | |||
"fullTime":"1682234340", | |||
"orgFullTime":"1682234340", | |||
"supplement":"", | |||
"key":"40" | |||
}, | |||
{ | |||
"name":"2", | |||
"lineNumber":"2", | |||
"lineCode":"31002", | |||
"subname":"Stadtbahn", | |||
"direction":"Bielefeld, Altenhagen", | |||
"directionCode":"H", | |||
"route":"Bielefeld, Altenhagen", | |||
"type":4, | |||
"day":"23", | |||
"month":"4", | |||
"year":"2023", | |||
"hour":"9", | |||
"minute":"30", | |||
"orgDay":"23", | |||
"orgHour":"9", | |||
"orgMinute":"30", | |||
"countdown":"31", | |||
"platform":"", | |||
"delay":"0", | |||
"isRealTime":true, | |||
"isDateOverflow":false, | |||
"lineInfo":{ | |||
"lineInfo":{ | |||
"messages":[ | |||
], | |||
"text":"", | |||
"priority":0 | |||
}, | |||
"lineBlocking":{ | |||
"messages":[ | |||
], | |||
"text":"", | |||
"priority":0 | |||
} | |||
}, | |||
"fullTime":"1682235000", | |||
"orgFullTime":"1682235000", | |||
"supplement":"", | |||
"key":"236" | |||
}, | |||
{ | |||
"name":"2", | |||
"lineNumber":"2", | |||
"lineCode":"31002", | |||
"subname":"Stadtbahn", | |||
"direction":"Bielefeld, Sieker", | |||
"directionCode":"R", | |||
"route":"Bielefeld, Sieker", | |||
"type":4, | |||
"day":"23", | |||
"month":"4", | |||
"year":"2023", | |||
"hour":"9", | |||
"minute":"34", | |||
"orgDay":"23", | |||
"orgHour":"9", | |||
"orgMinute":"34", | |||
"countdown":"35", | |||
"platform":"", | |||
"delay":"0", | |||
"isRealTime":true, | |||
"isDateOverflow":false, | |||
"lineInfo":{ | |||
"lineInfo":{ | |||
"messages":[ | |||
], | |||
"text":"", | |||
"priority":0 | |||
}, | |||
"lineBlocking":{ | |||
"messages":[ | |||
], | |||
"text":"", | |||
"priority":0 | |||
} | |||
}, | |||
"fullTime":"1682235240", | |||
"orgFullTime":"1682235240", | |||
"supplement":"", | |||
"key":"43" | |||
} | |||
], | |||
"departureInfo":{ | |||
"stopInfo":{ | |||
"text":"" | |||
}, | |||
"stopBlocking":{ | |||
"text":"" | |||
}, | |||
"areaInfo":{ | |||
"text":"" | |||
}, | |||
"areaBlocking":{ | |||
"text":"" | |||
} | |||
}, | |||
"globalInfo":"", | |||
"stationName":"Bielefeld, Ziegelstra\u00dfe", | |||
"marquee":-1, | |||
"stationInfo":[ | |||
], | |||
"currentTime":1682233123, | |||
"currentTimeReal":1682233123 | |||
} | |||
</nowiki> | |||
==== Q&D Example ==== | |||
"Bielefeld existiert, und PHP ist OK" ;) | |||
<nowiki> | |||
<?php | |||
$url = "https://haltestellenmonitor.vrr.de/backend/api/stations/table"; | |||
$data = "table%5Bdeparture%5D%5BstationId%5D=23005614&table%5Bdeparture%5D%5BstationName%5D=Bielefeld+Ziegelstra%C3%9Fe&table%5Bdeparture%5D%5BplatformVisibility%5D=1&table%5Bdeparture%5D%5Btransport%5D=0%2C1%2C2%2C3%2C4%2C15%2C6&table%5Bdeparture%5D%5BuseAllLines%5D=1&table%5Bdeparture%5D%5BlinesFilter%5D=&table%5Bdeparture%5D%5BoptimizedForStation%5D=0&table%5Bdeparture%5D%5BrowCount%5D=6&table%5Bdeparture%5D%5BrefreshInterval%5D=60&table%5Bdeparture%5D%5Bdistance%5D=0&table%5Bdeparture%5D%5Bmarquee%5D=-1&table%5BsortBy%5D=0"; | |||
$curl = curl_init(); | |||
curl_setopt($curl, CURLOPT_URL, $url); | |||
curl_setopt($curl, CURLOPT_POST, true); | |||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); | |||
curl_setopt($curl, CURLOPT_POSTFIELDS, $data); | |||
$resp = curl_exec($curl); | |||
curl_close($curl); | |||
$data = json_decode($resp, true); | |||
foreach ($data["departureData"] as $dep) { | |||
$dir = $dep["direction"]; | |||
$time = strftime("%R", $dep["orgFullTime"]); | |||
if ($dep["delay"] > 0) { | |||
$time .= " +".$dep["delay"]; | |||
} | |||
$left = ($dep["fullTime"] - time())/60; | |||
printf("+%-3d %-15s %s\n", $left, $time, $dir); | |||
} | |||
</nowiki> | |||
== Nextride in der Sudbrackstraße == | |||
Der nextride-Teil bestand aus einem Haskell-Programm, welches cronjob-gesteuert die Bahn-Seite für die nächstgelegene Straßenbahnhaltestelle abgriff und die Abfahrtszeiten als JSON in eine Datei schrieb. Diese Datei wurde bei Änderung vom Infobeamer ([[Armageddon_Notifier]]) per Lua-Script eingelesen und dargestellt. | |||
Diese Lösung funktioniert aus verschiedenen Gründen leider nicht mehr, unter anderem weil das damals genutzte API der Bahn keine Daten anderer Verkehrsbetriebe mehr zur Verfügung stellt. | |||
* [https://github.com/HackerspaceBielefeld/Nextride nextride code auf GitHub] | |||
[[Kategorie:Projekt]] | [[Kategorie:Projekt]] | ||
[[Kategorie:Sudbrackstraße]] | |||
Aktuelle Version vom 24. April 2023, 06:13 Uhr
Wann fährt die nächste Bahn?
Nextride 2.0?
Im alten Space an der Sudbrackstraße hatten wir ein Display der nächsten Nahverkehr-Abfahrzeiten (s.u.), an der Blomestraße fehlt so etwas leider bisher. Der Link oben wurde mit dem VRR-Haltestellenmonitor erstellt.
Der eigentliche API-Endpunkt hinter dem Haltestellenmonitor ist "https://haltestellenmonitor.vrr.de/backend/api/stations/table, darauf aufbauend könnte ein neues nextride entstehen.
Als neue Anzeigemöglichkeit könnte ich mir zB. -- energiesparend :) -- einen Arduino mit eInk-Display vorstellen?
VRR API
Dokumentation zu diesem API habe ich beim VRR auf die Schnelle nicht gefunden, es gibt dort zwar einen "Open Data" Bereich, aber dort scheinen nur Download-Datensätze angeboten zu werden, aber keine Live-Daten. Daher ist alles was hier folgt Ergebnis von Reverse Engineering.
Suche von Stationen
Request
Der Haltestellenmonitor schickt die Haltestellendaten als POST-Request, und die POST-Parameter für eine Haltestelle sind konstant, zB. für die Stadtbahn-Haltestelle Ziegelstraße:
table%5Bdeparture%5D%5BstationId%5D=23005614&table%5Bdeparture%5D%5BstationName%5D=Bielefeld+Ziegelstra%C3%9Fe&table%5Bdeparture%5D%5BplatformVisibility%5D=1&table%5Bdeparture%5D%5Btransport%5D=0%2C1%2C2%2C3%2C4%2C15%2C6&table%5Bdeparture%5D%5BuseAllLines%5D=1&table%5Bdeparture%5D%5BlinesFilter%5D=&table%5Bdeparture%5D%5BoptimizedForStation%5D=0&table%5Bdeparture%5D%5BrowCount%5D=6&table%5Bdeparture%5D%5BrefreshInterval%5D=60&table%5Bdeparture%5D%5Bdistance%5D=0&table%5Bdeparture%5D%5Bmarquee%5D=-1&table%5BsortBy%5D=0
oder netter formatiert:
table[departure][stationId] "23005614" table[departure][stationName] "Bielefeld+Ziegelstraße" table[departure][platformVisibility] "1" table[departure][transport] "0,1,2,3,4,15,6" table[departure][useAllLines] "1" table[departure][linesFilter] "" table[departure][optimizedForStation] "0" table[departure][rowCount] "6" table[departure][refreshInterval] "60" table[departure][distance] "0" table[departure][marquee] "-1" table[sortBy] "0"
Feldwerte
- table[departure][transport]
| 0 | ICE/IC/EC |
| 1 | Zug |
| 2 | S-Bahn |
| 3 | U-Bahn |
| 4 | Straßenbahn |
| 5 | Bus |
| 6 | Schwebebahn |
Response
Die Antwort kommt als JSON-Dokument zurück, damit lässt sich gut weiterarbeiten:
{
"departureData":[
{
"name":"2",
"lineNumber":"2",
"lineCode":"31002",
"subname":"Stadtbahn",
"direction":"Bielefeld, Altenhagen",
"directionCode":"H",
"route":"Bielefeld, Altenhagen",
"type":4,
"day":"23",
"month":"4",
"year":"2023",
"hour":"9",
"minute":"03",
"orgDay":"23",
"orgHour":"9",
"orgMinute":"00",
"countdown":"4",
"platform":"",
"delay":"3",
"isRealTime":true,
"isDateOverflow":false,
"lineInfo":{
"lineInfo":{
"messages":[
],
"text":"",
"priority":0
},
"lineBlocking":{
"messages":[
],
"text":"",
"priority":0
}
},
"fullTime":"1682233380",
"orgFullTime":"1682233200",
"supplement":"",
"key":"231"
},
{
"name":"2",
"lineNumber":"2",
"lineCode":"31002",
"subname":"Stadtbahn",
"direction":"Bielefeld, Sieker",
"directionCode":"R",
"route":"Bielefeld, Sieker",
"type":4,
"day":"23",
"month":"4",
"year":"2023",
"hour":"9",
"minute":"04",
"orgDay":"23",
"orgHour":"9",
"orgMinute":"04",
"countdown":"5",
"platform":"",
"delay":"0",
"isRealTime":true,
"isDateOverflow":false,
"lineInfo":{
"lineInfo":{
"messages":[
],
"text":"",
"priority":0
},
"lineBlocking":{
"messages":[
],
"text":"",
"priority":0
}
},
"fullTime":"1682233440",
"orgFullTime":"1682233440",
"supplement":"",
"key":"38"
},
{
"name":"2",
"lineNumber":"2",
"lineCode":"31002",
"subname":"Stadtbahn",
"direction":"Bielefeld, Altenhagen",
"directionCode":"H",
"route":"Bielefeld, Altenhagen",
"type":4,
"day":"23",
"month":"4",
"year":"2023",
"hour":"9",
"minute":"15",
"orgDay":"23",
"orgHour":"9",
"orgMinute":"15",
"countdown":"16",
"platform":"",
"delay":"0",
"isRealTime":true,
"isDateOverflow":false,
"lineInfo":{
"lineInfo":{
"messages":[
],
"text":"",
"priority":0
},
"lineBlocking":{
"messages":[
],
"text":"",
"priority":0
}
},
"fullTime":"1682234100",
"orgFullTime":"1682234100",
"supplement":"",
"key":"234"
},
{
"name":"2",
"lineNumber":"2",
"lineCode":"31002",
"subname":"Stadtbahn",
"direction":"Bielefeld, Sieker",
"directionCode":"R",
"route":"Bielefeld, Sieker",
"type":4,
"day":"23",
"month":"4",
"year":"2023",
"hour":"9",
"minute":"19",
"orgDay":"23",
"orgHour":"9",
"orgMinute":"19",
"countdown":"20",
"platform":"",
"delay":"0",
"isRealTime":true,
"isDateOverflow":false,
"lineInfo":{
"lineInfo":{
"messages":[
],
"text":"",
"priority":0
},
"lineBlocking":{
"messages":[
],
"text":"",
"priority":0
}
},
"fullTime":"1682234340",
"orgFullTime":"1682234340",
"supplement":"",
"key":"40"
},
{
"name":"2",
"lineNumber":"2",
"lineCode":"31002",
"subname":"Stadtbahn",
"direction":"Bielefeld, Altenhagen",
"directionCode":"H",
"route":"Bielefeld, Altenhagen",
"type":4,
"day":"23",
"month":"4",
"year":"2023",
"hour":"9",
"minute":"30",
"orgDay":"23",
"orgHour":"9",
"orgMinute":"30",
"countdown":"31",
"platform":"",
"delay":"0",
"isRealTime":true,
"isDateOverflow":false,
"lineInfo":{
"lineInfo":{
"messages":[
],
"text":"",
"priority":0
},
"lineBlocking":{
"messages":[
],
"text":"",
"priority":0
}
},
"fullTime":"1682235000",
"orgFullTime":"1682235000",
"supplement":"",
"key":"236"
},
{
"name":"2",
"lineNumber":"2",
"lineCode":"31002",
"subname":"Stadtbahn",
"direction":"Bielefeld, Sieker",
"directionCode":"R",
"route":"Bielefeld, Sieker",
"type":4,
"day":"23",
"month":"4",
"year":"2023",
"hour":"9",
"minute":"34",
"orgDay":"23",
"orgHour":"9",
"orgMinute":"34",
"countdown":"35",
"platform":"",
"delay":"0",
"isRealTime":true,
"isDateOverflow":false,
"lineInfo":{
"lineInfo":{
"messages":[
],
"text":"",
"priority":0
},
"lineBlocking":{
"messages":[
],
"text":"",
"priority":0
}
},
"fullTime":"1682235240",
"orgFullTime":"1682235240",
"supplement":"",
"key":"43"
}
],
"departureInfo":{
"stopInfo":{
"text":""
},
"stopBlocking":{
"text":""
},
"areaInfo":{
"text":""
},
"areaBlocking":{
"text":""
}
},
"globalInfo":"",
"stationName":"Bielefeld, Ziegelstra\u00dfe",
"marquee":-1,
"stationInfo":[
],
"currentTime":1682233123,
"currentTimeReal":1682233123
}
Q&D Example
"Bielefeld existiert, und PHP ist OK" ;)
<?php
$url = "https://haltestellenmonitor.vrr.de/backend/api/stations/table";
$data = "table%5Bdeparture%5D%5BstationId%5D=23005614&table%5Bdeparture%5D%5BstationName%5D=Bielefeld+Ziegelstra%C3%9Fe&table%5Bdeparture%5D%5BplatformVisibility%5D=1&table%5Bdeparture%5D%5Btransport%5D=0%2C1%2C2%2C3%2C4%2C15%2C6&table%5Bdeparture%5D%5BuseAllLines%5D=1&table%5Bdeparture%5D%5BlinesFilter%5D=&table%5Bdeparture%5D%5BoptimizedForStation%5D=0&table%5Bdeparture%5D%5BrowCount%5D=6&table%5Bdeparture%5D%5BrefreshInterval%5D=60&table%5Bdeparture%5D%5Bdistance%5D=0&table%5Bdeparture%5D%5Bmarquee%5D=-1&table%5BsortBy%5D=0";
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
$resp = curl_exec($curl);
curl_close($curl);
$data = json_decode($resp, true);
foreach ($data["departureData"] as $dep) {
$dir = $dep["direction"];
$time = strftime("%R", $dep["orgFullTime"]);
if ($dep["delay"] > 0) {
$time .= " +".$dep["delay"];
}
$left = ($dep["fullTime"] - time())/60;
printf("+%-3d %-15s %s\n", $left, $time, $dir);
}
Nextride in der Sudbrackstraße
Der nextride-Teil bestand aus einem Haskell-Programm, welches cronjob-gesteuert die Bahn-Seite für die nächstgelegene Straßenbahnhaltestelle abgriff und die Abfahrtszeiten als JSON in eine Datei schrieb. Diese Datei wurde bei Änderung vom Infobeamer (Armageddon_Notifier) per Lua-Script eingelesen und dargestellt.
Diese Lösung funktioniert aus verschiedenen Gründen leider nicht mehr, unter anderem weil das damals genutzte API der Bahn keine Daten anderer Verkehrsbetriebe mehr zur Verfügung stellt.