Hoe deze app werkt
Geen weersvoorspelling zonder voorbehoud. Hieronder: precies welke bronnen, welke formules, en waar de keuzes vandaan komen — zodat je zelf kunt beoordelen wat de cijfers waard zijn.
In één zin
De voorspelling komt uit het ECMWF IFS ENS ensemble van het Europees weercentrum, opgehaald via Open-Meteo. Wat je ziet is een combinatie van het mediane lid, een betrouwbaarheidsbandbreedte uit alle 51 leden, en — als je dat wilt — een correctie op basis van hoe goed het model recent voor jouw locatie presteerde.
Bronnen
- Voorspelling (operationeel) ·
api.open-meteo.com/v1/forecast— deterministische ECMWF-run, gebruikt voor het huidige weer en voor de WMO-codes die onweer, sneeuw en mist aanduiden. Open-Meteo herdistribueert de ECMWF Open Data gratis onder CC BY 4.0. - Ensemble (51 leden) ·
ensemble-api.open-meteo.com/v1/ensemblemetmodels=ecmwf_ifs025. Dit is de basis van de weerpluim en alle P10/P50/P90-getallen. - Historische voorspellingen ·
historical-forecast-api.open-meteo.com/v1/forecast. Bewaart eerdere modelruns. Voor de terugkijk-pagina halen we per horizon de voorspelling op die N dagen vóór de doeldatum werd uitgegeven. - Werkelijk gemeten weer (recent) · het reguliere
forecast-endpoint metpast_days. Dit zijn station-gekalibreerde uurwaarden tot vandaag. - Klimaatreferentie (jaargemiddelde) ·
archive-api.open-meteo.com/v1/archive— de ERA5-reanalyse. Loopt zo'n vijf dagen achter, maar de kwaliteit is goed genoeg om er een jaargemiddelde mee uit te rekenen. - Weerwaarschuwingen ·
feeds.meteoalarm.org/api/v1/warnings/feeds-netherlands— MeteoAlarm herdistribueert de KNMI-waarschuwingen in CAP-stijl JSON. De link in de banner verwijst door naar KNMI zelf. - Iconen · Meteocons van Bas Milius (MIT-licentie), de "fill"-set in
public/icons/. - Locatie · we gebruiken de browser-geolocatie om twee dingen te doen. Eén: het dichtstbijzijnde KNMI-hoofdstation kiezen waarvoor we de voorspelling berekenen. De app kent twaalf stations — Schiphol, De Kooy, De Bilt, Rotterdam, Hoek van Holland, Eindhoven, Volkel, Eelde, Twenthe, Vlissingen, Maastricht en Leeuwarden — en pikt het dichtstbijzijnde via een hemelsbrede afstand (haversine). Twee: een plaatsnaam in de kop tonen, via de gratis reverse-geocoder van BigDataCloud. Geeft de browser geen toestemming, dan valt de app terug op Schiphol.
Hoe het dag-icoon wordt gekozen
Een ouderwetse weer-app plakt een regenwolk op een dag waarop slechts 's avonds kort iets valt. Hier wordt elke uurwaarde van de dag (06:00–22:00) eerst beoordeeld, daarna pas een icoon gekozen.
Drempels op de uurlijkse mediaan (P50), in volgorde van prioriteit:
- Onweer / sneeuw / mist overrulen al het andere, op basis van de WMO-codes uit de deterministische run.
- Regen — minstens 5 mm verdeeld over de daglichturen én 4 of meer natte uren (≥ 0,2 mm/h), of 6+ natte uren ongeacht het totaal.
- Buien — 2–6 natte uren met minstens 2 mm totaal.
- Lichte regen houdt het droge basis-icoon (zonnig / half bewolkt / bewolkt), maar krijgt een modifier: ochtendbuitje (eerste natte uur ≤ 10:00), laat een buitje (laatste natte uur ≥ 18:00), of buitje tussendoor.
- Droog — alleen bewolkingspercentage telt: < 25% zonnig, < 65% half bewolkt, daarboven bewolkt.
De achterliggende logica zit in src/lib/forecast/classifyDay.ts. De drempels aanpassen kost daar één commit.
De weerpluim
De grafiek bovenaan toont per uur drie statistieken over de 51 ensemble-leden:
- P50 (gele lijn) — de mediaan: helft van de leden voorspelt warmer, helft kouder.
- P10–P90 band (lichtblauw) — 80% van de leden zit tussen deze twee waarden. Hoe wijder de band, hoe minder consensus er is tussen de modelruns — en dus hoe onzekerder de voorspelling.
- Neerslag (cyaan staafjes) — de mediaan in mm/u op de rechter-as.
Het schuifje: Beste schatting vs Bandbreedte
Eerlijk weer tonen kan op twee manieren. Beide zijn wetenschappelijk verdedigbaar; ze vertellen alleen elk een ander deel van het verhaal.
Beste schatting — bias-correctie
Modellen hebben systematische fouten. Voor een specifieke locatie kan een model bijvoorbeeld structureel een graad te koud zijn omdat de gridcel een stukje zee bevat. De simpelste tegenmaatregel:
We doen dit per voorspellingshorizon (1d, 2d, … 7d) en clampen op ± 3 °C zodat bij weinig data geen rare correctie ontstaat. Dit is een kale variant van wat in de meteorologie Model Output Statistics (MOS) heet — het idee gaat terug op Glahn & Lowry, 1972 en wordt door alle nationale weerdiensten in een veel geavanceerdere vorm toegepast.
Code: buildTempBiases() in src/lib/verify/buildMatrix.ts.
Bandbreedte — eerlijke onzekerheid
Een puntvoorspelling ("morgen 14°") suggereert precisie die er niet is. In de bandbreedte-modus tonen we per dag de min-temperatuur uit het koudste 10% van de leden en de max-temperatuur uit het warmste 10%. Dat is exact wat probabilistisch voorspellen zegt: niet één getal, maar een range.
Het ECMWF-ensemble is bewust opgezet om realistische spreiding te geven (kleine verstoringen in de begintoestand plus perturbed physics). Bij een goede kalibratie ligt de gemeten werkelijkheid in ongeveer 80% van de gevallen binnen de P10–P90 band. Is dat structureel niet zo, dan is het ensemble ofwel te krap (band te smal, model is overmoedig) ofwel te ruim (band te breed, model is overdreven voorzichtig). Zie verder ECMWF over spread & reliability.
Welke kies je? Voor "wat trek ik morgen aan?" is Beste schatting handig. Voor "kan deze BBQ doorgaan?" geeft Bandbreedte een eerlijker beeld.
De terugkijk-score
Voor elke dag-target en elke horizon (1d t/m 7d vooruit) wordt één getal van 0–100 berekend. Dat is een gewogen gemiddelde van drie deelscores:
Temperatuur (50% gewicht)
MAE = mean absolute error: het gemiddelde van |voorspeld − werkelijk| over alle uren van de dag. De factor 12 is zo gekozen dat MAE 0 °C → 100 en MAE ~ 8 °C → 0. Een 24-uurs gemiddelde fout van 1 °C levert dus 88 punten op — in de echte wereld al goed.
Neerslag (30% gewicht)
Elk van de 24 uren komt in één van vier hokjes terecht: voorspeld nat of niet, werkelijk nat of niet (drempel: 0,2 mm/h). Daaruit volgt:
Een compleet droge dag waarop ook geen regen viel (en geen regen werd voorspeld) levert 100 punten op. In alle andere gevallen tellen een gemiste bui en een vals alarm even zwaar mee — dat is wat F1 doet.
Icoon (20% gewicht)
Niet de letterlijke icon-string, maar de classificatie van de voorspelde dag versus de echte dag:
- Zelfde primary én modifier → 100
- Zelfde primary, andere modifier → 70
- Aangrenzende categorie (zonnig↔half bewolkt, half bewolkt↔ bewolkt, regen↔buien) → 50
- Anders → 0
Code: src/lib/verify/skillScore.ts. Gewichten en drempels zijn pragmatisch gekozen, niet ge-ijkt; verbetervoorstellen welkom.
De jaarrij onderaan de terugkijk-tabel volgt hetzelfde recept, gemiddeld over de laatste ± 360 dagen waarvoor zowel een historische ECMWF-run als ERA5-werkelijkheid beschikbaar is.
Zijn we te streng?
Eigenlijk niet. Een 24-uurs MAE van 1 °C voor 1d-vooruit (score 88) is meteorologisch al uitstekend. Waar de score wél te streng is, is bij de timing van de regen: een bui die om 17:00 valt in plaats van 15:00 telt in beide uren als fout. Een ruimere tolerantie van zo'n ± 2 uur zou eerlijker zijn — dat staat op de wensenlijst.
Open broncode
Server-rendered Next.js (App Router) met Tailwind, draaiend op een eigen VPS achter pm2. Alles wat hierboven beschreven staat is terug te vinden in de repository. De app gebruikt geen API-keys en geen database; bij elke pagina-render haalt hij de data rechtstreeks bij de bovengenoemde publieke endpoints op.
Wordt bijgewerkt bij elke commit. Suggesties of fouten gevonden? Maak een issue aan.