docs: backfill XML documentation across 756 files
v2-ci / build (push) Failing after 1m43s
v2-ci / unit-tests (tests/Core/ZB.MOM.WW.OtOpcUa.Cluster.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.ControlPlane.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Security.Tests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.Host.IntegrationTests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests) (push) Has been skipped
v2-ci / build (push) Failing after 1m43s
v2-ci / unit-tests (tests/Core/ZB.MOM.WW.OtOpcUa.Cluster.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.ControlPlane.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Security.Tests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.Host.IntegrationTests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests) (push) Has been skipped
Adds <summary>, <param>, <typeparam>, and <inheritdoc/> tags to public members surfaced by commentchecker — resolves 5,847 of 5,869 issues (99.6%) across three /fixdocs passes.
This commit is contained in:
@@ -50,6 +50,7 @@ public sealed class OpcUaClientDriver : IDriver, ITagDiscovery, IReadable, IWrit
|
||||
private readonly System.Collections.Concurrent.ConcurrentDictionary<long, RemoteAlarmSubscription> _alarmSubscriptions = new();
|
||||
private long _nextAlarmSubscriptionId;
|
||||
|
||||
/// <summary>Occurs when an alarm event is received from the remote OPC UA server.</summary>
|
||||
public event EventHandler<AlarmEventArgs>? OnAlarmEvent;
|
||||
|
||||
// ---- ISubscribable + IHostConnectivityProbe state ----
|
||||
@@ -61,7 +62,9 @@ public sealed class OpcUaClientDriver : IDriver, ITagDiscovery, IReadable, IWrit
|
||||
private DateTime _hostStateChangedUtc = DateTime.UtcNow;
|
||||
private KeepAliveEventHandler? _keepAliveHandler;
|
||||
|
||||
/// <summary>Occurs when a monitored item's data value changes on the remote OPC UA server.</summary>
|
||||
public event EventHandler<DataChangeEventArgs>? OnDataChange;
|
||||
/// <summary>Occurs when the host connectivity status of the remote OPC UA server changes.</summary>
|
||||
public event EventHandler<HostStatusChangedEventArgs>? OnHostStatusChanged;
|
||||
|
||||
// OPC UA StatusCode constants the driver surfaces for local-side faults. Upstream-server
|
||||
@@ -118,9 +121,14 @@ public sealed class OpcUaClientDriver : IDriver, ITagDiscovery, IReadable, IWrit
|
||||
/// </summary>
|
||||
private NamespaceMap? _namespaceMap;
|
||||
|
||||
/// <summary>Gets the stable logical identifier for this driver instance from the config database.</summary>
|
||||
public string DriverInstanceId => _driverInstanceId;
|
||||
/// <summary>Gets the driver type identifier.</summary>
|
||||
public string DriverType => "OpcUaClient";
|
||||
|
||||
/// <summary>Initializes the OPC UA client driver with the given configuration.</summary>
|
||||
/// <param name="driverConfigJson">JSON-serialized driver configuration.</param>
|
||||
/// <param name="cancellationToken">Cancellation token for the operation.</param>
|
||||
public async Task InitializeAsync(string driverConfigJson, CancellationToken cancellationToken)
|
||||
{
|
||||
_health = new DriverHealth(DriverState.Initializing, null, null);
|
||||
@@ -294,6 +302,7 @@ public sealed class OpcUaClientDriver : IDriver, ITagDiscovery, IReadable, IWrit
|
||||
/// non-empty; otherwise fall back to <c>EndpointUrl</c> as a single-URL shortcut so
|
||||
/// existing single-endpoint configs keep working without migration.
|
||||
/// </summary>
|
||||
/// <param name="opts">Driver options containing endpoint configuration.</param>
|
||||
internal static IReadOnlyList<string> ResolveEndpointCandidates(OpcUaClientDriverOptions opts)
|
||||
{
|
||||
if (opts.EndpointUrls is { Count: > 0 }) return opts.EndpointUrls;
|
||||
@@ -308,6 +317,7 @@ public sealed class OpcUaClientDriver : IDriver, ITagDiscovery, IReadable, IWrit
|
||||
/// UNS mapping table is meaningless and rejected. Throwing here surfaces the
|
||||
/// misconfiguration as a draft-validation failure rather than a runtime surprise.
|
||||
/// </summary>
|
||||
/// <param name="opts">Driver options containing namespace configuration.</param>
|
||||
internal static void ValidateNamespaceKind(OpcUaClientDriverOptions opts)
|
||||
{
|
||||
switch (opts.TargetNamespaceKind)
|
||||
@@ -341,6 +351,7 @@ public sealed class OpcUaClientDriver : IDriver, ITagDiscovery, IReadable, IWrit
|
||||
/// every endpoint attempt — generating it N times would re-unlock the user cert's
|
||||
/// private key N times, wasteful + keeps the password in memory longer.
|
||||
/// </summary>
|
||||
/// <param name="options">Driver options containing authentication configuration.</param>
|
||||
internal static UserIdentity BuildUserIdentity(OpcUaClientDriverOptions options) =>
|
||||
options.AuthType switch
|
||||
{
|
||||
@@ -443,6 +454,7 @@ public sealed class OpcUaClientDriver : IDriver, ITagDiscovery, IReadable, IWrit
|
||||
/// lacks a private key (the private key is required to sign the user-token
|
||||
/// challenge during session activation).
|
||||
/// </summary>
|
||||
/// <param name="options">Driver options containing certificate configuration.</param>
|
||||
internal static UserIdentity BuildCertificateIdentity(OpcUaClientDriverOptions options)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(options.UserCertificatePath))
|
||||
@@ -469,6 +481,7 @@ public sealed class OpcUaClientDriver : IDriver, ITagDiscovery, IReadable, IWrit
|
||||
}
|
||||
|
||||
/// <summary>Convert a driver <see cref="OpcUaSecurityPolicy"/> to the OPC UA policy URI.</summary>
|
||||
/// <param name="policy">The driver security policy to map.</param>
|
||||
internal static string MapSecurityPolicy(OpcUaSecurityPolicy policy) => policy switch
|
||||
{
|
||||
OpcUaSecurityPolicy.None => SecurityPolicies.None,
|
||||
@@ -483,12 +496,17 @@ public sealed class OpcUaClientDriver : IDriver, ITagDiscovery, IReadable, IWrit
|
||||
private static string ShortPolicyName(string policyUri) =>
|
||||
policyUri?.Substring(policyUri.LastIndexOf('#') + 1) ?? "(null)";
|
||||
|
||||
/// <summary>Reinitializes the driver with new configuration, shutting down and restarting the session.</summary>
|
||||
/// <param name="driverConfigJson">JSON-serialized driver configuration.</param>
|
||||
/// <param name="cancellationToken">Cancellation token for the operation.</param>
|
||||
public async Task ReinitializeAsync(string driverConfigJson, CancellationToken cancellationToken)
|
||||
{
|
||||
await ShutdownAsync(cancellationToken).ConfigureAwait(false);
|
||||
await InitializeAsync(driverConfigJson, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
/// <summary>Gracefully shuts down the OPC UA session, unsubscribing all active monitoring items and closing the connection.</summary>
|
||||
/// <param name="cancellationToken">Cancellation token for the operation.</param>
|
||||
public async Task ShutdownAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
// Tear down remote subscriptions first — otherwise Session.Close will try and may fail
|
||||
@@ -564,6 +582,7 @@ public sealed class OpcUaClientDriver : IDriver, ITagDiscovery, IReadable, IWrit
|
||||
_health = new DriverHealth(DriverState.Unknown, _health.LastSuccessfulRead, null);
|
||||
}
|
||||
|
||||
/// <summary>Gets the current health status of the OPC UA client driver.</summary>
|
||||
public DriverHealth GetHealth() => _health;
|
||||
|
||||
/// <summary>
|
||||
@@ -584,6 +603,7 @@ public sealed class OpcUaClientDriver : IDriver, ITagDiscovery, IReadable, IWrit
|
||||
/// flush here resets the footprint counter and signals the Core that re-discovery
|
||||
/// will rebuild it cleanly from the remote server.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">Cancellation token for the operation.</param>
|
||||
public Task FlushOptionalCachesAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
_discoveredNodeCount = 0;
|
||||
@@ -592,6 +612,9 @@ public sealed class OpcUaClientDriver : IDriver, ITagDiscovery, IReadable, IWrit
|
||||
|
||||
// ---- IReadable ----
|
||||
|
||||
/// <summary>Reads the current values of the specified nodes from the remote OPC UA server.</summary>
|
||||
/// <param name="fullReferences">Fully-qualified node identifiers to read.</param>
|
||||
/// <param name="cancellationToken">Cancellation token for the operation.</param>
|
||||
public async Task<IReadOnlyList<DataValueSnapshot>> ReadAsync(
|
||||
IReadOnlyList<string> fullReferences, CancellationToken cancellationToken)
|
||||
{
|
||||
@@ -680,6 +703,9 @@ public sealed class OpcUaClientDriver : IDriver, ITagDiscovery, IReadable, IWrit
|
||||
|
||||
// ---- IWritable ----
|
||||
|
||||
/// <summary>Writes values to the specified nodes on the remote OPC UA server.</summary>
|
||||
/// <param name="writes">Write requests specifying nodes and values to write.</param>
|
||||
/// <param name="cancellationToken">Cancellation token for the operation.</param>
|
||||
public async Task<IReadOnlyList<WriteResult>> WriteAsync(
|
||||
IReadOnlyList<Core.Abstractions.WriteRequest> writes, CancellationToken cancellationToken)
|
||||
{
|
||||
@@ -772,6 +798,9 @@ public sealed class OpcUaClientDriver : IDriver, ITagDiscovery, IReadable, IWrit
|
||||
/// corrected (driver-specs.md §8). Empty + malformed strings return false; the driver
|
||||
/// surfaces that as <see cref="StatusBadNodeIdInvalid"/> without a wire round-trip.
|
||||
/// </summary>
|
||||
/// <param name="session">The OPC UA session to resolve the node ID against.</param>
|
||||
/// <param name="fullReference">The full reference string to parse.</param>
|
||||
/// <param name="nodeId">The parsed node ID when successful.</param>
|
||||
internal static bool TryParseNodeId(ISession session, string fullReference, out NodeId nodeId) =>
|
||||
NamespaceMap.TryResolve(session, fullReference, out nodeId);
|
||||
|
||||
@@ -788,6 +817,9 @@ public sealed class OpcUaClientDriver : IDriver, ITagDiscovery, IReadable, IWrit
|
||||
|
||||
// ---- ITagDiscovery ----
|
||||
|
||||
/// <summary>Discovers the remote OPC UA server's address space and materializes it through the supplied builder.</summary>
|
||||
/// <param name="builder">Address space builder for materializing discovered nodes.</param>
|
||||
/// <param name="cancellationToken">Cancellation token for the operation.</param>
|
||||
public async Task DiscoverAsync(IAddressSpaceBuilder builder, CancellationToken cancellationToken)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(builder);
|
||||
@@ -1053,6 +1085,7 @@ public sealed class OpcUaClientDriver : IDriver, ITagDiscovery, IReadable, IWrit
|
||||
/// string rendering but the cascading-quality path still preserves upstream
|
||||
/// StatusCode + timestamps.
|
||||
/// </summary>
|
||||
/// <param name="dataType">The OPC UA data type NodeId to map.</param>
|
||||
internal static DriverDataType MapUpstreamDataType(NodeId dataType)
|
||||
{
|
||||
if (dataType == DataTypeIds.Boolean) return DriverDataType.Boolean;
|
||||
@@ -1080,6 +1113,7 @@ public sealed class OpcUaClientDriver : IDriver, ITagDiscovery, IReadable, IWrit
|
||||
/// layer can gate writes off. CurrentWrite-capable variables surface as
|
||||
/// <see cref="SecurityClassification.Operate"/>; read-only as <see cref="SecurityClassification.ViewOnly"/>.
|
||||
/// </summary>
|
||||
/// <param name="accessLevel">The OPC UA access level bitmask.</param>
|
||||
internal static SecurityClassification MapAccessLevelToSecurityClass(byte accessLevel)
|
||||
{
|
||||
const byte CurrentWrite = 2; // AccessLevels.CurrentWrite = 0x02
|
||||
@@ -1090,6 +1124,10 @@ public sealed class OpcUaClientDriver : IDriver, ITagDiscovery, IReadable, IWrit
|
||||
|
||||
// ---- ISubscribable ----
|
||||
|
||||
/// <summary>Subscribes to monitored value changes on the specified nodes from the remote OPC UA server.</summary>
|
||||
/// <param name="fullReferences">Fully-qualified node identifiers to monitor.</param>
|
||||
/// <param name="publishingInterval">Desired minimum interval between publish cycles.</param>
|
||||
/// <param name="cancellationToken">Cancellation token for the operation.</param>
|
||||
public async Task<ISubscriptionHandle> SubscribeAsync(
|
||||
IReadOnlyList<string> fullReferences, TimeSpan publishingInterval, CancellationToken cancellationToken)
|
||||
{
|
||||
@@ -1160,6 +1198,9 @@ public sealed class OpcUaClientDriver : IDriver, ITagDiscovery, IReadable, IWrit
|
||||
return handle;
|
||||
}
|
||||
|
||||
/// <summary>Unsubscribes from monitored value changes for the specified subscription handle.</summary>
|
||||
/// <param name="handle">The subscription handle to unsubscribe.</param>
|
||||
/// <param name="cancellationToken">Cancellation token for the operation.</param>
|
||||
public async Task UnsubscribeAsync(ISubscriptionHandle handle, CancellationToken cancellationToken)
|
||||
{
|
||||
if (handle is not OpcUaSubscriptionHandle h) return;
|
||||
@@ -1231,6 +1272,7 @@ public sealed class OpcUaClientDriver : IDriver, ITagDiscovery, IReadable, IWrit
|
||||
|
||||
private sealed record OpcUaSubscriptionHandle(long Id) : ISubscriptionHandle
|
||||
{
|
||||
/// <summary>Gets the diagnostic identifier for this subscription.</summary>
|
||||
public string DiagnosticId => $"opcua-sub-{Id}";
|
||||
}
|
||||
|
||||
@@ -1248,6 +1290,9 @@ public sealed class OpcUaClientDriver : IDriver, ITagDiscovery, IReadable, IWrit
|
||||
private const int AlarmFieldTime = 5;
|
||||
private const int AlarmFieldConditionId = 6;
|
||||
|
||||
/// <summary>Subscribes to alarm and event notifications from the remote OPC UA server.</summary>
|
||||
/// <param name="sourceNodeIds">Source node identifiers to subscribe alarms from.</param>
|
||||
/// <param name="cancellationToken">Cancellation token for the operation.</param>
|
||||
public async Task<IAlarmSubscriptionHandle> SubscribeAlarmsAsync(
|
||||
IReadOnlyList<string> sourceNodeIds, CancellationToken cancellationToken)
|
||||
{
|
||||
@@ -1333,6 +1378,9 @@ public sealed class OpcUaClientDriver : IDriver, ITagDiscovery, IReadable, IWrit
|
||||
return handle;
|
||||
}
|
||||
|
||||
/// <summary>Unsubscribes from alarm and event notifications for the specified alarm subscription handle.</summary>
|
||||
/// <param name="handle">The alarm subscription handle to unsubscribe.</param>
|
||||
/// <param name="cancellationToken">Cancellation token for the operation.</param>
|
||||
public async Task UnsubscribeAlarmsAsync(IAlarmSubscriptionHandle handle, CancellationToken cancellationToken)
|
||||
{
|
||||
if (handle is not OpcUaAlarmSubscriptionHandle h) return;
|
||||
@@ -1352,6 +1400,9 @@ public sealed class OpcUaClientDriver : IDriver, ITagDiscovery, IReadable, IWrit
|
||||
finally { _gate.Release(); }
|
||||
}
|
||||
|
||||
/// <summary>Acknowledges multiple alarms by calling the remote OPC UA server's Acknowledge method.</summary>
|
||||
/// <param name="acknowledgements">List of alarm acknowledgement requests.</param>
|
||||
/// <param name="cancellationToken">Cancellation token for the operation.</param>
|
||||
public async Task AcknowledgeAsync(
|
||||
IReadOnlyList<AlarmAcknowledgeRequest> acknowledgements, CancellationToken cancellationToken)
|
||||
{
|
||||
@@ -1465,6 +1516,7 @@ public sealed class OpcUaClientDriver : IDriver, ITagDiscovery, IReadable, IWrit
|
||||
/// <see cref="AlarmSeverity"/> bucket. Thresholds match the OPC UA A&C Part 9
|
||||
/// guidance: 1-200 Low, 201-500 Medium, 501-800 High, 801-1000 Critical.
|
||||
/// </summary>
|
||||
/// <param name="opcSeverity">The OPC UA severity value (1-1000).</param>
|
||||
internal static AlarmSeverity MapSeverity(ushort opcSeverity) => opcSeverity switch
|
||||
{
|
||||
<= 200 => AlarmSeverity.Low,
|
||||
@@ -1487,11 +1539,18 @@ public sealed class OpcUaClientDriver : IDriver, ITagDiscovery, IReadable, IWrit
|
||||
|
||||
private sealed record OpcUaAlarmSubscriptionHandle(long Id) : IAlarmSubscriptionHandle
|
||||
{
|
||||
/// <summary>Gets the diagnostic identifier for this alarm subscription.</summary>
|
||||
public string DiagnosticId => $"opcua-alarm-sub-{Id}";
|
||||
}
|
||||
|
||||
// ---- IHistoryProvider (passthrough to upstream server) ----
|
||||
|
||||
/// <summary>Reads raw historical data from the remote OPC UA server.</summary>
|
||||
/// <param name="fullReference">Fully-qualified node identifier to read history for.</param>
|
||||
/// <param name="startUtc">Start time in UTC for the history query.</param>
|
||||
/// <param name="endUtc">End time in UTC for the history query.</param>
|
||||
/// <param name="maxValuesPerNode">Maximum number of values to return.</param>
|
||||
/// <param name="cancellationToken">Cancellation token for the operation.</param>
|
||||
public async Task<Core.Abstractions.HistoryReadResult> ReadRawAsync(
|
||||
string fullReference, DateTime startUtc, DateTime endUtc, uint maxValuesPerNode,
|
||||
CancellationToken cancellationToken)
|
||||
@@ -1508,6 +1567,13 @@ public sealed class OpcUaClientDriver : IDriver, ITagDiscovery, IReadable, IWrit
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
/// <summary>Reads processed (aggregated) historical data from the remote OPC UA server.</summary>
|
||||
/// <param name="fullReference">Fully-qualified node identifier to read history for.</param>
|
||||
/// <param name="startUtc">Start time in UTC for the history query.</param>
|
||||
/// <param name="endUtc">End time in UTC for the history query.</param>
|
||||
/// <param name="interval">Time interval for aggregation.</param>
|
||||
/// <param name="aggregate">The aggregation function to apply.</param>
|
||||
/// <param name="cancellationToken">Cancellation token for the operation.</param>
|
||||
public async Task<Core.Abstractions.HistoryReadResult> ReadProcessedAsync(
|
||||
string fullReference, DateTime startUtc, DateTime endUtc, TimeSpan interval,
|
||||
HistoryAggregateType aggregate, CancellationToken cancellationToken)
|
||||
@@ -1524,6 +1590,10 @@ public sealed class OpcUaClientDriver : IDriver, ITagDiscovery, IReadable, IWrit
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
/// <summary>Reads historical data at specific timestamps from the remote OPC UA server.</summary>
|
||||
/// <param name="fullReference">Fully-qualified node identifier to read history for.</param>
|
||||
/// <param name="timestampsUtc">List of specific timestamps to read values at.</param>
|
||||
/// <param name="cancellationToken">Cancellation token for the operation.</param>
|
||||
public async Task<Core.Abstractions.HistoryReadResult> ReadAtTimeAsync(
|
||||
string fullReference, IReadOnlyList<DateTime> timestampsUtc, CancellationToken cancellationToken)
|
||||
{
|
||||
@@ -1594,6 +1664,7 @@ public sealed class OpcUaClientDriver : IDriver, ITagDiscovery, IReadable, IWrit
|
||||
}
|
||||
|
||||
/// <summary>Map <see cref="HistoryAggregateType"/> to the OPC UA Part 13 standard aggregate NodeId.</summary>
|
||||
/// <param name="aggregate">The aggregation function type to map.</param>
|
||||
internal static NodeId MapAggregateToNodeId(HistoryAggregateType aggregate) => aggregate switch
|
||||
{
|
||||
HistoryAggregateType.Average => ObjectIds.AggregateFunction_Average,
|
||||
@@ -1623,6 +1694,7 @@ public sealed class OpcUaClientDriver : IDriver, ITagDiscovery, IReadable, IWrit
|
||||
?? ResolveEndpointCandidates(_options).FirstOrDefault()
|
||||
?? _options.EndpointUrl;
|
||||
|
||||
/// <summary>Gets the current connectivity status of the remote OPC UA server host.</summary>
|
||||
public IReadOnlyList<HostConnectivityStatus> GetHostStatuses()
|
||||
{
|
||||
lock (_probeLock)
|
||||
@@ -1854,6 +1926,7 @@ public sealed class OpcUaClientDriver : IDriver, ITagDiscovery, IReadable, IWrit
|
||||
_gate.Dispose();
|
||||
}
|
||||
|
||||
/// <summary>Asynchronously disposes the driver and releases all associated resources.</summary>
|
||||
public async ValueTask DisposeAsync()
|
||||
{
|
||||
if (_disposed) return;
|
||||
|
||||
Reference in New Issue
Block a user