Abfahrtsmonitor für die heimische Haltestelle

Aus LinuxUser 06/2024

Abfahrtsmonitor für die heimische Haltestelle

© Olena Yakobchuk / 123RF.com

Abgefahren!

Ein auf Ihre Bedürfnisse zugeschnittener Abfahrtsmonitor sorgt dafür, dass Sie nicht sinnlos an der Haltestelle auf den nächsten Bus warten.

Nach wie vor ist in Deutschland wenig Verlass auf die Pünktlichkeit der öffentlichen Verkehrsmittel. Zum Glück gibt es Webseiten und Apps, die Verspätungen in Echtzeit anzeigen. Bei kurzfristigen Ausfällen oder Streckensperrungen taugen die Daten wenig: Da haben selbst Fahrdienstleiter und Fahrzeugführer oft keine Infos. Im Großen und Ganzen sind die verfügbaren Daten aber recht zuverlässig.

Als Bastelidee gibt es deshalb in diesem Artikel einen Abfahrtsmonitor für die eigene Haltestelle. Statt Smartphone-Fummelei genügt ein schneller Blick auf die kleine Appliance: So behalten Sie den morgendlichen Ablauf im Griff. Die Projektaufgabe teilt sich dabei in zwei Bereiche: das Eruieren und die Anzeige der Daten.

Verkehrsdaten

Deutschlandweit buhlen mehr als 100 Verkehrs-Apps um die Gunst der Nutzer. Alleine in München gibt es eine vom Verkehrsverbund (MVV) selbst und jeweils eine von den Mitgliedsfirmen (MVG und Bahn). Wahrscheinlich sind es noch mehr. Zum Glück zeigen alle ungefähr dasselbe an. Das verdanken wir der EU-Verordnung 2010/40/EU, die zum Datenaustausch verpflichtet.

Als Maker kann man sich trotzdem nicht zurücklehnen, denn die Daten sind zwar zugänglich, aber nicht dokumentiert. Zum Glück gibt es Privatinitiativen, die eine einheitliche API entwickeln und darüber den Zugriff deutlich vereinfachen. Die hier vorgestellte Anwendung greift dabei auf die API v6.db.transport.rest [1] zu. Sie ist öffentlich zugänglich und lässt sich ohne Anmeldung nutzen, solange man den Server nicht mit Anfragen überflutet. Alternativ hosten Sie die Schnittstelle auch auf einem eigenen Server.

Der API-Server greift auf die Daten der Deutschen Bahn zurück, die zwar nicht alle, aber sehr viele Informationen liefert. Reicht das nicht aus, müssen Sie beim lokalen Verkehrsverbund auf die Suche gehen. Meist genügt dafür die Überwachung der Kommunikation des Browsers mit den Servern mittels der im Browser eingebauten Entwicklungswerkzeuge. Die dokumentieren unter anderem alle Zugriffe des Browsers, und neben viel Unbrauchbarem finden Sie so auch die URLs mit den eigentlichen Daten. Mühsam ist das trotzdem. Alternativ wenden Sie sich direkt an Ihren Verkehrsverbund. Eine Übersicht mit E-Mail-Adressen finden Sie online [2].

Schnittstellen

Zentrales Element in der v6-API ist die Stations-ID. Dabei handelt es sich um eine eindeutige Identifikation der Haltestelle. Zum Glück gibt es für die Suche auch eine Schnittstelle. Das Vorgehen besteht also darin, die entsprechende URL zusammenzubasteln, abzusenden und das Ergebnis auszulesen. Beispiel-URLs sehen Sie in Listing 1. Die erste Zeile sucht nach der Stations-ID, die zweite Zeile nach Abfahrten (Abbildung 1). Wie Sie sehen, führt die Bahn die Verspätung (delay) sekundengenau in ihren Systemen – man weiß nicht, ob man darüber lachen oder weinen soll.

Listing 1

API-URLs für Stationen und Abfahrten

https://v6.db.transport.rest/locations?query=Neu%20Perlach%Zentrum&results=10
https://v6.db.transport.rest/stops/8005676/departures?duration=10&linesOfStops=false&remarks=true&language=en&bus=false

Abbildung 1: Das Ergebnis einer Abfrage zum Ermitteln einer U-Bahn-Ankunft.

Abbildung 1: Das Ergebnis einer Abfrage zum Ermitteln einer U-Bahn-Ankunft.

Um die mühsame URL-Bastelei zu umgehen, entstanden als erster Schritt bei der Programmentwicklung zwei kleine Python-Skripte, die diese Aufgaben übernehmen (Abbildung 2). Beide erhalten Sie über das Projekt-Repository des Autors [3]. Das Readme.md zum Projekt beschreibt die notwendigen Schritte für die Softwareinstallation. Beide Skripte nutzen die Python-Klasse pyHafas [4], die eine objektorientierte Schnittstelle zur v6-API bereitstellt.

