Docs menu Weather & expected generation
Docs

Weather & expected generation

Why we pull weather data, how it shapes the expected-generation model, and why clipping days don't trigger alarms.

Why weather matters for fault detection

"Site X produced 30% less than yesterday" sounds like a fault until you remember yesterday was clear and today's overcast. Without weather, your alerting engine either fires on every cloudy afternoon or sleeps through real faults that happen on a bright day. Neither is useful.

SolarFleet pulls hourly irradiance, ambient temperature and cloud cover for every site's latitude/longitude and uses the irradiance to build a weather-normalised expected generation curve. Alerts compare actual to expected, not actual to yesterday.

solarfleet.io/sites/…/generation
Generation vs expected
Actual Expected
60 45 30 15 now 06 09 12 15 18 21
tracking expected Open-Meteo satellite irradiance · weather-normalised

Illustrative: actual output (lime) tracks the amber expected curve derived from satellite irradiance, with a live “now” marker. Numbers are generic.

The data source

We use Open-Meteo for everything weather-related. It's free, fast, and has enough resolution for the UK. Hourly readings, pulled every hour. We don't co-locate weather calls — sites in the same town share a forecast lookup so we're not double-billing the upstream or our own poll budget.

The fields we read:

  • Shortwave radiation — global horizontal irradiance at the site, W/m² hourly. This is measured on the horizontal plane, not your panels' plane-of-array; the learned yield factor (below) absorbs that gap. This is the field that drives the expected curve. Each value is the average over the hour before its timestamp, so the 14:00 value is drawn and compared against 13:00–14:00 generation.
  • Cloud cover — total percentage. Shown for context alongside generation data; it isn't a separate model input.
  • Temperature — ambient °C, stored for context. There's no explicit temperature coefficient in the model; temperature losses are absorbed into the learned yield factor.

The expected curve

For each site we learn a per-site yield factor — the median of daily actual-vs-modelled ratios over the last 30 days (very dark days excluded), bounded to a sane range. The yield factor accounts for orientation, soiling, shading, temperature and inverter efficiency without needing you to enter any of that.

At each hour, the irradiance-based potential = irradiance × DC capacity × yield factor. The expected curve takes the minimum of that potential, the inverters' AC ceiling, and — on export-limited sites — the export limit plus typical on-site load. The sustained partial-output detection fires when actual stays well below the weather-adjusted expectation across enough peak-hour readings, with today's data confirming the trend.

Why clipping days don't cause alarms

On a hot, clear summer afternoon a site can hit the inverter's AC export cap (or a DNO-imposed G99/G100 limit) and "clip" — the output curve flattens at the cap rather than tracking irradiance. Naïve performance ratio drops below 100% because the irradiance is higher than what the inverter is allowed to convert.

The expected model caps the irradiance-based potential at two ceilings: the inverters' AC nameplate, and — on export-limited sites — the export limit plus typical on-site load (a curtailed site still serves its own consumption; the load floors are configurable in site settings). On the site detail chart, expected flattens at whichever ceiling binds, so clipping reads as clipping rather than a fault. Performance ratio uses the same two ceilings: its reference energy is the irradiance-based potential capped hour by hour at the inverters' AC nameplate and, on export-limited sites, the export limit plus load floor — so clipping and curtailment aren't counted as losses. A day on which a site sent no data at all counts against it, as it does for availability, when its monitoring platform answered for that day with nothing — a tripped isolator or a dead inverter often reports no readings at all. It is left out only when the platform couldn't be reached (a credentials, rate-limit or API gap, back-filled once it clears) or before the site first reported: that output is unknown, not zero.

Where you see this

  • The generation vs expected chart on every site detail page draws the expected curve live.
  • The performance ratio tile uses the weather-normalised expectation, not nameplate × theoretical.
  • The monthly client PDF includes a weather-normalised "performance ratio" headline and a chart annotating days where weather was unfavourable.
  • The sustained partial-output detection compares actual against the expected curve, so a dull day doesn't read as a fault. The other derived detections use simpler daylight and peak-hour gating rather than the full model.

Next up