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.
18 lines
536 B
Python
18 lines
536 B
Python
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
|
|
|
|
SCREEN_CLASSES = {
|
|
ClockScreen.id: ClockScreen,
|
|
WeatherScreen.id: WeatherScreen,
|
|
DeparturesScreen.id: DeparturesScreen,
|
|
PictureScreen.id: PictureScreen,
|
|
NavidromeScreen.id: NavidromeScreen,
|
|
}
|
|
|
|
|
|
def create_screens() -> dict:
|
|
return {screen_id: cls() for screen_id, cls in SCREEN_CLASSES.items()}
|