Lagged demand and wind dominate
Top 10 features by total gain across all three quantile boosters. demand_lag_30m and wind_forecast_3h together account for ~58% of split gain — unsurprising given GB's 30 GW of wind capacity.
A half-hourly forecast of UK grid carbon intensity you can actually run a dishwasher against. Trained on 4.2M rows of half-hourly grid data; deployed on a K3s cluster behind a tiny FastAPI service.
Five stages, retrained nightly. Each box is a small thing that does one job, and fails loudly when it cannot.
NESO API, REST, 5-min cron. Generation mix, demand, interconnector flow.
Lags, rolling means, ECMWF wind & temperature forecasts. pandas, DuckDB.
LightGBM, pinball loss, P10/P50/P90. Retrained nightly. MLflow tracking.
FastAPI on Cloud Run. Cached 30s. Returns JSON quantiles by horizon.
This widget, an iOS shortcut, Home Assistant. Open API, CC-BY 4.0.
Three diagnostics I check when something looks off. Same figures used internally, embedded straight from the training notebook.
Top 10 features by total gain across all three quantile boosters. demand_lag_30m and wind_forecast_3h together account for ~58% of split gain — unsurprising given GB's 30 GW of wind capacity.
Empirical coverage of the P10–P90 band over the last 90 days, by hour-of-day. Slight under-coverage between 17:00 and 20:00 — peak demand period, where the model is least confident.
Mean absolute pinball loss vs forecast horizon, last 30 days. Roughly flat to 4 hours, then climbs steeply — this is why the default horizon button is 4 hours.
No exotic dependencies. Everything here has been in production somewhere for at least five years. That's the point.