feat(alarms): bridge driver comms-loss into scripted-alarm input quality (Layer 4 of #477) #481
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Layer 4 of the condition-Quality chain (#477 → #478). #478 shipped scripted-alarm
Qualityderived from the worst of its input tags' qualities, but only for inputs whose driver publishes a data change carrying a Bad/UncertainStatusCode(e.g. an OpcUaClient input forwarding a server's per-item Bad).It does not cover a driver comms loss: a poll driver (Modbus/S7) whose device goes unreachable emits only
DriverInstanceActor.ConnectivityChanged(false)and goes silent on the value feed — it does not republish its tags as Bad. So the scripted engine keeps the last-known Good value,WorstInputStatusstays Good, and:Qualitystays Good (opposite of the "can I trust this condition's state?" intent), andAreInputsReadystays true (last value is Good), so the predicate keeps evaluating a stale value after the source died.Native alarms already solve this:
DriverHostActor.OnDriverConnectivityChangedfans anAlarmQualityUpdate(Bad)to every native condition the driver owns (_alarmNodeIdByDriverRef). Scripted alarms need the symmetric bridge into their inputs.The ask
Bridge driver connectivity into scripted-alarm input quality:
ConnectivityChanged(false), mark every mux ref the driver publishes asBadfor the scripted engine (restored to real quality on reconnect, which self-heals viaResubscribeDesiredrepublishing values).DriverHostActorcurrently tracks driver → native alarm nodes (_alarmNodeIdByDriverRef) but not driver → all tag refs; that per-driver ref set needs to exist to fan connectivity into the mux.WorstInputStatusskips a null-value input as "no data yet" (contributes Good) to avoid a deploy-time Bad flash, but that makes a genuine runtimeBadwith a null value indistinguishable from cold start. Distinguish "never pushed" (cold → Good) from "pushed Bad" (→ Bad), e.g. by tracking pushed-ness inDependencyMuxTagUpstreamSource.Notes / considerations
Bad— arguably correct, but a behavior change to weigh (VT already has its own Bad-propagation path; confirm no double-handling).Badon the wire; unpause →Good. (This is the same live-gate style the #477 native path used.)References
OnDriverConnectivityChangedbridge.docs/AlarmTracking.md§"Scripted alarms (Layer 3, #478)" "Coverage boundary" anddocs/plans/2026-07-17-alarm-condition-quality-477-design.md.