fix(dcl): identify MxGateway native alarms by object-relative reference #4
@@ -86,7 +86,14 @@ public static class MxGatewayAlarmMapper
|
|||||||
/// <param name="body">The gateway alarm transition event proto message to map.</param>
|
/// <param name="body">The gateway alarm transition event proto message to map.</param>
|
||||||
/// <returns>The protocol-neutral <see cref="NativeAlarmTransition"/>.</returns>
|
/// <returns>The protocol-neutral <see cref="NativeAlarmTransition"/>.</returns>
|
||||||
public static NativeAlarmTransition MapTransition(OnAlarmTransitionEvent body) => new(
|
public static NativeAlarmTransition MapTransition(OnAlarmTransitionEvent body) => new(
|
||||||
SourceReference: body.AlarmFullReference,
|
// Identify the condition by the object-relative reference (e.g.
|
||||||
|
// "Z28061.HeartbeatTimeoutAlarm") rather than the gateway's full provider
|
||||||
|
// reference ("Galaxy!<area>.<object>.<alarm>"). The area is preserved in
|
||||||
|
// Category; the object reference is globally unique within the galaxy and
|
||||||
|
// is the form operators expect. Falls back to the full reference only if
|
||||||
|
// the gateway omits the object reference.
|
||||||
|
SourceReference: string.IsNullOrEmpty(body.SourceObjectReference)
|
||||||
|
? body.AlarmFullReference : body.SourceObjectReference,
|
||||||
SourceObjectReference: body.SourceObjectReference,
|
SourceObjectReference: body.SourceObjectReference,
|
||||||
AlarmTypeName: body.AlarmTypeName,
|
AlarmTypeName: body.AlarmTypeName,
|
||||||
Kind: MapKind(body.TransitionKind),
|
Kind: MapKind(body.TransitionKind),
|
||||||
@@ -112,7 +119,10 @@ public static class MxGatewayAlarmMapper
|
|||||||
/// <param name="snapshot">The active alarm snapshot proto message to map.</param>
|
/// <param name="snapshot">The active alarm snapshot proto message to map.</param>
|
||||||
/// <returns>A <see cref="NativeAlarmTransition"/> with <c>AlarmTransitionKind.Snapshot</c>.</returns>
|
/// <returns>A <see cref="NativeAlarmTransition"/> with <c>AlarmTransitionKind.Snapshot</c>.</returns>
|
||||||
public static NativeAlarmTransition MapSnapshot(ActiveAlarmSnapshot snapshot) => new(
|
public static NativeAlarmTransition MapSnapshot(ActiveAlarmSnapshot snapshot) => new(
|
||||||
SourceReference: snapshot.AlarmFullReference,
|
// See MapTransition: identify by the object-relative reference, not the
|
||||||
|
// full "Galaxy!<area>.<object>.<alarm>" provider reference.
|
||||||
|
SourceReference: string.IsNullOrEmpty(snapshot.SourceObjectReference)
|
||||||
|
? snapshot.AlarmFullReference : snapshot.SourceObjectReference,
|
||||||
SourceObjectReference: snapshot.SourceObjectReference,
|
SourceObjectReference: snapshot.SourceObjectReference,
|
||||||
AlarmTypeName: snapshot.AlarmTypeName,
|
AlarmTypeName: snapshot.AlarmTypeName,
|
||||||
Kind: AlarmTransitionKind.Snapshot,
|
Kind: AlarmTransitionKind.Snapshot,
|
||||||
|
|||||||
@@ -65,6 +65,54 @@ public class MxGatewayAlarmMapperTests
|
|||||||
Assert.Equal(1000, t.Condition.Severity);
|
Assert.Equal(1000, t.Condition.Severity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void SourceReference_IsObjectRelative_NotFullProviderReference()
|
||||||
|
{
|
||||||
|
// The condition identity surfaced upward is the object-relative reference
|
||||||
|
// (e.g. "Z28061.HeartbeatTimeoutAlarm"), not the gateway's full provider
|
||||||
|
// reference ("Galaxy!<area>.<object>.<alarm>"). Area lives in Category.
|
||||||
|
var snap = new ActiveAlarmSnapshot
|
||||||
|
{
|
||||||
|
AlarmFullReference = "Galaxy!CVDAisle_1.Z28061.HeartbeatTimeoutAlarm",
|
||||||
|
SourceObjectReference = "Z28061.HeartbeatTimeoutAlarm",
|
||||||
|
AlarmTypeName = "Syst",
|
||||||
|
Category = "CVDAisle_1",
|
||||||
|
CurrentState = ProtoConditionState.Active,
|
||||||
|
Severity = 400
|
||||||
|
};
|
||||||
|
var ev = new OnAlarmTransitionEvent
|
||||||
|
{
|
||||||
|
AlarmFullReference = "Galaxy!CVDAisle_1.Z28061.HeartbeatTimeoutAlarm",
|
||||||
|
SourceObjectReference = "Z28061.HeartbeatTimeoutAlarm",
|
||||||
|
AlarmTypeName = "Syst",
|
||||||
|
TransitionKind = ProtoTransitionKind.Raise,
|
||||||
|
Severity = 400
|
||||||
|
};
|
||||||
|
|
||||||
|
var snapT = MxGatewayAlarmMapper.MapSnapshot(snap);
|
||||||
|
var liveT = MxGatewayAlarmMapper.MapTransition(ev);
|
||||||
|
|
||||||
|
Assert.Equal("Z28061.HeartbeatTimeoutAlarm", snapT.SourceReference);
|
||||||
|
Assert.Equal("Z28061.HeartbeatTimeoutAlarm", liveT.SourceReference);
|
||||||
|
Assert.Equal("CVDAisle_1", snapT.Category);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void SourceReference_FallsBackToFullReference_WhenObjectReferenceEmpty()
|
||||||
|
{
|
||||||
|
var snap = new ActiveAlarmSnapshot
|
||||||
|
{
|
||||||
|
AlarmFullReference = "Galaxy!Area.Obj.Alarm",
|
||||||
|
SourceObjectReference = "",
|
||||||
|
CurrentState = ProtoConditionState.Active,
|
||||||
|
Severity = 100
|
||||||
|
};
|
||||||
|
|
||||||
|
var t = MxGatewayAlarmMapper.MapSnapshot(snap);
|
||||||
|
|
||||||
|
Assert.Equal("Galaxy!Area.Obj.Alarm", t.SourceReference);
|
||||||
|
}
|
||||||
|
|
||||||
// ── CurrentValue / LimitValue (M2.13 / #27) ──────────────────────────────
|
// ── CurrentValue / LimitValue (M2.13 / #27) ──────────────────────────────
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|||||||
Reference in New Issue
Block a user