Abbildung 2: Die Ankunftszeiten der gewünschten Transportmittel lassen sich bequem via Kommandozeile abfragen.

Abbildung 2: Die Ankunftszeiten der gewünschten Transportmittel lassen sich bequem via Kommandozeile abfragen.

Die Stationssuche ist üblicherweise eine einmalige Angelegenheit. Sie benötigen die Stations-IDs für die von Ihnen genutzten Haltestellen sowie für solche, die die Richtung der Fahrt vorgeben. In aller Regel wollen Sie ja mit dem Bus zum Bahnhof und nicht in die andere Richtung. Völlig konsistent ist der Datenbestand der Bahn nicht. Für den Münchner Hauptbahnhof gibt es etwa mehrere Stations-IDs. Für manche Ziele führt die Bahn Abfahrten von Regionalzügen irrtümlich vom Tiefbahnhof auf, bei anderen Zielen gar nicht. Hier hilft nur ausprobieren.

Haben Sie die IDs beisammen, dann beginnen Sie mit der Suche nach den Abfahrten. Für Verbindungen gibt es ebenfalls eine Schnittstelle, die in diesem Artikel aber keine Rolle spielt. Diverse Parameter, die die Anzahl der Treffer einschränken, helfen bei der Abfahrtssuche – die Richtung wurde bereits erwähnt. Darüber hinaus können Sie auch die gewünschten Verkehrsmittel auswählen, etwa subway für U-Bahn oder suburban für S-Bahnen. Auch hier ist auf die Klassifizierung kein absoluter Verlass – die Bahn hat auch ICEs im Datenbestand, die fälschlicherweise unter suburban laufen.

Das Skript tools/departures.py unterstützt die parametrisierte Suche. Fans der Kommandozeile lassen es in einer Endlosschleife laufen und erhalten damit die aktuellen Abfahrten ständig auf dem Bildschirm. Als Alternative und für den PC-unabhängigen Betrieb bietet sich aber eine Kombination aus Mikrocontroller oder RasPi und einem Minibildschirm an.

Hardware …

Bei Projekten wie dem Abfahrtsmonitor sind Hard- und Software eng verwoben. Trotzdem schreibt der Autor gern über hardwareunabhängige Lösungen. Prinzipiell kommt ja eine große Auswahl an Hardware infrage, und am Anfang steht nicht fest, auf welcher davon letztlich das Programm läuft. Außerdem programmiert der Autor unterwegs häufig auf dem Laptop.

Diese Rahmenbedingungen machen CircuitPython zur ersten Wahl. Der Abfahrtsmonitor läuft damit vom PC über den RasPi bis hin zum Mikrocontroller mit fast identischem Code. Auf dem PC und dem RasPi emuliert Blinka [5] die Hardwareschicht. Hinzu kommt Pygame [6] zum Ansteuern herkömmlicher Bildschirme. Mikrocontroller steuern die Displays dagegen üblicherweise über die SPI-Schnittstelle an. Da es sich beim RasPi um einen Zwitter aus normalem Rechner und Mikrocontroller handelt, haben Sie dort die Wahl.

Abbildung 3 zeigt ein Badger 2040 W [7], Abbildung 4 ein MagTag [8]. Ersteres verbirgt hinter dem 296 x 128 Pixel großen E-Ink-Display einen Raspberry Pi Pico W. Das zweite verwendet ein fast identisches Display, jedoch von einem ESP32-S2 angetrieben. Die Wahl des Autors fiel nicht von ungefähr auf diese Geräte, denn die integrierten Taster erlauben das Blättern sowohl zwischen verschiedenen Stationen als auch zeitlich vor und zurück.

Abbildung 3: Das Badger 2040 W von Pimoroni erfordert wegen des beschränkten Hauptspeichers einige Klimmzüge.

Abbildung 3: Das Badger 2040 W von Pimoroni erfordert wegen des beschränkten Hauptspeichers einige Klimmzüge.


Abbildung 4: Das MagTag von Adafruit unterscheidet sich optisch kaum vom Pimoroni-Pendant, bringt aber mehr Hauptspeicher mit, was das Umsetzen des Projekts erleichtert.

Abbildung 4: Das MagTag von Adafruit unterscheidet sich optisch kaum vom Pimoroni-Pendant, bringt aber mehr Hauptspeicher mit, was das Umsetzen des Projekts erleichtert.

Der ESP32-S2 tut sich mit der Aufgabe insgesamt leichter, insbesondere deswegen, weil er deutlich mehr Hauptspeicher mitbringt. Um den Pico zur Zusammenarbeit zu überreden, bedurfte es einiger Klimmzüge. Beide Bildschirme könnten etwas breiter ausfallen, aber entsprechende Displays gibt es nicht in dieser Größe. Waveshare bietet ein paar extrem breitformatige Bildschirme an, dann benötigen Sie aber zwingend einen RasPi für die Aufgabe.

