Second PR of the alarms-over-gateway epic (docs/plans/alarms-over-gateway.md). Depends on PR A.1 in mxaccessgw (merged) which added the OnAlarmTransitionEvent body + family. No runtime impact yet — the gateway doesn't emit the new family until A.3 ships; this PR just stops dropping it on the floor. EventPump.Dispatch becomes a switch on MxEventFamily. The new DispatchAlarmTransition decodes the proto event, runs the raw severity through MxAccessSeverityMapper (the same four-bucket ladder v1 used — 250/500/750/1000 boundaries per docs/v1/AlarmTracking.md), and fires an internal OnAlarmTransition event with a GalaxyAlarmTransition record carrying the full payload. Body absent or transition-kind unspecified → counted via galaxy.alarm_transitions.decoding_failures and dropped. Gateway version skew or worker malformed event therefore degrades to "fall back to the sub-attribute path" rather than crashing the pump. GalaxyDriver consumes the internal event in PR B.2 (next), wrapping it onto IAlarmSource.OnAlarmEvent. The richer fields (operator user + comment, original raise time, category) become visible on the OPC UA Part 9 condition once AlarmEventArgs gets extended in E.7. Tests: - MxAccessSeverityMapperTests — full bucket ladder + clamp behaviour for negative + out-of-range inputs. - EventPumpAlarmTests — raise/ack/clear sequence dispatches in order with operator metadata + original-raise preserved; unspecified kind drops; missing body drops; mixed data-change + alarm streams dispatch independently; OnWriteComplete / OperationComplete filtered out. Full Driver.Galaxy.Tests suite: 196 passed (was 191 — 5 new tests). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
56 lines
2.4 KiB
C#
56 lines
2.4 KiB
C#
using ZB.MOM.WW.OtOpcUa.Core.Abstractions;
|
|
|
|
namespace ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Runtime;
|
|
|
|
/// <summary>
|
|
/// Maps a raw MXAccess alarm severity (0-999, MXAccess scale) onto the
|
|
/// <see cref="AlarmSeverity"/> ladder + an OPC UA Part 9 numeric severity (1-1000).
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// <para>
|
|
/// The four-bucket OPC UA ladder (250 / 500 / 750 / 1000 — Low / Medium / High /
|
|
/// Critical) is the same ladder v1's <c>GalaxyAlarmTracker</c> exposed (per
|
|
/// <c>docs/v1/AlarmTracking.md</c>). Galaxy templates assign severity values
|
|
/// 0-999; the bucket boundaries below match v1 so customers see no
|
|
/// surprise re-classification when the v2 path takes over.
|
|
/// </para>
|
|
/// <para>
|
|
/// Out-of-range inputs (negative or >= 1000) are clamped into the nearest
|
|
/// bucket rather than rejected. MXAccess occasionally surfaces slightly
|
|
/// out-of-range severities for legacy alarm types and we want them to flow
|
|
/// through the alarm path rather than disappear at the mapper.
|
|
/// </para>
|
|
/// </remarks>
|
|
internal static class MxAccessSeverityMapper
|
|
{
|
|
/// <summary>OPC UA Part 9 numeric severity for the Low bucket (0-249 MxAccess).</summary>
|
|
public const int OpcUaSeverityLow = 250;
|
|
/// <summary>OPC UA Part 9 numeric severity for the Medium bucket (250-499 MxAccess).</summary>
|
|
public const int OpcUaSeverityMedium = 500;
|
|
/// <summary>OPC UA Part 9 numeric severity for the High bucket (500-749 MxAccess).</summary>
|
|
public const int OpcUaSeverityHigh = 750;
|
|
/// <summary>OPC UA Part 9 numeric severity for the Critical bucket (750+ MxAccess).</summary>
|
|
public const int OpcUaSeverityCritical = 1000;
|
|
|
|
/// <summary>
|
|
/// Translate a raw MXAccess severity into the four-bucket
|
|
/// <see cref="AlarmSeverity"/> + OPC UA Part 9 numeric severity tuple.
|
|
/// </summary>
|
|
public static (AlarmSeverity Bucket, int OpcUaSeverity) Map(int rawMxAccessSeverity)
|
|
{
|
|
if (rawMxAccessSeverity < 250)
|
|
{
|
|
return (AlarmSeverity.Low, OpcUaSeverityLow);
|
|
}
|
|
if (rawMxAccessSeverity < 500)
|
|
{
|
|
return (AlarmSeverity.Medium, OpcUaSeverityMedium);
|
|
}
|
|
if (rawMxAccessSeverity < 750)
|
|
{
|
|
return (AlarmSeverity.High, OpcUaSeverityHigh);
|
|
}
|
|
return (AlarmSeverity.Critical, OpcUaSeverityCritical);
|
|
}
|
|
}
|