fix(alarms): atomic InactiveUnacknowledged + flagged Clear/Acknowledge first sight for OpcUaClient (#657)
After an OpcUaClient respawn an upstream inactive+unacked condition went out as Retrigger+Clear (duplicate Activated+Cleared rows, Active flicker), and a first-sight inactive+acked one as Unspecified (an Activated row for an inactive alarm; a retained-Active host condition never cleared). - New AlarmTransitionKind.InactiveUnacknowledged: one projection, rows only for what changed (Activated+Cleared from acked, Cleared from active+unacked, none when already inactive+unacked). - OpcUaClient uses it for moves into inactive+unacked; first sight of an inactive condition is InactiveUnacknowledged or Clear+Acknowledge, flagged. - Projector: a flagged Acknowledge on an already-acked condition writes no row. - E2E tests through DriverHostActor.ForwardNativeAlarm (red-proven). Claude-Session: https://claude.ai/code/session_01Ef2ozxS7QPanGT8uoATbTe
This commit is contained in:
@@ -101,9 +101,12 @@ initialise (the AdminUI form drops them on the next save). Pinned by
|
||||
> `Raise`/`Acknowledge`/`Clear`/`Retrigger` kinds the host projector consumes (without a kind no upstream alarm could ever
|
||||
> show active); the kinds are emitted from the state **last told to the host** per RawPath, so an identical re-delivery
|
||||
> emits nothing (no re-raise, which would un-ack). An inactive → active+acked move is ONE `ActiveAcknowledged` (#656; it
|
||||
> used to be `Raise` + `Acknowledge`, a client-visible unacked intermediate). The first event per condition after a
|
||||
> start or deploy respawn is flagged `IsRestatement`, so the host writes no duplicate "Activated" row when its
|
||||
> condition already shows that state (see `docs/AlarmTracking.md`). Condition **branch** events (non-null `BranchId`) are ignored.
|
||||
> used to be `Raise` + `Acknowledge`, a client-visible unacked intermediate); a move into inactive+unacked is ONE
|
||||
> `InactiveUnacknowledged` (#657; it used to be `Raise`/`Retrigger` + `Clear`, an Active flicker). The first event per
|
||||
> condition after a start or deploy respawn is flagged `IsRestatement` and states the upstream condition so it lands
|
||||
> from whatever the host retained: an inactive+acked one goes out as `Clear` + `Acknowledge` (#657; it used to be an
|
||||
> `Unspecified` the host wrote as "Activated", and a retained-Active host condition stayed Active). So the host writes no
|
||||
> duplicate row when its condition already shows that state (see `docs/AlarmTracking.md`). Condition **branch** events (non-null `BranchId`) are ignored.
|
||||
> **`ConditionRefresh`** is called after the event item is created, after every in-place reconnect, and on a
|
||||
> `RefreshRequired` event, so a condition already active upstream is reported at subscribe; `RefreshStart`/`RefreshEnd`
|
||||
> markers are dropped. A server without it (`BadNotSupported`/`BadMethodInvalid`/…) is logged once and tolerated.
|
||||
|
||||
Reference in New Issue
Block a user