… und Software

Die Software folgt dem bekannten MVC-Prinzip (Model-View-Controller). Das Rahmenprogramm (Controller) ruft regelmäßig einen Daten-Provider auf (v6-API, Update des Modells) und delegiert die Anzeige an den View. Wie das im Detail funktioniert, lesen Sie im Quellcode nach [3]. Hier geben wir lediglich ein paar Hinweise.

Neben den im vorherigen Abschnitt erwähnten Bibliotheken verwendet das Programm noch eine eigene Hardwareabstraktionsschicht. Dabei handelt es sich je nach unterstützter Hardware um eine kleine Python-Datei, die Zugriff auf LED, Bildschirm und Taster abstrahiert. Für eigene Hardware müssen Sie also zuerst die passende Datei erstellen, am einfachsten durch Kopieren und Anpassen. Falls das von Ihnen genutzte Display keine Tasten besitzt, dann bietet sich ein Fünf-Wege-Button an, den es für wenig Geld auf den üblichen Marktplätzen gibt.

Damit die Mikrocontroller mit der Anwendung zurechtkommen, gilt es, mit dem Speicher sorgfältig zu haushalten. Dazu gibt es diverse Tricks. Einer davon nennt sich json_stream. Der naive Ansatz, die Daten der v6-API aus dem Netz zu laden und dann zu verarbeiten, scheitert womöglich an der Größe der zurückgelieferten Datei. Mit json_stream extrahieren Sie Informationen aus dem Datenstrom, ohne die gesamte Datei im Speicher zu halten. Jedes Byte des Datenstroms kommt aber immer nur einmal vorbei.

Völlig unproblematisch ist der Ansatz nicht, denn die interessanten Attribute müssen zum einen immer vorhanden sein und zum anderen immer in der richtigen Reihenfolge vorkommen. Im Fall des Abfahrtsmonitors gehören dazu plannedWhen, delay und direction. Das Attribut cancelled kommt dagegen einmal vor, einmal nicht. Die Suche danach mit json_stream leert den Datenstrom im ungünstigsten Fall also ohne ein Ergebnis, und für die anderen Attribute ist es dann zu spät.

Beim Pico genügt der Weg über json_stream aber noch nicht. Hier hilft ein automatischer Neustart vor jeder Datenabfrage. Wegen der minimalen Boot-Zeit des Mikrocontrollers fällt das jedoch nicht nennenswert ins Gewicht.

Fazit

Die Datenbeschaffung stellte sich letztlich doch als einfacher heraus als befürchtet. Auch wenn die Daten nicht perfekt sind, sie entsprechen in ihrer Qualität denen der offiziellen Webseiten beziehungsweise Apps. Der Zugang zu den eigentlichen Quellsystemen ist aufwendiger und mit einem Antrag samt Projektbeschreibung verbunden. Unter Open Data versteht der Autor aber definitiv etwas anderes als die deutschen Verkehrsverbünde.

Damit reduziert sich die Hauptaufgabe auf die Darstellung der Ergebnisse. Das Programm des Autors verfolgt einen minimalistischen Ansatz, der aber viel Luft nach oben lässt. Hier können Sie einsteigen und Ihrer Fantasie und Kreativität Raum geben. Bei Farbbildschirmen könnten Sie zum Beispiel Verspätungen rot einfärben. Damit auch lange Haltestellennamen auf das Display passen, zeigen Sie die Einträge alternativ zweizeilig an. Auch ein Portieren des Projekts auf MicroPython oder C/C++ dürfte kein Problem darstellen, denn die grundlegende Logik ist in jeder Programmiersprache dieselbe. (tle)

Der Autor

Bernhard Bablok ist im Ruhestand. Wenn er nicht Musik hört oder mit dem Radl respektive zu Fuß unterwegs ist, beschäftigt er sich mit Themen rund um Linux, Programmierung und Kleinstrechner. Sie erreichen ihn unter mailto:mail@bablokb.de.

DIESEN ARTIKEL ALS PDF KAUFEN
EXPRESS-KAUF ALS PDF
LinuxUser 06/2024 KAUFEN
EINZELNE AUSGABE
ABONNEMENTS
TABLET & SMARTPHONE APPS
E-Mail Benachrichtigung
Benachrichtige mich zu:

Hinweis: Dieser Artikel ist älter als ein Jahr, enthaltene Informationen sind möglicherweise veraltet.

0 Kommentare
Älteste
Neuste Beste Bewertung
Inline Feedbacks
Alle Kommentare anzeigen
Nach oben