Skip to content

Weather and Degree Days

delabrcd edited this page Jun 6, 2026 · 1 revision

Weather and Degree-Days

Full bill-history temperatures and the degree-day math that weather-normalizes usage — so a cold January doesn't read as waste.

Why Open-Meteo, not the portal

National Grid's own weather feed (weather-cu-uwp-gql) only covers ~24 months and can't be widened (widening its from/last returns empty — see How the Scraper Works). So the primary source is Open-Meteo (free, no key), which has full history. The portal feed remains the fallback. In the Weather table both can coexist for the same region/month via a source column (open-meteo vs ng); the read layer prefers the external/full-history source.

Geocoding

Each account's serviceAddress is geocoded once (Open-Meteo geocoding, lib/weather/geocode.ts) to Account.latitude / longitude and cached. The geocode drives the historical archive pull; it's null until the first successful geocode.

Data fetched (lib/weather/)

  • openMeteo.ts — pulls the daily temperature archive for the geocoded point.
  • WeatherDaily — per-account daily temps (tMean/tMin/tMax, unit, source). We persist full daily resolution because degree-days are computed per bill period, not per calendar month.
  • monthlyTemp.ts — rolls daily up into the monthly Weather rows used by the weather chart.
  • sync.ts — orchestrates geocode → daily archive → monthly rollup during a scrape.

Degree-days (lib/weather/degreeDays.ts, PURE)

Heating/Cooling Degree-Days normalize for weather. Per day against a balance point (default 65°F, the US convention):

HDD = max(0, base − tMean)      # colder day ⇒ more heating demand
CDD = max(0, tMean − base)      # hotter day ⇒ more cooling demand

sumDegreeDays(daily, baseF) sums these over a period (a day exactly at base contributes 0 to both). Dividing usage by degree-days gives a weather-independent per-degree-day intensity, so months are comparable across a mild vs harsh season. The arithmetic lives only here and is exercised by a hand-calculated test (Testing); series.ts folds the result into the monthly series and chartSpec.ts surfaces it.

Accuracy note

Degree-days and weather-normalization are an analysis layer over usage quantities — they don't change how cost is sourced. Cost still comes from the bill PDF's Total Current Charges (Data Accuracy); weather never overrides a billed number.

Clone this wiki locally