Files
sachsen_pegel_proxy/README.md
T
Matthias JacobandCopilot b9cee0a7fb feat: add alarm_thresholds to pegel detail endpoint
Scrape the official alarm level thresholds (Richtwasserstände) from the
station detail page and include them in GET /api/pegel/{pegel_id} as
alarm_thresholds, cached for 24 hours with a stale-cache fallback on
errors. null for stations without a flood alert function.

Also clarify in the flood_alert_level docs that 'Kein Hochwassermeldepegel'
means the station is not used for official flood alerts/control, not
that measurement data is missing.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-10-28 01:42:10 +01:00

232 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Sachsen Pegel Proxy
Kleiner FastAPI-Dienst, der Pegelstationen und Messwerte aus dem sächsischen Hochwasser- und Wasserstands-Informationssystem (HWIMS) als JSON bereitstellt. Die Daten stammen aus der offiziellen Stationsübersicht und den RSS-Feeds der Stationen.
## Live-Dienst und API-Dokumentation
- API-Basis-URL: <https://sachsen-pegel-proxy.vercel.app>
- Interaktive Swagger-Dokumentation: <https://sachsen-pegel-proxy.vercel.app/docs>
- Alternatives ReDoc: <https://sachsen-pegel-proxy.vercel.app/redoc>
- OpenAPI-Schema: <https://sachsen-pegel-proxy.vercel.app/openapi.json>
Alle API-Antworten sind JSON. Die Endpunkte benötigen keine Authentifizierung.
## Endpunkte
| Methode | Pfad | Beschreibung |
| --- | --- | --- |
| `GET` | `/api/pegel` | Verfügbare Pegelstationen auflisten |
| `GET` | `/api/pegel/{pegel_id}` | Messwerte und Feed-Historie einer Station abrufen |
### Stationsliste
`GET /api/pegel`
Optional kann die Anzahl der zurückgegebenen Stationen mit `limit` begrenzt werden:
```text
GET /api/pegel?limit=5
```
`limit` muss eine positive ganze Zahl sein. `count` ist die Anzahl der tatsächlich zurückgegebenen Elemente; `total_available` gibt die Gesamtzahl der gefundenen Stationen an und wird durch `limit` nicht verändert.
Beispielantwort:
```json
{
"count": 1,
"total_available": 312,
"items": [
{
"station_id": "560021",
"station_title": "Golzern 1 / Vereinigte Mulde",
"source": "https://www.umwelt.sachsen.de/umwelt/infosysteme/hwims/portal/web/feed/wasserstand-pegel-560021"
}
],
"source": "https://www.umwelt.sachsen.de/umwelt/infosysteme/hwims/portal/web/wasserstand-uebersicht",
"fetched_at": "2026-05-05T00:15:00+00:00"
}
```
| Feld | Typ | Bedeutung |
| --- | --- | --- |
| `count` | integer | Anzahl der Elemente in `items` |
| `total_available` | integer | Gesamtzahl der gefundenen Stationen vor Anwendung von `limit` |
| `items` | array | Stationen mit `station_id`, `station_title` und RSS-Feed-URL `source` |
| `station_title` | string oder `null` | Stationsname, sofern er aus der Quelle ermittelt werden konnte |
| `source` | string | Verwendete Discovery-Quelle; beim Cache-Fallback der Wert `"cache"` |
| `fetched_at` | string | Zeitpunkt der Antworterstellung als ISO-8601-Zeitstempel |
| `warnings` | array, optional | Hinweise auf Fehler der Discovery-Quelle, wenn ein Cache-Fallback verwendet wurde |
| `cache_fetched_at` | string, optional | Zeitpunkt, an dem der verwendete Discovery-Cache geladen wurde; nur beim Cache-Fallback |
Die Stationsübersicht wird intern 15 Minuten zwischengespeichert. Ist die Quelle vorübergehend nicht erreichbar, liefert der Dienst vorhandene Cache-Daten mit `warnings` und `cache_fetched_at`. Gibt es keinen verwendbaren Cache, antwortet der Endpunkt mit HTTP `502`.
### Messwerte einer Station
`GET /api/pegel/{pegel_id}`
Die Pegel-ID muss aus mindestens sechs Ziffern bestehen. Der Endpunkt liefert alle Einträge, die im RSS-Feed der Station verfügbar sind. `latest` ist der neueste Messwert und entspricht dem ersten Eintrag in `entries`.
```text
GET /api/pegel/560021
```
Beispielantwort:
```json
{
"station_id": "560021",
"station_title": "Golzern 1 / Vereinigte Mulde",
"count": 2,
"latest": {
"timestamp": "2026-05-05T02:15:00+02:00",
"title": "Wasserstand und Durchfluss für 05.05.2026 02:15 Uhr (MESZ)",
"water_level_cm": 98.0,
"flow_m3s": 20.8,
"flood_alert_level": "Kein Hochwasser"
},
"entries": [
{
"timestamp": "2026-05-05T02:15:00+02:00",
"title": "Wasserstand und Durchfluss für 05.05.2026 02:15 Uhr (MESZ)",
"water_level_cm": 98.0,
"flow_m3s": 20.8,
"flood_alert_level": "Kein Hochwasser"
},
{
"timestamp": "2026-05-05T02:00:00+02:00",
"title": "Wasserstand und Durchfluss für 05.05.2026 02:00 Uhr (MESZ)",
"water_level_cm": 98.0,
"flow_m3s": 20.8,
"flood_alert_level": "Kein Hochwasser"
}
],
"alarm_thresholds": [
{ "level": 1, "water_level_cm": 360 },
{ "level": 2, "water_level_cm": 400 },
{ "level": 3, "water_level_cm": 480 },
{ "level": 4, "water_level_cm": 600 }
],
"source": "https://www.umwelt.sachsen.de/umwelt/infosysteme/hwims/portal/web/feed/wasserstand-pegel-560021",
"fetched_at": "2026-05-05T00:16:00+00:00"
}
```
| Feld | Typ | Bedeutung |
| --- | --- | --- |
| `station_id` | string | Angefragte Pegel-ID |
| `station_title` | string oder `null` | Stationsname aus dem RSS-Feed |
| `count` | integer | Anzahl der vom Feed gelieferten Einträge |
| `latest` | Objekt | Neuester Eintrag; identisch mit `entries[0]` |
| `entries` | array | Feed-Einträge in der Reihenfolge der Quelle, normalerweise neueste zuerst |
| `timestamp` | string oder `null` | Messzeitpunkt als ISO-8601 mit Zeitzonenoffset |
| `title` | string oder `null` | Originaltitel des RSS-Eintrags |
| `water_level_cm` | number oder `null` | Wasserstand in Zentimetern |
| `flow_m3s` | number oder `null` | Durchfluss in Kubikmetern pro Sekunde |
| `flood_alert_level` | string oder `null` | Meldestufe als Text, siehe unten |
| `alarm_thresholds` | array oder `null` | Richtwasserstände der Alarmstufen 1–4, siehe unten |
| `source` | string | URL des verwendeten RSS-Feeds |
| `fetched_at` | string | Zeitpunkt des Abrufs durch die API als UTC-Zeitstempel |
Ein Messwert ist `null`, wenn er im jeweiligen RSS-Eintrag fehlt oder nicht erkannt werden kann. Zeitstempel werden, wenn möglich, aus der Uhrzeit im RSS-Titel gebildet; andernfalls verwendet die API das Datumsfeld des Feeds. Sommer- und Winterzeit werden als Offset berücksichtigt.
Einträge ohne Wasserstand und ohne Durchfluss (Platzhalter der Quelle für noch nicht verfügbare Messwerte, Meldestufe „Keine aktuellen Daten verfügbar“) werden herausgefiltert. `latest` ist daher der neueste Eintrag mit mindestens einem Messwert und kann vom neuesten Eintrag der Quelle abweichen.
### Werte von `flood_alert_level`
| Wert | Bedeutung |
| --- | --- |
| `Niedrigwasser` | Niedrigwasser |
| `Kein Hochwasser` | Hochwassermeldepegel, Richtwerte nicht erreicht |
| `Kein Hochwassermeldepegel` | Der Pegel wird nicht für amtliche Hochwassermeldungen bzw. -steuerung genutzt. Das bedeutet nicht, dass Messwerte fehlen; solche Pegel haben lediglich keine Alarmstufen und `alarm_thresholds` ist `null` |
| `Alarmstufe 1` bis `Alarmstufe 4` | Richtwert der jeweiligen Alarmstufe überschritten (1 Meldedienst, 2 Kontrolldienst, 3 Wachdienst, 4 Hochwasserabwehr) |
Die ersten drei Werte wurden in den Feeds aller Pegel beobachtet. Die Alarmstufen stammen aus der Legende der HWIMS-Übersichtsseite; ihre genaue Schreibweise im RSS-Feed ist nicht verifiziert, da sie bei der Prüfung nicht aufgetreten sind. Clients sollten unbekannte Werte tolerieren.
### `alarm_thresholds`
Richtwasserstände (in cm), ab denen die jeweilige Alarmstufe laut HWIMS gilt. Die Werte werden von der Pegel-Detailseite (nicht dem RSS-Feed) ermittelt und 24 Stunden zwischengespeichert, da sie sich praktisch nie ändern. Ist die Detailseite nicht erreichbar, liefert die API einen vorhandenen (ggf. abgelaufenen) Cache-Wert oder `null`, ohne dass die übrige Antwort davon betroffen ist. Pegel ohne Hochwassermeldefunktion (`flood_alert_level` = `Kein Hochwassermeldepegel`) haben keine Richtwasserstände; hier ist das Feld `null`.
| Feld | Typ | Bedeutung |
| --- | --- | --- |
| `level` | integer | Alarmstufe, 1 bis 4 |
| `water_level_cm` | integer | Richtwasserstand dieser Alarmstufe in Zentimetern |
## Fehlerantworten
Fehler der API enthalten ein JSON-Objekt mit dem Feld `detail`.
| HTTP-Status | Ursache | Beispiel für `detail` |
| --- | --- | --- |
| `400` | `limit` ist kleiner oder gleich null | `Ungültiger limit-Parameter` |
| `400` | Pegel-ID hat nicht mindestens sechs Ziffern | `Ungültige Pegel-ID` |
| `404` | Feed enthält keine Einträge mit Messwerten für die Pegel-ID | `Keine Daten gefunden` |
| `422` | Query-Parameter kann nicht als Zahl interpretiert werden | FastAPI-Validierungsfehler |
| `502` | Stationsübersicht nicht erreichbar und kein Cache vorhanden | `Upstream-Discovery nicht verfügbar` |
## Beispiele
Mit `curl`:
```bash
curl "https://sachsen-pegel-proxy.vercel.app/api/pegel?limit=5"
curl "https://sachsen-pegel-proxy.vercel.app/api/pegel/560021"
```
### Home Assistant
```yaml
rest:
- resource: "https://sachsen-pegel-proxy.vercel.app/api/pegel/560021"
scan_interval: 300
sensor:
- name: "Pegel Golzern Wasserstand"
value_template: "{{ value_json.latest.water_level_cm }}"
unit_of_measurement: "cm"
json_attributes_path: "$.latest"
json_attributes:
- timestamp
- flow_m3s
- flood_alert_level
```
## Lokale Entwicklung
```bash
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -r requirements.txt
uvicorn api.app:app --reload
```
Lokal erreichbare Endpunkte:
- API: <http://127.0.0.1:8000/api/pegel>
- Swagger: <http://127.0.0.1:8000/docs>
- ReDoc: <http://127.0.0.1:8000/redoc>
- OpenAPI: <http://127.0.0.1:8000/openapi.json>
## Bereitstellung auf Vercel
Das Repository enthält keine plattformspezifische Deployment-Konfiguration. Das Projekt kann mit Vercel verbunden und anschließend beispielsweise mit der CLI bereitgestellt werden:
```bash
npx vercel
npx vercel --prod
```
Nach der Bereitstellung beide API-Endpunkte und `/docs` prüfen.
## Datenquelle und Hinweise
Die Messwerte werden von der offiziellen Website des Freistaats Sachsen bereitgestellt:
- Übersicht: <https://www.umwelt.sachsen.de/umwelt/infosysteme/hwims/portal/web/wasserstand-uebersicht>
- Beispiel-Feed: <https://www.umwelt.sachsen.de/umwelt/infosysteme/hwims/portal/web/feed/wasserstand-pegel-560021>
- Beispiel-Detailseite (Quelle für `alarm_thresholds`): <https://www.umwelt.sachsen.de/umwelt/infosysteme/hwims/portal/web/wasserstand-pegel-560021>
Verfügbarkeit und Richtigkeit der Quelldaten werden nicht garantiert. Änderungen am Aufbau der HWIMS-Seiten oder RSS-Feeds können die Verarbeitung beeinträchtigen. Dieses Projekt ist nicht mit dem Freistaat Sachsen verbunden.
## Lizenz
MIT