sync reference days
This commit is contained in:
21
db/migration/V076__pv_forecast_reference_day.sql
Normal file
21
db/migration/V076__pv_forecast_reference_day.sql
Normal file
@@ -0,0 +1,21 @@
|
||||
-- Kalendářní dny lokality označené jako referenční pro učení delty PV forecastu (dobrá obloha).
|
||||
|
||||
create table ems.site_pv_forecast_reference_day (
|
||||
site_id int not null references ems.site (id) on delete cascade,
|
||||
day_local date not null,
|
||||
notes text null,
|
||||
created_at timestamptz not null default now(),
|
||||
primary key (site_id, day_local)
|
||||
);
|
||||
|
||||
comment on table ems.site_pv_forecast_reference_day is
|
||||
'Dny v kalendáři lokality podle jejího site.timezone (typicky datum ve zdi Europe/Prague), kterým se v ems.fn_pv_forecast_delta_profile zvýší váha řádků forecast_accuracy při počítání delta profilu.';
|
||||
|
||||
comment on column ems.site_pv_forecast_reference_day.day_local is
|
||||
'Kalendářní datum v časové zóně lokality; porovnává se na (interval_start AT TIME ZONE site.timezone)::date ze slotů.';
|
||||
|
||||
alter table ems.site_pv_forecast_calibration
|
||||
add column if not exists reference_day_weight_mult numeric null;
|
||||
|
||||
comment on column ems.site_pv_forecast_calibration.reference_day_weight_mult is
|
||||
'Násobitel váhy učícího vzorku pro všechny sloty jejichž den spadá do site_pv_forecast_reference_day; NULL použije default v fn_pv_forecast_delta_profile (aktuálně 3).';
|
||||
@@ -19,14 +19,16 @@ LANGUAGE sql
|
||||
STABLE
|
||||
SET work_mem = '64MB'
|
||||
AS $fn$
|
||||
WITH eff AS (
|
||||
WITH 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_top_n_days) AS top_n_days,
|
||||
coalesce(cal.non_top_day_factor, p_non_top_day_factor) AS non_top_day_factor,
|
||||
coalesce(cal.day_weight_gamma, p_day_weight_gamma) AS day_weight_gamma
|
||||
coalesce(cal.day_weight_gamma, p_day_weight_gamma) AS day_weight_gamma,
|
||||
greatest(1::numeric, coalesce(cal.reference_day_weight_mult, 3::numeric))
|
||||
AS reference_day_w_mult
|
||||
FROM ems.site s
|
||||
LEFT JOIN ems.site_pv_forecast_calibration cal ON cal.site_id = s.id
|
||||
WHERE s.id = p_site_id
|
||||
@@ -170,6 +172,11 @@ AS $fn$
|
||||
) AS rn
|
||||
FROM day_stats ds
|
||||
),
|
||||
ref_wall AS (
|
||||
SELECT d.day_local
|
||||
FROM ems.site_pv_forecast_reference_day d
|
||||
WHERE d.site_id = p_site_id
|
||||
),
|
||||
filtered AS (
|
||||
SELECT
|
||||
s.pv_array_id,
|
||||
@@ -194,7 +201,12 @@ AS $fn$
|
||||
),
|
||||
greatest(0.25, least(coalesce(e.day_weight_gamma, 1.0), 8.0))
|
||||
)
|
||||
) AS w
|
||||
)
|
||||
* CASE
|
||||
WHEN EXISTS (SELECT 1 FROM ref_wall rw WHERE rw.day_local = s.day_local)
|
||||
THEN e.reference_day_w_mult
|
||||
ELSE 1::numeric
|
||||
END AS w
|
||||
FROM slots s
|
||||
CROSS JOIN bounds b
|
||||
CROSS JOIN eff e
|
||||
@@ -281,4 +293,6 @@ AS $fn$
|
||||
$fn$;
|
||||
|
||||
COMMENT ON FUNCTION ems.fn_pv_forecast_delta_profile IS
|
||||
'Aditivní delta profil PV forecastu po 15min slotu dne (96 slotů) per pv_array_id v `deltas_by_array`; `deltas` je součet delt přes pole (kompatibilita). Zdroj: forecast_accuracy s learning_eligible, cutoff a numerické defaulty z ems.site_pv_forecast_calibration (NULL sloupce = parametry volání).';
|
||||
'Aditivní delta profil PV forecastu po 15min slotu dne (96 slotů) per pv_array_id v deltas_by_array; deltas je součet delt přes pole.'
|
||||
' Zdroj forecast_accuracy learning_eligible, cutoff kalibrace, váhy dnů.'
|
||||
' Dny z ems.site_pv_forecast_reference_day (den = interval ve site.timezone) mají násobenou váhu (site_pv_forecast_calibration.reference_day_weight_mult nebo default 3).';
|
||||
|
||||
120
db/routines/R__086_fn_forecast_pv_prague_day_ops.sql
Normal file
120
db/routines/R__086_fn_forecast_pv_prague_day_ops.sql
Normal file
@@ -0,0 +1,120 @@
|
||||
-- Operace nad PV forecastem v DB a správa referenčních dnů kalibrace (náhrada dřívějších .sh nástrojů).
|
||||
|
||||
create or replace function ems.fn_delete_forecast_pv_prague_calendar_day(
|
||||
p_day date,
|
||||
p_site_id int default null
|
||||
)
|
||||
returns table (
|
||||
targets_interval_rows bigint,
|
||||
deleted_forecast_accuracy_rows bigint,
|
||||
deleted_forecast_pv_interval_rows bigint,
|
||||
deleted_empty_forecast_pv_run_rows bigint
|
||||
)
|
||||
language plpgsql
|
||||
volatile
|
||||
as $fn$
|
||||
declare
|
||||
v_ts_start timestamptz;
|
||||
v_ts_end timestamptz;
|
||||
v_tgt interval_rows bigint;
|
||||
v_acc bigint;
|
||||
v_iv bigint;
|
||||
v_run bigint;
|
||||
begin
|
||||
v_ts_start := (p_day::text || ' 00:00:00')::timestamp at time zone 'Europe/Prague';
|
||||
v_ts_end := ((p_day + 1)::text || ' 00:00:00')::timestamp at time zone 'Europe/Prague';
|
||||
|
||||
drop table if exists _ems_wipe_pv_forecast_targets;
|
||||
|
||||
create temporary table _ems_wipe_pv_forecast_targets (
|
||||
run_id int not null,
|
||||
pv_array_id int not null,
|
||||
interval_start timestamptz not null
|
||||
) on commit drop;
|
||||
|
||||
insert into _ems_wipe_pv_forecast_targets (run_id, pv_array_id, interval_start)
|
||||
select fi.run_id, fi.pv_array_id, fi.interval_start
|
||||
from ems.forecast_pv_interval fi
|
||||
inner join ems.forecast_pv_run r on r.id = fi.run_id
|
||||
where fi.interval_start >= v_ts_start
|
||||
and fi.interval_start < v_ts_end
|
||||
and (p_site_id is null or r.site_id = p_site_id);
|
||||
|
||||
get diagnostics v_tgt = row_count;
|
||||
|
||||
delete from ems.forecast_accuracy fa
|
||||
using (select distinct run_id, interval_start from _ems_wipe_pv_forecast_targets) t
|
||||
where fa.run_id = t.run_id
|
||||
and fa.interval_start = t.interval_start;
|
||||
|
||||
get diagnostics v_acc = row_count;
|
||||
|
||||
delete from ems.forecast_pv_interval fi
|
||||
using _ems_wipe_pv_forecast_targets t
|
||||
where fi.run_id = t.run_id
|
||||
and fi.pv_array_id = t.pv_array_id
|
||||
and fi.interval_start = t.interval_start;
|
||||
|
||||
get diagnostics v_iv = row_count;
|
||||
|
||||
delete from ems.forecast_pv_run fr
|
||||
where fr.id in (select distinct run_id from _ems_wipe_pv_forecast_targets)
|
||||
and not exists (
|
||||
select 1 from ems.forecast_pv_interval x where x.run_id = fr.id
|
||||
);
|
||||
|
||||
get diagnostics v_run = row_count;
|
||||
|
||||
targets_interval_rows := v_tgt;
|
||||
deleted_forecast_accuracy_rows := v_acc;
|
||||
deleted_forecast_pv_interval_rows := v_iv;
|
||||
deleted_empty_forecast_pv_run_rows := v_run;
|
||||
return next;
|
||||
end;
|
||||
$fn$;
|
||||
|
||||
comment on function ems.fn_delete_forecast_pv_prague_calendar_day is
|
||||
'Maze forecast_pv_interval (a navázané forecast_accuracy) pro řádky podle začátku intervalu '
|
||||
'na daný kalendářní den hranovaný půlnocí Europe/Prague — ne podle TZ lokality.'
|
||||
' p_site_id NULL = všechny lokality. Prázdné forecast_pv_run v mazané množině smaže návazně.'
|
||||
' Destruktivní vůči historii přesnosti; preferuj jen provozní re-import forecastu.';
|
||||
|
||||
|
||||
create or replace function ems.fn_pv_forecast_sync_reference_days(
|
||||
p_site_id int,
|
||||
p_days_local date[],
|
||||
p_replace_existing boolean default false
|
||||
)
|
||||
returns int
|
||||
language plpgsql
|
||||
volatile
|
||||
as $fn$
|
||||
declare
|
||||
v_after int;
|
||||
begin
|
||||
if not exists (select 1 from ems.site s where s.id = p_site_id) then
|
||||
raise exception using
|
||||
message = format('site_id %s neexistuje v ems.site', p_site_id),
|
||||
errcode = 'P0001';
|
||||
end if;
|
||||
|
||||
if p_replace_existing then
|
||||
delete from ems.site_pv_forecast_reference_day d where d.site_id = p_site_id;
|
||||
end if;
|
||||
|
||||
insert into ems.site_pv_forecast_reference_day (site_id, day_local)
|
||||
select p_site_id, d::date
|
||||
from unnest(p_days_local) as u(d)
|
||||
where d is not null
|
||||
on conflict (site_id, day_local) do nothing;
|
||||
|
||||
select count(*)::int into v_after from ems.site_pv_forecast_reference_day d where d.site_id = p_site_id;
|
||||
return v_after;
|
||||
end;
|
||||
$fn$;
|
||||
|
||||
comment on function ems.fn_pv_forecast_sync_reference_days is
|
||||
'Zapíše kalendářní dny (datum ve zdi site.timezone lokality při použití s fn_pv_forecast_delta_profile) jako referenční. '
|
||||
'p_replace_existing true smaže předchozí záznamy dané lokality; false jen doplňuje unnest bez přepsání. '
|
||||
'Vrací počet řádků v site_pv_forecast_reference_day po operaci.';
|
||||
|
||||
@@ -29,6 +29,7 @@ GRANT SELECT ON ems.vw_telemetry_hourly_7d TO ems_anon;
|
||||
GRANT SELECT ON ems.vw_telemetry_15m_7d TO ems_anon;
|
||||
GRANT SELECT ON ems.forecast_accuracy TO ems_anon;
|
||||
GRANT SELECT ON ems.site_pv_forecast_calibration TO ems_anon;
|
||||
GRANT SELECT ON ems.site_pv_forecast_reference_day TO ems_anon;
|
||||
GRANT SELECT ON ems.vw_forecast_accuracy_by_lead_time TO ems_anon;
|
||||
GRANT SELECT ON ems.vw_forecast_accuracy_daily TO ems_anon;
|
||||
GRANT SELECT ON ems.consumption_baseline_stats TO ems_anon;
|
||||
|
||||
Reference in New Issue
Block a user