8.1 KiB
8.1 KiB
Modul: Forecast (Predikce výroby FVE)
Co modul dělá
- Stahuje meteorologická data (irradiance, teplota) pro každé FVE pole zvlášť
- Vypočítává predikovaný výkon v 15min intervalech
- Ukládá výsledek per
pv_array_id+run_id - Predikce se spouští denně a před každým plánovacím během
FVE pole na první instalaci (home-01)
| Pole | Výkon | Azimut | Sklon | Střídač | Řízení |
|---|---|---|---|---|---|
| A | 10 kWp | TBD | TBD | Deye 20kW | řídíme |
| B | 10 kWp | TBD | TBD | Ongridový | autonomní, nepredikujeme odděleně |
Předpoklad: Pole B (ongridový) je zapojeno do GEN portu Deye. Jeho výkon se projeví v
pv_power_wtelemetrie jako součást celkového výkonu. Pro plánování modelujeme jen pole A. Pole B bereme jako šum / bonus který se projeví v auditu.
Azimuty a sklony je nutné doplnit při konfiguraci lokality do
asset_pv_array.
Zdroj meteorologických dat
Primární: Open-Meteo (open-meteo.com)
- Zdarma pro nekomerční použití, API bez registrace
- Poskytuje GHI (Global Horizontal Irradiance), DNI, teplotu, oblačnost
- Historická data + forecast na 7–16 dní dopředu
- 15min granularita nativně ✓
Endpoint:
GET https://api.open-meteo.com/v1/forecast
?latitude={lat}
&longitude={lon}
&hourly=shortwave_radiation,temperature_2m
&minutely_15=shortwave_radiation,temperature_2m
&timezone=Europe/Prague
&forecast_days=3
Záložní / budoucí: Solcast
- Přesnější pro FVE, ale placený
- Podporuje per-array predikci s azimutem a sklonem přímo
- Zatím neimplementujeme, architektura to umožňuje přes
forecast_source
Výpočet výkonu z irradiance
Jednoduchý fyzikální model (dostatečný pro plánování):
def calculate_pv_power(
irradiance_wm2: float, # GHI ze weather service
temp_c: float,
nominal_power_wp: int,
azimuth_deg: float,
tilt_deg: float,
shading_factor: float = 1.0,
temp_coeff: float = -0.004 # typicky -0.4%/°C pro křemík
) -> int:
# 1. Korekce na teplotu panelu
panel_temp = temp_c + 25 # zjednodušený NOCT model
temp_correction = 1 + temp_coeff * (panel_temp - 25)
# 2. Korekce na azimut a sklon (zjednodušená, bez přesného GHI→POA)
# Přesnější model: pvlib knihovna (doporučeno pro produkci)
orientation_factor = cos_angle_of_incidence(azimuth_deg, tilt_deg)
# 3. Výsledný výkon
power_w = (irradiance_wm2 / 1000) * nominal_power_wp * temp_correction * orientation_factor * shading_factor
return max(0, int(power_w))
Doporučení pro implementaci: Použít knihovnu
pvlib(Python) pro přesný POA irradiance výpočet z GHI + azimut + sklon. Je to standardní nástroj, dobře dokumentovaný.
Kdo spouští predikci
Python service: forecast_service
Kdy se spouští
| Trigger | Čas | Popis |
|---|---|---|
| Scheduled (cron) | každé 2 hodiny v :05 |
Průběžný refresh forecastu pro všechny aktivní site |
| Manual trigger | na vyžádání | POST /api/v1/sites/{site_id}/forecast/run |
Implementované provozní změny (2026-03)
- Forecast horizont je konfigurovatelný přes
open_meteo_forecast_days. - Runtime guard: hodnota se clampuje do rozmezí
2..16. - Default je
7dní. - Endpoint
GET /api/v1/sites/{site_id}/forecast/pv?date=YYYY-MM-DDvrací vždy posledníokrun per(interval_start, pv_array_id)(DISTINCT ON), takže UI nevidí duplikáty z historických běhů. - Kalibrace delty:
GET /api/v1/sites/{site_id}/forecast/pv-delta-profile?from=…&to=…vrací JSON zems.fn_pv_forecast_delta_profile(deltas,deltas_by_array,delta_learn_min_tszems.site_pv_forecast_calibration). Volitelné query parametry:half_life_days,threshold_w,top_n_days,non_top_day_factor,day_weight_gamma(NULL u numerických přepsání = hodnota z kalibrační tabulky / default funkce). - Úprava kalibrace z API:
PATCH /api/v1/sites/{site_id}/configuration/pv-forecast-calibrations JSON tělem (částečný update); odpověď je aktuální řádek kalibrace. Souhrn konfigurace vGET …/configurationobsahuje klíčpv_forecast_calibration.
Logika běhu predikce
def run_forecast(site_id: int, horizon_days: int = 2):
site = db.get_site(site_id)
arrays = db.get_pv_arrays(site_id, controllable=True)
for array in arrays:
# 1. Stáhnout meteorologická data
weather = open_meteo_client.fetch(
lat=site.lat, lon=site.lon,
start=today, end=today + horizon_days
)
# 2. Vytvořit forecast_pv_run
run = db.create_forecast_run(
site_id=site_id,
pv_array_id=array.id,
forecast_source="open_meteo",
horizon_start=today_00,
horizon_end=today_end + horizon_days
)
# 3. Vypočítat a uložit intervaly (15min)
intervals = []
for slot in weather.slots_15min:
power = calculate_pv_power(
irradiance_wm2=slot.shortwave_radiation,
temp_c=slot.temperature_2m,
nominal_power_wp=array.nominal_power_wp,
azimuth_deg=array.azimuth_deg,
tilt_deg=array.tilt_deg,
shading_factor=array.shading_factor
)
intervals.append(ForecastInterval(
run_id=run.id,
pv_array_id=array.id,
interval_start=slot.time,
power_w=power,
irradiance_wm2=slot.shortwave_radiation,
temp_c=slot.temperature_2m
))
db.upsert_forecast_intervals(intervals)
db.update_forecast_run_status(run.id, "ok")
DB struktura
Viz 03-data-model.md:
forecast_pv_run– každý běh predikceforecast_pv_interval– 15min výsledky per pole a běh
Tracking přesnosti forecastu
ems.forecast_accuracy– pro každý úspěšnýforecast_pv_runa každý 15min slot ukládá predikovaný výkon, čas vzniku predikce, lead time (hodiny před začátkem slotu), později doplněnou skutečnost z telemetrie a odchylku (error_w,error_pct). Záznamy se uchovávají trvale (včetně všech historických běhů vforecast_pv_run/forecast_pv_interval– ty se nemazají).ems.fn_fill_forecast_accuracy(site_id, lookback_hours)– inkrementálně vloží nebo aktualizuje řádky zforecast_pv_interval+ run metadata a dopočteactual_power_wjako průměr 1min telemetrie ve slotu (pole B:gen_port_power_w, pole A:pv1_power_w+pv2_power_w). Volat každých 15 minut (např. spolu s audit fillerem); parametrlookback_hoursomezuje okno zpětného zpracování (např. 48 h běžně, větší hodnota pro jednorázový backfill).ems.vw_forecast_accuracy_by_lead_time– agregace přesnosti podle bucketů lead time (0–6 h, …, 48 h+); noční sloty s nízkou výrobou (actual_power_w≤ 100 W) se v metrikách typicky vynechávají.ems.vw_forecast_accuracy_daily– denní součty forecast vs actual v kWh (Praha kalendářní den) a relativní odchylka dne.- Po 4+ týdnech dat lze statistiky použít pro kalibraci
safety_factor(nebo obdobných parametrů) v solveru – viz plánovací modul.
Konfigurace (env proměnné)
OPEN_METEO_API_URL=https://api.open-meteo.com/v1/forecast
OPEN_METEO_FORECAST_DAYS=7
FORECAST_MAX_AGE_HOURS=2 # plánovač odmítne starší predikci
FORECAST_RETRY_COUNT=3
Monitoring
- Alert pokud forecast pro dnešní den + zítřek není k dispozici do 15:00
- Endpoint
GET /health/forecast?site_id=1&date=YYYY-MM-DD→ čerstvost a počet intervalů - Log každého běhu (délka horizontu, počet intervalů, trvání, zdroj)
Otevřené body
- Doplnit přesný azimut a sklon obou FVE polí při instalaci
- Rozhodnout: pvlib pro přesnější POA výpočet vs jednoduchý model – doporučujeme pvlib od začátku
- Pole B (ongridový) – zda vůbec modelovat nebo ignorovat v plánu a jen sledovat v auditu
- Solcast jako alternativa v budoucnu –
forecast_sourceto umožňuje bez DB změn