feat(scripted-alarms): richer AlarmConditionState bridge to the OPC UA node (T15)
This commit is contained in:
@@ -246,12 +246,11 @@ public sealed class OpcUaPublishActorRebuildTests : RuntimeActorTestBase
|
||||
/// <param name="ts">The timestamp of the write.</param>
|
||||
public void WriteValue(string nodeId, object? value, OpcUaQuality quality, DateTime ts)
|
||||
=> Calls.Enqueue($"WV:{nodeId}");
|
||||
/// <summary>Records an alarm state write call.</summary>
|
||||
/// <summary>Records an alarm condition write call.</summary>
|
||||
/// <param name="alarmNodeId">The alarm node ID.</param>
|
||||
/// <param name="active">Whether the alarm is active.</param>
|
||||
/// <param name="acknowledged">Whether the alarm is acknowledged.</param>
|
||||
/// <param name="state">The full condition state snapshot.</param>
|
||||
/// <param name="ts">The timestamp of the state change.</param>
|
||||
public void WriteAlarmState(string alarmNodeId, bool active, bool acknowledged, DateTime ts)
|
||||
public void WriteAlarmCondition(string alarmNodeId, AlarmConditionSnapshot state, DateTime ts)
|
||||
=> Calls.Enqueue($"WA:{alarmNodeId}");
|
||||
/// <summary>Records a materialise-alarm-condition call.</summary>
|
||||
/// <param name="alarmNodeId">The alarm node ID (== ScriptedAlarmId).</param>
|
||||
|
||||
@@ -18,7 +18,7 @@ public sealed class OpcUaPublishActorTests : RuntimeActorTestBase
|
||||
{
|
||||
var actor = Sys.ActorOf(OpcUaPublishActor.PropsForTests());
|
||||
actor.Tell(new OpcUaPublishActor.AttributeValueUpdate("ns=2;s=Tag1", 42.0, OpcUaQuality.Good, DateTime.UtcNow));
|
||||
actor.Tell(new OpcUaPublishActor.AlarmStateUpdate("ns=2;s=Alarm1", true, false, DateTime.UtcNow));
|
||||
actor.Tell(new OpcUaPublishActor.AlarmStateUpdate("ns=2;s=Alarm1", Snapshot(active: true), DateTime.UtcNow));
|
||||
actor.Tell(new OpcUaPublishActor.RebuildAddressSpace(CorrelationId.NewId()));
|
||||
actor.Tell(new OpcUaPublishActor.ServiceLevelChanged(240));
|
||||
|
||||
@@ -53,24 +53,38 @@ public sealed class OpcUaPublishActorTests : RuntimeActorTestBase
|
||||
}, duration: TimeSpan.FromMilliseconds(500));
|
||||
}
|
||||
|
||||
/// <summary>Verifies that AlarmStateUpdate routes to sink WriteAlarmState.</summary>
|
||||
/// <summary>Verifies that AlarmStateUpdate routes to sink WriteAlarmCondition with the full snapshot.</summary>
|
||||
[Fact]
|
||||
public void AlarmStateUpdate_routes_to_sink_WriteAlarmState()
|
||||
public void AlarmStateUpdate_routes_to_sink_WriteAlarmCondition()
|
||||
{
|
||||
var sink = new RecordingSink();
|
||||
var actor = Sys.ActorOf(OpcUaPublishActor.PropsForTests(sink: sink));
|
||||
|
||||
actor.Tell(new OpcUaPublishActor.AlarmStateUpdate("ns=2;s=A1", Active: true, Acknowledged: false, DateTime.UtcNow));
|
||||
actor.Tell(new OpcUaPublishActor.AlarmStateUpdate(
|
||||
"ns=2;s=A1", Snapshot(active: true, acknowledged: false, severity: 700), DateTime.UtcNow));
|
||||
|
||||
AwaitAssert(() =>
|
||||
{
|
||||
sink.Alarms.Count.ShouldBe(1);
|
||||
sink.Alarms[0].AlarmNodeId.ShouldBe("ns=2;s=A1");
|
||||
sink.Alarms[0].Active.ShouldBeTrue();
|
||||
sink.Alarms[0].Acknowledged.ShouldBeFalse();
|
||||
sink.Alarms[0].State.Active.ShouldBeTrue();
|
||||
sink.Alarms[0].State.Acknowledged.ShouldBeFalse();
|
||||
sink.Alarms[0].State.Severity.ShouldBe((ushort)700);
|
||||
}, duration: TimeSpan.FromMilliseconds(500));
|
||||
}
|
||||
|
||||
/// <summary>Builds a test <see cref="AlarmConditionSnapshot"/> with sensible defaults so each test
|
||||
/// only specifies the fields it cares about.</summary>
|
||||
private static AlarmConditionSnapshot Snapshot(
|
||||
bool active = false,
|
||||
bool acknowledged = true,
|
||||
bool confirmed = true,
|
||||
bool enabled = true,
|
||||
AlarmShelvingKind shelving = AlarmShelvingKind.Unshelved,
|
||||
ushort severity = 500,
|
||||
string message = "test") =>
|
||||
new(active, acknowledged, confirmed, enabled, shelving, severity, message);
|
||||
|
||||
/// <summary>Verifies that RebuildAddressSpace calls sink Rebuild.</summary>
|
||||
[Fact]
|
||||
public void RebuildAddressSpace_calls_sink_Rebuild()
|
||||
@@ -148,16 +162,16 @@ public sealed class OpcUaPublishActorTests : RuntimeActorTestBase
|
||||
{
|
||||
/// <summary>Gets the queue of recorded value updates.</summary>
|
||||
public ConcurrentQueue<(string NodeId, object? Value, OpcUaQuality Quality, DateTime Ts)> ValueQueue { get; } = new();
|
||||
/// <summary>Gets the queue of recorded alarm state updates.</summary>
|
||||
public ConcurrentQueue<(string AlarmNodeId, bool Active, bool Acknowledged, DateTime Ts)> AlarmQueue { get; } = new();
|
||||
/// <summary>Gets the queue of recorded alarm condition updates.</summary>
|
||||
public ConcurrentQueue<(string AlarmNodeId, AlarmConditionSnapshot State, DateTime Ts)> AlarmQueue { get; } = new();
|
||||
/// <summary>Count of rebuild calls.</summary>
|
||||
public int RebuildCalls;
|
||||
|
||||
/// <summary>Gets the list of recorded value updates.</summary>
|
||||
public List<(string NodeId, object? Value, OpcUaQuality Quality, DateTime Ts)> Values =>
|
||||
ValueQueue.ToList();
|
||||
/// <summary>Gets the list of recorded alarm state updates.</summary>
|
||||
public List<(string AlarmNodeId, bool Active, bool Acknowledged, DateTime Ts)> Alarms =>
|
||||
/// <summary>Gets the list of recorded alarm condition updates.</summary>
|
||||
public List<(string AlarmNodeId, AlarmConditionSnapshot State, DateTime Ts)> Alarms =>
|
||||
AlarmQueue.ToList();
|
||||
|
||||
/// <summary>Records a value update.</summary>
|
||||
@@ -168,13 +182,12 @@ public sealed class OpcUaPublishActorTests : RuntimeActorTestBase
|
||||
public void WriteValue(string nodeId, object? value, OpcUaQuality quality, DateTime ts) =>
|
||||
ValueQueue.Enqueue((nodeId, value, quality, ts));
|
||||
|
||||
/// <summary>Records an alarm state update.</summary>
|
||||
/// <summary>Records an alarm condition update.</summary>
|
||||
/// <param name="alarmNodeId">The OPC UA alarm node identifier.</param>
|
||||
/// <param name="active">Whether the alarm is active.</param>
|
||||
/// <param name="acknowledged">Whether the alarm is acknowledged.</param>
|
||||
/// <param name="state">The full condition state snapshot.</param>
|
||||
/// <param name="ts">The timestamp of the update.</param>
|
||||
public void WriteAlarmState(string alarmNodeId, bool active, bool acknowledged, DateTime ts) =>
|
||||
AlarmQueue.Enqueue((alarmNodeId, active, acknowledged, ts));
|
||||
public void WriteAlarmCondition(string alarmNodeId, AlarmConditionSnapshot state, DateTime ts) =>
|
||||
AlarmQueue.Enqueue((alarmNodeId, state, ts));
|
||||
|
||||
/// <summary>Materialises an alarm condition (no-op in test).</summary>
|
||||
/// <param name="alarmNodeId">The alarm node ID.</param>
|
||||
|
||||
Reference in New Issue
Block a user