sjednoceni forecastu
This commit is contained in:
@@ -65,27 +65,6 @@ declare
|
||||
begin
|
||||
drop table if exists _ems_plan_slot_wk;
|
||||
create temp table _ems_plan_slot_wk on commit drop as
|
||||
with prof as (
|
||||
select ems.fn_pv_forecast_delta_profile(
|
||||
p_site_id,
|
||||
greatest(p_from, now() - interval '120 days'),
|
||||
now()
|
||||
) as j
|
||||
),
|
||||
delta_unnest as (
|
||||
select (kv.key)::int as pv_array_id,
|
||||
(x->>'slot_of_day')::int as slot_of_day,
|
||||
(x->>'delta_w')::int as delta_w
|
||||
from prof
|
||||
cross join lateral jsonb_each((prof.j)->'deltas_by_array') kv(key, value)
|
||||
cross join lateral jsonb_array_elements(kv.value->'deltas') x
|
||||
),
|
||||
legacy_slot_delta as (
|
||||
select (x->>'slot_of_day')::int as slot_of_day,
|
||||
(x->>'delta_w')::int as delta_w
|
||||
from prof
|
||||
cross join lateral jsonb_array_elements((prof.j)->'deltas') x
|
||||
),
|
||||
slot_spine as (
|
||||
select gs as interval_start
|
||||
from generate_series(
|
||||
@@ -93,6 +72,26 @@ begin
|
||||
(p_to - interval '15 minutes')::timestamptz,
|
||||
interval '15 minutes'
|
||||
) as gs
|
||||
),
|
||||
pv_canon as (
|
||||
select
|
||||
r.interval_start,
|
||||
coalesce(r.pv_a_forecast_canonical_w, 0)::int as pv_a_forecast_w,
|
||||
coalesce(r.pv_b_forecast_canonical_w, 0)::int as pv_b_forecast_w
|
||||
from jsonb_to_recordset(
|
||||
ems.fn_forecast_pv_slots_range_canonical_ab(
|
||||
p_site_id,
|
||||
p_from,
|
||||
p_to,
|
||||
now(),
|
||||
greatest(p_from, now() - interval '120 days'),
|
||||
now()
|
||||
)
|
||||
) as r(
|
||||
interval_start timestamptz,
|
||||
pv_a_forecast_canonical_w bigint,
|
||||
pv_b_forecast_canonical_w bigint
|
||||
)
|
||||
)
|
||||
select
|
||||
(row_number() over (order by s.interval_start) - 1)::int as slot_ord,
|
||||
@@ -106,8 +105,8 @@ begin
|
||||
ems.fn_get_predicted_price(p_site_id, s.interval_start) * 0.85
|
||||
) as sell_price,
|
||||
(ep.effective_buy_price_czk_kwh is null) as is_predicted_price,
|
||||
coalesce(fpi_a.power_w, 0)::int as pv_a_forecast_w,
|
||||
coalesce(fpi_b.power_w, 0)::int as pv_b_forecast_w,
|
||||
coalesce(pv.pv_a_forecast_w, 0)::int as pv_a_forecast_w,
|
||||
coalesce(pv.pv_b_forecast_w, 0)::int as pv_b_forecast_w,
|
||||
coalesce(
|
||||
(
|
||||
select bs.avg_power_w
|
||||
@@ -127,7 +126,7 @@ begin
|
||||
(coalesce(ev2.status, 'available') not in ('available', 'unavailable')) as ev2_connected,
|
||||
greatest(
|
||||
0,
|
||||
coalesce(fpi_a.power_w, 0) + coalesce(fpi_b.power_w, 0)
|
||||
coalesce(pv.pv_a_forecast_w, 0) + coalesce(pv.pv_b_forecast_w, 0)
|
||||
- coalesce(
|
||||
(
|
||||
select bs.avg_power_w
|
||||
@@ -147,106 +146,9 @@ begin
|
||||
false::boolean as allow_charge,
|
||||
false::boolean as allow_discharge_export
|
||||
from slot_spine s
|
||||
left join pv_canon pv on pv.interval_start = s.interval_start
|
||||
left join ems.vw_site_effective_price ep
|
||||
on ep.site_id = p_site_id and ep.interval_start = s.interval_start
|
||||
left join lateral (
|
||||
with uq as (
|
||||
select distinct on (apa.id)
|
||||
apa.id as pv_array_id,
|
||||
fpi.power_w
|
||||
from ems.asset_pv_array apa
|
||||
join ems.forecast_pv_run fpr
|
||||
on fpr.pv_array_id = apa.id
|
||||
and fpr.site_id = apa.site_id
|
||||
and fpr.status = 'ok'
|
||||
join ems.forecast_pv_interval fpi
|
||||
on fpi.run_id = fpr.id
|
||||
and fpi.pv_array_id = apa.id
|
||||
and fpi.interval_start = s.interval_start
|
||||
where apa.site_id = p_site_id
|
||||
and apa.controllable is true
|
||||
order by apa.id, fpr.created_at desc
|
||||
),
|
||||
slot_of as (
|
||||
select (
|
||||
(extract(hour from (s.interval_start at time zone 'Europe/Prague'))::int * 60)
|
||||
+ extract(minute from (s.interval_start at time zone 'Europe/Prague'))::int
|
||||
) / 15 as slot_of_day
|
||||
),
|
||||
tot as (select coalesce(sum(uq.power_w), 0)::numeric as w from uq)
|
||||
select coalesce(sum(
|
||||
greatest(
|
||||
0,
|
||||
uq.power_w - coalesce(
|
||||
du.delta_w,
|
||||
case
|
||||
when exists (select 1 from delta_unnest limit 1) then null
|
||||
else round(
|
||||
ld.delta_w::numeric * uq.power_w::numeric / nullif((select w from tot), 0)
|
||||
)::int
|
||||
end,
|
||||
0
|
||||
)
|
||||
)
|
||||
), 0)::int as power_w
|
||||
from uq
|
||||
cross join slot_of
|
||||
cross join tot
|
||||
left join delta_unnest du
|
||||
on du.pv_array_id = uq.pv_array_id
|
||||
and du.slot_of_day = slot_of.slot_of_day
|
||||
left join legacy_slot_delta ld
|
||||
on ld.slot_of_day = slot_of.slot_of_day
|
||||
) fpi_a on true
|
||||
left join lateral (
|
||||
with uq as (
|
||||
select distinct on (apa.id)
|
||||
apa.id as pv_array_id,
|
||||
fpi.power_w
|
||||
from ems.asset_pv_array apa
|
||||
join ems.forecast_pv_run fpr
|
||||
on fpr.pv_array_id = apa.id
|
||||
and fpr.site_id = apa.site_id
|
||||
and fpr.status = 'ok'
|
||||
join ems.forecast_pv_interval fpi
|
||||
on fpi.run_id = fpr.id
|
||||
and fpi.pv_array_id = apa.id
|
||||
and fpi.interval_start = s.interval_start
|
||||
where apa.site_id = p_site_id
|
||||
and apa.controllable is false
|
||||
order by apa.id, fpr.created_at desc
|
||||
),
|
||||
slot_of as (
|
||||
select (
|
||||
(extract(hour from (s.interval_start at time zone 'Europe/Prague'))::int * 60)
|
||||
+ extract(minute from (s.interval_start at time zone 'Europe/Prague'))::int
|
||||
) / 15 as slot_of_day
|
||||
),
|
||||
tot as (select coalesce(sum(uq.power_w), 0)::numeric as w from uq)
|
||||
select coalesce(sum(
|
||||
greatest(
|
||||
0,
|
||||
uq.power_w - coalesce(
|
||||
du.delta_w,
|
||||
case
|
||||
when exists (select 1 from delta_unnest limit 1) then null
|
||||
else round(
|
||||
ld.delta_w::numeric * uq.power_w::numeric / nullif((select w from tot), 0)
|
||||
)::int
|
||||
end,
|
||||
0
|
||||
)
|
||||
)
|
||||
), 0)::int as power_w
|
||||
from uq
|
||||
cross join slot_of
|
||||
cross join tot
|
||||
left join delta_unnest du
|
||||
on du.pv_array_id = uq.pv_array_id
|
||||
and du.slot_of_day = slot_of.slot_of_day
|
||||
left join legacy_slot_delta ld
|
||||
on ld.slot_of_day = slot_of.slot_of_day
|
||||
) fpi_b on true
|
||||
left join lateral (
|
||||
select t.status
|
||||
from ems.telemetry_ev_charger t
|
||||
|
||||
Reference in New Issue
Block a user