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(), av.default_target_soc_pct, case when av.default_deadline_hour is not null then ( (timezone('Europe/Prague', now()))::date + interval '1 day' + make_interval(hours => av.default_deadline_hour) )::timestamp at time zone 'Europe/Prague' end from ems.asset_ev_charger ac left join lateral ( select v.id, v.default_target_soc_pct, v.default_deadline_hour 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 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(int, int, text, text, timestamptz) is 'Detekce příjezdu/odjezdu EV po změně statusu nabíječky (telemetry_collector).';