docs(xmldoc): fill missing XML docs + strip tracking-ID comments across src
v2-ci / build (push) Failing after 41s
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 41s
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>/<returns>/<inheritdoc> where missing and removes project bookkeeping IDs (task/tracking refs) from shipped code comments, so the docs read cleanly and CommentChecker is quiet except for known false positives (PLC/protocol terms, event/IEqualityComparer inheritdoc). Doc/comment-only; no logic changed; solution builds clean.
This commit is contained in:
@@ -16,14 +16,22 @@ public interface IBrowseSession : IAsyncDisposable
|
||||
DateTime LastUsedUtc { get; }
|
||||
|
||||
/// <summary>Returns the top-level browse nodes.</summary>
|
||||
/// <param name="cancellationToken">Cancellation token for the operation.</param>
|
||||
/// <returns>The top-level browse nodes.</returns>
|
||||
Task<IReadOnlyList<BrowseNode>> RootAsync(CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>Returns the direct children of the node identified by
|
||||
/// <paramref name="nodeId"/>.</summary>
|
||||
/// <param name="nodeId">The node whose direct children are returned.</param>
|
||||
/// <param name="cancellationToken">Cancellation token for the operation.</param>
|
||||
/// <returns>The direct children of the node.</returns>
|
||||
Task<IReadOnlyList<BrowseNode>> ExpandAsync(string nodeId, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>Returns the attributes of the node identified by <paramref name="nodeId"/>.
|
||||
/// Empty for drivers whose tree is uniform (OPC UA Client). Galaxy uses this to populate
|
||||
/// the attribute side-panel after the user selects an object.</summary>
|
||||
/// <param name="nodeId">The node whose attributes are returned.</param>
|
||||
/// <param name="cancellationToken">Cancellation token for the operation.</param>
|
||||
/// <returns>The attributes of the node.</returns>
|
||||
Task<IReadOnlyList<AttributeInfo>> AttributesAsync(string nodeId, CancellationToken cancellationToken);
|
||||
}
|
||||
|
||||
@@ -15,5 +15,6 @@ public interface IDriverBrowser
|
||||
/// <param name="configJson">Driver options serialized as JSON; same shape the runtime
|
||||
/// driver would consume.</param>
|
||||
/// <param name="cancellationToken">Cancellation for the connect phase only.</param>
|
||||
/// <returns>The opened browse session.</returns>
|
||||
Task<IBrowseSession> OpenAsync(string configJson, CancellationToken cancellationToken);
|
||||
}
|
||||
|
||||
@@ -43,11 +43,7 @@ public sealed class NullVirtualTagEvaluator : IVirtualTagEvaluator
|
||||
{
|
||||
public static readonly NullVirtualTagEvaluator Instance = new();
|
||||
private NullVirtualTagEvaluator() { }
|
||||
/// <summary>Returns <see cref="VirtualTagEvalResult.NoChange"/> for every evaluation.</summary>
|
||||
/// <param name="virtualTagId">The virtual tag identifier (ignored).</param>
|
||||
/// <param name="expression">The expression string (ignored).</param>
|
||||
/// <param name="dependencies">The variable dependencies (ignored).</param>
|
||||
/// <returns>Always returns <see cref="VirtualTagEvalResult.NoChange"/>.</returns>
|
||||
/// <inheritdoc />
|
||||
public VirtualTagEvalResult Evaluate(string virtualTagId, string expression, IReadOnlyDictionary<string, object?> dependencies)
|
||||
=> VirtualTagEvalResult.NoChange;
|
||||
}
|
||||
|
||||
@@ -53,5 +53,6 @@ public interface IAdminOperationsClient
|
||||
/// <typeparam name="T">Expected reply type.</typeparam>
|
||||
/// <param name="message">The message to send.</param>
|
||||
/// <param name="ct">Cancellation token (caller-controlled timeout).</param>
|
||||
/// <returns>The reply of type <typeparamref name="T"/> received from the admin singleton.</returns>
|
||||
Task<T> AskAsync<T>(object message, CancellationToken ct);
|
||||
}
|
||||
|
||||
@@ -11,5 +11,6 @@ public interface IFleetDiagnosticsClient
|
||||
/// <summary>Gets diagnostics for the specified node.</summary>
|
||||
/// <param name="nodeId">The node ID to retrieve diagnostics for.</param>
|
||||
/// <param name="ct">The cancellation token.</param>
|
||||
/// <returns>The diagnostics snapshot for the requested node.</returns>
|
||||
Task<NodeDiagnosticsSnapshot> GetDiagnosticsAsync(NodeId nodeId, CancellationToken ct);
|
||||
}
|
||||
|
||||
@@ -69,6 +69,7 @@ public static class OtOpcUaTelemetry
|
||||
/// null when no listener is attached so the call site stays cheap on undecorated builds.
|
||||
/// </summary>
|
||||
/// <param name="deploymentId">The deployment identifier to tag the span with.</param>
|
||||
/// <returns>The started activity, or <c>null</c> when no listener is attached.</returns>
|
||||
public static Activity? StartDeployApplySpan(string deploymentId)
|
||||
{
|
||||
var activity = ActivitySource.StartActivity("otopcua.deploy.apply", ActivityKind.Internal);
|
||||
@@ -77,6 +78,7 @@ public static class OtOpcUaTelemetry
|
||||
}
|
||||
|
||||
/// <summary>Span wrapping a full OPC UA address-space rebuild (AddressSpace plan → apply).</summary>
|
||||
/// <returns>The started activity, or <c>null</c> when no listener is attached.</returns>
|
||||
public static Activity? StartAddressSpaceRebuildSpan()
|
||||
=> ActivitySource.StartActivity("otopcua.opcua.address_space_rebuild", ActivityKind.Internal);
|
||||
}
|
||||
|
||||
@@ -22,85 +22,49 @@ public sealed class DeferredAddressSpaceSink : IOpcUaAddressSpaceSink, ISurgical
|
||||
public void SetSink(IOpcUaAddressSpaceSink? sink) =>
|
||||
_inner = sink ?? NullOpcUaAddressSpaceSink.Instance;
|
||||
|
||||
/// <summary>Writes a value to the OPC UA address space through the inner sink.</summary>
|
||||
/// <param name="nodeId">The node ID of the variable.</param>
|
||||
/// <param name="value">The value to write.</param>
|
||||
/// <param name="quality">The OPC UA quality value.</param>
|
||||
/// <param name="sourceTimestampUtc">The source timestamp in UTC.</param>
|
||||
/// <inheritdoc />
|
||||
public void WriteValue(string nodeId, object? value, OpcUaQuality quality, DateTime sourceTimestampUtc)
|
||||
=> _inner.WriteValue(nodeId, value, quality, sourceTimestampUtc);
|
||||
|
||||
/// <summary>Writes a full alarm-condition state through the inner sink.</summary>
|
||||
/// <param name="alarmNodeId">The node ID of the alarm condition.</param>
|
||||
/// <param name="state">The full condition state to project onto the node.</param>
|
||||
/// <param name="sourceTimestampUtc">The source timestamp in UTC.</param>
|
||||
/// <inheritdoc />
|
||||
public void WriteAlarmCondition(string alarmNodeId, AlarmConditionSnapshot state, DateTime sourceTimestampUtc)
|
||||
=> _inner.WriteAlarmCondition(alarmNodeId, state, sourceTimestampUtc);
|
||||
|
||||
/// <summary>Materialises a real Part 9 alarm-condition node through the inner sink.</summary>
|
||||
/// <param name="alarmNodeId">The alarm node ID (== ScriptedAlarmId).</param>
|
||||
/// <param name="equipmentNodeId">The equipment folder node ID the condition parents under.</param>
|
||||
/// <param name="displayName">The human-readable condition name.</param>
|
||||
/// <param name="alarmType">The domain alarm type.</param>
|
||||
/// <param name="severity">The domain severity.</param>
|
||||
/// <param name="isNative">True for a driver-fed (native) equipment-tag alarm; false (default) for a scripted alarm.</param>
|
||||
/// <inheritdoc />
|
||||
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>
|
||||
/// <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="displayName">The display name of the folder.</param>
|
||||
/// <inheritdoc />
|
||||
public void EnsureFolder(string folderNodeId, string? parentNodeId, string displayName)
|
||||
=> _inner.EnsureFolder(folderNodeId, parentNodeId, displayName);
|
||||
|
||||
/// <summary>Ensures a variable exists in the address space through the inner sink.</summary>
|
||||
/// <param name="variableNodeId">The node ID of the variable.</param>
|
||||
/// <param name="parentFolderNodeId">The node ID of the parent folder, or null for root.</param>
|
||||
/// <param name="displayName">The display name of the variable.</param>
|
||||
/// <param name="dataType">The OPC UA data type of the variable.</param>
|
||||
/// <param name="writable">When true the node is created read/write; otherwise read-only.</param>
|
||||
/// <param name="historianTagname">null ⇒ not historized; non-null ⇒ create Historizing with the
|
||||
/// HistoryRead access bit and register the historian tagname.</param>
|
||||
/// <param name="isArray">When true the node is created as a 1-D array; when false (default) scalar.</param>
|
||||
/// <param name="arrayLength">The declared length of the 1-D array when <paramref name="isArray"/> is true.</param>
|
||||
/// <inheritdoc />
|
||||
public void EnsureVariable(string variableNodeId, string? parentFolderNodeId, string displayName, string dataType, bool writable, string? historianTagname = null, bool isArray = false, uint? arrayLength = null)
|
||||
=> _inner.EnsureVariable(variableNodeId, parentFolderNodeId, displayName, dataType, writable, historianTagname, isArray, arrayLength);
|
||||
|
||||
/// <summary>Rebuilds the address space through the inner sink.</summary>
|
||||
/// <inheritdoc />
|
||||
public void RebuildAddressSpace() => _inner.RebuildAddressSpace();
|
||||
|
||||
/// <summary>Announces a runtime NodeAdded model-change (discovered-node injection) through the inner sink.</summary>
|
||||
/// <param name="affectedNodeId">The node under which discovered nodes were added.</param>
|
||||
/// <inheritdoc />
|
||||
public void RaiseNodesAddedModelChange(string affectedNodeId) => _inner.RaiseNodesAddedModelChange(affectedNodeId);
|
||||
|
||||
/// <summary>Forwards an in-place tag-attribute update (F10b) to the inner sink when it supports the
|
||||
/// surgical capability. Returns false otherwise — before the real <c>SdkAddressSpaceSink</c> is
|
||||
/// swapped in (inner is still the null sink), or any inner sink that isn't surgical — so the caller
|
||||
/// (AddressSpaceApplier) falls back to a full rebuild. Without this forward the surgical optimization is
|
||||
/// inert on every driver-role host, because actors inject THIS wrapper, not the inner sink. ALL six args
|
||||
/// (including the FB-7 DataType/array-shape ones) MUST be forwarded — a partial forward silently drops the
|
||||
/// shape update on every driver-role host.</summary>
|
||||
/// <param name="variableNodeId">The node ID of the variable to update in place.</param>
|
||||
/// <param name="writable">Whether the node should be read/write.</param>
|
||||
/// <param name="historianTagname">null ⇒ not historized; non-null ⇒ Historizing + historian binding.</param>
|
||||
/// <param name="dataType">The OPC UA built-in data type name to apply in place.</param>
|
||||
/// <param name="isArray">When true the node becomes a 1-D array; when false scalar.</param>
|
||||
/// <param name="arrayLength">The declared length of the 1-D array when <paramref name="isArray"/> is true.</param>
|
||||
/// <returns>True when the inner sink applied the update; false when it lacks the capability or the node is missing.</returns>
|
||||
/// <inheritdoc />
|
||||
// Forwards to the inner sink when it supports the surgical capability; returns false otherwise —
|
||||
// before the real SdkAddressSpaceSink is swapped in (inner is still the null sink), or any inner
|
||||
// sink that isn't surgical — so the caller (AddressSpaceApplier) falls back to a full rebuild.
|
||||
// Without this forward the surgical optimization is inert on every driver-role host, because
|
||||
// actors inject THIS wrapper, not the inner sink. ALL six args (including the DataType/array-shape
|
||||
// ones) MUST be forwarded — a partial forward silently drops the shape update on every driver-role host.
|
||||
public bool UpdateTagAttributes(string variableNodeId, bool writable, string? historianTagname, string dataType, bool isArray, uint? arrayLength)
|
||||
=> _inner is ISurgicalAddressSpaceSink surgical
|
||||
&& surgical.UpdateTagAttributes(variableNodeId, writable, historianTagname, dataType, isArray, arrayLength);
|
||||
|
||||
/// <summary>Forwards an in-place folder-display-name update (OpcUaServer-001 — UNS Area / Line
|
||||
/// rename) to the inner sink when it supports the surgical capability. Returns false otherwise —
|
||||
/// before the real <c>SdkAddressSpaceSink</c> is swapped in (inner is still the null sink), or any
|
||||
/// inner sink that isn't surgical — so the caller (AddressSpaceApplier) falls back to a full rebuild.
|
||||
/// Without this forward the rename-refresh optimization is inert on every driver-role host, because
|
||||
/// actors inject THIS wrapper, not the inner sink.</summary>
|
||||
/// <param name="folderNodeId">The folder node id whose display name to update in place.</param>
|
||||
/// <param name="displayName">The new display name to apply.</param>
|
||||
/// <returns>True when the inner sink applied the update; false when it lacks the capability or the folder is missing.</returns>
|
||||
/// <inheritdoc />
|
||||
// Forwards to the inner sink when it supports the surgical capability; returns false otherwise —
|
||||
// before the real SdkAddressSpaceSink is swapped in (inner is still the null sink), or any inner
|
||||
// sink that isn't surgical — so the caller (AddressSpaceApplier) falls back to a full rebuild.
|
||||
// Without this forward the rename-refresh optimization is inert on every driver-role host, because
|
||||
// actors inject THIS wrapper, not the inner sink.
|
||||
public bool UpdateFolderDisplayName(string folderNodeId, string displayName)
|
||||
=> _inner is ISurgicalAddressSpaceSink surgical
|
||||
&& surgical.UpdateFolderDisplayName(folderNodeId, displayName);
|
||||
|
||||
@@ -16,7 +16,6 @@ public sealed class DeferredServiceLevelPublisher : IServiceLevelPublisher
|
||||
public void SetInner(IServiceLevelPublisher? inner) =>
|
||||
_inner = inner ?? NullServiceLevelPublisher.Instance;
|
||||
|
||||
/// <summary>Publishes a service level value to the inner publisher.</summary>
|
||||
/// <param name="serviceLevel">The service level to publish.</param>
|
||||
/// <inheritdoc />
|
||||
public void Publish(byte serviceLevel) => _inner.Publish(serviceLevel);
|
||||
}
|
||||
|
||||
@@ -23,7 +23,6 @@ public sealed class NullServiceLevelPublisher : IServiceLevelPublisher
|
||||
/// <summary>Gets the last published service level value.</summary>
|
||||
public byte LastPublished { get; private set; }
|
||||
|
||||
/// <summary>Records the service level value without publishing.</summary>
|
||||
/// <param name="serviceLevel">The service level value (0-255).</param>
|
||||
/// <inheritdoc />
|
||||
public void Publish(byte serviceLevel) => LastPublished = serviceLevel;
|
||||
}
|
||||
|
||||
@@ -3,15 +3,18 @@ namespace ZB.MOM.WW.OtOpcUa.Commons.Types;
|
||||
public readonly record struct CorrelationId(Guid Value)
|
||||
{
|
||||
/// <summary>Creates a new CorrelationId with a randomly generated GUID.</summary>
|
||||
/// <returns>A new, randomly generated <see cref="CorrelationId"/>.</returns>
|
||||
public static CorrelationId NewId() => new(Guid.NewGuid());
|
||||
/// <inheritdoc />
|
||||
public override string ToString() => Value.ToString("N");
|
||||
/// <summary>Parses a lowercase hex string without hyphens into a CorrelationId.</summary>
|
||||
/// <param name="s">The string to parse.</param>
|
||||
/// <returns>The parsed <see cref="CorrelationId"/>.</returns>
|
||||
public static CorrelationId Parse(string s) => new(Guid.ParseExact(s, "N"));
|
||||
/// <summary>Attempts to parse a lowercase hex string without hyphens into a CorrelationId.</summary>
|
||||
/// <param name="s">The string to parse, or null.</param>
|
||||
/// <param name="id">The resulting CorrelationId if parsing succeeds.</param>
|
||||
/// <returns><c>true</c> if <paramref name="s"/> was successfully parsed.</returns>
|
||||
public static bool TryParse(string? s, out CorrelationId id)
|
||||
{
|
||||
if (Guid.TryParseExact(s, "N", out var g)) { id = new CorrelationId(g); return true; }
|
||||
|
||||
@@ -41,6 +41,7 @@ public static class EquipmentScriptPaths
|
||||
|
||||
/// <summary>True when the source uses the <c>{{equip}}</c> token anywhere.</summary>
|
||||
/// <param name="source">The script source to scan.</param>
|
||||
/// <returns>True if <paramref name="source"/> contains the <c>{{equip}}</c> token; otherwise false.</returns>
|
||||
public static bool ContainsEquipToken(string? source) =>
|
||||
!string.IsNullOrEmpty(source) && source.Contains(EquipToken, StringComparison.Ordinal);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user