mirror of
https://github.com/Akkudoktor-EOS/EOS.git
synced 2026-11-13 09:13:30 +01:00
feat(pvforecast): model snow on the modules in the local backend (#1484)
No PV forecast modelled snow lying on the modules, so after a snowfall the optimizer planned with PV that never came. The local Open-Meteo/pvlib backend can now reduce the forecast by the snow coverage (opt-in via pvforecast.akkudoktor.snow_enabled): - Request hourly snowfall and snow depth with the weather and run the NREL snow coverage model (pvlib.snow) per plane. - Correct the coverage with measured PV production: production above the model clears it at once; low production raises it only while snow is plausible, so curtailment and inverter outages are not learned as snow. Persisting snow damps the slide rate, fading with snow_feedback_memory_hours. - Rebuild the coverage from snow_lookback_days on every update instead of storing state. - Exclude intervals with possible snow from the calibration fit. - Warn when PV meter readings are missing or stale; ignore impossible meter jumps. _plane_power keeps its two-value signature (used by the adaptive provider in #1422); the irradiance comes from the new _plane_power_and_poa. Tests replay real February 2026 data from one plant (snow on 02-19/20). Signed-off-by: SchaafAlexander <86607129+SchaafAlexander@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
a06473b6d6
commit
628226d3d9
@@ -908,6 +908,50 @@ Hourly meters are fitted hourly; native quarter-hour meters retain their cadence
|
||||
Probable outage or curtailment days are excluded by default. Without sufficient
|
||||
usable measurements the uncalibrated physical model is used.
|
||||
|
||||
##### Snow on the modules
|
||||
|
||||
Set `snow_enabled` to true to model snow lying on the modules. The local backend
|
||||
then also requests hourly `snowfall` and `snow_depth` from Open-Meteo and runs the
|
||||
NREL snow coverage model (`pvlib.snow.coverage_nrel`) per plane: heavy snowfall
|
||||
covers the modules, warmth and sunshine let the snow slide off, and the modules
|
||||
count as clear once the ground snow depth drops below `snow_threshold_depth_cm`.
|
||||
The forecast is reduced by the covered fraction. No state is stored between runs;
|
||||
every update replays the last `snow_lookback_days` of weather to rebuild the
|
||||
current coverage.
|
||||
|
||||
The weather model alone often misjudges how long snow stays on the modules. With
|
||||
`measurement.pv_production_emr_keys` configured (cumulative meter readings in
|
||||
kWh), `snow_feedback_enabled` corrects the coverage with the measured production
|
||||
of the past hours:
|
||||
|
||||
- Production above the snow model clears the coverage at once.
|
||||
- Production far below the clean-module model (less than `snow_detection_ratio`)
|
||||
raises the coverage, but only while snow is plausible: snow lies on the ground
|
||||
or the model already holds some coverage. Low production on a snow-free day
|
||||
(curtailment, an inverter fault) is ignored.
|
||||
- Persisting snow also slows the modelled slide rate. This fades back with
|
||||
`snow_feedback_memory_hours`, so a warm night after a covered day still clears
|
||||
the modules in the forecast.
|
||||
|
||||
Intervals with possible snow are excluded from the calibration fit, so snow is
|
||||
never learned as a permanent model loss. Meter jumps larger than the plant can
|
||||
produce are ignored.
|
||||
|
||||
```json
|
||||
{
|
||||
"pvforecast": {
|
||||
"provider": "PVForecastAkkudoktor",
|
||||
"akkudoktor": {
|
||||
"backend": "local",
|
||||
"snow_enabled": true
|
||||
}
|
||||
},
|
||||
"measurement": {
|
||||
"pv_production_emr_keys": ["pv_production_emr"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Transient weather errors are retried. If an update still fails, existing usable
|
||||
AC forecasts are retained; a cold start or expired-only forecast reports the
|
||||
error. Retention does not extend the available forecast horizon. Calibration and
|
||||
|
||||
Reference in New Issue
Block a user