fix nabijeni z gridu u fixnich tarifu
This commit is contained in:
@@ -62,6 +62,7 @@ declare
|
||||
v_night_buf_pct numeric;
|
||||
v_degrad_czk_kwh numeric;
|
||||
v_ref_buy_czk_kwh numeric;
|
||||
v_purchase_pricing_mode text;
|
||||
begin
|
||||
drop table if exists _ems_plan_slot_wk;
|
||||
create temp table _ems_plan_slot_wk on commit drop as
|
||||
@@ -227,6 +228,17 @@ begin
|
||||
raise exception 'No asset_battery for site_id=%', p_site_id;
|
||||
end if;
|
||||
|
||||
select coalesce(smc.purchase_pricing_mode, 'spot')
|
||||
into v_purchase_pricing_mode
|
||||
from ems.site_market_config smc
|
||||
where smc.site_id = p_site_id
|
||||
and smc.valid_from <= p_from
|
||||
and (smc.valid_to is null or smc.valid_to > p_from)
|
||||
order by smc.valid_from desc
|
||||
limit 1;
|
||||
|
||||
v_purchase_pricing_mode := coalesce(v_purchase_pricing_mode, 'spot');
|
||||
|
||||
v_per_slot_charge_wh := v_max_charge_w * v_charge_eff * 0.25;
|
||||
v_per_slot_discharge_wh := v_max_discharge_w * v_discharge_eff * 0.25;
|
||||
v_energy_to_fill := v_soc_max_wh - p_current_soc_wh;
|
||||
@@ -266,13 +278,9 @@ begin
|
||||
-- Toto je hlavní mechanismus proti mikro-cyklování z PV:
|
||||
-- v drahých slotech se PV prodává přímo, nabíjení jen v levných.
|
||||
--
|
||||
-- B) Non-PV sloty (pv_surplus_w <= 0): AM/PM budget, OTE-first.
|
||||
-- Nejlevnější non-PV sloty (dle buy_price) s prioritou OTE cen
|
||||
-- před predikovanými (is_predicted_price::int ASC). AM a PM mají
|
||||
-- oddělený rozpočet (50/50), aby solver nekoncentroval veškeré
|
||||
-- nabíjení/vybíjení do jediné půlky dne (double-cycle ochrana).
|
||||
-- OTE-first: levné OTE sloty aktuálního dne nesmí být vytlačeny
|
||||
-- levnějšími predikovanými cenami vzdálených dní (den 3–4 z 96h).
|
||||
-- B) Non-PV sloty (pv_surplus_w <= 0): AM/PM budget, OTE-first (jen spot nákup).
|
||||
-- U purchase_pricing_mode = fixed se grid nabíjení neplánuje — buy je
|
||||
-- v každém slotu stejný, cyklus ze sítě by byl čistá ztráta; nabíjení jen z FVE.
|
||||
if v_charge_buf <= 0 then
|
||||
update _ems_plan_slot_wk wk set allow_charge = true;
|
||||
elsif v_energy_to_fill <= 0 then
|
||||
@@ -293,35 +301,37 @@ begin
|
||||
v_cum := v_cum + least(r_slot.pv_surplus_w, v_max_charge_w) * v_charge_eff * 0.25;
|
||||
end loop;
|
||||
|
||||
-- B) Non-PV AM: OTE-first, then predicted, ordered by buy_price
|
||||
v_cum := 0;
|
||||
for r_slot in
|
||||
select wk.slot_ord
|
||||
from _ems_plan_slot_wk wk
|
||||
where wk.pv_surplus_w <= 0
|
||||
and extract(hour from wk.interval_start at time zone 'Europe/Prague') < 12
|
||||
order by 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;
|
||||
update _ems_plan_slot_wk wk set allow_charge = true where wk.slot_ord = r_slot.slot_ord;
|
||||
v_cum := v_cum + v_per_slot_charge_wh;
|
||||
end loop;
|
||||
if v_purchase_pricing_mode <> 'fixed' then
|
||||
-- B) Non-PV AM: OTE-first, then predicted, ordered by buy_price
|
||||
v_cum := 0;
|
||||
for r_slot in
|
||||
select wk.slot_ord
|
||||
from _ems_plan_slot_wk wk
|
||||
where wk.pv_surplus_w <= 0
|
||||
and extract(hour from wk.interval_start at time zone 'Europe/Prague') < 12
|
||||
order by 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;
|
||||
update _ems_plan_slot_wk wk set allow_charge = true where wk.slot_ord = r_slot.slot_ord;
|
||||
v_cum := v_cum + v_per_slot_charge_wh;
|
||||
end loop;
|
||||
|
||||
-- B) Non-PV PM: OTE-first, then predicted, ordered by buy_price
|
||||
v_cum := 0;
|
||||
for r_slot in
|
||||
select wk.slot_ord
|
||||
from _ems_plan_slot_wk wk
|
||||
where wk.pv_surplus_w <= 0
|
||||
and extract(hour from wk.interval_start at time zone 'Europe/Prague') >= 12
|
||||
order by 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;
|
||||
update _ems_plan_slot_wk wk set allow_charge = true where wk.slot_ord = r_slot.slot_ord;
|
||||
v_cum := v_cum + v_per_slot_charge_wh;
|
||||
end loop;
|
||||
-- B) Non-PV PM: OTE-first, then predicted, ordered by buy_price
|
||||
v_cum := 0;
|
||||
for r_slot in
|
||||
select wk.slot_ord
|
||||
from _ems_plan_slot_wk wk
|
||||
where wk.pv_surplus_w <= 0
|
||||
and extract(hour from wk.interval_start at time zone 'Europe/Prague') >= 12
|
||||
order by 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;
|
||||
update _ems_plan_slot_wk wk set allow_charge = true where wk.slot_ord = r_slot.slot_ord;
|
||||
v_cum := v_cum + v_per_slot_charge_wh;
|
||||
end loop;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
-- Referenční nákup pro arbitráž exportu: nejlevnější buy mezi sloty, kde lze nabíjet
|
||||
@@ -346,7 +356,14 @@ begin
|
||||
for r_slot in
|
||||
select wk.slot_ord
|
||||
from _ems_plan_slot_wk wk
|
||||
where wk.sell_price > v_ref_buy_czk_kwh + v_degrad_czk_kwh
|
||||
where (
|
||||
case
|
||||
when v_purchase_pricing_mode = 'fixed' then
|
||||
wk.sell_price > v_degrad_czk_kwh
|
||||
else
|
||||
wk.sell_price > v_ref_buy_czk_kwh + v_degrad_czk_kwh
|
||||
end
|
||||
)
|
||||
order by wk.sell_price desc, wk.slot_ord desc
|
||||
loop
|
||||
exit when v_cum >= v_discharge_target_wh;
|
||||
|
||||
Reference in New Issue
Block a user