
efand
Motivation

Departure boards have been existing for decades: almost every transport network in Germany offers one. These often contain real-time information about delays like fahrplan.guru, but departures do not update automatically the way they do on stop displays (besides advertisement). Google Maps doesn’t offer real-time information about departures in the city of Chemnitz. Often this information is not even accurate.
That’s when I came up with efand: a simple, lightweight departure board that has real time delay support and easy but beautiful user interface. At the beginning front and backend were implemented with Python (frontend: tkinter, customtkinter, backend: Flask), however, the containerization of the application became too complex, so that I switched to JavaScript + Python (front- and backend are now isolated from each other).
efand stands for EFA + elephant. Elephants are resource-saving: they require little food and water to survive. Lightweight software requires fewer resources than traditional software, making it a good choice for devices with limited resources. Elephants are adaptable. They can navigate a variety of environments, from savannah to jungle. efand can be easily adapted to the user’s station he wishes.
Problem

Right at the beginning of the development, I had to realize that public documentation was not available or even desired. So my information about the EFA interface is based exclusively on publicly available documents or presentations, code snippets in repositories and blog articles. I have linked some of the resources below.
The departure board should run on some 4K TV screen throughout the day and update continuously without error.
Implementation
General
The architecture is essentially the same as the client-server architecture. The client makes queries to the server for departures and search results. The server processes these and returns JSON results. Using JavaScript, the results are then dynamically updated and displayed in the application.
Lastly, a stress test was performed where the departure board updated continuously for at least 24h without any problems (approx. 2880 queries a day).
Frontend

The Bootstrap framework served as the basis. Components such as the striped tables or search bars were used, with additional design adjustments in index.css
.
The station search bar supports autocomplete suggestions, which is implemented by autocomplete-library, which supports Bootstrap 5 (see resources). If a user enters more than three letters, the prompt will at most show three station suggestions. Selecting by mouse or arrow keys and then click triggers the change station event. All entries of the departure board will be reset and replaced at this point.
A new stop query is sent every 30 seconds to receive the most current data. Threshold can be modified in the source code.
Backend

settings.json contains all relevant static data regarding queries. Such as data about current EFA version, station, stop and suggestion query header information. These can only be changed manually (for example, if I type in some other station and take that suggestion). Backend consists out of the following components:
util.py
: Utilities, helper methods and enables read/write into settings file.
suggestion.py
: Implementation of retrieving search suggestions. JSON
-like object containing all (max. three) search suggestions, sorted by best and quality of result. Actual query is done by EFA request handler in efa.py
.
departures.py
: Processes departures, interacts with EFA request handler. Departure list is sorted by next arrival. This class provides methods to return specific no. values and retrieve dictionary objects of departures.
efa.py
: Request handler for stop finder and suggestion queries. Adds dynamic information such as date, time to queries (excluded from settings).
interface.py
: Provides the API paths and enables communication, parsing header input into the other modules.
station.py
: Class models station objects and allows changing station and returning object as dictionary. At any current time, there can just one station object exist.
Backend serves as an adapter and shortens the query results of the EFA interface by the few, relevant values for visualization purposes.
Outlook
In the event of road works or accidents, the course of the journey may be severely delayed or even changed. At the stops, the displays can already provide such important information. Therefore, it would make sense to dynamically integrate status messages in the future that provide exactly such information. The API provides such information in part.
Next, GPS functionality is targeted: If confirmation for location is given, then the nearest stop is automatically selected. Until now, the stop must be determined and selected by means of a search. For this purpose, the coordinates must be read out and transferred to the interface as a query.
Screenshot(s)

Resources
- used technologies: HTML, CSS, Javascript, Bootstrap framework, Bootstrap Autocomplete library, Python, Flask and Flask-CORS library
- Git repository efand on GitLab
- Depature board of Merseytravel
- EFA-Linz docs (pdf, [1], [2])
- TfL Journey Planer (docs)
- Ruttloff, Stephan: VmsStationScraper on GitHub