feat(alarms): thread isNative through MaterialiseAlarmCondition; node manager tracks native conditions [H6a]
This commit is contained in:
@@ -43,8 +43,9 @@ public sealed class DeferredAddressSpaceSink : IOpcUaAddressSpaceSink
|
|||||||
/// <param name="displayName">The human-readable condition name.</param>
|
/// <param name="displayName">The human-readable condition name.</param>
|
||||||
/// <param name="alarmType">The domain alarm type.</param>
|
/// <param name="alarmType">The domain alarm type.</param>
|
||||||
/// <param name="severity">The domain severity.</param>
|
/// <param name="severity">The domain severity.</param>
|
||||||
public void MaterialiseAlarmCondition(string alarmNodeId, string equipmentNodeId, string displayName, string alarmType, int severity)
|
/// <param name="isNative">True for a driver-fed (native) equipment-tag alarm; false (default) for a scripted alarm.</param>
|
||||||
=> _inner.MaterialiseAlarmCondition(alarmNodeId, equipmentNodeId, displayName, alarmType, severity);
|
public void MaterialiseAlarmCondition(string alarmNodeId, string equipmentNodeId, string displayName, string alarmType, int severity, bool isNative = false)
|
||||||
|
=> _inner.MaterialiseAlarmCondition(alarmNodeId, equipmentNodeId, displayName, alarmType, severity, isNative);
|
||||||
|
|
||||||
/// <summary>Ensures a folder exists in the address space through the inner sink.</summary>
|
/// <summary>Ensures a folder exists in the address space through the inner sink.</summary>
|
||||||
/// <param name="folderNodeId">The node ID of the folder.</param>
|
/// <param name="folderNodeId">The node ID of the folder.</param>
|
||||||
|
|||||||
@@ -38,7 +38,10 @@ public interface IOpcUaAddressSpaceSink
|
|||||||
/// <param name="displayName">Human-readable condition name (BrowseName / DisplayName / Message).</param>
|
/// <param name="displayName">Human-readable condition name (BrowseName / DisplayName / Message).</param>
|
||||||
/// <param name="alarmType">Domain alarm type — mapped to the SDK condition subtype by the sink.</param>
|
/// <param name="alarmType">Domain alarm type — mapped to the SDK condition subtype by the sink.</param>
|
||||||
/// <param name="severity">Domain severity (OPC UA 1..1000 scale); mapped to the SDK severity buckets.</param>
|
/// <param name="severity">Domain severity (OPC UA 1..1000 scale); mapped to the SDK severity buckets.</param>
|
||||||
void MaterialiseAlarmCondition(string alarmNodeId, string equipmentNodeId, string displayName, string alarmType, int severity);
|
/// <param name="isNative">When true this is a driver-fed (native, e.g. Galaxy) equipment-tag alarm; when
|
||||||
|
/// false (default) it is a scripted alarm. The node manager tracks native condition node ids so a later
|
||||||
|
/// task can route a native condition's inbound Acknowledge to the driver instead of the scripted engine.</param>
|
||||||
|
void MaterialiseAlarmCondition(string alarmNodeId, string equipmentNodeId, string displayName, string alarmType, int severity, bool isNative = false);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Ensure a folder node exists under the given parent. Used by <c>Phase7Applier</c> to
|
/// Ensure a folder node exists under the given parent. Used by <c>Phase7Applier</c> to
|
||||||
@@ -95,7 +98,7 @@ public sealed class NullOpcUaAddressSpaceSink : IOpcUaAddressSpaceSink
|
|||||||
public void WriteAlarmCondition(string alarmNodeId, AlarmConditionSnapshot state, DateTime sourceTimestampUtc) { }
|
public void WriteAlarmCondition(string alarmNodeId, AlarmConditionSnapshot state, DateTime sourceTimestampUtc) { }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void MaterialiseAlarmCondition(string alarmNodeId, string equipmentNodeId, string displayName, string alarmType, int severity) { }
|
public void MaterialiseAlarmCondition(string alarmNodeId, string equipmentNodeId, string displayName, string alarmType, int severity, bool isNative = false) { }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void EnsureFolder(string folderNodeId, string? parentNodeId, string displayName) { }
|
public void EnsureFolder(string folderNodeId, string? parentNodeId, string displayName) { }
|
||||||
|
|||||||
@@ -36,6 +36,13 @@ public sealed class OtOpcUaNodeManager : CustomNodeManager2
|
|||||||
private readonly ConcurrentDictionary<string, BaseDataVariableState> _variables = new(StringComparer.Ordinal);
|
private readonly ConcurrentDictionary<string, BaseDataVariableState> _variables = new(StringComparer.Ordinal);
|
||||||
private readonly ConcurrentDictionary<string, FolderState> _folders = new(StringComparer.Ordinal);
|
private readonly ConcurrentDictionary<string, FolderState> _folders = new(StringComparer.Ordinal);
|
||||||
private readonly ConcurrentDictionary<string, AlarmConditionState> _alarmConditions = new(StringComparer.Ordinal);
|
private readonly ConcurrentDictionary<string, AlarmConditionState> _alarmConditions = new(StringComparer.Ordinal);
|
||||||
|
/// <summary>H6a: the subset of <see cref="_alarmConditions"/> node ids materialised as NATIVE
|
||||||
|
/// (driver-fed, e.g. Galaxy equipment-tag alarms) rather than scripted. A later task routes a native
|
||||||
|
/// condition's inbound Acknowledge to the driver instead of the scripted engine, so the node manager
|
||||||
|
/// must know which conditions are native. Maintained in lock-step with <see cref="_alarmConditions"/>:
|
||||||
|
/// a native re-materialise adds, and <see cref="RebuildAddressSpace"/> clears it alongside
|
||||||
|
/// <see cref="_alarmConditions"/> so a re-materialise as the other kind is correct.</summary>
|
||||||
|
private readonly HashSet<string> _nativeAlarmNodeIds = new(StringComparer.Ordinal);
|
||||||
/// <summary>Phase C: NodeId → resolved historian tagname for every variable materialised
|
/// <summary>Phase C: NodeId → resolved historian tagname for every variable materialised
|
||||||
/// Historizing. Populated by <see cref="EnsureVariable"/> when a historian tagname is supplied; the
|
/// Historizing. Populated by <see cref="EnsureVariable"/> when a historian tagname is supplied; the
|
||||||
/// (later) HistoryRead override resolves a HistoryRead request's NodeId against this map. Cleared on
|
/// (later) HistoryRead override resolves a HistoryRead request's NodeId against this map. Cleared on
|
||||||
@@ -535,7 +542,7 @@ public sealed class OtOpcUaNodeManager : CustomNodeManager2
|
|||||||
/// <see cref="AlarmConditionState"/>. LimitAlarm deliberately falls back to base per the T13
|
/// <see cref="AlarmConditionState"/>. LimitAlarm deliberately falls back to base per the T13
|
||||||
/// notes — a script alarm carries no High/Low limits to populate.</para>
|
/// notes — a script alarm carries no High/Low limits to populate.</para>
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public void MaterialiseAlarmCondition(string alarmNodeId, string equipmentNodeId, string displayName, string alarmType, int severity)
|
public void MaterialiseAlarmCondition(string alarmNodeId, string equipmentNodeId, string displayName, string alarmType, int severity, bool isNative = false)
|
||||||
{
|
{
|
||||||
ArgumentException.ThrowIfNullOrEmpty(alarmNodeId);
|
ArgumentException.ThrowIfNullOrEmpty(alarmNodeId);
|
||||||
ArgumentException.ThrowIfNullOrEmpty(displayName);
|
ArgumentException.ThrowIfNullOrEmpty(displayName);
|
||||||
@@ -550,6 +557,10 @@ public sealed class OtOpcUaNodeManager : CustomNodeManager2
|
|||||||
PredefinedNodes?.Remove(existing.NodeId);
|
PredefinedNodes?.Remove(existing.NodeId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// H6a: re-materialising the same id as the OTHER kind (native↔scripted) must reflect the new
|
||||||
|
// kind, so always drop the stale native flag first and only re-add it below when isNative.
|
||||||
|
_nativeAlarmNodeIds.Remove(alarmNodeId);
|
||||||
|
|
||||||
var parent = ResolveParentFolder(equipmentNodeId);
|
var parent = ResolveParentFolder(equipmentNodeId);
|
||||||
|
|
||||||
AlarmConditionState alarm = CreateAlarmConditionOfType(alarmType, parent);
|
AlarmConditionState alarm = CreateAlarmConditionOfType(alarmType, parent);
|
||||||
@@ -632,9 +643,23 @@ public sealed class OtOpcUaNodeManager : CustomNodeManager2
|
|||||||
|
|
||||||
AddPredefinedNode(SystemContext, alarm);
|
AddPredefinedNode(SystemContext, alarm);
|
||||||
_alarmConditions[alarmNodeId] = alarm;
|
_alarmConditions[alarmNodeId] = alarm;
|
||||||
|
// H6a: record native (driver-fed) conditions so a later task can route their inbound
|
||||||
|
// Acknowledge to the driver rather than the scripted engine.
|
||||||
|
if (isNative) _nativeAlarmNodeIds.Add(alarmNodeId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>H6a — true if the condition materialised at <paramref name="alarmNodeId"/> is a NATIVE
|
||||||
|
/// (driver-fed) alarm rather than a scripted one. A later task uses this to route a native condition's
|
||||||
|
/// inbound Acknowledge to the driver instead of the scripted engine.</summary>
|
||||||
|
/// <param name="alarmNodeId">The alarm condition node id.</param>
|
||||||
|
internal bool IsNativeAlarmNode(string alarmNodeId)
|
||||||
|
{
|
||||||
|
// _nativeAlarmNodeIds is a plain HashSet mutated only under Lock (in MaterialiseAlarmCondition /
|
||||||
|
// RebuildAddressSpace), so guard the read with the same Lock rather than risk a torn concurrent read.
|
||||||
|
lock (Lock) return _nativeAlarmNodeIds.Contains(alarmNodeId);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Shared body for every inbound Part 9 alarm method handler (T18). Resolves the calling
|
/// Shared body for every inbound Part 9 alarm method handler (T18). Resolves the calling
|
||||||
/// principal off the SDK <paramref name="context"/>, applies the <c>AlarmAck</c> role gate
|
/// principal off the SDK <paramref name="context"/>, applies the <c>AlarmAck</c> role gate
|
||||||
@@ -1289,6 +1314,9 @@ public sealed class OtOpcUaNodeManager : CustomNodeManager2
|
|||||||
PredefinedNodes?.Remove(alarm.NodeId);
|
PredefinedNodes?.Remove(alarm.NodeId);
|
||||||
}
|
}
|
||||||
_alarmConditions.Clear();
|
_alarmConditions.Clear();
|
||||||
|
// H6a: drop the native-alarm flags in lock-step with the conditions they classify, so a
|
||||||
|
// re-materialise on the next apply (possibly as the other kind) starts from a clean slate.
|
||||||
|
_nativeAlarmNodeIds.Clear();
|
||||||
|
|
||||||
foreach (var f in _folders.Values)
|
foreach (var f in _folders.Values)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -201,7 +201,7 @@ public sealed class Phase7Applier
|
|||||||
{
|
{
|
||||||
// Native alarm tag → a real Part 9 condition node (reuses the scripted-alarm path),
|
// Native alarm tag → a real Part 9 condition node (reuses the scripted-alarm path),
|
||||||
// NOT a value variable. Parent is the sub-folder when set, else the equipment folder.
|
// NOT a value variable. Parent is the sub-folder when set, else the equipment folder.
|
||||||
SafeMaterialiseAlarmCondition(nodeId, parent, tag.Name, tag.Alarm.AlarmType, tag.Alarm.Severity);
|
SafeMaterialiseAlarmCondition(nodeId, parent, tag.Name, tag.Alarm.AlarmType, tag.Alarm.Severity, isNative: true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -292,7 +292,7 @@ public sealed class Phase7Applier
|
|||||||
foreach (var alarm in composition.EquipmentScriptedAlarms)
|
foreach (var alarm in composition.EquipmentScriptedAlarms)
|
||||||
{
|
{
|
||||||
if (!alarm.Enabled) continue;
|
if (!alarm.Enabled) continue;
|
||||||
SafeMaterialiseAlarmCondition(alarm.ScriptedAlarmId, alarm.EquipmentId, alarm.Name, alarm.AlarmType, alarm.Severity);
|
SafeMaterialiseAlarmCondition(alarm.ScriptedAlarmId, alarm.EquipmentId, alarm.Name, alarm.AlarmType, alarm.Severity, isNative: false);
|
||||||
materialised++;
|
materialised++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -333,9 +333,9 @@ public sealed class Phase7Applier
|
|||||||
catch (Exception ex) { _logger.LogWarning(ex, "Phase7Applier: WriteAlarmCondition threw for {Node}", nodeId); }
|
catch (Exception ex) { _logger.LogWarning(ex, "Phase7Applier: WriteAlarmCondition threw for {Node}", nodeId); }
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SafeMaterialiseAlarmCondition(string alarmNodeId, string equipmentNodeId, string displayName, string alarmType, int severity)
|
private void SafeMaterialiseAlarmCondition(string alarmNodeId, string equipmentNodeId, string displayName, string alarmType, int severity, bool isNative)
|
||||||
{
|
{
|
||||||
try { _sink.MaterialiseAlarmCondition(alarmNodeId, equipmentNodeId, displayName, alarmType, severity); }
|
try { _sink.MaterialiseAlarmCondition(alarmNodeId, equipmentNodeId, displayName, alarmType, severity, isNative); }
|
||||||
catch (Exception ex) { _logger.LogWarning(ex, "Phase7Applier: MaterialiseAlarmCondition threw for {Node}", alarmNodeId); }
|
catch (Exception ex) { _logger.LogWarning(ex, "Phase7Applier: MaterialiseAlarmCondition threw for {Node}", alarmNodeId); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,8 +41,9 @@ public sealed class SdkAddressSpaceSink : IOpcUaAddressSpaceSink
|
|||||||
/// <param name="displayName">The human-readable condition name.</param>
|
/// <param name="displayName">The human-readable condition name.</param>
|
||||||
/// <param name="alarmType">The domain alarm type.</param>
|
/// <param name="alarmType">The domain alarm type.</param>
|
||||||
/// <param name="severity">The domain severity.</param>
|
/// <param name="severity">The domain severity.</param>
|
||||||
public void MaterialiseAlarmCondition(string alarmNodeId, string equipmentNodeId, string displayName, string alarmType, int severity)
|
/// <param name="isNative">True for a driver-fed (native) equipment-tag alarm; false (default) for a scripted alarm.</param>
|
||||||
=> _nodeManager.MaterialiseAlarmCondition(alarmNodeId, equipmentNodeId, displayName, alarmType, severity);
|
public void MaterialiseAlarmCondition(string alarmNodeId, string equipmentNodeId, string displayName, string alarmType, int severity, bool isNative = false)
|
||||||
|
=> _nodeManager.MaterialiseAlarmCondition(alarmNodeId, equipmentNodeId, displayName, alarmType, severity, isNative);
|
||||||
|
|
||||||
/// <summary>Ensures a folder node exists in the address space.</summary>
|
/// <summary>Ensures a folder node exists in the address space.</summary>
|
||||||
/// <param name="folderNodeId">The folder node identifier.</param>
|
/// <param name="folderNodeId">The folder node identifier.</param>
|
||||||
|
|||||||
@@ -323,6 +323,37 @@ public sealed class AlarmCommandRouterTests : IDisposable
|
|||||||
await host.DisposeAsync();
|
await host.DisposeAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>H6a — a condition materialised with <c>isNative:true</c> is tracked so later inbound-ack
|
||||||
|
/// routing can dispatch its Acknowledge to the driver rather than the scripted engine.</summary>
|
||||||
|
[Fact]
|
||||||
|
public async Task Native_materialise_is_tracked_as_native()
|
||||||
|
{
|
||||||
|
var (host, server) = await BootAsync();
|
||||||
|
var nm = server.NodeManager!;
|
||||||
|
|
||||||
|
nm.EnsureFolder("eq", parentNodeId: null, displayName: "Equipment");
|
||||||
|
nm.MaterialiseAlarmCondition("a1", "eq", "d", "OffNormalAlarm", 700, isNative: true);
|
||||||
|
|
||||||
|
nm.IsNativeAlarmNode("a1").ShouldBeTrue();
|
||||||
|
|
||||||
|
await host.DisposeAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>H6a — a scripted condition (the default, <c>isNative:false</c>) is NOT tracked as native.</summary>
|
||||||
|
[Fact]
|
||||||
|
public async Task Scripted_materialise_is_not_native()
|
||||||
|
{
|
||||||
|
var (host, server) = await BootAsync();
|
||||||
|
var nm = server.NodeManager!;
|
||||||
|
|
||||||
|
nm.EnsureFolder("eq", parentNodeId: null, displayName: "Equipment");
|
||||||
|
nm.MaterialiseAlarmCondition("a2", "eq", "d", "OffNormalAlarm", 700, isNative: false);
|
||||||
|
|
||||||
|
nm.IsNativeAlarmNode("a2").ShouldBeFalse();
|
||||||
|
|
||||||
|
await host.DisposeAsync();
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Builds a <see cref="ServerSystemContext"/> (an <see cref="ISessionOperationContext"/>)
|
/// <summary>Builds a <see cref="ServerSystemContext"/> (an <see cref="ISessionOperationContext"/>)
|
||||||
/// carrying a <see cref="RoleCarryingUserIdentity"/> with the given name + roles — the exact seam the
|
/// carrying a <see cref="RoleCarryingUserIdentity"/> with the given name + roles — the exact seam the
|
||||||
/// gate reads via <c>(context as ISessionOperationContext)?.UserIdentity as RoleCarryingUserIdentity</c>.</summary>
|
/// gate reads via <c>(context as ISessionOperationContext)?.UserIdentity as RoleCarryingUserIdentity</c>.</summary>
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ public sealed class DeferredAddressSpaceSinkTests
|
|||||||
public void WriteAlarmCondition(string alarmNodeId, AlarmConditionSnapshot state, DateTime sourceTimestampUtc)
|
public void WriteAlarmCondition(string alarmNodeId, AlarmConditionSnapshot state, DateTime sourceTimestampUtc)
|
||||||
=> CallQueue.Enqueue($"WA:{alarmNodeId}");
|
=> CallQueue.Enqueue($"WA:{alarmNodeId}");
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void MaterialiseAlarmCondition(string alarmNodeId, string equipmentNodeId, string displayName, string alarmType, int severity)
|
public void MaterialiseAlarmCondition(string alarmNodeId, string equipmentNodeId, string displayName, string alarmType, int severity, bool isNative = false)
|
||||||
=> CallQueue.Enqueue($"MA:{alarmNodeId}");
|
=> CallQueue.Enqueue($"MA:{alarmNodeId}");
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void EnsureFolder(string folderNodeId, string? parentNodeId, string displayName)
|
public void EnsureFolder(string folderNodeId, string? parentNodeId, string displayName)
|
||||||
|
|||||||
@@ -252,7 +252,7 @@ public sealed class Phase7ApplierHierarchyTests : IDisposable
|
|||||||
/// <param name="displayName">The condition display name.</param>
|
/// <param name="displayName">The condition display name.</param>
|
||||||
/// <param name="alarmType">The domain alarm type.</param>
|
/// <param name="alarmType">The domain alarm type.</param>
|
||||||
/// <param name="severity">The domain severity.</param>
|
/// <param name="severity">The domain severity.</param>
|
||||||
public void MaterialiseAlarmCondition(string alarmNodeId, string equipmentNodeId, string displayName, string alarmType, int severity) { }
|
public void MaterialiseAlarmCondition(string alarmNodeId, string equipmentNodeId, string displayName, string alarmType, int severity, bool isNative = false) { }
|
||||||
/// <summary>Records a folder creation request.</summary>
|
/// <summary>Records a folder creation request.</summary>
|
||||||
/// <param name="folderNodeId">The node ID of the folder.</param>
|
/// <param name="folderNodeId">The node ID of the folder.</param>
|
||||||
/// <param name="parentNodeId">The node ID of the parent folder, or null for root.</param>
|
/// <param name="parentNodeId">The node ID of the parent folder, or null for root.</param>
|
||||||
|
|||||||
@@ -750,7 +750,7 @@ public sealed class Phase7ApplierTests
|
|||||||
/// <param name="displayName">The condition display name.</param>
|
/// <param name="displayName">The condition display name.</param>
|
||||||
/// <param name="alarmType">The domain alarm type.</param>
|
/// <param name="alarmType">The domain alarm type.</param>
|
||||||
/// <param name="severity">The domain severity.</param>
|
/// <param name="severity">The domain severity.</param>
|
||||||
public void MaterialiseAlarmCondition(string alarmNodeId, string equipmentNodeId, string displayName, string alarmType, int severity)
|
public void MaterialiseAlarmCondition(string alarmNodeId, string equipmentNodeId, string displayName, string alarmType, int severity, bool isNative = false)
|
||||||
=> AlarmConditionQueue.Enqueue((alarmNodeId, equipmentNodeId, displayName, alarmType, severity));
|
=> AlarmConditionQueue.Enqueue((alarmNodeId, equipmentNodeId, displayName, alarmType, severity));
|
||||||
/// <summary>Records a folder creation call.</summary>
|
/// <summary>Records a folder creation call.</summary>
|
||||||
/// <param name="folderNodeId">The folder node ID.</param>
|
/// <param name="folderNodeId">The folder node ID.</param>
|
||||||
@@ -802,7 +802,7 @@ public sealed class Phase7ApplierTests
|
|||||||
/// <param name="displayName">The condition display name.</param>
|
/// <param name="displayName">The condition display name.</param>
|
||||||
/// <param name="alarmType">The domain alarm type.</param>
|
/// <param name="alarmType">The domain alarm type.</param>
|
||||||
/// <param name="severity">The domain severity.</param>
|
/// <param name="severity">The domain severity.</param>
|
||||||
public void MaterialiseAlarmCondition(string alarmNodeId, string equipmentNodeId, string displayName, string alarmType, int severity) { }
|
public void MaterialiseAlarmCondition(string alarmNodeId, string equipmentNodeId, string displayName, string alarmType, int severity, bool isNative = false) { }
|
||||||
/// <summary>No-op folder creation call.</summary>
|
/// <summary>No-op folder creation call.</summary>
|
||||||
/// <param name="folderNodeId">The folder node ID.</param>
|
/// <param name="folderNodeId">The folder node ID.</param>
|
||||||
/// <param name="parentNodeId">The parent folder node ID, if any.</param>
|
/// <param name="parentNodeId">The parent folder node ID, if any.</param>
|
||||||
|
|||||||
+1
-1
@@ -206,7 +206,7 @@ public sealed class OtOpcUaTelemetryHookTests : RuntimeActorTestBase
|
|||||||
/// <param name="displayName">The condition display name.</param>
|
/// <param name="displayName">The condition display name.</param>
|
||||||
/// <param name="alarmType">The domain alarm type.</param>
|
/// <param name="alarmType">The domain alarm type.</param>
|
||||||
/// <param name="severity">The domain severity.</param>
|
/// <param name="severity">The domain severity.</param>
|
||||||
public void MaterialiseAlarmCondition(string alarmNodeId, string equipmentNodeId, string displayName, string alarmType, int severity) { }
|
public void MaterialiseAlarmCondition(string alarmNodeId, string equipmentNodeId, string displayName, string alarmType, int severity, bool isNative = false) { }
|
||||||
/// <summary>Ensures folder exists (stub implementation).</summary>
|
/// <summary>Ensures folder exists (stub implementation).</summary>
|
||||||
/// <param name="folderNodeId">The folder node identifier.</param>
|
/// <param name="folderNodeId">The folder node identifier.</param>
|
||||||
/// <param name="parentNodeId">The parent folder node identifier.</param>
|
/// <param name="parentNodeId">The parent folder node identifier.</param>
|
||||||
|
|||||||
@@ -274,7 +274,7 @@ public sealed class OpcUaPublishActorRebuildTests : RuntimeActorTestBase
|
|||||||
/// <param name="displayName">The condition display name.</param>
|
/// <param name="displayName">The condition display name.</param>
|
||||||
/// <param name="alarmType">The domain alarm type.</param>
|
/// <param name="alarmType">The domain alarm type.</param>
|
||||||
/// <param name="severity">The domain severity.</param>
|
/// <param name="severity">The domain severity.</param>
|
||||||
public void MaterialiseAlarmCondition(string alarmNodeId, string equipmentNodeId, string displayName, string alarmType, int severity)
|
public void MaterialiseAlarmCondition(string alarmNodeId, string equipmentNodeId, string displayName, string alarmType, int severity, bool isNative = false)
|
||||||
=> Calls.Enqueue($"MA:{alarmNodeId}");
|
=> Calls.Enqueue($"MA:{alarmNodeId}");
|
||||||
/// <summary>Records a folder ensure call.</summary>
|
/// <summary>Records a folder ensure call.</summary>
|
||||||
/// <param name="folderNodeId">The folder node ID.</param>
|
/// <param name="folderNodeId">The folder node ID.</param>
|
||||||
|
|||||||
@@ -577,7 +577,7 @@ public sealed class OpcUaPublishActorTests : RuntimeActorTestBase
|
|||||||
/// <param name="displayName">The condition display name.</param>
|
/// <param name="displayName">The condition display name.</param>
|
||||||
/// <param name="alarmType">The domain alarm type.</param>
|
/// <param name="alarmType">The domain alarm type.</param>
|
||||||
/// <param name="severity">The domain severity.</param>
|
/// <param name="severity">The domain severity.</param>
|
||||||
public void MaterialiseAlarmCondition(string alarmNodeId, string equipmentNodeId, string displayName, string alarmType, int severity) { }
|
public void MaterialiseAlarmCondition(string alarmNodeId, string equipmentNodeId, string displayName, string alarmType, int severity, bool isNative = false) { }
|
||||||
|
|
||||||
/// <summary>Ensures a folder exists (no-op in test).</summary>
|
/// <summary>Ensures a folder exists (no-op in test).</summary>
|
||||||
/// <param name="folderNodeId">The OPC UA folder node identifier.</param>
|
/// <param name="folderNodeId">The OPC UA folder node identifier.</param>
|
||||||
|
|||||||
Reference in New Issue
Block a user