Add Departures screen (train departure board)

New screens/departures.py using the free, unofficial db-vendo-client REST
API (v6.db.transport.rest) -- no key needed, same "no API key" philosophy
as Weather's Open-Meteo integration. Community-run infra though, not
official DB, and it was actually down (503, then timing out entirely) for
the whole time I was building this -- couldn't live-verify against real
data the way Open-Meteo was earlier, so I built the parsing against the
project's documented example response and stress-tested render() with
mocked requests.get() covering on-time/delayed/cancelled/missing-platform/
very-long-direction cases instead. check() fails soft (logs a warning,
returns None) on any request error, matching the "service might be down"
reality of this API -- the screen shows a plain "not available" message
rather than erroring out.

Settings: station name (resolved to a station ID via /locations, same
pattern as Weather's city->coordinates geocoding), how many departures to
show (3/5/8), and its own configurable update interval via the
get_poll_interval() mechanism built for Weather (defaults to 2 min --
departure boards go stale much faster than weather does).

Caught two real layout bugs while stress-testing render() before shipping:
line names ("ICE 1234") and delayed/cancelled time text ("Fällt aus") were
both wider than the columns I'd budgeted for them, with the second one
overlapping the direction text when right-aligned past its column's own
left edge. Fixed by measuring actual worst-case widths at the chosen font
size instead of guessing, and truncating every field to its column as a
defensive backstop regardless.
This commit is contained in:
Honey committed 2026-07-22 21:38:20 +02:00
1 parent 889c062212
commit 8c9b3e1bfa
6 files changed
+287 -2

No files matched your search

+2
View File
@@ -1,4 +1,5 @@
from screens.clock import ClockScreen
from screens.departures import DeparturesScreen
from screens.navidrome import NavidromeScreen
from screens.picture import PictureScreen
from screens.weather import WeatherScreen
@@ -6,6 +7,7 @@ from screens.weather import WeatherScreen
SCREEN_CLASSES = {
ClockScreen.id: ClockScreen,
WeatherScreen.id: WeatherScreen,
DeparturesScreen.id: DeparturesScreen,
PictureScreen.id: PictureScreen,
NavidromeScreen.id: NavidromeScreen,
}