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>
104 lines
3.7 KiB
PL/PgSQL
104 lines
3.7 KiB
PL/PgSQL
-- Defaulty nové ev_session pro vozidlo: kaskáda
|
|
-- 1) ems.ev_weekly_requirement — nejbližší budoucí výskyt enabled řádku
|
|
-- do 48 h od příjezdu (deadline_hour v den dow, Europe/Prague),
|
|
-- 2) forecast z týdenního rytmu (V089: fn_ev_next_departure +
|
|
-- fn_ev_required_soc), jen při asset_vehicle.target_soc_forecast_enabled,
|
|
-- 3) defaulty vozidla (default_target_soc_pct; deadline = příští výskyt
|
|
-- default_deadline_hour v Europe/Prague).
|
|
-- Volá fn_ev_session_transition při založení session; ruční přepis přes
|
|
-- fn_ev_session_apply_patch (Discord / UI) vždy vyhrává.
|
|
|
|
create or replace function ems.fn_ev_session_defaults(
|
|
p_vehicle_id int,
|
|
p_arrival timestamptz
|
|
)
|
|
returns jsonb
|
|
language plpgsql
|
|
stable
|
|
as $fn$
|
|
declare
|
|
v_vehicle record;
|
|
v_weekly record;
|
|
v_forecast_departure timestamptz;
|
|
v_deadline timestamptz;
|
|
begin
|
|
select av.default_target_soc_pct, av.default_deadline_hour,
|
|
av.target_soc_forecast_enabled
|
|
into v_vehicle
|
|
from ems.asset_vehicle av
|
|
where av.id = p_vehicle_id;
|
|
|
|
if not found then
|
|
return jsonb_build_object(
|
|
'target_soc_pct', null, 'deadline', null, 'source', 'none'
|
|
);
|
|
end if;
|
|
|
|
-- 1) týdenní požadavek: nejbližší budoucí výskyt do 48 h (Europe/Prague)
|
|
select wr.target_soc_pct, occ.deadline
|
|
into v_weekly
|
|
from generate_series(0, 2) as offs
|
|
cross join lateral (
|
|
select ((p_arrival at time zone 'Europe/Prague')::date + offs) as d
|
|
) day
|
|
join ems.ev_weekly_requirement wr
|
|
on wr.vehicle_id = p_vehicle_id
|
|
and wr.enabled
|
|
and wr.dow = extract(isodow from day.d)::int - 1
|
|
cross join lateral (
|
|
select (day.d::timestamp + make_interval(hours => wr.deadline_hour))
|
|
at time zone 'Europe/Prague' as deadline
|
|
) occ
|
|
where occ.deadline > p_arrival
|
|
and occ.deadline <= p_arrival + interval '48 hours'
|
|
order by occ.deadline
|
|
limit 1;
|
|
|
|
if v_weekly.deadline is not null then
|
|
return jsonb_build_object(
|
|
'target_soc_pct', v_weekly.target_soc_pct,
|
|
'deadline', v_weekly.deadline,
|
|
'source', 'weekly'
|
|
);
|
|
end if;
|
|
|
|
-- 2) forecast z týdenního rytmu (chování shodné s dřívějším
|
|
-- fn_ev_session_transition: deadline = typický odjezd; target P80,
|
|
-- při málo datech default target)
|
|
if v_vehicle.target_soc_forecast_enabled then
|
|
v_forecast_departure := ems.fn_ev_next_departure(p_vehicle_id, p_arrival);
|
|
if v_forecast_departure is not null then
|
|
return jsonb_build_object(
|
|
'target_soc_pct', coalesce(
|
|
ems.fn_ev_required_soc(p_vehicle_id, v_forecast_departure),
|
|
v_vehicle.default_target_soc_pct
|
|
),
|
|
'deadline', v_forecast_departure,
|
|
'source', 'forecast'
|
|
);
|
|
end if;
|
|
end if;
|
|
|
|
-- 3) defaulty vozidla: deadline = příští výskyt default_deadline_hour
|
|
v_deadline := (
|
|
(p_arrival at time zone 'Europe/Prague')::date::timestamp
|
|
+ make_interval(hours => v_vehicle.default_deadline_hour)
|
|
) at time zone 'Europe/Prague';
|
|
if v_deadline <= p_arrival then
|
|
v_deadline := (
|
|
((p_arrival at time zone 'Europe/Prague')::date + 1)::timestamp
|
|
+ make_interval(hours => v_vehicle.default_deadline_hour)
|
|
) at time zone 'Europe/Prague';
|
|
end if;
|
|
|
|
return jsonb_build_object(
|
|
'target_soc_pct', v_vehicle.default_target_soc_pct,
|
|
'deadline', v_deadline,
|
|
'source', 'default'
|
|
);
|
|
end;
|
|
$fn$;
|
|
|
|
comment on function ems.fn_ev_session_defaults is
|
|
'Target SoC + deadline pro novou ev_session: jsonb {target_soc_pct, deadline, source}. Kaskáda ev_weekly_requirement (výskyt do 48 h, Europe/Prague) → forecast (target_soc_forecast_enabled) → defaulty vozidla (deadline = příští výskyt default_deadline_hour). p_vehicle_id null/neznámé → null hodnoty.';
|