second version

This commit is contained in:
Dusan Vojacek
2026-04-03 14:23:16 +02:00
parent 897b95f728
commit 9f4126946d
105 changed files with 9738 additions and 1470 deletions

View File

@@ -12,7 +12,6 @@ import httpx
import pandas as pd
import pvlib
from pvlib import irradiance
from pvlib.pvsystem import pvwatts_dc
from app.config import get_settings
@@ -64,9 +63,12 @@ async def fetch_pv_forecast(site_id: int, db) -> tuple[int, int]:
arrays = await db.fetch(
"""
SELECT *
SELECT id, code, nominal_power_wp, azimuth_deg, tilt_deg,
shading_factor, controllable
FROM ems.asset_pv_array
WHERE site_id = $1
AND azimuth_deg IS NOT NULL
AND tilt_deg IS NOT NULL
ORDER BY id
""",
site_id,
@@ -91,7 +93,7 @@ async def fetch_pv_forecast(site_id: int, db) -> tuple[int, int]:
"temperature_2m",
]
),
"forecast_days": 2,
"forecast_days": max(2, min(int(settings.open_meteo_forecast_days), 16)),
"timezone": "auto",
}
@@ -148,6 +150,7 @@ async def fetch_pv_forecast(site_id: int, db) -> tuple[int, int]:
loc = pvlib.location.Location(lat, lon, tz=api_tz)
solar_pos = loc.get_solarposition(times)
dni_extra = irradiance.get_extra_radiation(times)
total_rows = 0
horizon_start = times[0].tz_convert(timezone.utc).to_pydatetime()
@@ -156,13 +159,13 @@ async def fetch_pv_forecast(site_id: int, db) -> tuple[int, int]:
)
for arr in arrays:
tilt = float(arr["tilt_deg"] or 0.0)
az_db = float(arr["azimuth_deg"] or 0.0)
tilt = float(arr["tilt_deg"])
az_db = float(arr["azimuth_deg"])
az_pvlib = _db_azimuth_to_pvlib(az_db)
pdc0 = float(arr["nominal_power_wp"])
nominal_power_wp = float(arr["nominal_power_wp"])
shading = float(arr["shading_factor"] or 1.0)
poa = irradiance.get_total_irradiance(
poa_global = irradiance.get_total_irradiance(
surface_tilt=tilt,
surface_azimuth=az_pvlib,
solar_zenith=solar_pos["apparent_zenith"],
@@ -170,20 +173,23 @@ async def fetch_pv_forecast(site_id: int, db) -> tuple[int, int]:
dni=dni,
ghi=ghi,
dhi=dhi,
dni_extra=dni_extra,
model="haydavies",
)["poa_global"].fillna(0).clip(lower=0)
temp_cell = temp_air + 0.04 * poa
p_dc = pvwatts_dc(poa, temp_cell, pdc0, -0.004)
p_dc = p_dc.fillna(0).clip(lower=0) * shading
power_w = p_dc.round().astype(int)
area_m2 = nominal_power_wp / (1000.0 * 0.20)
power_w = poa_global * area_m2 * 0.20 * shading
cap_w = nominal_power_wp * 1.1
power_w = power_w.clip(lower=0, upper=cap_w).round().astype(int)
model_params: dict[str, Any] = {
"source": "open_meteo",
"endpoint": base,
"params": params,
"pvlib_model": "haydavies",
"pvwatts_gamma_pdc": -0.004,
"nominal_power_wp": nominal_power_wp,
"shading_factor": shading,
"area_m2_ref_20pct": area_m2,
}
run_id = await db.fetchval(