MADRIDAire

Technical details

This is where sources, preparation, validation, and limits are documented. It is the layer for traceability, not the public entry point to the product.

Technical details

Methodology and traceability

This page explains where the data comes from, how it is prepared, and which limits shape the forecast before it reaches the site.

Forecast model

NO2 model v1

+5.6% vs. baseline

Horizon

24h

28 stations · 12 pollutants

Training window

2025-01-08 → 2025-12-31

358 training days

Test window

2026-01-01 → 2026-04-29

119 validation days

Current operational read

What is governing the system right now

Cloudflare D1 + ingestion

Cloudflare D1 is responding, but the signal is lagging

The API is already reading from Cloudflare D1, although the last valid observation is still 28 Sept 2026, 02:00. The next point to review is the protected ingestion cycle, not database connectivity.

Environment

production

reported by the API

Observation source

Cloudflare D1

active read path

Latest valid observation

28 Sept 2026, 02:00

over 12h old

Remote ingest

cron ready

D1 yes · jobs yes

Before the technical detail

If you only want to interpret current conditions, start with the overview, the map, or the forecast. This page goes through the full process: data, preparation, validation, and limits.

Back to guide

Sources

Comunidad de Madrid: official 2025 and 2026 historical air-quality exports.

Cloudflare D1 serves the recent normalized observation signal, while official daily CSV exports remain the verified raw input and fallback source.

Official station metadata for municipality, address, zone, and coordinates.

Weather variables remain documented for future iterations, but they are not part of the published v1 model yet.

ETL

Flexible ingestion of official CSV files with pandas.

Wide-to-long normalization into station, pollutant, and hourly observations.

Consolidation of `.normalized.csv` snapshots with timestamp-level deduplication before the operational signal is published.

Conservative `risk_level` assignment and explicit removal of invalid values.

Validation

Current observation coverage: 28 stations and 12 active pollutants.

No synthetic stations, no invented coordinates, and no frontend-side forecasting.

Freshness and consistency checks gate `/api/latest`, `/api/summary`, and `/api/system-status`.

ML artifacts are published only after an honest temporal split and baseline comparison.

Feature engineering

Temporal variables: hour, day of week, month, and weekend flag.

Station encoding to capture structural differences across official nodes.

NO2 lags at 1h, 3h, 6h, 24h, and 168h.

3h, 6h, and 24h rolling means computed per station without temporal leakage.

Temporal split

The current validation uses train 2025 / test 2026; an intermediate persisted validation window does not exist yet.

Training window

2025-01-08 → 2025-12-31

Test window

2026-01-01 → 2026-04-29

Evaluation

Real comparison between the selected predictor and the reference baselines on the test window.

persistence

n=78077

MAE8.32
RMSE14.07
R²0.205

same_hour_yesterday

n=78077

MAE9.92
RMSE16.26
R²-0.062

hist_gradient_boosting_v1

n=78077

MAE7.85
RMSE11.96
R²0.426

Limitations

The public API still does not expose station-level error even though the artifact computes it.

Observations already come from Cloudflare D1, but freshness still depends on the protected ingest cycle completing on time.

Weather features are not part of the current v1 model.

Forecasts and metrics are still published as versioned artifacts, and weekly historical reporting is not persisted yet.