Compare commits

...

2 commits

Author SHA1 Message Date
6565d6a999 DWD-Pipeline: Dauer-Container mit 5-Min-Schleife statt DSM-Cron
DSM-Aufgabenplaner kann minimal stuendlich (Rene) — Container laeuft jetzt
dauerhaft (restart: unless-stopped) mit interner Schleife (loop.sh, idle =
sh+sleep, Python/GDAL nur waehrend des Laufs). Einmal 'up -d --build',
ueberlebt Reboots. make_radar_tiles.py ist idempotent, Fehler brechen die
Schleife nicht.
2026-06-06 18:21:52 +02:00
e6558b64d3 DWD-Plan: Umsetzungsstand dokumentiert (Staging v1240, Cron + Geraetetest offen) 2026-06-06 18:13:30 +02:00
4 changed files with 46 additions and 5 deletions

View file

@ -1,6 +1,8 @@
# DWD-Regenvorhersage-Pipeline (RV-Komposit → PMTiles-Frames) — NICHT Teil des Default-Stacks.
# Trigger: DSM-Aufgabenplaner ALLE 5 MINUTEN:
# docker compose -f docker-compose.dwd.yml run --rm dwd-radar
# DAUER-CONTAINER mit interner 5-Min-Schleife (loop.sh): der DSM-Aufgabenplaner kann nur
# stündlich, daher KEIN Cron. Einmal starten (überlebt Reboots via restart-Policy):
# docker compose -f docker-compose.dwd.yml up -d --build
# Stoppen: docker compose -f docker-compose.dwd.yml down
# ⚠️ NIE mit --remove-orphans aufrufen (löscht den App-Container)!
# Schreibt ins data-Volume (./data/radar) — ausgeliefert von main.py /radar/* (Range-Route).
# Georeferenzierung PoC-bewiesen 2026-06-08, s. tools/dwd-radar/ + docs/DWD_RAIN_FORECAST_PLAN.md.
@ -13,6 +15,7 @@ services:
volumes:
- ./data/radar:/out
environment:
- INTERVAL_S=300 # Schleifen-Intervall (RV-Läufe kommen alle 5 Min)
- FRAME_STEP=1 # alle 25 Frames (5-Min-Schritte); 2 = 10-Min-Schritte falls DS-Last zu hoch
- KEEP_RUNS=2
restart: "no"
restart: unless-stopped

View file

@ -1,6 +1,28 @@
# DWD Regen-Vorhersage (Radar-Nowcast) — Scoping-Plan
**Status:** gescoppt + Datenformat verifiziert (2026-06-05). Umsetzung offen.
**Status:** UMGESETZT auf Staging (v1240, 2026-06-08) — PoC bestanden, Pipeline + Frontend live.
**Offen:** DSM-Aufgabenplaner-Cron (alle 5 Min, Staging + Prod) anlegen; Gerätetest; Prod-Deploy.
## Umsetzung (2026-06-08)
- **PoC Georeferenzierung BESTANDEN** (`tools/dwd-radar/poc/`): DE1200 = polar-stereografisch auf
WGS84-Ellipsoid (wradlib-Parameter, False Easting/Northing 543196.835/3622588.862 → LL-Ecke (0,0);
in GDAL-Konvention y südwärts negativ, Gitter y ∈ [-1200000, 0]). Anker (9°E, 51°N) = Mitte von
Pixel (470/600) ✓, Ecken decken sich mit der DE1200-Spec ✓.
- **Pipeline** `tools/dwd-radar/make_radar_tiles.py` (Container: GDAL + go-pmtiles): RV-Komposit →
je Frame dekodieren → RGBA-Farbskala (transparent < 0,05 mm/5min) Warp 3857 MBTiles z7-Basis
+ Overviews bis z4 → PMTiles. 25 Frames ≈ 14 s (Mac) / ~30 s (DS). Manifest + atomarer Swap
(`run-<id>/`), KEEP_RUNS=2. `docker-compose.dwd.yml`**DSM-Aufgabenplaner ALLE 5 MIN**:
`cd <pfad> && docker compose -f docker-compose.dwd.yml run --rm dwd-radar` (⚠️ NIE --remove-orphans).
- **Serving** main.py: `/radar/manifest.json` (no-store) + `/radar/{run}/{file}` (Range/206,
immutable — Run-Id im Pfad). sw.js: `/radar/` Pass-through.
- **Frontend** map.js: Radar-Frames heterogen (`{url, time, dwd}`) — DWD ersetzt den RainViewer-
Nowcast (0120 min) wenn: Toggle an + GL-Modus + Kartenmitte in DE1200-Bbox + Manifest frisch
(< 30 min). Sonst RainViewer-Fallback (auch außerhalb DE / offline / DWD-Ausfall). DWD-Frames
als `pmtiles://`-Raster-Template über das vorhandene Protokoll; Label „+X Min · DWD".
- **Settings-Toggle** „DWD-Regenvorhersage" (`by_dwd_radar`, Default AN), settings.js.
(Ursprüngliches Scoping:)
~~**Status:** gescoppt + Datenformat verifiziert (2026-06-05). Umsetzung offen.~~
**Ziel:** Verlässliche, längere Regen-**Vorhersage** als animiertes Karten-Overlay (bis +2 h) statt RainViewers
unzuverlässigem 30-Min-Nowcast (der oft leer ist). Self-hosted wie die Basemap — passt zur Tile-Server-Philosophie.

View file

@ -11,5 +11,9 @@ RUN ARCH=$([ "$TARGETARCH" = "arm64" ] && echo arm64 || echo x86_64) && \
rm /tmp/pmtiles.tar.gz && pmtiles version || true
COPY make_radar_tiles.py /app/make_radar_tiles.py
COPY loop.sh /app/loop.sh
RUN chmod +x /app/loop.sh
WORKDIR /app
CMD ["python3", "/app/make_radar_tiles.py"]
# Dauerbetrieb mit interner 5-Min-Schleife (DSM-Aufgabenplaner kann nur stündlich).
# Einmal-Lauf weiterhin möglich: docker compose run --rm dwd-radar python3 /app/make_radar_tiles.py
CMD ["/app/loop.sh"]

12
tools/dwd-radar/loop.sh Normal file
View file

@ -0,0 +1,12 @@
#!/bin/sh
# Endlos-Schleife statt Cron: Der DSM-Aufgabenplaner kann minimal stündlich (René 2026-06-08),
# die RV-Läufe kommen aber alle 5 Minuten. Der Container läuft daher dauerhaft (restart:
# unless-stopped) und schläft zwischen den Läufen — idle ist nur die sh+sleep (winzig),
# Python/GDAL leben nur während des Laufs. make_radar_tiles.py ist idempotent
# (gleicher Lauf vorhanden → sofort fertig), Fehler brechen die Schleife nicht.
INTERVAL="${INTERVAL_S:-300}"
echo "DWD-Radar-Loop: alle ${INTERVAL}s (INTERVAL_S zum Ändern)"
while true; do
python3 /app/make_radar_tiles.py || echo "Lauf fehlgeschlagen — nächster Versuch in ${INTERVAL}s"
sleep "$INTERVAL"
done