No description
  • JavaScript 45.9%
  • Python 29%
  • Kotlin 18.9%
  • HTML 6.1%
  • Shell 0.1%
Find a file
2026-10-25 13:05:00 +01:00
android Stand vom 2026-10-25 2026-10-25 13:05:00 +01:00
server Stand vom 2026-10-25 2026-10-25 13:05:00 +01:00
tools/gezeiten Stand vom 2026-10-25 2026-10-25 13:05:00 +01:00
web Stand vom 2026-10-25 2026-10-25 13:05:00 +01:00
.gitignore Stand vom 2026-10-25 2026-10-25 13:05:00 +01:00
COPYRIGHT Stand vom 2026-10-25 2026-10-25 13:05:00 +01:00
LICENSE Stand vom 2026-10-25 2026-10-25 13:05:00 +01:00
README.md Stand vom 2026-10-25 2026-10-25 13:05:00 +01:00

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/app ein.
  • 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 in README-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_ANALYSIS die 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().display oder 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.