Files
ScadaBridge/src/ZB.MOM.WW.ScadaBridge.DataConnectionLayer/Adapters/OpcUaAlarmMapper.cs
T

53 lines
2.6 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using ZB.MOM.WW.ScadaBridge.Commons.Types.Alarms;
using ZB.MOM.WW.ScadaBridge.Commons.Types.Enums;
namespace ZB.MOM.WW.ScadaBridge.DataConnectionLayer.Adapters;
/// <summary>
/// Pure mapping helpers turning OPC UA Alarms &amp; Conditions event fields into the
/// protocol-neutral <see cref="AlarmConditionState"/> / 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 <c>RealOpcUaClient</c> and is exercised by
/// the live smoke test (Task 28).
/// </summary>
public static class OpcUaAlarmMapper
{
/// <summary>Clamps an OPC UA severity (11000, sometimes out of range) to the unified 01000 scale.</summary>
public static int NormalizeSeverity(int severity) => Math.Clamp(severity, 0, 1000);
/// <summary>Builds an <see cref="AlarmConditionState"/> from the orthogonal A&amp;C sub-states.</summary>
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));
/// <summary>
/// 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.
/// </summary>
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;
}
/// <summary>Maps the OPC UA ShelvingState current-state node name to the shelve enum.</summary>
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
};
}