kalibrace per pole
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
-- Diagnostika: z kterých kalendářních dní (Europe/Prague) se skládá váha pro delta profil
|
||||
-- (stejná logika jako ems.fn_pv_forecast_delta_profile: best → slots → day_stats → day_rank → váhy w).
|
||||
-- (zarovnáno s ems.fn_pv_forecast_delta_profile: eff z site_pv_forecast_calibration, best s learning_eligible,
|
||||
-- agregace slotů na úroveň site pro day_rank / váhy w — stejné jako slot_totals v R__078).
|
||||
--
|
||||
-- Uprav params (site_id, okno, half_life, threshold, top_n_days / non_top / gamma) a spusť v psql.
|
||||
-- Jedna řádka = jeden kalendářní den v okně; p_top_n_days mění tier u vah (ne počet řádků).
|
||||
@@ -20,16 +21,26 @@ tz AS (
|
||||
FROM ems.site s
|
||||
JOIN params p ON s.id = p.site_id
|
||||
),
|
||||
cutoff AS (
|
||||
SELECT timestamptz '2026-04-11T22:00:00Z' AS min_ts
|
||||
eff AS (
|
||||
SELECT
|
||||
coalesce(cal.delta_learn_min_ts, timestamptz '2026-04-11T22:00:00Z') AS delta_learn_min_ts,
|
||||
coalesce(cal.half_life_days, p.half_life_days) AS half_life_days,
|
||||
coalesce(cal.threshold_w, p.threshold_w) AS threshold_w,
|
||||
coalesce(cal.top_n_days, p.p_top_n_days) AS top_n_days,
|
||||
coalesce(cal.non_top_day_factor, p.p_non_top_day_factor) AS non_top_day_factor,
|
||||
coalesce(cal.day_weight_gamma, p.p_day_weight_gamma) AS day_weight_gamma
|
||||
FROM params p
|
||||
JOIN ems.site s ON s.id = p.site_id
|
||||
LEFT JOIN ems.site_pv_forecast_calibration cal ON cal.site_id = s.id
|
||||
),
|
||||
bounds AS (
|
||||
SELECT
|
||||
greatest(p.p_data_from, p.p_data_to - interval '120 days', (SELECT min_ts FROM cutoff)) AS ts_from,
|
||||
greatest(p.p_data_from, p.p_data_to - interval '120 days', e.delta_learn_min_ts) AS ts_from,
|
||||
p.p_data_to AS ts_to,
|
||||
greatest(p.half_life_days, 1) AS half_life_days,
|
||||
greatest(p.threshold_w, 0) AS threshold_w
|
||||
greatest(e.half_life_days, 1::numeric) AS half_life_days,
|
||||
greatest(e.threshold_w, 0::numeric) AS threshold_w
|
||||
FROM params p
|
||||
CROSS JOIN eff e
|
||||
),
|
||||
best AS (
|
||||
SELECT
|
||||
@@ -49,12 +60,14 @@ best AS (
|
||||
AND fa.interval_start < b.ts_to
|
||||
AND fa.actual_power_w IS NOT NULL
|
||||
AND fa.forecast_created_at <= fa.interval_start
|
||||
AND coalesce(fa.learning_eligible, true) IS TRUE
|
||||
),
|
||||
slots AS (
|
||||
slots_array AS (
|
||||
SELECT
|
||||
b.interval_start,
|
||||
sum(b.forecast_power_w)::numeric AS forecast_total_w,
|
||||
sum(b.actual_power_w)::numeric AS actual_total_w,
|
||||
b.pv_array_id,
|
||||
b.forecast_power_w::numeric AS forecast_w,
|
||||
b.actual_power_w::numeric AS actual_w,
|
||||
(
|
||||
(extract(hour FROM (b.interval_start AT TIME ZONE tz.tz_name))::int * 60)
|
||||
+ extract(minute FROM (b.interval_start AT TIME ZONE tz.tz_name))::int
|
||||
@@ -64,7 +77,17 @@ slots AS (
|
||||
FROM best b
|
||||
CROSS JOIN tz
|
||||
WHERE b.rn = 1
|
||||
GROUP BY b.interval_start, slot_of_day, day_local, tz.tz_name
|
||||
),
|
||||
slots AS (
|
||||
SELECT
|
||||
sa.interval_start,
|
||||
sum(sa.forecast_w)::numeric AS forecast_total_w,
|
||||
sum(sa.actual_w)::numeric AS actual_total_w,
|
||||
sa.slot_of_day,
|
||||
sa.day_local,
|
||||
max(sa.age_days) AS age_days
|
||||
FROM slots_array sa
|
||||
GROUP BY sa.interval_start, sa.slot_of_day, sa.day_local
|
||||
),
|
||||
day_energy AS (
|
||||
SELECT s.day_local, sum(s.actual_total_w)::numeric / 4000.0 AS energy_kwh
|
||||
@@ -152,12 +175,12 @@ filtered AS (
|
||||
exp(-s.age_days / nullif((SELECT half_life_days FROM bounds), 0))
|
||||
* (
|
||||
CASE
|
||||
WHEN (SELECT p_top_n_days FROM params) IS NULL THEN 1::numeric
|
||||
WHEN (SELECT p_top_n_days FROM params) < 1 THEN 1::numeric
|
||||
WHEN dr.rn <= (SELECT p_top_n_days FROM params) THEN 1::numeric
|
||||
WHEN (SELECT top_n_days FROM eff) IS NULL THEN 1::numeric
|
||||
WHEN (SELECT top_n_days FROM eff) < 1 THEN 1::numeric
|
||||
WHEN dr.rn <= (SELECT top_n_days FROM eff) THEN 1::numeric
|
||||
ELSE greatest(
|
||||
0::numeric,
|
||||
least(1::numeric, coalesce((SELECT p_non_top_day_factor FROM params), 0.02))
|
||||
least(1::numeric, coalesce((SELECT non_top_day_factor FROM eff), 0.02))
|
||||
)
|
||||
END
|
||||
)
|
||||
@@ -171,7 +194,7 @@ filtered AS (
|
||||
),
|
||||
greatest(
|
||||
0.25,
|
||||
least(coalesce((SELECT p_day_weight_gamma FROM params), 1.0), 8.0)
|
||||
least(coalesce((SELECT day_weight_gamma FROM eff), 1.0), 8.0)
|
||||
)
|
||||
)
|
||||
) AS w
|
||||
|
||||
Reference in New Issue
Block a user