- JavaScript 45.9%
- Python 29%
- Kotlin 18.9%
- HTML 6.1%
- Shell 0.1%
| android | ||
| server | ||
| tools/gezeiten | ||
| web | ||
| .gitignore | ||
| COPYRIGHT | ||
| LICENSE | ||
| README.md | ||
thee weather
Werbe- und trackingfreie Wetter-App mit amtlichem Regenradar, als Android-WebView-App mit Homescreen-Kacheln — und dieselbe Seite läuft im Browser unter https://wetter.example.org.
Aufbau
web/— die eigentliche Web-App (web/app/app.html,app.js) samt Test- und Entwicklungswerkzeug.android/— die Android-Schale (WebView + Kacheln). Bindet die Web-App zur Bauzeit aus../web/appein.server/deradar/,server/frradar/,server/nlradar/,server/nordradar/— eigene Dienste für das deutsche, französische, niederländische und nordische Radar (siehe unten), laufen auf dem Server; Anleitung je inREADME-DEPLOY.md.
Woher die Daten kommen
Vorhersage: Open-Meteo (Temperatur, Stundenverlauf, sieben Tage, Sonne und Mond) und dessen Geocoding für die Ortssuche; deutsche Postleitzahlen über openPLZ, weil Open-Meteo sie nicht kann.
Regenradar — fünf Quellen, je Ort wird EINE gewählt. Alle liefern eine gemessene Lage; auf der Karte steht nie eine Modellrechnung. Der Schieber beginnt beim neuesten gemessenen Bild und endet am amtlichen Horizont — außer im Norden, wo es kein Vorhersagebild gibt (s. Tabelle).
| Quelle | Gebiet | Auflösung | Kurzfrist | Zugang |
|---|---|---|---|---|
| eigener Dienst (DWD RADOLAN-RV) | Deutschland | 1 km, 5 Min | +2 h | wetter.example.org/deradar, kein Schlüssel |
| DWD (RADOLAN-RV) — nur noch Rückfall | Deutschland | 1 km, 5 Min | +2 h | WMS, kein Schlüssel, langsam (s. u.) |
KNMI (radar_forecast) |
Niederlande, Belgien, Westdeutschland | 1 km, 5 Min | +2 h | anonymer WMS, kein Schlüssel |
| eigener Dienst (Météo-France) | Frankreich | 500 m, 10 Min | +3 h | wetter.example.org/frradar, Schlüssel bleibt auf dem Server |
| eigener Dienst (DMI + MET Norway + SMHI) | Dänemark, Schweden, ganz Norwegen, Finnland | 500 m / 1 km / 2 km, 5 Min | nur am Ort (met.no), kein Bild | wetter.example.org/nordradar, kein Schlüssel |
| RainViewer | Rest der Welt | grob (Zoom ≤ 7) | keine | frei, nur der aktuelle Stand |
⚠ Der Norden ist der einzige Fall, in dem Karte und Regenzeile verschieden weit reichen. Die drei Ämter geben nur Messungen frei, keinen Nowcast als Gitter — der Schieber steht dort still. Die Regenzeile schaut trotzdem zwei Stunden weit, weil MET Norway seine Kurzfrist am PUNKT anbietet. Und die Werte sind dort überwiegend aus Reflektivität gerechnet (Marshall-Palmer), nicht mit Regenmessern geeicht wie RADOLAN-RV.
Norwegens eigene Radare kamen erst am 2026-08-15 dazu — nicht über api.met.no
(dessen Radar-Endpunkt gibt nur fertige BILDER heraus, was zuerst wie ein „geht
nicht" aussah), sondern über den THREDDS-Server desselben Amtes, wo dasselbe
Komposit als Werte liegt. Bis dahin fiel Westnorwegen auf RainViewer zurück.
Die Wahl geht nach Abdeckung, nicht nach Land: erst den DWD fragen, und wo der „außerhalb" meldet, KNMI. Ein Lat/Lon-Rechteck „Niederlande" fängt sonst zwangsläufig Köln und Düsseldorf mit ein.
Kartengrund sind OpenStreetMap-Kacheln.
Was die eigenen Dienste an Verkehr ziehen
Die vier Dienste holen rund um die Uhr fremde Dateien. Alle Zahlen sind EINGEHEND und aus den tatsächlichen Dateigrößen mal Takt gerechnet:
| Dienst | Was, wie oft | pro Tag |
|---|---|---|
frradar |
PIAF-Kurzfrist: 18 GRIB-Schritte à ~3,5 MB alle 15 Min | ~6,0 GB |
frradar |
dazu das Mess-Mosaik alle 5 Min | einige 100 MB |
nordradar |
MET Norway 12,7 MB + DMI 45 KB + SMHI 335 KB alle 5 Min | ~3,8 GB |
nlradar |
eine KNMI-Datei à 225 KB alle 5 Min | ~65 MB |
deradar |
eine DWD-Datei à ~770 KB alle 5 Min | ~220 MB |
| zusammen | ~10 GB/Tag ≈ 300 GB/Monat |
Ausgehend ist es dagegen fast nichts: die Kacheln gehen an eine Handvoll Geräte, und die Bilder liegen bei ~350 KB. Auf der Platte bleiben je Dienst nur die aktuellen Bilder und Quelldateien (zusammen unter 50 MB) — es wächst nichts an.
Die zwei großen Posten sind Kurzfrist-Schritte (FR) und Bildauflösung (NO), also beides Stellschrauben, kein Naturgesetz:
| Stellschraube | spart | kostet |
|---|---|---|
FRRADAR_PIAF_TAKT=1800 |
~3,0 GB/Tag | Kurzfrist ist bis zu 30 Min alt statt 15 |
FRRADAR_PIAF_SCHRITTE gröber (10 statt 18) |
~2,7 GB/Tag | Sprünge im hinteren Schieberteil |
NORDRADAR_METNO=0 |
~3,8 GB/Tag | Westnorwegen fällt auf RainViewer zurück |
Genau nachzählen lassen sich die Dienste seit dem 2026-08-15 selbst — alle vier
Units haben IPAccounting=yes:
systemctl show -p ActiveEnterTimestamp -p IPIngressBytes -p IPEgressBytes \
deradar frradar nlradar nordradar
(Die Zähler beginnen beim Start des Dienstes bei null.)
Fallen, die beim Anfassen wichtig sind
Ausführlich stehen sie als Kommentare an der jeweiligen Stelle in app.js. Kurz:
- Einheiten nie aus dem Legendentitel übernehmen. Der DWD liefert in
RV_ANALYSISdie Menge des Fünf-Minuten-Schritts (× 12 für mm/h), KNMI dagegen schon mm/h. Beide Male an echten Werten gegengeprüft. - Der DWD meldet außerhalb seines Gitters
-999, nicht einen Fehler — in einer tadellosen JSON-Antwort. Ungeprüft wird daraus „kein Regen". - Beim KNMI-WMS darf die Punktserie nicht als Zeitspanne abgefragt werden
(
TIME=von/bis): die Werte sind dann falsch, bis hin zu negativem Niederschlag. Jeder Zeitpunkt einzeln, dafür parallel. - Im RADOLAN-Binärformat ist Zeile 0 die SÜDlichste (Gitterursprung unten
links). Wer die Datei wie ein Bild von oben nach unten liest, bekommt ein
Radarbild, das 200 km zu weit nördlich liegt — und merkt es fast nicht: die
Gitterkanten stimmen trotzdem, die Abdeckungsmaske sieht richtig aus, und über
trockenem Land stimmen sogar alle Punktwerte, weil beide Seiten 0 sagen.
Nachweisbar nur, indem man die REGENmasken überlagert
(
server/deradar/vergleich_bild.py). - Ein Punktvergleich bei trockenem Wetter beweist gar nichts. Zehn Orte „perfekt übereinstimmend" hieß in Wahrheit zehnmal 0 gegen 0. Prüfskripte müssen die nassen Paare getrennt zählen und Alarm schlagen, wenn es keine gibt.
- Ein Cache für genau EIN Bild ist in der Karte ein Bremsklotz. Die App holt Kacheln für alle Frames gleichzeitig; jede Anfrage warf dann das Bild der vorigen hinaus. Einzeln gemessen 30 ms je Kachel, mit sechs gleichzeitig 756 ms — und 60 Kacheln parallel langsamer als seriell. Kacheldienste immer mit mehreren Verbindungen messen, nicht nacheinander.
- Sichtbarkeit über
getComputedStyle().displayoder einen Screenshot prüfen, nie über die.hidden-Eigenschaft — eigenes CSS sticht das Attribut aus.
Bauen
cd android && ./gradlew assembleRelease # JDK 21
Testen
Ein lokaler Server ist Voraussetzung (Geolocation und fetch brauchen einen
sicheren bzw. echten Ursprung):
python3 -m http.server 8080 --directory web/app
cd web && node mock-test.mjs # alle Quellen gefälscht, kostet kein Kontingent
Weitere Suiten in web/: merk-test.mjs (Ortsgedächtnis), zoom-test.mjs,
sonne-test.mjs, stapel-test.mjs, geo-test.mjs (eigener Server, weil
Geolocation einen sicheren Ursprung braucht). Für die Sichtprüfung mit echten
Daten live-check.mjs "Ort" <lat> <lon> [zoom] — das kostet einen echten Abruf.