dalsi ladenik
Some checks failed
CI and deploy / migration-check (push) Failing after 13s
CI and deploy / deploy (push) Has been skipped

This commit is contained in:
Dusan Vojacek
2026-05-21 14:10:22 +02:00
parent ba1cdcbee4
commit 739249a244
3 changed files with 116 additions and 16 deletions

View File

@@ -82,6 +82,7 @@ declare
v_est_pv_wh numeric;
v_est_grid_cost numeric;
v_est_pv_cost numeric;
v_export_window_start timestamptz;
begin
drop table if exists _ems_plan_slot_wk;
create temp table _ems_plan_slot_wk on commit drop as
@@ -288,11 +289,19 @@ begin
from _ems_plan_slot_wk wk
where extract(hour from wk.interval_start at time zone 'Europe/Prague') >= 12;
-- První „výkupní“ okno v horizontu (stejná logika jako discharge maska) — grid nabíjení
-- před tím má prioritu (dnes PM levně → dnes večer prodáš), ne nejlevnější slot zítra.
select min(wk.interval_start)
into v_export_window_start
from _ems_plan_slot_wk wk
where wk.sell_price > v_ref_buy_czk_kwh + v_degrad_czk_kwh;
-- Lookahead min buy (VT→NT) a store_score pro vrstvu A.
alter table _ems_plan_slot_wk
add column if not exists future_sell_lookahead numeric,
add column if not exists buy_min_next_n numeric,
add column if not exists store_score numeric;
add column if not exists store_score numeric,
add column if not exists allow_grid_charge boolean default false;
update _ems_plan_slot_wk wk
set
@@ -309,6 +318,10 @@ begin
from _ems_plan_slot_wk w2
where w2.slot_ord > wk.slot_ord
and w2.slot_ord <= wk.slot_ord + v_lookahead_slots
and (
v_export_window_start is null
or w2.interval_start < v_export_window_start
)
),
store_score =
coalesce(
@@ -385,12 +398,23 @@ begin
wk.buy_min_next_n is null
or wk.buy_price <= wk.buy_min_next_n + v_buy_lookahead_eps
)
order by wk.is_predicted_price::int, wk.buy_price, wk.slot_ord
order by
case
when v_export_window_start is not null
and wk.interval_start < v_export_window_start
then 0
else 1
end,
wk.is_predicted_price::int,
wk.buy_price,
wk.slot_ord
loop
exit when v_cum >= v_chg_am_wh;
exit when v_per_slot_charge_wh <= 0;
exit when v_grid_slots_am >= v_grid_charge_cap_am;
update _ems_plan_slot_wk wk set allow_charge = true where wk.slot_ord = r_slot.slot_ord;
update _ems_plan_slot_wk wk
set allow_charge = true, allow_grid_charge = true
where wk.slot_ord = r_slot.slot_ord;
v_cum := v_cum + v_per_slot_charge_wh;
v_grid_slots_am := v_grid_slots_am + 1;
end loop;
@@ -408,12 +432,23 @@ begin
wk.buy_min_next_n is null
or wk.buy_price <= wk.buy_min_next_n + v_buy_lookahead_eps
)
order by wk.is_predicted_price::int, wk.buy_price, wk.slot_ord
order by
case
when v_export_window_start is not null
and wk.interval_start < v_export_window_start
then 0
else 1
end,
wk.is_predicted_price::int,
wk.buy_price,
wk.slot_ord
loop
exit when v_cum >= v_chg_pm_wh;
exit when v_per_slot_charge_wh <= 0;
exit when v_grid_slots_pm >= v_grid_charge_cap_pm;
update _ems_plan_slot_wk wk set allow_charge = true where wk.slot_ord = r_slot.slot_ord;
update _ems_plan_slot_wk wk
set allow_charge = true, allow_grid_charge = true
where wk.slot_ord = r_slot.slot_ord;
v_cum := v_cum + v_per_slot_charge_wh;
v_grid_slots_pm := v_grid_slots_pm + 1;
end loop;
@@ -471,11 +506,11 @@ begin
from _ems_plan_slot_wk wk
where wk.allow_discharge_export;
-- Acquisition: vážený buy v allow_charge slotech před 1. exportem (ne future_sell z FVE).
-- Acquisition: jen grid vrstva B (ne odpolední FVE z vrstvy A) před 1. exportem.
select
coalesce(sum(
case
when wk.allow_charge
when wk.allow_grid_charge
and (
v_acquisition_cutoff is null
or wk.interval_start < v_acquisition_cutoff
@@ -486,7 +521,7 @@ begin
), 0),
coalesce(sum(
case
when wk.allow_charge
when wk.allow_grid_charge
and (
v_acquisition_cutoff is null
or wk.interval_start < v_acquisition_cutoff
@@ -494,10 +529,22 @@ begin
then wk.buy_price * v_per_slot_charge_wh
else 0
end
), 0)
), 0),
min(
case
when wk.allow_grid_charge
and (
v_acquisition_cutoff is null
or wk.interval_start < v_acquisition_cutoff
)
then wk.buy_price
else null
end
)
into
v_est_grid_wh,
v_est_grid_cost
v_est_grid_cost,
v_charge_acquisition
from _ems_plan_slot_wk wk;
v_est_pv_wh := 0;
@@ -505,12 +552,13 @@ begin
if v_est_grid_wh > 0 then
v_charge_acquisition := v_est_grid_cost / v_est_grid_wh;
else
elsif v_charge_acquisition is null then
v_charge_acquisition := coalesce(
(v_ref_buy_am_czk_kwh + v_ref_buy_pm_czk_kwh) / 2.0,
v_ref_buy_czk_kwh
);
end if;
-- v_charge_acquisition z min(grid) zůstane, pokud je jen jeden grid slot před exportem
return query
with night_tot as (