mirror of
https://github.com/Akkudoktor-EOS/EOS.git
synced 2026-11-13 09:13:30 +01:00
feat(pvforecast): add adaptive per-plane PV learning and diagnostics (#1422)
PV arrays with different orientations and curtailment need separate plant calibration and weather correction. This opt-in provider publishes normal EOS AC/DC forecast keys at 15-minute resolution. - Preserve daily per-plane energy/shape calibration and validated short-term local/trend selection. Curtailment-sensitive arrays require a fresh release flag or an explicitly configured learning guard. - Add switchable empirical solar-angle response relative to separate eligible reference arrays, removing their common weather error. This learns angular residuals, not physical angles or a measured geometric horizon. - Archive actually received weather model inputs, first local receipt and frozen per-member PV candidates. Returned past weather is excluded; unknown source issuance remains explicit. Learn model weights and forecast-regime bias separately at 2–6, 6–24 and 24–48 hours. - New long-horizon candidates remain in shadow until their genuinely issued outputs improve equal-day MAE by the configured margin, win on at least 60% of validation days and pass a matched-support energy-bias guard. Insufficient evidence retains calibration. Daily yields still require complete local days, including DST. - Expose fitted parameters, independent training/validation day counts, errors, selected methods and persistence in the existing status API, with additional normal prediction keys for Grafana. Retain physical DC through angular/weather corrections an enforce individual inverter AC limits. Co-authored-by: Normann <github@koldrack.com> Co-authored-by: Christin <chrissi@von-perbandt.de> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: YMT <yn276364@dal.ca> Co-authored-by: sarankumar1325 <120080287+sarankumar1325@users.noreply.github.com>
This commit is contained in:
co-authored by
Normann
Christin
Claude Opus 5.5
YMT
sarankumar1325
parent
298d46a527
commit
f804d48072
@@ -27,6 +27,9 @@ from akkudoktoreos.prediction.prediction import (
|
||||
Prediction,
|
||||
PredictionCommonSettings,
|
||||
)
|
||||
from akkudoktoreos.prediction.pvakkuadapt import (
|
||||
PVForecastAdaptiveAkkudoktor,
|
||||
)
|
||||
from akkudoktoreos.prediction.pvforecastakkudoktor import PVForecastAkkudoktor
|
||||
from akkudoktoreos.prediction.pvforecastforecastsolar import PVForecastForecastSolar
|
||||
from akkudoktoreos.prediction.pvforecasthomeassistant import PVForecastHomeAssistant
|
||||
@@ -75,6 +78,7 @@ def forecast_providers():
|
||||
LoadImport(),
|
||||
LoadVrm(),
|
||||
PVForecastAkkudoktor(),
|
||||
PVForecastAdaptiveAkkudoktor(),
|
||||
PVForecastForecastSolar(),
|
||||
PVForecastHomeAssistant(),
|
||||
PVForecastImport(),
|
||||
@@ -138,19 +142,23 @@ def test_provider_sequence(prediction):
|
||||
assert isinstance(prediction.providers[21], LoadImport)
|
||||
assert isinstance(prediction.providers[22], LoadVrm)
|
||||
assert isinstance(prediction.providers[23], PVForecastAkkudoktor)
|
||||
assert isinstance(prediction.providers[24], PVForecastForecastSolar)
|
||||
assert isinstance(prediction.providers[25], PVForecastHomeAssistant)
|
||||
assert isinstance(prediction.providers[26], PVForecastImport)
|
||||
assert isinstance(prediction.providers[27], PVForecastPVLib)
|
||||
assert isinstance(prediction.providers[28], PVForecastPVNode)
|
||||
assert isinstance(prediction.providers[29], PVForecastSolcast)
|
||||
assert isinstance(prediction.providers[30], PVForecastVrm)
|
||||
assert isinstance(prediction.providers[24], PVForecastAdaptiveAkkudoktor)
|
||||
assert isinstance(prediction.providers[25], PVForecastForecastSolar)
|
||||
assert isinstance(prediction.providers[26], PVForecastHomeAssistant)
|
||||
assert isinstance(prediction.providers[27], PVForecastImport)
|
||||
assert isinstance(prediction.providers[28], PVForecastPVLib)
|
||||
assert isinstance(prediction.providers[29], PVForecastPVNode)
|
||||
assert isinstance(prediction.providers[30], PVForecastSolcast)
|
||||
assert isinstance(prediction.providers[31], PVForecastVrm)
|
||||
|
||||
|
||||
def test_provider_by_id(prediction, forecast_providers):
|
||||
"""Test that provider_by_id method returns the correct provider."""
|
||||
for provider in forecast_providers:
|
||||
assert prediction.provider_by_id(provider.provider_id()).provider_id() == provider.provider_id()
|
||||
assert (
|
||||
prediction.provider_by_id(provider.provider_id()).provider_id()
|
||||
== provider.provider_id()
|
||||
)
|
||||
|
||||
|
||||
def test_prediction_repr(prediction):
|
||||
|
||||
Reference in New Issue
Block a user