telemetrie per pv_array, fix predictinos
Some checks failed
CI and deploy / migration-check (push) Failing after 24s
CI and deploy / deploy (push) Has been skipped

This commit is contained in:
Dusan Vojacek
2026-04-29 13:03:41 +02:00
parent afee62ba4e
commit 9d37efb991
6 changed files with 179 additions and 23 deletions

View File

@@ -50,7 +50,9 @@ BEGIN
v.learning_exclude_reason
FROM ems.forecast_pv_interval fpi
JOIN ems.forecast_pv_run fpr ON fpr.id = fpi.run_id
JOIN ems.asset_pv_array pa ON pa.id = fpr.pv_array_id
JOIN ems.asset_pv_array pa
ON pa.id = fpr.pv_array_id
AND pa.site_id = fpr.site_id
LEFT JOIN ems.site_pv_forecast_calibration cal
ON cal.site_id = fpr.site_id
LEFT JOIN LATERAL (
@@ -115,16 +117,47 @@ BEGIN
(flags.is_curtailed_learning_slot OR flags.is_telemetry_derated_slot) AS exclude_actual_for_learning
) v ON true
LEFT JOIN LATERAL (
SELECT AVG(
WITH base AS (
SELECT AVG(
CASE coalesce(pa.telemetry_source, '')
WHEN 'pv1' THEN ti.pv1_power_w::NUMERIC
WHEN 'pv2' THEN ti.pv2_power_w::NUMERIC
WHEN 'pv_strings' THEN (COALESCE(ti.pv1_power_w, 0) + COALESCE(ti.pv2_power_w, 0))::NUMERIC
WHEN 'pv_total' THEN ti.pv_power_w::NUMERIC
WHEN 'gen_port' THEN ti.gen_port_power_w::NUMERIC
ELSE NULL
END
) AS avg_actual_w
FROM ems.telemetry_inverter ti
WHERE ti.site_id = fpr.site_id
AND ti.measured_at >= fpi.interval_start
AND ti.measured_at < fpi.interval_start + INTERVAL '15 minutes'
),
grp AS (
-- Pokud více pv_array sdílí stejné měření (např. GEN port rozdělený do více orientací),
-- rozdělíme actual proporčně podle forecastu v daném slotu.
SELECT
sum(fpi2.power_w)::numeric AS forecast_group_w
FROM ems.forecast_pv_interval fpi2
JOIN ems.forecast_pv_run fpr2 ON fpr2.id = fpi2.run_id
JOIN ems.asset_pv_array pa2
ON pa2.id = fpi2.pv_array_id
AND pa2.site_id = fpr2.site_id
WHERE pa.telemetry_group IS NOT NULL
AND pa2.site_id = fpr.site_id
AND pa2.telemetry_group = pa.telemetry_group
AND pa2.telemetry_source = pa.telemetry_source
AND fpi2.interval_start = fpi.interval_start
AND fpr2.id = fpr.id
)
SELECT
CASE
WHEN pa.controllable = false THEN ti.gen_port_power_w::NUMERIC
ELSE (COALESCE(ti.pv1_power_w, 0) + COALESCE(ti.pv2_power_w, 0))::NUMERIC
END
) AS avg_actual_w
FROM ems.telemetry_inverter ti
WHERE ti.site_id = fpr.site_id
AND ti.measured_at >= fpi.interval_start
AND ti.measured_at < fpi.interval_start + INTERVAL '15 minutes'
WHEN pa.telemetry_group IS NULL THEN (SELECT avg_actual_w FROM base)
WHEN (SELECT forecast_group_w FROM grp) IS NULL THEN NULL
WHEN (SELECT forecast_group_w FROM grp) <= 0 THEN NULL
WHEN (SELECT avg_actual_w FROM base) IS NULL THEN NULL
ELSE (SELECT avg_actual_w FROM base) * (fpi.power_w::numeric / (SELECT forecast_group_w FROM grp))
END AS avg_actual_w
) slot ON true
WHERE fpr.site_id = p_site_id
AND fpr.status = 'ok'