Was hier liegt — und wie es entsteht
Ein geplanter Lauf holt alle sechs Stunden
(00:30, 06:30, 12:30, 18:30 UTC, jeweils versetzt hinter die Modellläufe) die
keyless-Daten und schreibt statische JSON-Dateien ins Repo; Netlify liefert sie unverändert
unter /data/… aus. Kein Backend, kein Schlüssel, kein Tracker
— genau wie die Seite selbst. Zwei getrennte Stränge, die nie vermischt werden: die
Vorhersage (elf Modelle, Open-Meteo) und die Wahrheit (echte
DWD-Stationsmessung, Bright Sky). Kein Modellwert wird je als Messung ausgegeben.
Was sich wie oft ändert: forecasts/,
ensemble/ und warnlage/ bekommen bei jedem Lauf eine neue Datei, und
index.json wird jedes Mal neu geschrieben — also alle sechs Stunden.
measured.json wird ebenfalls bei jedem Lauf neu geschrieben, neue Messwerte kommen
wegen des DWD-Verzugs aber nur für einen Tag je Tag dazu: den abgeschlossenen Vortag,
sobald der DWD ihn geprüft hat. Der kommt meist auf zwei Läufe verteilt an — vom
10. bis 26.09.2026 jeden Tag gleich: für 17 der 25 Städte mit dem Lauf am frühen
Morgen, für die übrigen acht erst mit dem nächsten, sechs Stunden später (in
diesen Tagen gegen 12:45 Uhr deutscher Zeit). Wer nur einmal am Tag abruft, holt deshalb
am besten danach. Die Kurzbeschreibung dieser Seite für Suchmaschinen und
Vorschaukarten sprach bis zum 30.09.2026 von „täglich einen JSON-Schnappschuss“,
obwohl seit dem 19.07.2026 alle sechs Stunden gesichert wird.
Wie du dieses Archiv selbst abrufst — mit Beispielen für curl, JavaScript und Python — steht auf Daten nutzen.
Zwei Lücken im Archiv — und warum sie stehen bleiben
Wer dieses Archiv auswertet, muss von zwei Ausfällen wissen. In beiden Fällen fehlen Vorhersage-Schnappschüsse, Ensemble- und Warnlage-Stände; die Messreihe ist in beiden Fällen vollständig nachgeholt, weil sich vergangene Messtage nachträglich abrufen lassen.
- 10.08.2026 02:40 UTC bis 19.08.2026 12:05 UTC. Der geplante Lauf wurde neun Tage lang gar nicht erst gestartet — nicht ein Fehler im Code, sondern eine Abrechnungssperre beim Betreiber der Automatik. 74 Anläufe scheiterten nacheinander nach drei bis vier Sekunden, ohne eine Zeile auszuführen.
- 21.08.2026 10:35 UTC bis 08.09.2026 15:01 UTC. Der als Ersatz eingerichtete Lauf war nach einem Neustart nicht wieder aktiv. Achtzehn Tage. Aufgefallen ist es erst, als jemand nachsah — und genau deshalb prüft seither ein eigener Test bei jeder Änderung, ob das Archiv noch nachkommt.
Nachgezählt statt nur beschrieben
Die Liste oben ist von Hand geschrieben und veraltet, sobald die
Sicherung wieder steht. Deshalb zählt diese Seite seit dem 01.10.2026 beim Laden selbst
nach: jede Stelle in index.json (Feld snapshots),
an der zwischen zwei gespeicherten Läufen mehr als zwölf Stunden liegen, und zuletzt
der Abstand vom jüngsten Lauf bis jetzt. Die Uhrzeiten sind die Erzeugungszeiten aus dem
Feld utc; oben steht teils die Startzeit aus dem Dateinamen, deshalb können
beide um ein paar Minuten auseinanderliegen.
Diese Liste rechnet ein Skript aus
/data/index.json; ohne JavaScript bleibt sie leer, die Datei selbst ist
trotzdem abrufbar.
Beide Lücken ließen sich technisch füllen: Es gibt eine
Schnittstelle, die vergangene Modellläufe zurückgibt. Die Gegenprobe an einem Tag,
für den der echte Schnappschuss vorliegt, fällt aber negativ aus.
Nachgemessen am 08.09.2026 gegen data/forecasts/2026-08-09T0234Z.json
(Karlsruhe, Berlin, München × 11 Modelle × 8 Tage = 231 Werte):
nur 3,9 % der Werte sind identisch, die Abweichung liegt im Median bei
0,80 K, im Mittel bei 1,11 K, im Einzelfall bei 7,3 K —
und sie wächst mit dem Vorhersage-Horizont, von 0,30 K an Tag +1 auf
2,90 K an Tag +7. Genau
dieses Muster verrät, was dort geliefert wird: nicht, was ein Modell damals sagte,
sondern die später besser informierte Fassung. Wer damit auffüllte,
fälschte ausgerechnet die Zahl, gegen die diese Seite ihre eigenen Vorhersagen
prüft. Eine Lücke, die man sieht, ist besser als eine, die man
zugespachtelt hat.
Der Stillstand im August ist nicht der einzige Fehler, den das Archiv hatte. Alle belegten Fehler der Seite — im Archiv, in den Rechnungen und im Text dieser Datenseite — stehen mit Datum und Commit im Fehlerprotokoll.
Unsere eigene Nachkontrolle — und die gemessene Historie
Aus dem eigenen Archiv, ehrlich gerechnet: sobald abgelegte Vorhersagen ihren Zieltag erreichen, vergleichen wir sie mit dem gemessenen DWD-Wert. Darunter die reine, gemessene Temperatur-Historie. Das Archiv ist eine Ergänzung — die belastbare Quelle bleibt das DWD-/API-Fenster der Startseite. Solange das eigene Archiv noch wenige Tage jung ist, steht das hier offen dabei, statt eine Zahl vorzutäuschen.
Neu: Weil wir die Vorhersage jetzt mehrmals am Tag speichern, lässt sich sehen, wie sie sich für einen Zieltag von Stand zu Stand verschiebt — das zeigt Vorhersage-Verlauf.
Unter der Messgrafik kannst du dieselben gespeicherten Werte als Tabelle öffnen. Sie zeigt bis zu 30 vorhandene Messtage, nicht zwingend 30 aufeinanderfolgende Kalendertage. Fehlende Werte bleiben fehlend; auch ein einzelner Messwert ist dort lesbar.
Archivdaten werden geladen …
Die Bestandteile des Archivs
Hier stand „Die drei Dateien“. Das stimmte einmal; inzwischen
sind es mehr: Zu den drei unten beschriebenen kamen die Ensemble-Streuung
(/data/ensemble/), die europäische Warnlage (/data/warnlage/) und
die Klimaprojektionen (/data/klimaprojektion/). Deren Dateinamen stehen ebenfalls
im Index.
- /data/index.json Maschinenlesbares Verzeichnis: alle Orte (Slug, Name, lat, lon), die elf Modelle, die Liste der verfügbaren Vorhersage-Tage, der Verweis auf die Messung und die Lizenz. Der beste Einstieg für ein Skript.
-
/data/measured.json
Die wachsende echte Messung: je Ort die nächste
DWD-Station und der Tageshöchstwert je Kalendertag (
tmax). Seit dem 26.09.2026 zusätzlichtmin(Tiefstwert) undniederschlag(Tagessumme in mm) — beide nur für Tage, an denen jede Stunde einen geprüften Wert der Station hat. Seit dem 01.10.2026 dazutemperatur_fehlstunden: je unvollständigem Tag die Stunden ohne eigenen Temperaturwert der Station. Wächst mit jedem Tag; alte Werte bleiben stehen. Startbestand: rund 60 Tage rückwirkend. -
/data/faustregel.json
Ist die Vorhersage besser als „wie gestern“ und als das
langjährige Mittel? Je Vorlauftag, für Höchst- und Tiefstwert. Das
langjährige Mittel selbst (ERA5, 1991–2020, je Stadt und Kalendertag) liegt in
/data/klimatologie.json. Ausgewertet auf Faustregel. -
/data/klimatologie.json
Das langjährige Mittel: je Stadt und Kalendertag der
mittlere Höchst- und Tiefstwert 1991–2020 aus ERA5, gemittelt über ± 3 Tage
um den Kalendertag, dazu Lage und Höhe des Gitterpunkts. ERA5 ist ein Gitter von rund
30 km, keine Station — die Werte beschreiben die Gitterzelle, nicht den Ort der
DWD-Station. Geholt wird nur, solange Städte fehlen; danach ändert sich die Datei nicht
mehr. Grundlage für Faustregel,
Hitzetage im Rückspiegel und
Monatszeugnis. Bis zum 01.10.2026 stand die Datei hier nur als
Nebensatz im Eintrag darüber, ohne eigenen Link — obwohl
index.jsonsie als eigenes Feld führt. -
/data/extremtage.json
Hitzetage (Höchstwert ab 30 °C) in zwei Blickrichtungen: mittlere
Abweichung der Vorhersage, gefiltert nach gemessenen und nach angesagten Hitzetagen, mit 95-%-Spanne
aus Ziehungen ganzer Zieltage; Kontingenztafel (Treffer, verpasst, Fehlalarm), Gegenprobe mit den
Faustregeln, je Vorlauf dieselben Zahlen ohne die Städte, deren Station seit dem 26.09.2026 keinen
eigenen Höchstwert mehr liefert, und die gemessenen Hitzetage, die das Archiv nicht prüfen kann. Unter der
Mindestzahl steht im Feld
zustandder Wertwaechststatt einer Zahl. Ausgewertet auf Hitzetage im Rückspiegel. - /data/tendenz.json Trifft die Vorhersage die Richtung — unter, nahe oder über dem langjährigen Gittermittel — öfter als „wird eh wärmer“ und „Abweichung bleibt“? Je Vorlauftag, mit der mittleren Abweichung der Fälle, einer Gegenprobe auf gleichen Zieltagen und dem Versatz je Stadt. Ausgewertet auf Faustregel.
-
/data/ortsbilanz.json
Liegt der Konsens der Modelle an einem Ort beständig zu warm oder zu kalt? Je
Stadt Versatz und mittlerer Fehler für Vorlauf 0–1 und 0–7, die Station(en) mit Entfernung,
eine Halbierungsprobe und der Sieger der gleichen Aufgabe je Stadt, dazu eine Gegenprobe ohne die Städte,
deren Station seit dem 26.09.2026 keinen eigenen Höchstwert mehr liefert.
tminläuft mit und meldetwaechst, bis genug Fälle da sind. Ausgewertet auf Ortsbilanz. -
/data/monatsbilanz.json
Je Zielmonat und je Vorlauf 0–7: Vergleiche, Zieltage, Ausgabetage und
fehlende Ausgabetage (vor Archivbeginn, Ausfall), Treffer der Modellspanne, mittlerer Fehler und
Schlagseite der Modellmitte, zu kalt / zu warm und der schlimmste Zieltag. Dazu je Monat der rohe und
der vorlaufbereinigte Wert mit 95-%-Spanne, je zwei Monate der Unterschied samt Vorlaufmix, eine
Gegenprobe auf gleichen Zieltagen, die Lücken mit Grund und der Abstand der Stationsmessung zum
ERA5-Mittel 1991–2020. Unter der Mindestzahl (Vergleiche und Zieltage) steht im Feld
zustandder Wertwaechststatt einer Zahl. Ausgewertet auf Monatszeugnis. - /data/spruenge.json Wie weit springt die Vorhersage für denselben Tag von Ausgabetag zu Ausgabetag? Je Schritt im Vorlauf: Sprunggröße, Gegenbewegung (nimmt der nächste Lauf den Sprung zurück?), Richtung zur DWD-Messung samt Gegenprobe ohne Schlagseite, das Mittel aus heutigem und gestrigem Lauf und der Fehler nach Sprunggröße in Dritteln — mit 95-%-Spannen aus Ziehungen ganzer Zieltage. Dazu eine Gegenprobe mit KNMI, DMI und MET Norway als einer Stimme, ECMWF, ICON und GFS einzeln und der Vergleich erster gegen letzter Lauf desselben Tages. Ausgewertet auf Vorhersagesprünge.
- /data/trefferquote_tmin.json Dieselbe Gegenprobe wie die Trefferquote, für den Tagestiefstwert: Spanne trifft, Schlagseite, mittlerer Fehler, je Vorlauf und je Stadt — mit eigener Mindestzahl an Vergleichen und an Nächten und einem offenen Lückenbericht (seit wann gewertet wird, welche Städte keinen gemessenen Tiefstwert haben). Ausgewertet auf Trefferquote.
-
/data/regenprobe.json 30.09.2026: entsteht noch
Stimmt die Regenwahrscheinlichkeit? Angesagte gegen beobachtete
Regenhäufigkeit je Klasse, Brier-Score, und für die elf Modelle Treffer,
verpasster Regen und Fehlalarme. Ausgewertet auf Regenprobe.
Die Datei entsteht erst, wenn genug Fälle mit Vorhersage und gemessenem
Niederschlag beisammen sind (gesammelt wird seit dem 26.09.2026); am 30.09.2026 gab es sie
noch nicht. Solange sie fehlt, liefert der Link „nicht gefunden“, und
index.jsonführtregenprobealsnull. Ob es sie inzwischen gibt, steht verlässlich dort und auf der Seite Regenprobe — dieser Eintrag stellt sich nicht von selbst um. Bis zum 30.09.2026 stand er ohne diesen Hinweis hier. - /data/trefferquote.json Die Gegenprobe: wie oft die gemessene Temperatur wirklich zwischen dem kältesten und dem wärmsten Modell lag — nach Vorlaufzeit, nach Stadt, nach Breite der Spanne, dazu das Rangdiagramm. Aus den beiden Dateien darüber vorab gerechnet, damit der Browser nicht das gesamte Archiv laden muss. Die Datei nennt ihre eigenen Rechenregeln. Ausgewertet auf der Seite Trefferquote.
- /data/rangliste.json Die Modell-Rangliste: je Modell der mittlere absolute Fehler gegen die später gemessene DWD-Höchsttemperatur — einmal über alle eigenen Werte, einmal nur über die Vergleiche, bei denen alle Modelle geliefert haben. Dazu der Konsensfehler nach Vorlauf und eine Gegenprobe mit nur einem Lauf je Ausgabetag. Ebenfalls vorab gerechnet: der Browser lädt gut vier Kilobyte statt rund vier Megabyte Archiv. Ausgewertet auf der Seite Feldbericht.
- /data/modellprofil.json Das Modellprofil: je Modellpaar, wie oft beide bitgenau denselben Wert ausgeben; je Modell der mittlere Fehler mit Vorzeichen (die Schlagseite), aufgeschlüsselt nach Vorlauf; und die Gegenrechnung, ob die Spanne nach Abzug der Schlagseite besser wird — geschätzt auf der ersten Hälfte der Ausgabetage, geprüft auf der zweiten. Ausgewertet auf Elf Modelle — wie viele Meinungen? und Jedes Modell hat eine Schlagseite.
-
/data/ensemble_kalibrierung.json
War der Ensemble-Fächer ehrlich? Je Vorlauf: wie oft
die Messung im äußeren und im mittleren Band lag, wie oft sie über dem
Maximum und unter dem Minimum landete, und ein Rangdiagramm mit sechs Fächern
neben der Erwartung für ein ehrliches Ensemble. Dazu der Block
nach_streuung: ob ein breiter Fächer wirklich einen größeren Fehler ankündigt, je Vorlauf in drei Dritteln der Fächerbreite, und wie groß der Fehler im Verhältnis zur angekündigten Streuung war. Ausgewertet auf Der Ensemble-Fächer. - /data/warnlage_archiv.json Das Warnlagen-Archiv ausgewertet: je gespeichertem Stand die europaweite Summe nach Stufe und Art, und je Land nur Größen, die vom Zuschnitt der Warngebiete unabhängig sind — Anteil der Stände mit Warnung, mit orange, mit rot, die je erreichte Höchststufe. Ausgewertet auf Warnlage Europa.
-
/data/forecasts/<datei>.json
Je Lauf eine Datei: die zu diesem Lauf ausgegebene
8-Tage-Vorhersage des Tageshöchstwerts (
tmax), je Ort und je Modell; seit dem 26.09.2026 auchtminundniederschlag(Tagessumme in mm). Den Dateinamen nimmst du ausindex.json→snapshots[].file, nicht ausforecasts— letzteres ist eine Liste von Ausgabetagen, keine Liste von Dateinamen. Heute heissen die DateienJJJJ-MM-TTThhmmZ.json(Ausgabetag + UTC-Uhrzeit des Laufs); nur die älteste trägt noch das reine TagesformatJJJJ-MM-TT.jsonaus der Zeit, als pro Tag eine Datei überschrieben wurde. Hier stand bis zum 01.08.2026 das Tagesformat als Regel — wer danach abgerufen hat, bekam 404. (Kein Verzeichnis-Listing im Browser; die Namen kommen aus dem Index.) Seit dem 30.09.2026 trägt jede neue Datei das Feldfehlend: die Orte, die in diesem Lauf keine Antwort bekamen. Leer heißt: alle 25 sind da. Bis dahin brach ein einziger ausgefallener Ort den ganzen Lauf ab. -
/data/verlauf/<ort>.json
Seit dem 30.09.2026: je Ort eine Datei mit dem
Vorhersage-Verlauf — für jeden Zieltag jeder archivierte Lauf mit Vorlauf,
Median der Modelle, Zahl der Modelle und der verschiedenen Werte, dazu die
DWD-Messung, sobald es sie gibt. Vorab gerechnet aus
forecasts/undmeasured.json, damit Vorhersage-Verlauf nicht jeden Lauf einzeln laden muss. Bis dahin lud die Seite die jüngsten 240 Läufe einzeln und ließ die älteren still weg. Die Liste der Dateien steht inindex.json→verlauf.
Wie das Archiv aufgebaut ist — als Bild
Zwei Dinge geschehen jeden Tag. Oben: Es wird ein Vorhersage-Schnappschuss abgelegt — die an diesem Tag ausgegebene Vorhersage, acht Tage weit in die Zukunft. Am nächsten Tag kommt der nächste dazu, und der davor bleibt unverändert stehen. So stapeln sich die Schnappschüsse: nach Monaten ein Archiv. Unten: Die Messung wächst — jeden Tag kommt der echte Tageshöchstwert eines weiteren Kalendertags dazu. Beide Stränge treffen sich am heutigen Tag.
Schematisch: zeigt nur die Anordnung der Dateien über die Zeit, keine echten Messwerte. Jede Zelle steht für einen Kalendertag.
Das Schema — versioniert
Jede Datei trägt ein schema-Feld mit Versionsnummer. Ändert
sich die Form je, wächst die Nummer — alte Verbraucher merken es. Temperaturen sind °C,
auf eine Nachkommastelle gerundet; null ist erlaubt (nicht jedes Modell liefert jeden Ort
und Tag).
forecasts/JJJJ-MM-TT.json — wetter.kaipfstr.de/forecasts/1
{
"schema": "wetter.kaipfstr.de/forecasts/1",
"issued": "2026-07-18",
"generated_utc": "2026-07-18T06:30:00Z",
"models": ["icon_seamless", "gfs_seamless", ...], // 11 Modelle
"fehlend": [], // seit 30.09.2026: Orte ohne Antwort
"cities": {
"berlin": {
"name": "Berlin", "lat": 52.52, "lon": 13.405,
"dates": ["2026-07-18", ...], // 8 Tage ab issued
"tmax": {
"icon_seamless": [25.5, 24.1, ...], // 8 Werte, null erlaubt
"gfs_seamless": [26.6, 22.0, ...],
...
}
},
...
}
}
trefferquote.json — wetter.kaipfstr.de/trefferquote/1
{
"schema": "wetter.kaipfstr.de/trefferquote/1",
"berechnet_utc": "2026-09-08T16:02:07Z",
"quelle": {
"schnappschussdateien_gesamt": 187,
"schnappschussdateien_gewertet": 27, // je Ausgabetag der frueheste Lauf
"ausgabetage_gewertet": 27,
"zieltage_von": "2026-07-18", "zieltage_bis": "2026-08-28",
"staedte": 25, "messung": "...", "vorhersage": "..."
},
"regeln": ["Je Ausgabetag wird nur ein Lauf gewertet: der mit der kleinsten generated_utc. ...", ...],
"gesamt": { "paare": 5400, "treffer": 4421, "quote": 81.9,
"median_spanne": 6.0, "median_fehlbetrag": 0.9,
"median_mittelfehler": 1.12, "zu_kalt": 621, "zu_warm": 358 },
"nach_vorlauf": [{ "vorlauf": 0, "paare": 675, "quote": 95.3,
"erwartung_ideal": 83.3, "modelle_min": 11,
"modelle_max": 11, "modelle_median": 11, ... }, ...],
"rangdiagramm": { "faecher": [76, 113, 281, ..., 219, 150],
"paare": 2700, "modelle": 11, "erwartung_je_fach": 8.3 },
"nach_spannenbreite": [...], "nach_stadt": [...],
"nach_zieltag": [{ "tag": "2026-08-26", "paare": 75, "daneben": 51, "quote_daneben": 68.0,
"alle_zu_kalt": 13, "alle_zu_warm": 38, "orte_daneben": 24,
"median_fehlbetrag": 1.7, "max_fehlbetrag": 8.5 }, ...],
"schlimmste_zieltage": [...], // die zehn mit dem groessten Anteil daneben
"license": "CC BY 4.0 (Open-Meteo) / DWD GeoNutzV (Messung)"
}
Diese Datei war die erste im Archiv, die nicht gemessen oder
abgerufen, sondern gerechnet ist — und zwar aus den beiden anderen.
Deshalb trägt sie ihre Rechenregeln im Feld regeln mit: welcher Lauf je
Ausgabetag gewertet wird, wie der Vorlauf definiert ist, dass die Spanne nur die Modelle
umfasst, die für diesen Tag wirklich einen Wert geliefert haben, und dass eine
Stationsmessung gegen einen Gitterpunkt verglichen wird. modelle_min und
modelle_max stehen dabei, weil die Zahl der beteiligten Modelle mit dem
Vorlauf sinkt — ohne sie liest man die schmalere Spanne als Einigkeit statt als
Ausdünnung. erwartung_ideal ist (N−1)/(N+1) für die
tatsächlich beteiligte Modellzahl, nicht pauschal für elf.
Eine Lücke, die diese Auswahl mit sich bringt
(vermerkt am 30.09.2026): Wo je Ausgabetag nur ein Lauf zählt — hier, in
modellprofil.json, ensemble_kalibrierung.json,
faustregel.json, regenprobe.json und in der Gegenprobe von
rangliste.json —, ist es immer der früheste Lauf des Tages
(im Schnappschuss-Skript die Funktion _ein_lauf_je_ausgabetag und ihre
älteren Geschwister). Ist genau dieser Lauf für eine Stadt unvollständig, etwa
weil ihr Abruf scheiterte, fehlen dieser Stadt die Fälle des ganzen Ausgabetags —
auch wenn ein späterer Lauf desselben Tages sie vollständig hat. Die Auswahlregel
bleibt trotzdem, wie sie ist: Auf „den ersten vollständigen Lauf“ umgestellt,
würden sich schon veröffentlichte Zahlen still verschieben. Damit solche Lücken
wenigstens sichtbar werden, können Läufe künftig ein Feld fehlend
tragen, das sie im Lauf selbst vermerkt — wie es die Warnlage-Stände schon tun.
Wer auswertet, prüfe es, sobald es auftaucht. Ältere Läufe tragen es nicht;
bei ihnen zeigt nur der Inhalt selbst, ob einer Stadt etwas fehlt.
rangliste.json — wetter.kaipfstr.de/rangliste/1
{
"schema": "wetter.kaipfstr.de/rangliste/1",
"berechnet_utc": "2026-09-10T11:40:12Z",
"quelle": { "schnappschussdateien": 195, "ausgabetage": 30,
"zieltage_von": "2026-07-18", "zieltage_bis": "2026-09-09",
"staedte": 25, "modelle_bekannt": 11, "messung": "...", "vorhersage": "..." },
"regeln": ["Gewertet wird JEDER archivierte Lauf, nicht nur einer je Ausgabetag ...", ...],
"gesamt": { "vergleiche": 37400, "zieltage": 43, "max_vorlauf": 7, "konsens_mae": 1.5783 },
"fair": { "vergleiche": 18800, "zieltage": 35, "max_vorlauf": 3,
"konsens_mae": 0.9071, "belastbar": true },
"modelle": [{ "modell": "icon_seamless", "fair": 0.9594, "fair_n": 18800,
"mae": 1.6186, "n": 33850 }, ...], // nach "fair" sortiert
"gegenprobe_ein_lauf_je_tag": { "schnappschussdateien": 30, "vergleiche": 5475,
"laeufe_je_ausgabetag_min": 1,
"laeufe_je_ausgabetag_max": 9,
"reihenfolge_gleich": false,
"reihenfolge": ["icon_seamless", ...], "modelle": [...] },
"konsens_nach_vorlauf": [{ "vorlauf": 1, "mae": 0.8434, "n": 4700 }, ...],
"license": "CC BY 4.0 (Open-Meteo) / DWD GeoNutzV (Messung)"
}
Die zweite gerechnete Datei im Archiv — und sie rechnet
absichtlich anders als trefferquote.json: Dort zählt je Ausgabetag nur
ein Lauf, weil die Frage „wie oft lag die Spanne richtig“ eine Frage
nach Tagen ist. Hier zählt jeder Lauf, weil die Frage „wie
genau ist ein Modell“ eine Frage nach Vorhersagen ist. Weil diese Wahl das Ergebnis
beeinflussen kann, steht die andere Rechnung unter
gegenprobe_ein_lauf_je_tag daneben — samt dem geprüften Feld
reihenfolge_gleich. Es steht derzeit auf false: die Plätze
zwei bis sechs tauschen, und genau dort liegen die Modelle innerhalb von 0,17 K
beieinander. fair reicht strukturell nur bis Vorlauf 3, weil sie
verlangt, dass jedes Modell geliefert hat und die kurzfristigen Modelle vorher
aufhören — fair.max_vorlauf sagt, wie weit sie wirklich reicht.
modellprofil.json — wetter.kaipfstr.de/modellprofil/1
{
"schema": "wetter.kaipfstr.de/modellprofil/1",
"berechnet_utc": "2026-09-10T12:18:38Z",
"quelle": { "schnappschussdateien_gewertet": 30, "ausgabetage_gewertet": 30,
"zieltage_von": "2026-07-18", "zieltage_bis": "2026-09-09", "staedte": 25, ... },
"regeln": ["Je Ausgabetag wird nur ein Lauf gewertet ...", ...],
"schlagseite": {
"fenster": { "vergleiche": 2775, "max_vorlauf": 3, "bedingung": "..." },
"modelle": [{ "modell": "cma_grapes_global", "bias": -3.4659, "mae": 3.5832, "n": 2775,
"bias_ausgabetag": -2.9828, "trend_k_pro_tag": 0.1291, "reichweite_vorlauf": 4,
"nach_vorlauf": [{ "vorlauf": 0, "bias": -2.9828, "n": 725 }, ...] }, ...]
},
"wertgleichheit": {
"paare": [{ "a": "knmi_seamless", "b": "dmi_seamless", "vorlauf": [0, ..., 7],
"quote": [10.1, 10.8, 87.1, 100.0, ...], "n": [750, ...] }, ...], // alle 55
"identisch_ab": [{ "a": "dmi_seamless", "b": "metno_seamless", "ab_vorlauf": 3, "n": 3750 }, ...]
},
"korrektur": { "lernen": { "ausgabetage": 15, "von": "...", "bis": "..." },
"pruefen": { "ausgabetage": 14, ... },
"gesamt": { "n": 2475, "quote_vor": 84.3, "quote_nach": 78.6 },
"nach_vorlauf": [{ "vorlauf": 0, "n": 350, "quote_vor": 92.9, "quote_nach": 83.7,
"spanne_median_vor": 5.25, "spanne_median_nach": 3.23, ... }, ...] },
"license": "CC BY 4.0 (Open-Meteo) / DWD GeoNutzV (Messung)"
}
Die dritte gerechnete Datei. Sie wählt wie trefferquote.json
einen Lauf je Ausgabetag, weil beide Fragen nach Vorhersagesituationen fragen, nicht nach
Rechenläufen. korrektur ist bewusst nicht auf denselben Tagen
geschätzt und geprüft: Die Schlagseite kommt aus der ersten Hälfte der
Ausgabetage, gemessen wird auf der zweiten — sonst wäre das Ergebnis
zurechtgelegt. Die Zahlen im Abdruck sind der Stand vom 10.09.2026 und wandern mit jedem
Schnappschuss.
ensemble_kalibrierung.json — wetter.kaipfstr.de/ensemble_kalibrierung/1
{
"schema": "wetter.kaipfstr.de/ensemble_kalibrierung/1",
"berechnet_utc": "2026-09-10T13:55:48Z",
"quelle": { "ensemble_staende_gesamt": 96, "ausgabetage_gewertet": 17, "staedte": 25,
"modell": "ecmwf_ifs025", "mitglieder": 51, ... },
"regeln": ["Je Ausgabetag wird nur ein Stand gewertet ...", ...],
"erwartung": { "unter_min_prozent": 1.9, "ueber_max_prozent": 1.9, "im_mittleren_band_prozent": 50.0 },
"gesamt": { "n": 2875, "im_aeusseren_band": 88.2, "im_mittleren_band": 38.6,
"ueber_max": 10.0, "unter_min": 1.8, "mittlerer_abstand_zum_median": 1.7, ... },
"nach_vorlauf": [{ "vorlauf": 0, "n": 400, "im_aeusseren_band": 69.0, "im_mittleren_band": 26.0,
"ueber_max": 28.0, "unter_min": 3.0, ... }, ...],
"rangdiagramm": { "faecher": ["unter_min", "min_bis_q25", ..., "ueber_max"],
"anzahl": [52, 621, 521, 588, 805, 288], "prozent": [1.8, 21.6, 18.1, 20.5, 28.0, 10.0] },
"nach_streuung": { "zustand": "ok", "min_faelle_je_drittel": 30, "verhaeltnis_ideal": 1.01,
"ausgabetage": { "luecken": [...], ... }, "gesamt": { "schlagseite": ..., ... },
"regeln": [...], "nach_vorlauf": [{ "vorlauf": 0, "drittel": [...],
"halbierungsprobe": {...}, "verhaeltnis": ..., ... }, ...] },
"license": "CC BY 4.0 (Open-Meteo) / DWD GeoNutzV (Messung)"
}
Die vierte gerechnete Datei, aus data/ensemble/ gegen
data/measured.json. Sie ersetzt eine Rechnung, die ensemble.js bis zum
10.09.2026 im Browser machte (bis zu 60 Archivdateien je Besuch, mit stiller Obergrenze) —
und sie sieht, was jene nicht sehen konnte: die Richtung. Die Messung fällt
5,6-mal so oft nach oben aus dem Fächer wie nach unten. Abdruck: Stand vom 10.09.2026.
Seit dem 01.10.2026 kommt der Block nach_streuung dazu (ohne Zahlen abgedruckt, sie
stehen in der Datei): je Vorlauf drei Drittel nach der Breite q75−q25 mit dem mittleren Fehler
des Medians, eine Probe mit geraden und ungeraden Zieltagen und das Verhältnis aus mittlerem
quadratischem Fehler und Streuung — roh und ohne Schlagseite und Ortsversatz.
warnlage_archiv.json — wetter.kaipfstr.de/warnlage_archiv/1
{
"schema": "wetter.kaipfstr.de/warnlage_archiv/1",
"berechnet_utc": "2026-09-11T06:30:52Z",
"quelle": { "staende": 96, "von": "2026-07-31T13:12:37Z", "bis": "2026-09-11T04:38:55Z", "laender": 38,
"staende_mit_fehlenden_laendern": 5, ... },
"regeln": ["Jeder archivierte Stand zaehlt ...", ...],
"arten_namen": { "1": "Wind", "3": "Gewitter", "5": "Hitze", ... }, "stufen_namen": { "2": "gelb", ... },
"gesamt": { "warnungen_je_stand_min": 1591, "warnungen_je_stand_median": 5028, "warnungen_je_stand_max": 6178,
"spitze": { "zeit": "2026-08-05T22:39:12Z", "warnungen": 6178 },
"stufen_summe": {"2": 251798, "3": 160594, "4": 38193},
"laender_nie_rot": ["Andorra", "Estland", "Finnland", ...], "laender_ohne_meldung": ["Malta"], ... },
"laender": [{ "slug": "andorra", "name": "Andorra", "staende": 96, "mittel_je_stand": 10.1,
"anteil_staende_mit_warnung": 100.0, "anteil_staende_rot": 0.0, "anteil_staende_orange": 72.9,
"max_stufe": 3, "haeufigste_art": "Gewitter", "ohne_meldung": false }, ...],
"staende": [{ "zeit": "2026-07-31T13:12:37Z", "gesamt": 4446, "laender_mit_warnung": 31, "fehlend": 0,
"stufen": { ... }, "arten": { ... } }, ...],
"license": "CC BY 4.0 (MeteoAlarm/EUMETNET)"
}
Die fünfte gerechnete Datei, aus data/warnlage/. Anders als die
übrigen zählt sie jeden Stand, weil die Frage „wie oft war rot aktiv“
eine Frage nach Zeitpunkten ist und die Stände die Zeitpunkte sind. Ein Land, das in einem
Stand fehlt, wird für diesen Stand nicht gewertet. ohne_meldung markiert ein
Land, das in keinem Stand eine Warnung, keinen grünen Eintrag und keine Region hatte —
es liefert womöglich keinen Feed und wird nicht als „warnt nie“ gezählt.
Abdruck: Stand vom 11.09.2026.
tendenz.json — wetter.kaipfstr.de/tendenz/1
{
"schema": "wetter.kaipfstr.de/tendenz/1",
"berechnet_utc": "...",
"quelle": { "ausgabetage_gewertet": ..., "ausgabetage_von": "...", "ausgabetage_bis": "...",
"ausgabetage_ohne_lauf": ["...", ...], "spaete_laeufe": [{ "ausgabetag": "...",
"generated_utc": "...", "ortszeit": "...", "nach_mittag": ... }, ...], ... },
"grenze_k": ..., "mindestfaelle": ..., "mindest_zieltage": ...,
"regeln": ["Je Ausgabetag wird nur ein Lauf gewertet ...", ...],
"groessen": {
"tmax": { "zustand": "ok", "faelle": ..., "zieltage": ..., "ohne_vortag": ..., "ohne_mittel": ...,
"vorhersage_ab_ausgabetag": "...", "messung_von": "...", "messung_bis": "...",
"nach_vorlauf": [{ "vorlauf": 0, "zustand": "ok", "faelle": ..., "zieltage": ...,
"mittlere_abweichung_gemessen": ..., "quote": { "vorhersage": ...,
"immer_ueber": ..., "abweichung_bleibt": ... },
"vorsprung_pp": {...}, "vorsprung_spanne95_pp": {...},
"vorhersage_daneben": {...}, "matrix_vorhersage_gegen_gemessen": {...},
"faelle_aus_spaeten_laeufen": ..., "faelle_je_monat": {...} }, ...],
"gleiche_zieltage": { "paare": ..., "nach_vorlauf": [...] },
"versatz": { "staedte": [{ "slug": "...", "mittlere_abweichung_gemessen": ...,
"mittlere_abweichung_vorhersage": ..., "stationsanteil_k": ... }, ...],
"spanne_k": ..., "spanne_stationsanteil_k": ... } },
"tmin": { "zustand": "waechst", ... } },
"license": "CC BY 4.0 (Open-Meteo, ERA5) / DWD GeoNutzV (Messung)"
}
Seit dem 01.10.2026. Ordnet Vorhersage und Messung je Fall einer Klasse zu — unter, nahe oder über dem ERA5-Gittermittel des Kalendertags — und vergleicht die Trefferquote mit zwei faulen Regeln („wird eh wärmer“, „Abweichung bleibt“), nur innerhalb eines Vorlaufs. Der Vorsprung hat eine 95-%-Spanne aus Ziehungen ganzer Zieltage. Abgedruckt ohne Zahlen; sie stehen in der Datei. Ausgewertet auf Faustregel.
trefferquote_tmin.json — wetter.kaipfstr.de/trefferquote_tmin/1
{
"schema": "wetter.kaipfstr.de/trefferquote_tmin/1",
"berechnet_utc": "...", "mindestzahl": ..., "mindest_naechte": ...,
"quelle": { "schnappschussdateien_mit_tmin": ..., "ausgabetage_gewertet": ...,
"erster_gewerteter_ausgabetag": "...", "zieltage_von": "...", "zieltage_bis": "...", ... },
"regeln": ["Je Ausgabetag wird nur ein Lauf gewertet ...", ...],
"gesamt": { "zustand": "waechst", "faelle": ..., "naechte": ..., "fehlen_bis_mindestzahl": ...,
"fehlen_naechte": ..., "mindestzahl_fruehestens_mit_messung_vom": ..., "quote": null,
"schlagseite": null, "mae": null, "faelle_je_vorlauf": {...}, ... },
"nach_vorlauf": [{ "vorlauf": 0, ... }, ...], "nach_stadt": [{ "slug": "...", ... }, ...],
"tag_gegen_nacht": { "zustand": "...", "mae_tmin": ..., "mae_tmax": ..., "differenz_spanne95": ... },
"luecken": { "tmin_vorhersage_seit": {...}, "ausgabetage_ohne_tmin": [...],
"tmin_messung_von": "...", "tmin_messung_bis": "...", "staedte_ohne_tmin_messung": [...],
"tage_mit_tmax_ohne_tmin": [...], "quellenpruefung_je_wert_seit": "...",
"v0_spaete_laeufe": [...], "v0_ausgeschlossen": ... },
"license": "CC BY 4.0 (Open-Meteo) / DWD GeoNutzV (Messung)"
}
Seit dem 01.10.2026, getrennt von trefferquote.json, damit sich die
Höchstwert-Zahlen nicht still verschieben. Die Datei entsteht auch unter der Mindestzahl —
dann mit zustand auf waechst, ohne Quote, aber mit dem Lückenbericht. Abgedruckt ohne
Zahlen; sie stehen in der Datei.
extremtage.json — wetter.kaipfstr.de/extremtage/1
{
"schema": "wetter.kaipfstr.de/extremtage/1",
"berechnet_utc": "...",
"quelle": { "faelle": ..., "ausgabetage_gewertet": ..., "luecken_ausgabetage": [["...", "..."], ...],
"spaete_laeufe": [...], ... },
"regeln": ["Je Ausgabetag wird nur ein Lauf gewertet ...", ...],
"schwelle_c": ..., "anomalie_schwelle_k": ..., "mindestfaelle": ...,
"nach_vorlauf": [{ "vorlauf": 0, "faelle": ..., "zieltage": ..., "faelle_aus_spaeten_laeufen": ...,
"ohne_spaete_laeufe": {...},
"alle": { "mittlere_abweichung": ..., "spanne95": [..., ...], "mae": ... },
"nach_messung": { "zustand": "ok", "n": ..., "zieltage": ..., "episoden": ...,
"mittlere_abweichung": ..., "spanne95": [..., ...], ... },
"nach_ansage": {...}, "beide_heiss": {...}, "tafel": {...},
"weit_ueber_ueblich": {...}, "gegenprobe": {...} }, ...],
"gleiche_zieltage": { "paare": ..., "nach_vorlauf": [...] },
"nicht_pruefbar": { "hitzetage_gemessen": ..., "davon_geprueft": ..., "vor_archivbeginn": ...,
"in_archivluecke": ..., "sonstiger_grund": ..., "hoechste_vor_archivbeginn": [...] },
"amtlicher_rekord": {...}, "quellenpruefung_je_wert_seit": "...",
"license": "CC BY 4.0 (Open-Meteo, ERA5) / DWD GeoNutzV (Messung)"
}
Seit dem 01.10.2026. Hitzetage in zwei Blickrichtungen — gefiltert nach der Messung (zum guten Teil Auswahl, Regression zur Mitte) und nach der Ansage (bei einer kalibrierten Vorhersage im Mittel null) —, mit Spannen aus Ziehungen ganzer Zieltage, der Zahl der Hitzewellen dahinter und einer Gegenprobe auf gleichen Zieltagen. Der amtliche Rekord steht als Bezug in der Datei, er stammt nicht aus dem Archiv. Abgedruckt ohne Zahlen; sie stehen in der Datei.
ortsbilanz.json — wetter.kaipfstr.de/ortsbilanz/1
{
"schema": "wetter.kaipfstr.de/ortsbilanz/1",
"berechnet_utc": "...",
"quelle": { "ausgabetage_gewertet": ..., "luecken": [{ "von": "...", "bis": "...", "tage": ... }, ...],
"spaete_laeufe": [...], ... },
"regeln": ["Je Ausgabetag wird nur ein Lauf gewertet ...", ...],
"mindestfaelle": ..., "gruppen": [{ "schluessel": "nah", "vorlauf_von": 0, "vorlauf_bis": 1, ... }, ...],
"groessen": {
"tmax": { "zustand": "bereit", "faelle": ..., "gesamt": {...}, "spannweite": {...},
"halbierungsprobe": { "zeitlich": { "nah": { "r": ..., "spearman": ..., "niveau_a": ...,
"niveau_b": ..., "mittlere_aenderung_k": ..., ... }, ... }, ... },
"rangliste_fair": { "gesamtsieger": "...", "gesamt_zweiter": "...", "gesamt_abstand_k": ...,
"gesamtsieger_haelften": {...}, "gleichstand_k": ..., "knappe_siege": ...,
"siege": [...], "halbierung": {...}, ... },
"nach_stadt": [{ "slug": "...", "stationen": [{ "name": "...", "distance_km": ... }],
"nah": { "bias": ..., "mae": ... }, "alle": {...}, "haelften": {...},
"fair": { "sieger": "...", "abstand_k": ..., "knapp": ..., ... } }, ...] },
"tmin": { "zustand": "waechst", ... } },
"license": "CC BY 4.0 (Open-Meteo, ERA5) / DWD GeoNutzV (Messung)"
}
Seit dem 01.10.2026. Die Nachkontrolle nach Orten: Versatz des Konsenses gegen die
Station je Stadt, eine Halbierungsprobe nach Zieltagen (Korrelation, Rangkorrelation und das Niveau je
Hälfte) und je Stadt der Sieger der gleichen Aufgabe — Siege unter gleichstand_k
zählen als knapp. Abgedruckt ohne Zahlen; sie stehen in der Datei.
monatsbilanz.json — wetter.kaipfstr.de/monatsbilanz/1
{
"schema": "wetter.kaipfstr.de/monatsbilanz/1",
"berechnet_utc": "...",
"quelle": { "ausgabetage_archiviert": ..., "ausgabetage_mit_vergleich": ..., "fehlende_ausgabetage": [...],
"spaete_laeufe": [...], "messung_bis": "...", "paare": ..., ... },
"mindestfaelle": ..., "mindest_zieltage": ..., "min_orte_zieltag": ...,
"regeln": ["Je Ausgabetag wird nur ein Lauf gewertet ...", ...],
"monate": [{ "monat": "JJJJ-MM", "zieltage": ..., "mittlerer_vorlauf": ...,
"luecken": [{ "von": "...", "bis": "...", "tage": ..., "grund": "ausfall" }, ...],
"roh": { "paare": ..., "quote": ..., "mae": ..., "schlagseite": ... },
"vorlaufbereinigt": { "zustand": "gewertet", "mae": ..., "mae_spanne95": [..., ...], ... },
"gleiche_zieltage": {...},
"nach_vorlauf": [{ "vorlauf": 0, "zustand": "gewertet", "paare": ..., "zieltage": ...,
"mae": ..., "schlimmster_zieltag": {...}, ... }, ...] }, ...],
"vergleiche": [{ "von": "JJJJ-MM", "nach": "JJJJ-MM", "roh_differenz_k": ..., "roh_spanne95": [...],
"bereinigt_differenz_k": ..., "bereinigt_spanne95": [...], "mixeffekt_k": [..., ...] }, ...],
"stationsabstand_era5": { "fenster_tage": ..., "monate": [{ "monat": "...", "tage": ..., "mittel_k": ... }, ...] },
"license": "CC BY 4.0 (Open-Meteo, ERA5) / DWD GeoNutzV (Messung)"
}
Seit dem 01.10.2026. Das Zeugnis je Zielmonat und je Vorlauf — weil die Lücken
im Archiv von Monat zu Monat verschieben, wie viele Vergleiche auf kurze und lange Vorläufe fallen.
Die Spannen stammen aus Ziehungen ganzer Zieltage; mixeffekt_k ist der Teil des rohen
Unterschieds zweier Monate, der allein aus dem anderen Vorlaufmix folgt. Abgedruckt ohne Zahlen; sie stehen
in der Datei.
spruenge.json — wetter.kaipfstr.de/spruenge/1
{
"schema": "wetter.kaipfstr.de/spruenge/1",
"berechnet_utc": "...",
"quelle": { "ausgabetage_gewertet": ..., "ausgabetage_luecken": [{ "von": "...", "bis": "...", "tage": ... }],
"spaete_laeufe": [...], "messung_bis": "...", ... },
"regeln": ["Je Ausgabetag wird nur ein Lauf gewertet ...", ...],
"mindestfaelle": ..., "bootstrap": { "ziehungen": ..., "block": "Zieltag" },
"vergleich_gegenbewegung": { "neue_information_prozent": ..., "unabhaengig_gleich_verteilt_prozent": ... },
"nach_vorlauf": [{ "vorlauf": 0, "von_vorlauf": 1,
"sprung": { "zustand": "fertig", "n": ..., "median_k": ..., "q90_k": ..., ... },
"gegenbewegung": { "gegen_prozent": ..., "gegen_spanne95": [..., ...], "gross_ab_k": ...,
"nach_grossem_gegen_prozent": ..., ... },
"richtung": { "waermer_naeher_prozent": ..., "kaelter_naeher_prozent": ...,
"ohne_schlagseite": {...}, ... },
"mittel_heute_gestern": { "gewinn_k": ..., "gewinn_spanne95": [..., ...], ... },
"drittel": { "gruppen": [...], "gross_minus_klein_k": ..., "gross_minus_klein_spanne95": [...] },
"eine_stimme": { "sprung_median_k": ..., "gegen_prozent": ... },
"dubletten_gleich_prozent": ... }, ...],
"je_modell": [{ "modell": "ecmwf_ifs025", "nach_vorlauf": [...] }, ...],
"beispiel": { "slug": "...", "zieltag": "...", "drei_staende": [...], "alle_staende": [...] },
"innerhalb_des_tages": { "nach_vorlauf": [{ "vorlauf": 1, "differenz_k": ..., "differenz_spanne95": [...] }, ...] },
"license": "CC BY 4.0 (Open-Meteo) / DWD GeoNutzV (Messung)"
}
Seit dem 01.10.2026. Wie die Vorhersage für denselben Tag von Lauf zu Lauf springt
und ob ein Sprung zur Messung führt. Die Spannen stammen aus Ziehungen ganzer Zieltage, weil viele Städte
an einem Tag gemeinsam springen; eine_stimme rechnet die Kernzahlen mit KNMI, DMI und MET Norway als
einer Stimme nach. Abgedruckt ohne Zahlen; sie stehen in der Datei.
measured.json — wetter.kaipfstr.de/measured/1
{
"schema": "wetter.kaipfstr.de/measured/1",
"updated_utc": "2026-07-18T06:31:00Z",
"source": "Bright Sky (DWD historical)",
"cities": {
"berlin": {
"name": "Berlin",
"station": { "name": "Berlin-Friedrichshain/Spree", // Station des juengsten Tages
"dwd_station_id": "17473", "distance_km": 1.9 },
"stationen": [ { "name": "Berlin-Friedrichshain/Spree", // alle je gesehenen
"dwd_station_id": "17473", "distance_km": 1.9 } ],
"tmax": { "2026-05-18": 20.0, ..., "2026-07-16": 29.4 }, // waechst
"tmin": { ... }, "niederschlag": { ... }, // seit 26.09.2026
"temperatur_fehlstunden": { "JJJJ-MM-TT": [3, 4], ... } // seit 01.10.2026
},
...
}
}
temperatur_fehlstunden nennt je Tag die Stunden (Ortszeit),
für die die nächste Station keinen eigenen Temperaturwert hatte — nur für
unvollständige Tage. Ein Höchstwert gilt schon, sobald eine eigene Stunde ab 16 Uhr
dabei ist; hier sieht man, ob er aus einem lückenhaften Tag stammt. Für Tage, die vor
dem 01.10.2026 zuletzt abgerufen wurden, hält das Archiv das nicht fest.
verlauf/<ort>.json — wetter.kaipfstr.de/verlauf/1
{
"schema": "wetter.kaipfstr.de/verlauf/1",
"berechnet_utc": "2026-09-30T20:16:25Z",
"slug": "karlsruhe", "name": "Karlsruhe",
"quelle": { "laeufe": 266, "erster_lauf": ["2026-07-18T09:25Z", "2026-07-18"], ... },
"regeln": ["...", ...], // die Rechenregeln im Klartext
"felder_lauf": ["utc", "ausgabe"],
"felder_stand": ["lauf", "vorlauf", "median", "modelle", "verschieden"],
"laeufe": [["2026-07-18T09:25Z", "2026-07-18"], ...], // sortiert nach utc
"zieltage": {
"2026-10-03": { "staende": [[256, 7, 18.3, 7, 5], ...] },
"2026-09-26": { "staende": [...], "gemessen": 26.7 }, // sobald gemessen
...
}
}
Ein Stand verweist mit lauf auf seine Zeile in
laeufe, damit die Zeitangabe nicht in jedem Stand wiederholt wird. Der Median
ist wie auf der Seite auf eine Nachkommastelle gerundet.
index.json — wetter.kaipfstr.de/index/1
{
"schema": "wetter.kaipfstr.de/index/1",
"updated_utc": "2026-07-18T06:31:00Z",
"cities": [{ "slug": "berlin", "name": "Berlin", "lat": 52.52, "lon": 13.405 }, ...],
"models": ["icon_seamless", ...],
"forecasts": ["2026-07-18", ...], // Ausgabetage, KEINE Dateinamen
"snapshots": [{ "file": "2026-08-01T0630Z.json", "date": "2026-08-01",
"utc": "2026-08-01T06:30Z" }, ...], // hier steht der Dateiname
"ensembles": [{ "file": "...", "date": "...", "utc": "..." }, ...],
"warnlagen": [{ "file": "...", "date": "...", "utc": "..." }, ...],
"klimaprojektionen": [{ "file": "karlsruhe.json", "slug": "karlsruhe",
"erzeugt": "2026-08-01T...Z", "modelle": 7,
"nachkommastellen": 2 }, ...],
"verlauf": [{ "file": "karlsruhe.json", "slug": "karlsruhe",
"berechnet_utc": "2026-09-30T...Z", "laeufe": 266 }, ...],
"measured": "/data/measured.json",
"trefferquote": "/data/trefferquote.json",
"rangliste": "/data/rangliste.json",
"modellprofil": "/data/modellprofil.json",
"ensemble_kalibrierung": "/data/ensemble_kalibrierung.json",
"warnlage_archiv": "/data/warnlage_archiv.json",
"klimatologie": "/data/klimatologie.json",
"faustregel": "/data/faustregel.json",
"tendenz": "/data/tendenz.json",
"ortsbilanz": "/data/ortsbilanz.json",
"monatsbilanz": "/data/monatsbilanz.json",
"spruenge": "/data/spruenge.json",
"trefferquote_tmin": "/data/trefferquote_tmin.json",
"regenprobe": null, // null, solange die Datei fehlt
"extremtage": "/data/extremtage.json",
"license": "CC BY 4.0 (Open-Meteo) / DWD GeoNutzV (Messung)"
}
Drei Felder fehlten hier bis zum 30.09.2026, obwohl der Index sie
führte: klimatologie, faustregel und regenprobe
— derselbe Fehler wie der, den der nächste Absatz schon einmal eingesteht.
regenprobe stand am 30.09.2026 auf null, weil die Datei noch nicht entstanden war.
Das gilt für alle vorab gerechneten Felder von trefferquote bis
regenprobe: Solange ihre Datei nicht existiert, steht dort null statt
einer Adresse. Prüfe darauf, bevor du abrufst.
verlauf ist am 30.09.2026 dazugekommen. Der Index, der
am 30.09.2026 im Archiv lag, stammte noch vom 28.09. und führte das Feld deshalb
noch nicht; es erscheint mit dem ersten Schnappschuss danach. Die Dateien selbst liegen
schon unter /data/verlauf/.
Vier dieser Felder fehlten hier bis zum 01.08.2026, obwohl der
Index sie längst führte: snapshots, ensembles,
warnlagen und klimaprojektionen. Der Abdruck versprach eine
Form, die knapper war als die echte — und ausgerechnet snapshots
ist das Feld, aus dem man den Dateinamen nimmt.
klimaprojektionen hat ein anderes Namensschema als die übrigen: eine
Datei je Ort statt je Lauf, weil sich Projektionen nicht ändern.
Ein echter Ausschnitt — damit man es sieht
Kein erfundenes Beispiel: Die folgenden Ausschnitte stammen unverändert
aus den Dateien, die am 18. Juli 2026 unter /data/…
lagen — nur gekürzt (die … stehen für die übrigen Orte,
Modelle und Tage). So sehen die Daten wirklich aus, am Beispiel Berlin.
/data/index.json — das Verzeichnis
{
"schema": "wetter.kaipfstr.de/index/1",
"updated_utc": "2026-07-18T09:27:26Z",
"cities": [
{ "slug": "berlin", "name": "Berlin", "lat": 52.52, "lon": 13.405 },
{ "slug": "hamburg", "name": "Hamburg", "lat": 53.5507, "lon": 9.993 },
... // 25 Orte insgesamt
],
"models": ["icon_seamless", "gfs_seamless", "ecmwf_ifs025", ...], // 11 Modelle
"forecasts": ["2026-07-18"], // bisher genau ein Ausgabetag
"measured": "/data/measured.json",
"trefferquote": "/data/trefferquote.json",
"license": "CC BY 4.0 (Open-Meteo) / DWD GeoNutzV (Messung)"
}
/data/measured.json — die echte Messung
{
"schema": "wetter.kaipfstr.de/measured/1",
"updated_utc": "2026-07-18T09:27:26Z",
"source": "Bright Sky (DWD historical)",
"cities": {
"berlin": {
"name": "Berlin",
"station": { "name": "Berlin-Friedrichshain/Spree",
"dwd_station_id": "17473", "distance_km": 1.9 },
"tmax": {
"2026-05-18": 20.0,
...
"2026-07-14": 25.6,
"2026-07-15": 25.1,
"2026-07-16": 29.4
}
},
... // 25 Orte
}
}
/data/forecasts/2026-07-18.json — der Schnappschuss
{
"schema": "wetter.kaipfstr.de/forecasts/1",
"issued": "2026-07-18",
"generated_utc": "2026-07-18T09:25:28Z",
"models": ["icon_seamless", "gfs_seamless", "ecmwf_ifs025", ...],
"cities": {
"berlin": {
"name": "Berlin", "lat": 52.52, "lon": 13.405,
"dates": ["2026-07-18", "2026-07-19", "2026-07-20", "2026-07-21",
"2026-07-22", "2026-07-23", "2026-07-24", "2026-07-25"],
"tmax": {
"icon_seamless": [25.5, 24.1, 17.7, 24.2, 18.1, 22.4, 24.7, null],
"gfs_seamless": [26.6, 22.0, 18.6, 23.8, 20.0, 20.8, 24.0, 27.8],
... // 11 Modelle
}
},
... // 25 Orte
}
}
So liest man das zusammen: In measured.json steht für Berlin
am 16. Juli der echte Tageshöchstwert 29,4 °C,
gemessen an der Station Berlin-Friedrichshain, 1,9 km vom Stadtpunkt. Im Schnappschuss vom
18. Juli sagt das Modell gfs_seamless für den letzten der acht Tage
(25. Juli) 27,8 °C voraus — während
icon_seamless für denselben Tag null liefert: dieses Modell reicht
nicht so weit, und der Platz bleibt ehrlich leer statt geraten. Genau diese Paare — später
ausgegebene Vorhersage gegen später gemessene Wahrheit — sind der Stoff, aus dem der
Feldbericht seine Fehlerkurven rechnet.
Auch ohne Programmieren: Datei öffnen und lesen
Man braucht kein Skript. Eine .json-Datei ist reiner Text
— jeder Browser und jeder Texteditor zeigt sie an. So kommt man ran:
- 1. Öffnen: Auf einen der Datei-Links oben klicken. Der Browser zeigt den Inhalt direkt als Text an. Zum Speichern: Rechtsklick auf den Link → „Ziel/Verknüpfung speichern unter…".
- 2. Lesen: Der Text ist in Ebenen verschachtelt,
immer als Name: Wert. Ganz außen die Stadt (
"berlin"), darin"tmax"(der Tageshöchstwert), darin je ein Datum: Zahl — etwa"2026-07-16": 29.4. Das heißt schlicht: am 16. Juli war der Höchstwert 29,4 Grad. - 3. Finden: Mit
Strg + F(am MacCmd + F) nach einer Stadt oder einem Datum suchen — der Browser springt an die Stelle. - 4. Verstehen: In der Messungs-Datei ist jede
Zahl ein bereits gemessener, echter Tageswert. In der Vorhersage-Datei sind es
Prognosen: pro Modell acht Zahlen für die acht Tage in
"dates". Einnullbedeutet: für diesen Tag hat dieses Modell nichts geliefert.
Womit man loslegen kann, ohne eine Zeile Code: nachschauen, wie warm es an einem bestimmten Tag in der eigenen Stadt wirklich war; zwei Modelle für denselben Tag nebeneinanderhalten und sehen, wie weit sie auseinanderliegen; oder sich ein kleines Wetter-Tagebuch abschreiben. Wer doch programmiert, findet die Skizze weiter unten.
Wofür es gut ist: die 7-Tage-Grenze überspringen
Die keyless-Vorhersage- und Messungs-APIs zeigen nur ein schmales Fenster. Dieses Archiv hält beide Seiten fest, Tag für Tag — und erst dadurch kann man über Wochen und Monate nachrechnen, wie gut die Vorhersage wirklich war.
Ein Nachkontroll-Zeitraum, so lang wie das Archiv: Nimm aus
einer alten forecasts/JJJJ-MM-TT.json die an dem Tag für ein späteres Datum
ausgegebene Vorhersage (z. B. der Wert für issued + 3 Tage) und stell ihm
aus measured.json den echten Tageshöchstwert desselben Datums gegenüber. Der Betrag
der Differenz ist der Fehler dieser Vorhersage bei drei Tagen Vorlauf. Über viele Ausgabetage
gemittelt entsteht dieselbe Fehler-nach-Vorlauf-Kurve wie im Feldbericht — nur eben so weit
zurück, wie das Archiv reicht, statt nur sieben Tage.
Skizze (Python, nur Standardbibliothek)
import json, urllib.request
def hol(pfad):
with urllib.request.urlopen("https://wetter.kaipfstr.de" + pfad) as r:
return json.load(r)
idx = hol("/data/index.json")
messung = hol("/data/measured.json")["cities"]
# Fehler bei 3 Tagen Vorlauf fuer Berlin, ueber alle Ausgabetage:
fehler = []
for tag in idx["forecasts"]:
fc = hol("/data/forecasts/%s.json" % tag)["cities"]["berlin"]
if len(fc["dates"]) <= 3:
continue
ziel = fc["dates"][3] # issued + 3 Tage
vorh = fc["tmax"]["icon_seamless"][3] # ein Modell als Beispiel
echt = messung["berlin"]["tmax"].get(ziel)
if vorh is not None and echt is not None:
fehler.append(abs(vorh - echt))
print("MAE @3 Tage:", round(sum(fehler) / len(fehler), 2), "K (n =", len(fehler), ")")
Ehrlich dazu: Das Vorhersage-Archiv beginnt mit dem Tag, an dem es eingerichtet wurde, und wächst von da an — die damalige 8-Tage-Vorhersage lässt sich nicht glaubwürdig rückwirkend rekonstruieren, also wird sie es auch nicht. Die Messung dagegen ist ab Start rund 60 Tage tief (echte DWD-historical). Anfangs gibt es also mehr Wahrheit als Vorhersage; die Vorhersageseite holt Tag für Tag auf.
Die 25 Orte
Regional verteilt über Deutschland. Der Slug (kleingeschrieben, ohne Umlaute) ist der Schlüssel in allen Dateien des Archivs.
- Berlin —
berlin - Hamburg —
hamburg - München —
muenchen - Köln —
koeln - Frankfurt —
frankfurt - Stuttgart —
stuttgart - Düsseldorf —
duesseldorf - Leipzig —
leipzig - Dortmund —
dortmund - Essen —
essen - Bremen —
bremen - Dresden —
dresden - Hannover —
hannover - Nürnberg —
nuernberg - Karlsruhe —
karlsruhe - Freiburg —
freiburg - Rostock —
rostock - Kiel —
kiel - Saarbrücken —
saarbruecken - Erfurt —
erfurt - Magdeburg —
magdeburg - Münster —
muenster - Augsburg —
augsburg - Kassel —
kassel - Konstanz —
konstanz
Wie die Zahlen entstehen — zum Nachprüfen
Vorhersage (je Ort, alle elf Modelle in einem Aufruf, 8 Tage, Höchst- und Tiefstwert, Niederschlagssumme):
https://api.open-meteo.com/v1/forecast?latitude=52.52&longitude=13.405&daily=temperature_2m_max,temperature_2m_min,precipitation_sum&models=icon_seamless,gfs_seamless,ecmwf_ifs025,gem_seamless,ukmo_seamless,meteofrance_seamless,jma_seamless,knmi_seamless,dmi_seamless,metno_seamless,cma_grapes_global&forecast_days=8&timezone=Europe%2FBerlin
Messung (echte DWD-Station, Tageshöchstwert aus den Stundenwerten der
nächsten historical-Station; nur vollständig gemessene Tage zählen):
https://api.brightsky.dev/weather?lat=52.52&lon=13.405&date=2026-07-14&last_date=2026-07-16T23:59&tz=Europe/Berlin&units=dwd&observation_type=historical
Aus den Stundenwerten je Kalendertag das Maximum bilden — das ist der
Tageshöchstwert. Für die Messung zählt ausschließlich die nächstgelegene
Station mit observation_type = historical (qualitätsgeprüfte DWD-Messung),
nie current (roh) und nie forecast (Modell).
Wichtig, weil ehrlich: Der DWD prüft die Stunden eines
Tages nicht sofort, sondern nach und nach. Für die letzten ein, zwei Tage kann der
Nachmittags-Peak noch nicht als historical freigegeben sein — dann liegt der
hier gespeicherte Tageshöchstwert vorübergehend ein paar Zehntelgrad zu niedrig, bis der DWD
den Tag final prüft. Wir nehmen bewusst den geprüften Wert und nicht den rohen. Der
tägliche Lauf holt die letzten 14 Tage jedes Mal neu und überschreibt
sie mit dem Endwert. (Genauer: jeder Lauf, also alle sechs Stunden. „Der tägliche
Lauf“ stammt aus der Zeit bis zum 19.07.2026, als nur einmal am Tag gesichert wurde.)
Anders gesagt: Sogar die „Messung" wird nachrevidiert — genau die
Art Unsicherheit, die diese Seite sichtbar macht, statt sie zu verstecken.
Lizenz & Attribution
Die Vorhersage stammt von Open-Meteo und steht unter CC BY 4.0. Die Messung ist eine DWD-Stationsmessung, bezogen über Bright Sky, und unterliegt der DWD GeoNutzV (Quelle: Deutscher Wetterdienst). Verwendest du die Daten weiter, nenne diese Quellen. Das Archiv selbst ist frei nutzbar unter denselben Bedingungen — lade es herunter, rechne nach, bau etwas damit.