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>
44 lines
1.7 KiB
SQL
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.';
|