2026-08-01 20:23:27 +00:00
2026-08-01 21:44:54 +02:00
2026-08-01 21:47:50 +02:00
2026-08-01 20:20:27 +02:00
2026-08-01 20:20:27 +02:00
2026-08-01 21:21:03 +02:00
2026-08-01 20:20:27 +02:00
2026-08-01 20:23:27 +00:00
2026-08-01 21:22:34 +02:00
2026-08-01 21:21:03 +02:00

mvg-departures

Kompakter Abfahrtsmonitor fuer MVG U-Bahn und S-Bahn (Muenchen), primaer fuer mobile Nutzung optimiert.

Features

  • Konfigurierbare Stationsliste (config.yaml) mit Typ (UBAHN/SBAHN/TRAM/BUS)
  • Ausschluss-Filter pro Station: nur unerwuenschte Zielrichtungen werden ausgeblendet, neue/unbekannte Ziele werden automatisch weiter angezeigt
  • Zwei Endpunkte:
    • / — mobile-optimierte HTML-Ansicht mit Auto-Refresh (alle 60s per Meta-Refresh)
    • /api/departures — JSON-Ausgabe derselben Daten
  • Anzeige von Linie, Ziel, Abfahrtszeit, Verspaetung und Stoerungsmeldungen
  • Visuelle Unterscheidung von U-Bahn (blau) und S-Bahn (gruen) per Icon

Screenshot der Webseite

Konfiguration

Siehe config.yaml:

refresh_seconds: 60
cache_seconds: 20
departures_limit: 10

stations:
  - name: "Josephsburg, München"
    type: "UBAHN"
    exclude_destinations:
      - "Messestadt Ost"
      - "Messestadt West"

  - name: "Berg am Laim, München"
    type: "SBAHN"
    exclude_destinations:
      - "Erding"
      - "Markt Schwaben"

exclude_destinations filtert per exaktem destination-Stringvergleich. Alles was NICHT in der Liste steht, wird angezeigt — so fallen Linienaenderungen/Umleitungen sofort auf, statt lautlos verschwunden zu sein.

Lokal starten

pip install -r requirements.txt
uvicorn app.main:app --reload

Docker

docker build -t mvg-departures .
docker run -p 8000:8000 -v $(pwd)/config.yaml:/app/config.yaml mvg-departures

Deployment (Beispiel docker-compose, nicht im Repo)

services:
  mvg-departures:
    image: ghcr.io/<github-user>/mvg-departures:latest
    container_name: mvg-departures
    ports:
      - "8090:8000"
    volumes:
      - ./config.yaml:/app/config.yaml:ro
    environment:
      - TZ=Europe/Berlin
    restart: unless-stopped
    labels:
      - "com.centurylinklabs.watchtower.enable=true"

CI/CD

.github/workflows/build.yml:

  • Baut bei jedem Push auf main das Docker-Image und pusht es nach ghcr.io/<owner>/<repo>:latest sowie mit Short-SHA-Tag
  • Anschliessender Cleanup-Job loescht alte Image-Versionen in der GHCR-Package-Registry und behaelt nur die letzten 4 Versionen (min-versions-to-keep: 4)

Voraussetzung

Repo-Settings → Actions → General → Workflow permissions auf "Read and write permissions" stellen, sonst schlaegt der Push nach GHCR fehl.

mvg api

https://www.mvg.de/api/bgw-pt/v3/locations?query=Josephsburg
https://www.mvg.de/api/bgw-pt/v3/locations?query=Berg%20am
https://www.mvg.de/api/bgw-pt/v3/departures?globalId=de:09162:1220&limit=10&transportTypes=UBAHN
https://www.mvg.de/api/bgw-pt/v3/departures?globalId=de:09162:910&limit=10&transportTypes=SBAHN

Endpunkte

Route Beschreibung
/ HTML-Ansicht, mobile-optimiert, Auto-Refresh alle 60s
/api/departures JSON-Liste aller gefilterten Abfahrten
/healthz Healthcheck fuer Docker/Watchtower

Projektstruktur

mvg-departures/
├── app/
│   ├── main.py           # FastAPI-App, Endpunkte, Caching
│   ├── config.py          # Config-Loader (YAML → Dataclasses)
│   └── templates/
│       └── index.html     # Jinja2-Template (Mobile-UI)
├── config.yaml            # Stationskonfiguration
├── requirements.txt       # Python-Dependencies
├── Dockerfile
└── .github/workflows/
    └── build.yml          # CI/CD: Docker-Build + GHCR-Push

Tech-Stack

  • Runtime: Python 3.12
  • Framework: FastAPI + Uvicorn
  • Templating: Jinja2 (server-seitig)
  • MVG-API: mvg Python-Client (oeffentlich, kein Auth noetig)
  • Config: YAML via pyyaml
  • Container: Docker (python:3.12-slim)

Caching

  • Station-ID: In-memory Dict, lifetime=Session (loest Station-Namen auf)
  • Abfahrten: In-memory Dict, TTL=cache_seconds (Default: 20s) pro Station+Typ
  • Keine Persistenz → Neustart = Cache-Verlust

Einschraenkungen

  • Kein WebSocket/Live-Updates (nur periodischer Meta-Refresh)
  • Keine Datenbank (nur In-Memory)
  • Kein Test-Framework vorhanden
  • Ein config.yaml pro Deployment (kein Multi-Tenancy)
S
Description
No description provided
Readme MIT
196 KiB
Languages
Python 56.8%
HTML 37.9%
Dockerfile 5.3%