using ZB.MOM.WW.ScadaBridge.Commons.Types.Alarms; using ZB.MOM.WW.ScadaBridge.Commons.Types.Enums; namespace ZB.MOM.WW.ScadaBridge.DataConnectionLayer.Adapters; /// /// Pure mapping helpers turning OPC UA Alarms & Conditions event fields into the /// protocol-neutral / transition shape. Kept /// free of any OPC UA SDK types so it is unit-testable without a live server; /// the SDK field extraction lives in RealOpcUaClient and is exercised by /// the live smoke test (Task 28). /// public static class OpcUaAlarmMapper { /// Clamps an OPC UA severity (1–1000, sometimes out of range) to the unified 0–1000 scale. public static int NormalizeSeverity(int severity) => Math.Clamp(severity, 0, 1000); /// Builds an from the orthogonal A&C sub-states. public static AlarmConditionState BuildCondition( bool active, bool acked, bool? confirmed, AlarmShelveState shelve, bool suppressed, int severity) => new(Active: active, Acknowledged: acked, Confirmed: confirmed, Shelve: shelve, Suppressed: suppressed, Severity: NormalizeSeverity(severity)); /// /// Derives the transition kind from the change in active/acked sub-states. /// Acknowledgement takes precedence over an active/inactive edge when both /// change in the same event; an unchanged event is reported as a StateChange. /// public static AlarmTransitionKind DeriveKind(bool prevAcked, bool nowAcked, bool prevActive, bool nowActive) { if (!prevAcked && nowAcked) return AlarmTransitionKind.Acknowledge; if (!prevActive && nowActive) return AlarmTransitionKind.Raise; if (prevActive && !nowActive) return AlarmTransitionKind.Clear; if (prevActive && nowActive) return AlarmTransitionKind.Retrigger; return AlarmTransitionKind.StateChange; } /// Maps the OPC UA ShelvingState current-state node name to the shelve enum. public static AlarmShelveState MapShelve(string? shelvingStateName) => shelvingStateName switch { "OneShotShelved" => AlarmShelveState.OneShotShelved, "TimedShelved" => AlarmShelveState.TimedShelved, // OPC UA does not expose a distinct "permanent" shelve; treat any other // shelved name as one-shot and "Unshelved"/null as unshelved. null or "Unshelved" => AlarmShelveState.Unshelved, _ => AlarmShelveState.OneShotShelved }; }