feat(dcl): populate obtainable NativeAlarmTransition fields from OPC UA and MxGateway (#27, M2.13)
OPC UA (RealOpcUaClient): - Append 5 new SelectClauses at indices 13–17 (never renumber 0–12): - 13: AlarmConditionType/ActiveState/TransitionTime → OriginalRaiseTime - 14–17: LimitAlarmType HighHighLimit/HighLimit/LowLimit/LowLowLimit → LimitValue - New OpcUaAlarmMapper.PickLimitValue helper: first non-null in HiHi→Hi→Lo→LoLo priority order, InvariantCulture-formatted; empty string for non-limit alarm types. - HandleAlarmEvent reads new indices with fields.Count > N guards; hard minimum (6) unchanged so base ConditionType events still process without the limit fields. - Document unavailable-by-protocol fields (Category, Description, OperatorUser, CurrentValue) inline in BuildAlarmEventFilter and HandleAlarmEvent. MxGateway (MxGatewayAlarmMapper): - MapTransition: CurrentValue and LimitValue now populated via MxValueToString (uses MxValueExtensions.ToClrValue + InvariantCulture) from OnAlarmTransitionEvent proto fields current_value/limit_value. - MapSnapshot: same — populated from ActiveAlarmSnapshot.current_value/limit_value. - MxValueToString helper (internal): null-safe MxValue → string conversion. Tests (17 new, 40 total pass): - OpcUaAlarmMapperTests: PickLimitValue priority, InvariantCulture, all-null case. - MxGatewayAlarmMapperTests: CurrentValue/LimitValue populate from double/string MxValue; absent fields yield empty strings. - RealOpcUaClientAlarmFilterTests: index alignment assertions (count=18, per-index TypeDefinitionId+BrowsePath), regression guard on existing indices 0–12.
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
using System.Globalization;
|
||||
using ZB.MOM.WW.MxGateway.Client;
|
||||
using ZB.MOM.WW.MxGateway.Contracts.Proto;
|
||||
using ProtoConditionState = ZB.MOM.WW.MxGateway.Contracts.Proto.AlarmConditionState;
|
||||
using ProtoTransitionKind = ZB.MOM.WW.MxGateway.Contracts.Proto.AlarmTransitionKind;
|
||||
@@ -67,6 +69,19 @@ public static class MxGatewayAlarmMapper
|
||||
Shelve: AlarmShelveState.Unshelved, Suppressed: false, Severity: NormalizeSeverity(severity));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts an <see cref="MxValue"/> union to a display-only string using
|
||||
/// <see cref="MxValueExtensions.ToClrValue"/> and invariant culture formatting,
|
||||
/// so numeric values always use '.' as the decimal separator. Null or unset
|
||||
/// values produce an empty string.
|
||||
/// </summary>
|
||||
internal static string MxValueToString(MxValue? mxVal)
|
||||
{
|
||||
if (mxVal is null) return "";
|
||||
var clr = mxVal.ToClrValue();
|
||||
return clr is null ? "" : Convert.ToString(clr, CultureInfo.InvariantCulture) ?? "";
|
||||
}
|
||||
|
||||
/// <summary>Maps a live <see cref="OnAlarmTransitionEvent"/> to a transition.</summary>
|
||||
/// <param name="body">The gateway alarm transition event proto message to map.</param>
|
||||
/// <returns>The protocol-neutral <see cref="NativeAlarmTransition"/>.</returns>
|
||||
@@ -83,8 +98,8 @@ public static class MxGatewayAlarmMapper
|
||||
OperatorComment: body.OperatorComment,
|
||||
OriginalRaiseTime: body.OriginalRaiseTimestamp?.ToDateTimeOffset(),
|
||||
TransitionTime: body.TransitionTimestamp?.ToDateTimeOffset() ?? DateTimeOffset.UtcNow,
|
||||
CurrentValue: "",
|
||||
LimitValue: "");
|
||||
CurrentValue: MxValueToString(body.CurrentValue),
|
||||
LimitValue: MxValueToString(body.LimitValue));
|
||||
|
||||
/// <summary>The end-of-snapshot sentinel transition (no condition payload).</summary>
|
||||
/// <returns>A <see cref="NativeAlarmTransition"/> with <c>AlarmTransitionKind.SnapshotComplete</c>.</returns>
|
||||
@@ -109,6 +124,6 @@ public static class MxGatewayAlarmMapper
|
||||
OperatorComment: snapshot.OperatorComment,
|
||||
OriginalRaiseTime: snapshot.OriginalRaiseTimestamp?.ToDateTimeOffset(),
|
||||
TransitionTime: snapshot.LastTransitionTimestamp?.ToDateTimeOffset() ?? DateTimeOffset.UtcNow,
|
||||
CurrentValue: "",
|
||||
LimitValue: "");
|
||||
CurrentValue: MxValueToString(snapshot.CurrentValue),
|
||||
LimitValue: MxValueToString(snapshot.LimitValue));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user