feat(scripted-alarms): richer AlarmConditionState bridge to the OPC UA node (T15)
This commit is contained in:
@@ -38,7 +38,8 @@ public sealed class Phase7ApplierTests
|
||||
outcome.RemovedNodes.ShouldBe(2);
|
||||
outcome.RebuildCalled.ShouldBeTrue();
|
||||
sink.AlarmWrites.Select(a => a.NodeId).OrderBy(x => x).ShouldBe(new[] { "eq-1", "eq-2" });
|
||||
sink.AlarmWrites.All(a => a.Active == false && a.Acknowledged == false).ShouldBeTrue();
|
||||
// Removed nodes are reset to the "no-event" state: inactive + acked + confirmed + enabled.
|
||||
sink.AlarmWrites.All(a => !a.State.Active && a.State.Acknowledged && a.State.Confirmed).ShouldBeTrue();
|
||||
sink.RebuildCalls.ShouldBe(1);
|
||||
}
|
||||
|
||||
@@ -103,9 +104,9 @@ public sealed class Phase7ApplierTests
|
||||
sink.RebuildCalls.ShouldBe(0);
|
||||
}
|
||||
|
||||
/// <summary>Verifies that sink exceptions in WriteAlarmState do not propagate and rebuild still fires.</summary>
|
||||
/// <summary>Verifies that sink exceptions in WriteAlarmCondition do not propagate and rebuild still fires.</summary>
|
||||
[Fact]
|
||||
public void Sink_exception_in_WriteAlarmState_does_not_propagate_and_rebuild_still_fires()
|
||||
public void Sink_exception_in_WriteAlarmCondition_does_not_propagate_and_rebuild_still_fires()
|
||||
{
|
||||
var sink = new ThrowingSink(throwOnAlarmWrite: true);
|
||||
var applier = new Phase7Applier(sink, NullLogger<Phase7Applier>.Instance);
|
||||
@@ -445,8 +446,8 @@ public sealed class Phase7ApplierTests
|
||||
|
||||
private sealed class RecordingSink : IOpcUaAddressSpaceSink
|
||||
{
|
||||
/// <summary>Gets the queue of alarm state write calls.</summary>
|
||||
public ConcurrentQueue<(string NodeId, bool Active, bool Acknowledged)> AlarmQueue { get; } = new();
|
||||
/// <summary>Gets the queue of alarm condition write calls.</summary>
|
||||
public ConcurrentQueue<(string NodeId, AlarmConditionSnapshot State)> AlarmQueue { get; } = new();
|
||||
/// <summary>Gets the queue of folder creation calls.</summary>
|
||||
public ConcurrentQueue<(string NodeId, string? Parent, string DisplayName)> FolderQueue { get; } = new();
|
||||
/// <summary>Gets the queue of variable creation calls.</summary>
|
||||
@@ -457,7 +458,7 @@ public sealed class Phase7ApplierTests
|
||||
public int RebuildCalls;
|
||||
|
||||
/// <summary>Gets the list of recorded alarm writes.</summary>
|
||||
public List<(string NodeId, bool Active, bool Acknowledged)> AlarmWrites => AlarmQueue.ToList();
|
||||
public List<(string NodeId, AlarmConditionSnapshot State)> AlarmWrites => AlarmQueue.ToList();
|
||||
/// <summary>Gets the list of recorded folder creation calls.</summary>
|
||||
public List<(string NodeId, string? Parent, string DisplayName)> FolderCalls => FolderQueue.ToList();
|
||||
/// <summary>Gets the list of recorded variable creation calls.</summary>
|
||||
@@ -471,13 +472,12 @@ public sealed class Phase7ApplierTests
|
||||
/// <param name="quality">The OPC UA quality.</param>
|
||||
/// <param name="sourceTimestampUtc">The source timestamp in UTC.</param>
|
||||
public void WriteValue(string nodeId, object? value, OpcUaQuality quality, DateTime sourceTimestampUtc) { }
|
||||
/// <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="sourceTimestampUtc">The source timestamp in UTC.</param>
|
||||
public void WriteAlarmState(string alarmNodeId, bool active, bool acknowledged, DateTime sourceTimestampUtc)
|
||||
=> AlarmQueue.Enqueue((alarmNodeId, active, acknowledged));
|
||||
public void WriteAlarmCondition(string alarmNodeId, AlarmConditionSnapshot state, DateTime sourceTimestampUtc)
|
||||
=> AlarmQueue.Enqueue((alarmNodeId, state));
|
||||
/// <summary>Records an alarm-condition materialise call.</summary>
|
||||
/// <param name="alarmNodeId">The alarm node ID (== ScriptedAlarmId).</param>
|
||||
/// <param name="equipmentNodeId">The equipment folder node ID.</param>
|
||||
@@ -518,11 +518,10 @@ public sealed class Phase7ApplierTests
|
||||
public void WriteValue(string nodeId, object? value, OpcUaQuality quality, DateTime sourceTimestampUtc) { }
|
||||
/// <summary>Throws an exception if configured to do so.</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="sourceTimestampUtc">The source timestamp in UTC.</param>
|
||||
/// <exception cref="InvalidOperationException">Thrown when configured to throw on alarm write.</exception>
|
||||
public void WriteAlarmState(string alarmNodeId, bool active, bool acknowledged, DateTime sourceTimestampUtc)
|
||||
public void WriteAlarmCondition(string alarmNodeId, AlarmConditionSnapshot state, DateTime sourceTimestampUtc)
|
||||
{
|
||||
if (_throwOnAlarmWrite) throw new InvalidOperationException("simulated sink fault");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user