Files
ems/db/routines/R__100_fn_modbus_device_state_map.sql
Dusan Vojacek 7decfebdbd TeltoCharge write-on-change: zápis jen při změně hodnoty (EEPROM wear)
Wallbox dostával zápisy 15/19/20 každý export tick (~8x/hod: control_export
:14,:29,:44,:59 + rolling replan */15 s exportem), protože drop-unchanged
stál na fn_modbus_last_verified_map — dokud verify čtení nedoběhlo/selhalo,
mapa byla prázdná a celá trojice se psala pořád dokola. write_ev_arrival_hold
navíc psal trojici nepodmíněně při každém píchnutí kabelu (docstring lhal).

- nová ems.fn_modbus_device_state_map (R__100): nejnovější řádek journalu
  per registr, hodnota jen pro written/verified; failed/mismatch => registr
  chybí => po výpadku se konfigurace obnoví jedním zápisem
- write_ev_setpoints + write_ev_arrival_hold filtrují přes tuto mapu:
  reg 15 jen při změně plánu, watchdog 19/20 jednou po startu/po výpadku
- verify job EV chargery ověřuje už dnes (fn_modbus_written_command_ids bez
  filtru asset_type); registry 15/19/20 jsou dle oficiálního protokolu R/W
- watchdog Telto sytí jakákoli validní komunikace vč. FC3 čtení telemetrie
  (60 s << 300 s) — periodické zápisy k udržení spojení nejsou potřeba,
  failsafe 8 A nastane jen při skutečném výpadku EMS
- testy: tests/test_ev_write_on_change.py (drop, setpoints, arrival hold)
- docs: modbus-registers-teltocharge.md (sekce Zápis už není "NEimplementováno",
  R/W tabulka, watchdog sémantika), modbus-command-journal.md (sekce EV
  wallbox), CLAUDE.md (fn_modbus_device_state_map)

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

44 lines
1.7 KiB
SQL

-- map register -> poslední známá hodnota na zařízení podle journalu.
-- Na rozdíl od fn_modbus_last_verified_map bere NEJNOVĚJŠÍ řádek per registr
-- a hodnotu vrací jen pokud je 'verified' NEBO 'written' (zápis potvrzený
-- TCP ackem, verify ještě nedoběhl / čtení zpět selhalo). Novější řádek
-- failed/mismatch/pending => registr v mapě chybí => exporter zapíše znovu
-- (po výpadku zařízení se konfigurace obnoví jedním zápisem).
-- Motivace: write-on-change pro EV wallboxy (EEPROM wear) — zápis se nesmí
-- opakovat každý export tick jen proto, že verify ještě neproběhl.
drop function if exists ems.fn_modbus_device_state_map;
create or replace function ems.fn_modbus_device_state_map(
p_site_id int,
p_asset_id int,
p_asset_type text
)
returns jsonb
language sql
stable
as $fn$
select coalesce(
jsonb_object_agg(t.register::text, to_jsonb(t.val)),
'{}'::jsonb
)
from (
select distinct on (mc.register)
mc.register,
case
when mc.status = 'verified' then mc.value_verified
when mc.status = 'written' then coalesce(mc.value_written, mc.value_to_write)
else null
end as val
from ems.modbus_command mc
where mc.site_id = p_site_id
and mc.asset_type = p_asset_type
and mc.asset_id = p_asset_id
order by mc.register, mc.id desc
) t
where t.val is not null;
$fn$;
comment on function ems.fn_modbus_device_state_map is
'Mapa register -> poslední známá hodnota na zařízení (nejnovější řádek modbus_command per registr; jen status written/verified, jinak registr chybí). Pro write-on-change drop v control exporteru (EV wallboxy) — šetří EEPROM, po výpadku (failed) se zapíše znovu.';