Resolve all high-severity architecture review findings
This commit is contained in:
@@ -68,6 +68,7 @@ public class RealOpcUaClient : IOpcUaClient
|
||||
private readonly ConcurrentDictionary<string, MonitoredItem> _alarmItems = new();
|
||||
// Per-handle "currently inside a ConditionRefresh replay" flag → Snapshot kind.
|
||||
private readonly ConcurrentDictionary<string, bool> _alarmInRefresh = new();
|
||||
private readonly ConcurrentDictionary<string, Guid> _alarmSnapshotIds = new();
|
||||
// Per-handle last (active, acked) by source reference, to derive transition kind.
|
||||
private readonly ConcurrentDictionary<string, Dictionary<string, (bool Active, bool Acked)>> _alarmLastState = new();
|
||||
// Int flag toggled with Interlocked.Exchange so the
|
||||
@@ -543,6 +544,10 @@ public class RealOpcUaClient : IOpcUaClient
|
||||
}
|
||||
_monitoredItems.Clear();
|
||||
_callbacks.Clear();
|
||||
_alarmItems.Clear();
|
||||
_alarmInRefresh.Clear();
|
||||
_alarmSnapshotIds.Clear();
|
||||
_alarmLastState.Clear();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -925,6 +930,7 @@ public class RealOpcUaClient : IOpcUaClient
|
||||
}, cancellationToken);
|
||||
}
|
||||
_alarmInRefresh.TryRemove(subscriptionHandle, out _);
|
||||
_alarmSnapshotIds.TryRemove(subscriptionHandle, out _);
|
||||
_alarmLastState.TryRemove(subscriptionHandle, out _);
|
||||
}
|
||||
|
||||
@@ -1160,12 +1166,16 @@ public class RealOpcUaClient : IOpcUaClient
|
||||
if (eventType == ObjectTypeIds.RefreshStartEventType)
|
||||
{
|
||||
_alarmInRefresh[handle] = true;
|
||||
var startEpoch = Guid.NewGuid();
|
||||
_alarmSnapshotIds[handle] = startEpoch;
|
||||
onTransition(SnapshotBoundary(AlarmTransitionKind.SnapshotStart, subscriptionSourceReference, startEpoch));
|
||||
return;
|
||||
}
|
||||
if (eventType == ObjectTypeIds.RefreshEndEventType)
|
||||
{
|
||||
_alarmInRefresh[handle] = false;
|
||||
onTransition(SnapshotComplete());
|
||||
if (_alarmSnapshotIds.TryRemove(handle, out var endEpoch))
|
||||
onTransition(SnapshotBoundary(AlarmTransitionKind.SnapshotComplete, subscriptionSourceReference, endEpoch));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1253,13 +1263,16 @@ public class RealOpcUaClient : IOpcUaClient
|
||||
LimitValue: limitValue,
|
||||
// MES alarm-status API §6.4: true source ack instant (index 18) when supplied,
|
||||
// else the observed event time; null unless the condition is active AND acked.
|
||||
AckTime: OpcUaAlarmMapper.DeriveAckTime(active, acked, sourceAckTime, time)));
|
||||
AckTime: OpcUaAlarmMapper.DeriveAckTime(active, acked, sourceAckTime, time),
|
||||
SnapshotSourceReference: inRefresh ? subscriptionSourceReference ?? string.Empty : null,
|
||||
SnapshotId: inRefresh && _alarmSnapshotIds.TryGetValue(handle, out var epoch) ? epoch : null));
|
||||
}
|
||||
|
||||
private static NativeAlarmTransition SnapshotComplete() => new(
|
||||
"", "", "", AlarmTransitionKind.SnapshotComplete,
|
||||
private static NativeAlarmTransition SnapshotBoundary(AlarmTransitionKind kind, string? source, Guid epoch) => new(
|
||||
"", source ?? string.Empty, "", kind,
|
||||
new Commons.Types.Alarms.AlarmConditionState(false, true, null, AlarmShelveState.Unshelved, false, 0),
|
||||
"", "", "", "", "", null, DateTimeOffset.UtcNow, "", "");
|
||||
"", "", "", "", "", null, DateTimeOffset.UtcNow, "", "",
|
||||
SnapshotSourceReference: source ?? string.Empty, SnapshotId: epoch);
|
||||
|
||||
/// <summary>
|
||||
/// Nodes per OPC UA Read/Write service call. Stays under the
|
||||
|
||||
Reference in New Issue
Block a user