Files
ems/db/routines/R__016_fn_ev_session_transition.sql
Dusan Vojacek 60eda46dd7 V098: týdenní požadavky EV (ev_weekly_requirement) + fn_ev_session_defaults
Tabulka ems.ev_weekly_requirement (dow 0=pondělí..6, target_soc_pct,
deadline_hour Europe/Prague, enabled; unique per vozidlo+den) se seedem
tesla-my pondělí 07:00 → 90 %. Nová ems.fn_ev_session_defaults(vehicle,
arrival) → jsonb {target_soc_pct, deadline, source}: kaskáda týdenní
požadavek (výskyt do 48 h) → forecast z ev_usage_stats
(target_soc_forecast_enabled, chování V089 beze změny) → defaulty vozidla
(deadline = příští výskyt default_deadline_hour). fn_ev_session_transition
ji volá při založení session (SQL-first, Python beze změny); comment
funkce sjednocen na styl bez parametrů.

Docs: ev-charging.md sekce Týdenní požadavky + kaskáda, CLAUDE.md seznam fn.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-12 19:14:40 +02:00

88 lines
2.4 KiB
PL/PgSQL

create or replace function ems.fn_ev_session_transition(
p_site_id int,
p_charger_id int,
p_prev_status text,
p_new_status text,
p_measured_at timestamptz
)
returns jsonb
language plpgsql
as $fn$
declare
v_vehicle_id int;
begin
if p_prev_status is not distinct from p_new_status then
return jsonb_build_object('action', 'none');
end if;
if p_prev_status = 'available' and p_new_status is distinct from 'available' then
select av.id
into v_vehicle_id
from ems.asset_vehicle av
where av.site_id = p_site_id
and av.default_charger_id = p_charger_id
and av.active = true
order by av.id
limit 1;
perform ems.fn_update_ev_arrival_stats(
p_site_id,
p_charger_id,
v_vehicle_id,
p_measured_at
);
insert into ems.ev_session (
site_id,
charger_id,
vehicle_id,
session_start,
target_soc_pct,
target_deadline
)
select
ac.site_id,
ac.id,
av.id,
now(),
-- kaskáda fn_ev_session_defaults: týdenní požadavek (ev_weekly_requirement)
-- → forecast (ev_usage_stats) → defaulty vozidla; ruční přepis přes
-- fn_ev_session_apply_patch vždy vyhrává.
(d.defaults ->> 'target_soc_pct')::double precision,
(d.defaults ->> 'deadline')::timestamptz
from ems.asset_ev_charger ac
left join lateral (
select v.id
from ems.asset_vehicle v
where v.default_charger_id = ac.id
and v.site_id = ac.site_id
and v.active = true
order by v.id
limit 1
) av on true
cross join lateral (
select ems.fn_ev_session_defaults(av.id, now()) as defaults
) d
where ac.id = p_charger_id
and ac.site_id = p_site_id
on conflict (charger_id) where session_end is null do nothing;
return jsonb_build_object('action', 'arrival');
end if;
if p_prev_status is distinct from 'available' and p_new_status = 'available' then
update ems.ev_session es
set session_end = now()
where es.charger_id = p_charger_id
and es.session_end is null;
return jsonb_build_object('action', 'departure');
end if;
return jsonb_build_object('action', 'none');
end;
$fn$;
comment on function ems.fn_ev_session_transition is
'Detekce příjezdu/odjezdu EV po změně statusu nabíječky (telemetry_collector); defaulty nové session z ems.fn_ev_session_defaults.';