Files
ems/db/views/R__057_vw_forecast_accuracy.sql
2026-04-19 20:15:46 +02:00

79 lines
2.9 KiB
SQL

CREATE OR REPLACE VIEW ems.vw_forecast_accuracy_by_lead_time AS
SELECT *
FROM (
SELECT
site_id,
pv_array_id,
CASE
WHEN lead_time_hours <= 6 THEN '0-6h'
WHEN lead_time_hours <= 12 THEN '6-12h'
WHEN lead_time_hours <= 24 THEN '12-24h'
WHEN lead_time_hours <= 48 THEN '24-48h'
ELSE '48h+'
END AS lead_time_bucket,
COUNT(*) AS slot_count,
COUNT(*) FILTER (WHERE actual_power_w > 100) AS daylight_slots,
ROUND(AVG(error_pct)
FILTER (WHERE actual_power_w > 100), 2) AS avg_error_pct,
ROUND(AVG(ABS(error_pct))
FILTER (WHERE actual_power_w > 100), 2) AS avg_abs_error_pct,
ROUND(STDDEV(error_pct)
FILTER (WHERE actual_power_w > 100), 2) AS stddev_error_pct,
CASE
WHEN AVG(error_pct) FILTER (WHERE actual_power_w > 100) > 10
THEN 'nadhodnocuje'
WHEN AVG(error_pct) FILTER (WHERE actual_power_w > 100) < -10
THEN 'podhodnocuje'
ELSE 'ok'
END AS bias
FROM ems.forecast_accuracy
WHERE actual_power_w IS NOT NULL
GROUP BY
site_id,
pv_array_id,
CASE
WHEN lead_time_hours <= 6 THEN '0-6h'
WHEN lead_time_hours <= 12 THEN '6-12h'
WHEN lead_time_hours <= 24 THEN '12-24h'
WHEN lead_time_hours <= 48 THEN '24-48h'
ELSE '48h+'
END
) bucketed
ORDER BY
site_id,
pv_array_id,
CASE lead_time_bucket
WHEN '0-6h' THEN 1
WHEN '6-12h' THEN 2
WHEN '12-24h' THEN 3
WHEN '24-48h' THEN 4
WHEN '48h+' THEN 5
END;
COMMENT ON VIEW ems.vw_forecast_accuracy_by_lead_time IS
'Přesnost FVE forecastu dle lead time (jak daleko předem byl forecast vytvořen).
Ignoruje noční sloty (actual < 100W). avg_error_pct > 0 = forecast nadhodnocuje.
Po 4+ týdnech dat lze použít pro kalibraci safety_factor v solveru.';
CREATE OR REPLACE VIEW ems.vw_forecast_accuracy_daily AS
SELECT
site_id,
pv_array_id,
DATE(interval_start AT TIME ZONE 'Europe/Prague') AS day,
COUNT(*) FILTER (WHERE actual_power_w IS NOT NULL
AND actual_power_w > 100) AS daylight_slots,
ROUND(SUM(forecast_power_w)::NUMERIC / 4000, 2) AS forecast_kwh,
ROUND(SUM(actual_power_w)::NUMERIC / 4000, 2) AS actual_kwh,
ROUND((SUM(forecast_power_w) - SUM(COALESCE(actual_power_w,0)))
::NUMERIC / NULLIF(SUM(actual_power_w),0) * 100, 2) AS day_error_pct
FROM ems.forecast_accuracy
GROUP BY
site_id,
pv_array_id,
DATE(interval_start AT TIME ZONE 'Europe/Prague')
ORDER BY day DESC;
COMMENT ON VIEW ems.vw_forecast_accuracy_daily IS
'Denní souhrn přesnosti FVE forecastu v kWh. forecast_kwh vs actual_kwh.
day_error_pct > 0 = forecast nadhodnotil denní výrobu.';