Start with the simplest possible forecast: scale the nameplate rating by an expected capacity factor and call it a day. It will be wrong nearly every hour of operation, and it will be wrong by a lot. A plant rated at 10 MWp does not deliver 10 MW the instant the sun clears the horizon, and it does not trace a smooth bell curve through the day. The output is governed by plane-of-array irradiance, module temperature, the inverter's AC ceiling, and a stack of losses that shift by the hour and the season. Nameplate ignores all of it.
The model is almost never the bottleneck. The input data and the loss chain are.
It begins with irradiance, not the panel
A PV forecast is, first and foremost, an irradiance forecast translated into power. Get the irradiance wrong and no amount of model sophistication recovers it. Numerical weather prediction gives you global horizontal irradiance (GHI) on a grid; you then decompose it into direct and diffuse components and transpose it onto the tilted plane of the array to get plane-of-array (POA) irradiance. Each of those steps — the GHI forecast, the decomposition, the transposition model — adds error, and they compound.
Horizon also matters more than people expect. Day-ahead forecasts lean on NWP and are dominated by how well the model resolves cloud cover. Intraday, you switch regimes: satellite-derived cloud-motion vectors and, on the shortest horizons, on-site sky imagers and the plant's own live telemetry beat any weather model. The right forecasting stack is horizon-dependent, and a system that uses one source for everything leaves accuracy on the table at both ends.
The losses you forgot to subtract
Between POA irradiance and the energy that reaches the meter sits a chain of derating effects, and three of them move the error more than any model tweak.
The first is temperature derating. Module efficiency falls as cell temperature rises — typically around 0.3 to 0.4 percent per degree Celsius above the rated 25°C. On a hot, high-irradiance afternoon, a forecast that ignores cell temperature will systematically overshoot, precisely when output is highest and the error costs the most. Modelling cell temperature from ambient temperature, wind speed and POA irradiance is not optional.
The second is inverter clipping. Most plants are built with a DC-to-AC ratio above one, so on the brightest hours the array produces more DC power than the inverter can convert. The curve flattens at the AC ceiling. A linear irradiance-to-power model that doesn't know about the clipping limit will forecast a peak the plant is physically incapable of delivering — a clean, repeatable overshoot at midday.
The third is soiling. Dust, pollen and bird droppings accumulate gradually and shave a slowly drifting percentage off output until rain or a cleaning cycle resets it. Soiling is invisible to a weather model and to any forecast that treats the plant as static. Tracking it — from the gap between clear-sky expected output and measured output — is what keeps a forecast honest week over week.
A good forecast is mostly an honest accounting of losses. The clever part is small; the bookkeeping is everything.
Garbage telemetry, garbage forecast
Forecasting models are trained and corrected against the plant's own history, which means the forecast inherits every flaw in that history. A pyranometer that has drifted out of calibration, a string that was offline for maintenance, a meter that reported in the wrong units after a firmware update, a dead sensor reporting its last reading forever — each one quietly poisons the training data and the live bias correction. We have seen more accuracy lost to an unflagged sensor gap than to any choice of algorithm.
This is unglamorous and decisive. Before any model, you need ingestion that normalizes meter and IoT data across vendors and protocols, validates ranges, flags stale or physically impossible readings, and stores it as clean time series in a TSDB you can actually query. That data layer — ETL, normalization, gap handling — is exactly the kind of plumbing we build as part of our data & forecasting work, and it is where most of the real accuracy gains hide.
Measure error where the money is
"Our forecast is 95 percent accurate" means nothing without a metric and a horizon. Normalize the error to installed capacity so plants of different sizes are comparable: normalized mean absolute error (nMAE) tells you the average miss, and normalized root-mean-square error (nRMSE) punishes the large misses that hurt most in a market. Report both, and always state the temporal resolution.
Resolution is not a detail. A forecast that looks tidy at hourly resolution can fall apart at 15-minute resolution, where a single passing cloud bank produces a sharp ramp that hourly averaging smooths away. If you settle and dispatch on 15-minute intervals, evaluate at 15 minutes — and backtest over a full year so summer clear-sky bias and winter low-light behaviour both show up. A model tuned only on sunny months will disappoint every December.
1import numpy as np23def nmae(forecast, actual, capacity):4 # normalise to installed capacity (MW)5 return np.abs(forecast - actual).mean() / capacity67def nrmse(forecast, actual, capacity):8 err = forecast - actual9 return np.sqrt((err ** 2).mean()) / capacity # punishes big misses
1-- raw telemetry -> 15-min settlement intervals2SELECT3 time_bucket('15 minutes', ts) AS interval,4 plant_id,5 avg(power_kw) AS avg_kw6FROM telemetry7GROUP BY interval, plant_id8ORDER BY interval;
What the forecast is actually for
None of this is academic. On the intraday market, the gap between your forecast and reality becomes an imbalance position you pay for; a forecast biased high during clipping hours is a recurring, structural cost. Under curtailment, the operator needs a defensible expected-generation figure to argue compensation. For storage paired with PV, the dispatch schedule that charges and discharges the battery is only as good as the generation forecast underneath it.
Better forecasting is not a research project. It is irradiance you trust, losses you account for, and sensors you keep clean — measured at the resolution that settles your invoices.