diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/Commands/AlarmsCommand.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/Commands/AlarmsCommand.cs
index a0a10f79..e2821984 100644
--- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/Commands/AlarmsCommand.cs
+++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/Commands/AlarmsCommand.cs
@@ -42,6 +42,7 @@ public class AlarmsCommand : CommandBase
/// Connects to the server, subscribes to alarm events, and streams operator-facing alarm state changes to the console.
///
/// The CLI console used for output and cancellation handling.
+ ///
public override async ValueTask ExecuteAsync(IConsole console)
{
ConfigureLogging();
diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/Commands/BrowseCommand.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/Commands/BrowseCommand.cs
index fda8c057..d4650e1d 100644
--- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/Commands/BrowseCommand.cs
+++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/Commands/BrowseCommand.cs
@@ -36,10 +36,7 @@ public class BrowseCommand : CommandBase
[CommandOption("recursive", 'r', Description = "Browse recursively (uses --depth as max depth)")]
public bool Recursive { get; init; }
- ///
- /// Connects to the server and prints a tree view of the requested address-space branch.
- ///
- /// The CLI console used for output and cancellation handling.
+ ///
public override async ValueTask ExecuteAsync(IConsole console)
{
ConfigureLogging();
diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/Commands/ConnectCommand.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/Commands/ConnectCommand.cs
index a246d798..72e2c33e 100644
--- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/Commands/ConnectCommand.cs
+++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/Commands/ConnectCommand.cs
@@ -15,10 +15,7 @@ public class ConnectCommand : CommandBase
{
}
- ///
- /// Connects to the server and prints the negotiated endpoint details for operator verification.
- ///
- /// The CLI console used for output and cancellation handling.
+ ///
public override async ValueTask ExecuteAsync(IConsole console)
{
ConfigureLogging();
diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/Commands/HistoryReadCommand.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/Commands/HistoryReadCommand.cs
index 61926bd7..8ea809c4 100644
--- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/Commands/HistoryReadCommand.cs
+++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/Commands/HistoryReadCommand.cs
@@ -56,10 +56,7 @@ public class HistoryReadCommand : CommandBase
[CommandOption("interval", Description = "Processing interval in milliseconds for aggregates")]
public double IntervalMs { get; init; } = 3600000;
- ///
- /// Connects to the server and prints raw or processed historical values for the requested node.
- ///
- /// The CLI console used for output and cancellation handling.
+ ///
public override async ValueTask ExecuteAsync(IConsole console)
{
ConfigureLogging();
diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/Commands/ReadCommand.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/Commands/ReadCommand.cs
index 68892786..a8a0ff93 100644
--- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/Commands/ReadCommand.cs
+++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/Commands/ReadCommand.cs
@@ -24,10 +24,7 @@ public class ReadCommand : CommandBase
[CommandOption("node", 'n', Description = "Node ID (e.g. ns=2;s=MyNode)", IsRequired = true)]
public string NodeId { get; init; } = default!;
- ///
- /// Connects to the server and prints the current value, status, and timestamps for the requested node.
- ///
- /// The CLI console used for output and cancellation handling.
+ ///
public override async ValueTask ExecuteAsync(IConsole console)
{
ConfigureLogging();
diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/Commands/RedundancyCommand.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/Commands/RedundancyCommand.cs
index fd01b336..3f1a3459 100644
--- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/Commands/RedundancyCommand.cs
+++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/Commands/RedundancyCommand.cs
@@ -15,10 +15,8 @@ public class RedundancyCommand : CommandBase
{
}
- ///
- /// Connects to the server and prints redundancy mode, service level, and partner-server identity data.
- ///
- /// The CLI console used for output and cancellation handling.
+ /// Connects to the server and prints redundancy mode, service level, and partner-server identity data.
+ ///
public override async ValueTask ExecuteAsync(IConsole console)
{
ConfigureLogging();
diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/Commands/SubscribeCommand.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/Commands/SubscribeCommand.cs
index 28cccd52..d8c202b3 100644
--- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/Commands/SubscribeCommand.cs
+++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/Commands/SubscribeCommand.cs
@@ -67,11 +67,7 @@ public class SubscribeCommand : CommandBase
[CommandOption("summary-file", Description = "Write summary to this file path on exit (in addition to stdout)")]
public string? SummaryFile { get; init; }
- ///
- /// Connects to the server, subscribes to (or its subtree when recursive),
- /// streams data-change notifications to the console, and prints a summary when the command exits.
- ///
- /// The CLI console used for output and cancellation handling.
+ ///
public override async ValueTask ExecuteAsync(IConsole console)
{
ConfigureLogging();
diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/Commands/WriteCommand.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/Commands/WriteCommand.cs
index d92fa2df..f31a3a34 100644
--- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/Commands/WriteCommand.cs
+++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/Commands/WriteCommand.cs
@@ -35,6 +35,7 @@ public class WriteCommand : CommandBase
/// Connects to the server, converts the supplied value to the node's current data type, and issues the write.
///
/// The CLI console used for output and cancellation handling.
+ ///
public override async ValueTask ExecuteAsync(IConsole console)
{
ConfigureLogging();
diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Adapters/DefaultApplicationConfigurationFactory.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Adapters/DefaultApplicationConfigurationFactory.cs
index 36b5edff..18e683a7 100644
--- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Adapters/DefaultApplicationConfigurationFactory.cs
+++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Adapters/DefaultApplicationConfigurationFactory.cs
@@ -12,6 +12,9 @@ internal sealed class DefaultApplicationConfigurationFactory : IApplicationConfi
{
private static readonly ILogger Logger = Log.ForContext();
+ /// Creates an OPC UA application configuration from the provided connection settings.
+ /// The connection settings to use.
+ /// Token to cancel the operation.
public async Task CreateAsync(ConnectionSettings settings, CancellationToken ct)
{
// Resolve the canonical PKI path lazily on first use so constructing a
diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Adapters/DefaultEndpointDiscovery.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Adapters/DefaultEndpointDiscovery.cs
index bcf1997e..a8719460 100644
--- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Adapters/DefaultEndpointDiscovery.cs
+++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Adapters/DefaultEndpointDiscovery.cs
@@ -11,6 +11,10 @@ internal sealed class DefaultEndpointDiscovery : IEndpointDiscovery
{
private static readonly ILogger Logger = Log.ForContext();
+ /// Selects an OPC UA endpoint matching the requested security mode.
+ /// The application configuration.
+ /// The endpoint URL to query.
+ /// The requested message security mode.
public EndpointDescription SelectEndpoint(ApplicationConfiguration config, string endpointUrl,
MessageSecurityMode requestedMode)
{
diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Adapters/DefaultSessionFactory.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Adapters/DefaultSessionFactory.cs
index ecb81dad..4f44bd30 100644
--- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Adapters/DefaultSessionFactory.cs
+++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Adapters/DefaultSessionFactory.cs
@@ -11,6 +11,14 @@ internal sealed class DefaultSessionFactory : ISessionFactory
{
private static readonly ILogger Logger = Log.ForContext();
+ /// Creates a new OPC UA session.
+ /// The OPC UA application configuration.
+ /// The endpoint description to connect to.
+ /// The name for the session.
+ /// The session timeout in milliseconds.
+ /// The user identity for the session.
+ /// The cancellation token.
+ /// An adapter wrapping the created session.
public async Task CreateSessionAsync(
ApplicationConfiguration config,
EndpointDescription endpoint,
diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Adapters/IApplicationConfigurationFactory.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Adapters/IApplicationConfigurationFactory.cs
index b076bf59..29d8ae30 100644
--- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Adapters/IApplicationConfigurationFactory.cs
+++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Adapters/IApplicationConfigurationFactory.cs
@@ -11,5 +11,7 @@ internal interface IApplicationConfigurationFactory
///
/// Creates a validated ApplicationConfiguration for the given connection settings.
///
+ /// The connection settings to configure.
+ /// Cancellation token for the operation.
Task CreateAsync(ConnectionSettings settings, CancellationToken ct = default);
}
\ No newline at end of file
diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Adapters/IEndpointDiscovery.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Adapters/IEndpointDiscovery.cs
index bd881fd1..4f802729 100644
--- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Adapters/IEndpointDiscovery.cs
+++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Adapters/IEndpointDiscovery.cs
@@ -11,6 +11,9 @@ internal interface IEndpointDiscovery
/// Discovers endpoints at the given URL and returns the best match for the requested security mode.
/// Also rewrites the endpoint URL hostname to match the requested URL when they differ.
///
+ /// The OPC UA application configuration.
+ /// The endpoint URL to discover.
+ /// The requested message security mode.
EndpointDescription SelectEndpoint(ApplicationConfiguration config, string endpointUrl,
MessageSecurityMode requestedMode);
}
\ No newline at end of file
diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Helpers/AggregateTypeMapper.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Helpers/AggregateTypeMapper.cs
index 08fdee57..ab672344 100644
--- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Helpers/AggregateTypeMapper.cs
+++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Helpers/AggregateTypeMapper.cs
@@ -11,6 +11,8 @@ public static class AggregateTypeMapper
///
/// Returns the OPC UA NodeId for the specified aggregate type.
///
+ /// The aggregate type to map to a NodeId.
+ /// The OPC UA NodeId for the aggregate function.
public static NodeId ToNodeId(AggregateType aggregate)
{
return aggregate switch
diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Helpers/SecurityModeMapper.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Helpers/SecurityModeMapper.cs
index 1922cb86..d4adb6d6 100644
--- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Helpers/SecurityModeMapper.cs
+++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Helpers/SecurityModeMapper.cs
@@ -8,9 +8,9 @@ namespace ZB.MOM.WW.OtOpcUa.Client.Shared.Helpers;
///
public static class SecurityModeMapper
{
- ///
- /// Converts a to an OPC UA .
- ///
+ /// Converts a SecurityMode to an OPC UA MessageSecurityMode.
+ /// The security mode to convert.
+ /// The corresponding message security mode.
public static MessageSecurityMode ToMessageSecurityMode(SecurityMode mode)
{
return mode switch
diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/IOpcUaClientServiceFactory.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/IOpcUaClientServiceFactory.cs
index 72241959..f80aaaf4 100644
--- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/IOpcUaClientServiceFactory.cs
+++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/IOpcUaClientServiceFactory.cs
@@ -5,5 +5,7 @@ namespace ZB.MOM.WW.OtOpcUa.Client.Shared;
///
public interface IOpcUaClientServiceFactory
{
+ /// Creates a new OPC UA client service instance.
+ /// A new instance.
IOpcUaClientService Create();
}
\ No newline at end of file
diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Models/AlarmEventArgs.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Models/AlarmEventArgs.cs
index 069fa89d..b47e0426 100644
--- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Models/AlarmEventArgs.cs
+++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Models/AlarmEventArgs.cs
@@ -5,6 +5,20 @@ namespace ZB.MOM.WW.OtOpcUa.Client.Shared.Models;
///
public sealed class AlarmEventArgs : EventArgs
{
+ /// Initializes a new instance of the class.
+ /// The name of the source object that raised the alarm.
+ /// The condition type name.
+ /// The alarm severity (0-1000).
+ /// Human-readable alarm message.
+ /// Whether the alarm should be retained in the display.
+ /// Whether the alarm condition is currently active.
+ /// Whether the alarm has been acknowledged.
+ /// The time the event occurred.
+ /// The EventId used for alarm acknowledgment.
+ /// The NodeId of the condition instance.
+ /// Operator-supplied comment on acknowledgment transitions.
+ /// When the alarm originally entered the active state.
+ /// Upstream alarm taxonomy bucket (e.g. Process, Safety, Diagnostics).
public AlarmEventArgs(
string sourceName,
string conditionName,
diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Models/BrowseResult.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Models/BrowseResult.cs
index a8191e37..4e3658f8 100644
--- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Models/BrowseResult.cs
+++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Models/BrowseResult.cs
@@ -5,6 +5,11 @@ namespace ZB.MOM.WW.OtOpcUa.Client.Shared.Models;
///
public sealed class BrowseResult
{
+ /// Initializes a new instance of the BrowseResult class.
+ /// The string representation of the node's NodeId.
+ /// The display name of the node.
+ /// The node class (e.g., "Object", "Variable", "Method").
+ /// Whether the node has child references.
public BrowseResult(string nodeId, string displayName, string nodeClass, bool hasChildren)
{
NodeId = nodeId;
diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Models/ConnectionInfo.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Models/ConnectionInfo.cs
index 39bc0f49..1bf96318 100644
--- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Models/ConnectionInfo.cs
+++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Models/ConnectionInfo.cs
@@ -5,6 +5,13 @@ namespace ZB.MOM.WW.OtOpcUa.Client.Shared.Models;
///
public sealed class ConnectionInfo
{
+ /// Initializes a new instance of the ConnectionInfo with session details.
+ /// The endpoint URL of the connected server.
+ /// The server application name.
+ /// The security mode in use.
+ /// The security policy URI.
+ /// The session identifier.
+ /// The session name.
public ConnectionInfo(
string endpointUrl,
string serverName,
diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Models/ConnectionStateChangedEventArgs.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Models/ConnectionStateChangedEventArgs.cs
index 5949073e..449ae2a2 100644
--- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Models/ConnectionStateChangedEventArgs.cs
+++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Models/ConnectionStateChangedEventArgs.cs
@@ -5,6 +5,10 @@ namespace ZB.MOM.WW.OtOpcUa.Client.Shared.Models;
///
public sealed class ConnectionStateChangedEventArgs : EventArgs
{
+ /// Initializes a new instance of the ConnectionStateChangedEventArgs class.
+ /// The previous connection state.
+ /// The new connection state.
+ /// The endpoint URL associated with the state change.
public ConnectionStateChangedEventArgs(ConnectionState oldState, ConnectionState newState, string endpointUrl)
{
OldState = oldState;
diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Models/DataChangedEventArgs.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Models/DataChangedEventArgs.cs
index 30660495..719a92ff 100644
--- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Models/DataChangedEventArgs.cs
+++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Models/DataChangedEventArgs.cs
@@ -7,6 +7,9 @@ namespace ZB.MOM.WW.OtOpcUa.Client.Shared.Models;
///
public sealed class DataChangedEventArgs : EventArgs
{
+ /// Initializes a new instance of the DataChangedEventArgs class.
+ /// The node ID that changed.
+ /// The new data value.
public DataChangedEventArgs(string nodeId, DataValue value)
{
NodeId = nodeId;
diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Models/RedundancyInfo.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Models/RedundancyInfo.cs
index 1a376235..c6c3a339 100644
--- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Models/RedundancyInfo.cs
+++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/Models/RedundancyInfo.cs
@@ -5,6 +5,11 @@ namespace ZB.MOM.WW.OtOpcUa.Client.Shared.Models;
///
public sealed class RedundancyInfo
{
+ /// Initializes a new instance of the RedundancyInfo class.
+ /// The redundancy mode (e.g., "None", "Cold", "Warm", "Hot").
+ /// The server's current service level (0-255).
+ /// URIs of all servers in the redundant set.
+ /// The application URI of the connected server.
public RedundancyInfo(string mode, byte serviceLevel, string[] serverUris, string applicationUri)
{
Mode = mode;
diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/OpcUaClientServiceFactory.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/OpcUaClientServiceFactory.cs
index fee69237..e5107664 100644
--- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/OpcUaClientServiceFactory.cs
+++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/OpcUaClientServiceFactory.cs
@@ -5,6 +5,8 @@ namespace ZB.MOM.WW.OtOpcUa.Client.Shared;
///
public sealed class OpcUaClientServiceFactory : IOpcUaClientServiceFactory
{
+ /// Creates a new OPC UA client service instance with production adapters.
+ /// A new OpcUaClientService instance.
public IOpcUaClientService Create()
{
return new OpcUaClientService();
diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/App.axaml.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/App.axaml.cs
index 979be387..43d2bb87 100644
--- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/App.axaml.cs
+++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/App.axaml.cs
@@ -10,11 +10,13 @@ namespace ZB.MOM.WW.OtOpcUa.Client.UI;
public class App : Application
{
+ ///
public override void Initialize()
{
AvaloniaXamlLoader.Load(this);
}
+ ///
public override void OnFrameworkInitializationCompleted()
{
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Controls/DateTimeRangePicker.axaml.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Controls/DateTimeRangePicker.axaml.cs
index 39a2473b..89ef445b 100644
--- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Controls/DateTimeRangePicker.axaml.cs
+++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Controls/DateTimeRangePicker.axaml.cs
@@ -32,35 +32,41 @@ public partial class DateTimeRangePicker : UserControl
private bool _isUpdating;
+ /// Initializes a new instance of the class.
public DateTimeRangePicker()
{
InitializeComponent();
}
+ /// Gets or sets the start date and time.
public DateTimeOffset? StartDateTime
{
get => GetValue(StartDateTimeProperty);
set => SetValue(StartDateTimeProperty, value);
}
+ /// Gets or sets the end date and time.
public DateTimeOffset? EndDateTime
{
get => GetValue(EndDateTimeProperty);
set => SetValue(EndDateTimeProperty, value);
}
+ /// Gets or sets the start date/time as formatted text.
public string StartText
{
get => GetValue(StartTextProperty);
set => SetValue(StartTextProperty, value);
}
+ /// Gets or sets the end date/time as formatted text.
public string EndText
{
get => GetValue(EndTextProperty);
set => SetValue(EndTextProperty, value);
}
+ ///
protected override void OnLoaded(RoutedEventArgs e)
{
base.OnLoaded(e);
@@ -82,6 +88,7 @@ public partial class DateTimeRangePicker : UserControl
if (lastWeek != null) lastWeek.Click += (_, _) => ApplyPreset(TimeSpan.FromDays(7));
}
+ ///
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
{
base.OnPropertyChanged(change);
diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Helpers/StatusCodeFormatter.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Helpers/StatusCodeFormatter.cs
index 7aaf524d..2a43d215 100644
--- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Helpers/StatusCodeFormatter.cs
+++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Helpers/StatusCodeFormatter.cs
@@ -7,6 +7,9 @@ namespace ZB.MOM.WW.OtOpcUa.Client.UI.Helpers;
///
internal static class StatusCodeFormatter
{
+ /// Formats an OPC UA status code as a hexadecimal code with description.
+ /// The OPC UA status code to format.
+ /// A formatted string in the form "0xHEX (description)".
public static string Format(StatusCode statusCode)
{
var code = statusCode.Code;
diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Helpers/ValueFormatter.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Helpers/ValueFormatter.cs
index 07343a6d..9956d027 100644
--- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Helpers/ValueFormatter.cs
+++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Helpers/ValueFormatter.cs
@@ -7,6 +7,9 @@ namespace ZB.MOM.WW.OtOpcUa.Client.UI.Helpers;
///
internal static class ValueFormatter
{
+ /// Formats an OPC UA value for display, handling arrays and enumerables specially.
+ /// The value to format, or null.
+ /// A string representation of the value suitable for display.
public static string Format(object? value)
{
if (value is null) return "(null)";
diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Program.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Program.cs
index 6013f980..506d0d44 100644
--- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Program.cs
+++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Program.cs
@@ -4,8 +4,11 @@ using ZB.MOM.WW.OtOpcUa.Client.Shared;
namespace ZB.MOM.WW.OtOpcUa.Client.UI;
+/// Entry point for the OPC UA client UI application.
public class Program
{
+ /// Main entry point for the application.
+ /// Command-line arguments passed to the application.
[STAThread]
public static void Main(string[] args)
{
@@ -21,6 +24,8 @@ public class Program
}
}
+ /// Builds the Avalonia AppBuilder with platform-specific configuration.
+ /// Configured AppBuilder for desktop lifetime.
public static AppBuilder BuildAvaloniaApp()
{
return AppBuilder.Configure()
diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Services/AvaloniaUiDispatcher.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Services/AvaloniaUiDispatcher.cs
index 30b81729..13275830 100644
--- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Services/AvaloniaUiDispatcher.cs
+++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Services/AvaloniaUiDispatcher.cs
@@ -7,6 +7,8 @@ namespace ZB.MOM.WW.OtOpcUa.Client.UI.Services;
///
public sealed class AvaloniaUiDispatcher : IUiDispatcher
{
+ /// Posts an action to the Avalonia UI thread for execution.
+ /// The action to execute on the UI thread.
public void Post(Action action)
{
Dispatcher.UIThread.Post(action);
diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Services/ISettingsService.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Services/ISettingsService.cs
index 20563651..f95c56c0 100644
--- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Services/ISettingsService.cs
+++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Services/ISettingsService.cs
@@ -5,6 +5,9 @@ namespace ZB.MOM.WW.OtOpcUa.Client.UI.Services;
///
public interface ISettingsService
{
+ /// Loads user settings from persistent storage.
UserSettings Load();
+ /// Saves user settings to persistent storage.
+ /// The settings to save.
void Save(UserSettings settings);
}
diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Services/IUiDispatcher.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Services/IUiDispatcher.cs
index 46d0dc5c..a22c3087 100644
--- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Services/IUiDispatcher.cs
+++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Services/IUiDispatcher.cs
@@ -8,5 +8,6 @@ public interface IUiDispatcher
///
/// Posts an action to be executed on the UI thread.
///
+ /// The action to execute on the UI thread.
void Post(Action action);
}
\ No newline at end of file
diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Services/JsonSettingsService.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Services/JsonSettingsService.cs
index d2b418a9..2f793cad 100644
--- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Services/JsonSettingsService.cs
+++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Services/JsonSettingsService.cs
@@ -19,6 +19,8 @@ public sealed class JsonSettingsService : ISettingsService
WriteIndented = true
};
+ /// Loads user settings from the settings file.
+ /// The loaded user settings, or a new default instance if load fails.
public UserSettings Load()
{
try
@@ -35,6 +37,8 @@ public sealed class JsonSettingsService : ISettingsService
}
}
+ /// Saves user settings to the settings file.
+ /// The user settings to save.
public void Save(UserSettings settings)
{
try
diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Services/SynchronousUiDispatcher.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Services/SynchronousUiDispatcher.cs
index 46772cec..06c5f6bc 100644
--- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Services/SynchronousUiDispatcher.cs
+++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Services/SynchronousUiDispatcher.cs
@@ -6,6 +6,8 @@ namespace ZB.MOM.WW.OtOpcUa.Client.UI.Services;
///
public sealed class SynchronousUiDispatcher : IUiDispatcher
{
+ /// Executes the action synchronously on the calling thread.
+ /// The action to execute.
public void Post(Action action)
{
action();
diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/ViewModels/AlarmsViewModel.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/ViewModels/AlarmsViewModel.cs
index db20fadf..f7033901 100644
--- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/ViewModels/AlarmsViewModel.cs
+++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/ViewModels/AlarmsViewModel.cs
@@ -44,6 +44,9 @@ public partial class AlarmsViewModel : ObservableObject
[ObservableProperty] private int _activeAlarmCount;
+ /// Initializes a new instance of the AlarmsViewModel class.
+ /// The OPC UA client service.
+ /// The UI dispatcher for thread-safe operations.
public AlarmsViewModel(IOpcUaClientService service, IUiDispatcher dispatcher)
{
_service = service;
@@ -168,6 +171,9 @@ public partial class AlarmsViewModel : ObservableObject
///
/// Acknowledges an alarm and returns (success, message).
///
+ /// The alarm event to acknowledge.
+ /// Optional comment for the acknowledgment.
+ /// A tuple with success flag and message.
public async Task<(bool Success, string Message)> AcknowledgeAlarmAsync(AlarmEventViewModel alarm, string comment)
{
if (!IsConnected || alarm.EventId == null || alarm.ConditionNodeId == null)
@@ -197,6 +203,8 @@ public partial class AlarmsViewModel : ObservableObject
///
/// Restores an alarm subscription and requests a condition refresh.
///
+ /// The source node ID to restore the subscription for.
+ /// A task that completes when the restore operation finishes.
public async Task RestoreAlarmSubscriptionAsync(string? sourceNodeId)
{
if (!IsConnected || string.IsNullOrWhiteSpace(sourceNodeId)) return;
diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/ViewModels/BrowseTreeViewModel.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/ViewModels/BrowseTreeViewModel.cs
index f19281ec..6ca20cbf 100644
--- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/ViewModels/BrowseTreeViewModel.cs
+++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/ViewModels/BrowseTreeViewModel.cs
@@ -13,6 +13,11 @@ public class BrowseTreeViewModel : ObservableObject
private readonly IUiDispatcher _dispatcher;
private readonly IOpcUaClientService _service;
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The OPC UA client service.
+ /// The UI dispatcher for marshaling updates.
public BrowseTreeViewModel(IOpcUaClientService service, IUiDispatcher dispatcher)
{
_service = service;
diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/ViewModels/HistoryValueViewModel.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/ViewModels/HistoryValueViewModel.cs
index a128ae21..04abe5a7 100644
--- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/ViewModels/HistoryValueViewModel.cs
+++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/ViewModels/HistoryValueViewModel.cs
@@ -7,6 +7,11 @@ namespace ZB.MOM.WW.OtOpcUa.Client.UI.ViewModels;
///
public class HistoryValueViewModel : ObservableObject
{
+ /// Initializes a new instance of the class.
+ /// The historical value.
+ /// The status code or text.
+ /// The source timestamp in string format.
+ /// The server timestamp in string format.
public HistoryValueViewModel(string value, string status, string sourceTimestamp, string serverTimestamp)
{
Value = value;
@@ -15,8 +20,12 @@ public class HistoryValueViewModel : ObservableObject
ServerTimestamp = serverTimestamp;
}
+ /// Gets the historical value.
public string Value { get; }
+ /// Gets the status code or text.
public string Status { get; }
+ /// Gets the source timestamp in string format.
public string SourceTimestamp { get; }
+ /// Gets the server timestamp in string format.
public string ServerTimestamp { get; }
}
\ No newline at end of file
diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/ViewModels/HistoryViewModel.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/ViewModels/HistoryViewModel.cs
index d828dfa3..dbc82b1c 100644
--- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/ViewModels/HistoryViewModel.cs
+++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/ViewModels/HistoryViewModel.cs
@@ -34,6 +34,9 @@ public partial class HistoryViewModel : ObservableObject
[ObservableProperty] private DateTimeOffset? _startTime = DateTimeOffset.UtcNow.AddHours(-1);
+ /// Initializes a new instance of the HistoryViewModel.
+ /// The OPC UA client service.
+ /// The UI dispatcher for thread marshalling.
public HistoryViewModel(IOpcUaClientService service, IUiDispatcher dispatcher)
{
_service = service;
@@ -53,6 +56,7 @@ public partial class HistoryViewModel : ObservableObject
AggregateType.StandardDeviation
];
+ /// Gets a value indicating whether an aggregate read is selected.
public bool IsAggregateRead => SelectedAggregateType != null;
/// History read results.
diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/ViewModels/ReadWriteViewModel.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/ViewModels/ReadWriteViewModel.cs
index 6d94913e..cbad31d0 100644
--- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/ViewModels/ReadWriteViewModel.cs
+++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/ViewModels/ReadWriteViewModel.cs
@@ -36,12 +36,16 @@ public partial class ReadWriteViewModel : ObservableObject
[ObservableProperty] private string? _writeValue;
+ /// Initializes a new instance of the ReadWriteViewModel class.
+ /// The OPC UA client service for read/write operations.
+ /// The UI dispatcher for posting updates to the UI thread.
public ReadWriteViewModel(IOpcUaClientService service, IUiDispatcher dispatcher)
{
_service = service;
_dispatcher = dispatcher;
}
+ /// Gets a value indicating whether a node is currently selected.
public bool IsNodeSelected => !string.IsNullOrEmpty(SelectedNodeId);
partial void OnSelectedNodeIdChanged(string? value)
diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/ViewModels/SubscriptionItemViewModel.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/ViewModels/SubscriptionItemViewModel.cs
index c14c7bd3..f8af20dc 100644
--- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/ViewModels/SubscriptionItemViewModel.cs
+++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/ViewModels/SubscriptionItemViewModel.cs
@@ -13,6 +13,9 @@ public partial class SubscriptionItemViewModel : ObservableObject
[ObservableProperty] private string? _value;
+ /// Initializes a new subscription item with the specified node ID and interval.
+ /// The OPC UA NodeId to subscribe to.
+ /// The subscription interval in milliseconds.
public SubscriptionItemViewModel(string nodeId, int intervalMs)
{
NodeId = nodeId;
diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/ViewModels/TreeNodeViewModel.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/ViewModels/TreeNodeViewModel.cs
index 492b7c6a..7e7cefd2 100644
--- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/ViewModels/TreeNodeViewModel.cs
+++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/ViewModels/TreeNodeViewModel.cs
@@ -31,6 +31,13 @@ public partial class TreeNodeViewModel : ObservableObject
HasChildren = false;
}
+ /// Initializes a new tree node view model.
+ /// The OPC UA node identifier.
+ /// The display name for this node.
+ /// The OPC UA node class.
+ /// Whether this node has child nodes.
+ /// The OPC UA client service for browsing.
+ /// The UI dispatcher for thread-safe updates.
public TreeNodeViewModel(
string nodeId,
string displayName,
diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/AckAlarmWindow.axaml.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/AckAlarmWindow.axaml.cs
index 79f69a3c..0ea27bbe 100644
--- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/AckAlarmWindow.axaml.cs
+++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/AckAlarmWindow.axaml.cs
@@ -10,6 +10,7 @@ public partial class AckAlarmWindow : Window
private readonly AlarmsViewModel _alarmsVm;
private readonly AlarmEventViewModel _alarm;
+ /// Initializes a new instance of the AckAlarmWindow class for XAML designer support.
public AckAlarmWindow()
{
InitializeComponent();
@@ -17,6 +18,9 @@ public partial class AckAlarmWindow : Window
_alarm = null!;
}
+ /// Initializes a new instance of the AckAlarmWindow class with alarm context.
+ /// The alarms view model.
+ /// The alarm event to acknowledge.
public AckAlarmWindow(AlarmsViewModel alarmsVm, AlarmEventViewModel alarm)
{
InitializeComponent();
diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/AlarmsView.axaml.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/AlarmsView.axaml.cs
index 4fc6b51f..10d902c2 100644
--- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/AlarmsView.axaml.cs
+++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/AlarmsView.axaml.cs
@@ -16,11 +16,13 @@ public partial class AlarmsView : UserControl
private static readonly IBrush HighBrush = new SolidColorBrush(Color.Parse("#FEE2E2")); // light red (666-899)
private static readonly IBrush CriticalBrush = new SolidColorBrush(Color.Parse("#FECACA")); // red (900-1000)
+ /// Initializes a new instance of the class.
public AlarmsView()
{
InitializeComponent();
}
+ ///
protected override void OnLoaded(RoutedEventArgs e)
{
base.OnLoaded(e);
diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/BrowseTreeView.axaml.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/BrowseTreeView.axaml.cs
index 5432f962..6a365047 100644
--- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/BrowseTreeView.axaml.cs
+++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/BrowseTreeView.axaml.cs
@@ -4,6 +4,7 @@ namespace ZB.MOM.WW.OtOpcUa.Client.UI.Views;
public partial class BrowseTreeView : UserControl
{
+ /// Initializes a new instance of the BrowseTreeView.
public BrowseTreeView()
{
InitializeComponent();
diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/HistoryView.axaml.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/HistoryView.axaml.cs
index ebe3d59c..f20beae3 100644
--- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/HistoryView.axaml.cs
+++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/HistoryView.axaml.cs
@@ -4,6 +4,7 @@ namespace ZB.MOM.WW.OtOpcUa.Client.UI.Views;
public partial class HistoryView : UserControl
{
+ /// Initializes a new instance of the HistoryView control.
public HistoryView()
{
InitializeComponent();
diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/MainWindow.axaml.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/MainWindow.axaml.cs
index 57516d2e..02da7bde 100644
--- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/MainWindow.axaml.cs
+++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/MainWindow.axaml.cs
@@ -11,6 +11,7 @@ namespace ZB.MOM.WW.OtOpcUa.Client.UI.Views;
public partial class MainWindow : Window
{
+ /// Initializes a new instance of the MainWindow, loading the application icon.
public MainWindow()
{
InitializeComponent();
@@ -51,6 +52,7 @@ public partial class MainWindow : Window
}
}
+ ///
protected override void OnLoaded(RoutedEventArgs e)
{
base.OnLoaded(e);
@@ -157,6 +159,7 @@ public partial class MainWindow : Window
vm.CertificateStorePath = picked;
}
+ ///
protected override void OnClosing(WindowClosingEventArgs e)
{
if (DataContext is MainWindowViewModel vm)
diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/ReadWriteView.axaml.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/ReadWriteView.axaml.cs
index 4f4326dd..7edbaa72 100644
--- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/ReadWriteView.axaml.cs
+++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/ReadWriteView.axaml.cs
@@ -4,6 +4,7 @@ namespace ZB.MOM.WW.OtOpcUa.Client.UI.Views;
public partial class ReadWriteView : UserControl
{
+ /// Initializes a new instance of the ReadWriteView class.
public ReadWriteView()
{
InitializeComponent();
diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/SubscriptionsView.axaml.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/SubscriptionsView.axaml.cs
index 9dd248c7..d71aa06c 100644
--- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/SubscriptionsView.axaml.cs
+++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/SubscriptionsView.axaml.cs
@@ -8,11 +8,13 @@ namespace ZB.MOM.WW.OtOpcUa.Client.UI.Views;
public partial class SubscriptionsView : UserControl
{
+ /// Initializes a new instance of the class.
public SubscriptionsView()
{
InitializeComponent();
}
+ ///
protected override void OnLoaded(RoutedEventArgs e)
{
base.OnLoaded(e);
diff --git a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/WriteValueWindow.axaml.cs b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/WriteValueWindow.axaml.cs
index 8d629b98..d0d5ee3d 100644
--- a/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/WriteValueWindow.axaml.cs
+++ b/src/Client/ZB.MOM.WW.OtOpcUa.Client.UI/Views/WriteValueWindow.axaml.cs
@@ -10,6 +10,7 @@ public partial class WriteValueWindow : Window
private readonly SubscriptionsViewModel _subscriptionsVm;
private readonly string _nodeId;
+ /// Initializes a default instance of the WriteValueWindow for XAML designer support.
public WriteValueWindow()
{
InitializeComponent();
@@ -17,6 +18,10 @@ public partial class WriteValueWindow : Window
_nodeId = string.Empty;
}
+ /// Initializes a WriteValueWindow with the node to write and its current value.
+ /// The subscriptions view model for write operations.
+ /// The OPC UA node ID to write to.
+ /// The current value of the node, or null if unknown.
public WriteValueWindow(SubscriptionsViewModel subscriptionsVm, string nodeId, string? currentValue)
{
InitializeComponent();
diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Cluster/AkkaClusterOptions.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Cluster/AkkaClusterOptions.cs
index 89a7cc7b..9e46b0fa 100644
--- a/src/Core/ZB.MOM.WW.OtOpcUa.Cluster/AkkaClusterOptions.cs
+++ b/src/Core/ZB.MOM.WW.OtOpcUa.Cluster/AkkaClusterOptions.cs
@@ -4,8 +4,13 @@ public sealed class AkkaClusterOptions
{
public const string SectionName = "Cluster";
+ /// Gets or sets the Akka system name.
public string SystemName { get; set; } = "otopcua";
+
+ /// Gets or sets the hostname to bind to (default 0.0.0.0).
public string Hostname { get; set; } = "0.0.0.0";
+
+ /// Gets or sets the port to listen on (default 4053).
public int Port { get; set; } = 4053;
///
@@ -15,6 +20,7 @@ public sealed class AkkaClusterOptions
///
public string PublicHostname { get; set; } = "127.0.0.1";
+ /// Gets or sets the seed nodes for cluster bootstrapping.
public string[] SeedNodes { get; set; } = Array.Empty();
///
diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Cluster/ClusterRoleInfo.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Cluster/ClusterRoleInfo.cs
index ef1a1455..512be105 100644
--- a/src/Core/ZB.MOM.WW.OtOpcUa.Cluster/ClusterRoleInfo.cs
+++ b/src/Core/ZB.MOM.WW.OtOpcUa.Cluster/ClusterRoleInfo.cs
@@ -25,6 +25,10 @@ public sealed class ClusterRoleInfo : IClusterRoleInfo, IDisposable
private readonly Dictionary> _membersByRole = new(StringComparer.Ordinal);
private IActorRef? _subscriber;
+ /// Initializes a new instance of the ClusterRoleInfo class.
+ /// The Akka actor system.
+ /// The cluster configuration options.
+ /// The logger instance.
public ClusterRoleInfo(ActorSystem system, IOptions options, ILogger logger)
{
_cluster = Akka.Cluster.Cluster.Get(system);
@@ -39,12 +43,20 @@ public sealed class ClusterRoleInfo : IClusterRoleInfo, IDisposable
_subscriber = system.ActorOf(Props.Create(() => new SubscriberActor(this)), "clusterroleinfo-subscriber");
}
+ /// Gets the local cluster node identifier.
public CommonsNodeId LocalNode => _localNode;
+ /// Gets the set of roles assigned to the local node.
public IReadOnlySet LocalRoles => _localRoles;
+ /// Checks if the local node has a specific role.
+ /// The role name to check.
+ /// True if the local node has the specified role; otherwise false.
public bool HasRole(string role) => _localRoles.Contains(role);
+ /// Gets all cluster members that have a specific role.
+ /// The role name.
+ /// A read-only list of node IDs with the specified role.
public IReadOnlyList MembersWithRole(string role)
{
lock (_lock)
@@ -56,6 +68,9 @@ public sealed class ClusterRoleInfo : IClusterRoleInfo, IDisposable
}
}
+ /// Gets the current leader node for a specific role.
+ /// The role name.
+ /// The node ID of the current role leader, or null if no leader is elected.
public CommonsNodeId? RoleLeader(string role)
{
lock (_lock)
@@ -66,6 +81,7 @@ public sealed class ClusterRoleInfo : IClusterRoleInfo, IDisposable
}
}
+ /// Occurs when the leader for a role changes.
public event EventHandler? RoleLeaderChanged;
private void SeedFromCurrentState()
@@ -91,6 +107,8 @@ public sealed class ClusterRoleInfo : IClusterRoleInfo, IDisposable
}
}
+ /// Handles a cluster member event (member up/removed).
+ /// The member event from the cluster.
internal void HandleMemberEvent(ClusterEvent.IMemberEvent evt)
{
lock (_lock)
@@ -114,6 +132,8 @@ public sealed class ClusterRoleInfo : IClusterRoleInfo, IDisposable
}
}
+ /// Handles a role leader change event.
+ /// The role leader changed event from the cluster.
internal void HandleRoleLeaderChanged(ClusterEvent.RoleLeaderChanged evt)
{
CommonsNodeId? previous = null;
@@ -156,6 +176,7 @@ public sealed class ClusterRoleInfo : IClusterRoleInfo, IDisposable
private static CommonsNodeId ToNodeId(Akka.Actor.Address address) =>
CommonsNodeId.Parse($"{address.Host ?? string.Empty}:{address.Port ?? 0}");
+ /// Disposes the ClusterRoleInfo and stops the subscriber actor.
public void Dispose()
{
_subscriber?.Tell(PoisonPill.Instance);
@@ -164,6 +185,8 @@ public sealed class ClusterRoleInfo : IClusterRoleInfo, IDisposable
private sealed class SubscriberActor : ReceiveActor
{
+ /// Initializes a new instance of the SubscriberActor class.
+ /// The ClusterRoleInfo instance to forward events to.
public SubscriberActor(ClusterRoleInfo owner)
{
Receive(e => owner.HandleMemberEvent(e));
@@ -172,6 +195,7 @@ public sealed class ClusterRoleInfo : IClusterRoleInfo, IDisposable
Receive(_ => { /* seeded from initial snapshot */ });
}
+ ///
protected override void PreStart()
{
Akka.Cluster.Cluster.Get(Context.System).Subscribe(
@@ -182,6 +206,7 @@ public sealed class ClusterRoleInfo : IClusterRoleInfo, IDisposable
typeof(ClusterEvent.RoleLeaderChanged));
}
+ ///
protected override void PostStop() =>
Akka.Cluster.Cluster.Get(Context.System).Unsubscribe(Self);
}
diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Cluster/HoconLoader.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Cluster/HoconLoader.cs
index 23f1b00c..d3448416 100644
--- a/src/Core/ZB.MOM.WW.OtOpcUa.Cluster/HoconLoader.cs
+++ b/src/Core/ZB.MOM.WW.OtOpcUa.Cluster/HoconLoader.cs
@@ -1,9 +1,12 @@
namespace ZB.MOM.WW.OtOpcUa.Cluster;
+/// Loads embedded HOCON configuration resources.
public static class HoconLoader
{
private const string ResourceName = "ZB.MOM.WW.OtOpcUa.Cluster.Resources.akka.conf";
+ /// Loads the base Akka configuration from embedded resources.
+ /// The loaded HOCON configuration as a string.
public static string LoadBaseConfig()
{
using var stream = typeof(HoconLoader).Assembly.GetManifestResourceStream(ResourceName)
diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Cluster/RoleParser.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Cluster/RoleParser.cs
index c233a19c..a2de2290 100644
--- a/src/Core/ZB.MOM.WW.OtOpcUa.Cluster/RoleParser.cs
+++ b/src/Core/ZB.MOM.WW.OtOpcUa.Cluster/RoleParser.cs
@@ -7,6 +7,8 @@ public static class RoleParser
"admin", "driver", "dev",
};
+ /// Parses a comma-separated string of role names into a validated array.
+ /// The raw role string to parse.
public static string[] Parse(string? raw)
{
if (string.IsNullOrWhiteSpace(raw)) return Array.Empty();
diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Cluster/ServiceCollectionExtensions.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Cluster/ServiceCollectionExtensions.cs
index eb743d0b..e2bab992 100644
--- a/src/Core/ZB.MOM.WW.OtOpcUa.Cluster/ServiceCollectionExtensions.cs
+++ b/src/Core/ZB.MOM.WW.OtOpcUa.Cluster/ServiceCollectionExtensions.cs
@@ -16,6 +16,8 @@ public static class ServiceCollectionExtensions
/// configurator via — keeping the entire Akka graph
/// under Akka.Hosting's management so cluster singletons land on the same ActorSystem.
///
+ /// The service collection to configure.
+ /// The application configuration containing cluster options.
public static IServiceCollection AddOtOpcUaCluster(this IServiceCollection services, IConfiguration configuration)
{
services.AddOptions()
@@ -41,6 +43,8 @@ public static class ServiceCollectionExtensions
/// });
///
///
+ /// The Akka configuration builder to configure.
+ /// The service provider for resolving cluster options.
public static AkkaConfigurationBuilder WithOtOpcUaClusterBootstrap(
this AkkaConfigurationBuilder builder,
IServiceProvider serviceProvider)
diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Engines/IAlarmActorStateStore.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Engines/IAlarmActorStateStore.cs
index d84d3821..56b195a4 100644
--- a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Engines/IAlarmActorStateStore.cs
+++ b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Engines/IAlarmActorStateStore.cs
@@ -10,7 +10,14 @@ namespace ZB.MOM.WW.OtOpcUa.Commons.Engines;
///
public interface IAlarmActorStateStore
{
+ /// Loads the persisted state snapshot for an alarm actor.
+ /// The alarm identifier.
+ /// Cancellation token.
+ /// The alarm state snapshot if found; null if the alarm has no persisted state.
Task LoadAsync(string alarmId, CancellationToken ct);
+ /// Saves the alarm actor state snapshot.
+ /// The state snapshot to persist.
+ /// Cancellation token.
Task SaveAsync(AlarmActorStateSnapshot snapshot, CancellationToken ct);
}
@@ -34,8 +41,14 @@ public sealed class NullAlarmActorStateStore : IAlarmActorStateStore
{
public static readonly NullAlarmActorStateStore Instance = new();
private NullAlarmActorStateStore() { }
+ /// Always returns null, indicating no persisted state.
+ /// The alarm identifier (unused).
+ /// Cancellation token (unused).
public Task LoadAsync(string alarmId, CancellationToken ct) =>
Task.FromResult(null);
+ /// Completes immediately without persisting anything.
+ /// The state snapshot (ignored).
+ /// Cancellation token (unused).
public Task SaveAsync(AlarmActorStateSnapshot snapshot, CancellationToken ct) =>
Task.CompletedTask;
}
diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Engines/IScriptedAlarmEvaluator.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Engines/IScriptedAlarmEvaluator.cs
index b1239364..6ad1464e 100644
--- a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Engines/IScriptedAlarmEvaluator.cs
+++ b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Engines/IScriptedAlarmEvaluator.cs
@@ -8,6 +8,11 @@ namespace ZB.MOM.WW.OtOpcUa.Commons.Engines;
///
public interface IScriptedAlarmEvaluator
{
+ /// Evaluates an alarm predicate against the provided dependencies.
+ /// The unique identifier of the alarm being evaluated.
+ /// The predicate expression to evaluate.
+ /// Read-only dictionary of variable names to values for predicate evaluation.
+ /// Result containing success flag, alarm active state, and optional failure reason.
ScriptedAlarmEvalResult Evaluate(string alarmId, string predicate, IReadOnlyDictionary dependencies);
}
@@ -15,7 +20,14 @@ public interface IScriptedAlarmEvaluator
/// Success is true; on failure the caller should keep the prior state and log Reason.
public sealed record ScriptedAlarmEvalResult(bool Success, bool Active, string? Reason)
{
+ /// Creates a successful alarm evaluation result with the given active state.
+ /// Whether the alarm condition is active.
+ /// A successful evaluation result.
public static ScriptedAlarmEvalResult Ok(bool active) => new(true, active, null);
+
+ /// Creates a failed alarm evaluation result with the given reason.
+ /// Description of the evaluation failure cause.
+ /// A failed evaluation result.
public static ScriptedAlarmEvalResult Failure(string reason) => new(false, false, reason);
}
@@ -25,6 +37,11 @@ public sealed class NullScriptedAlarmEvaluator : IScriptedAlarmEvaluator
{
public static readonly NullScriptedAlarmEvaluator Instance = new();
private NullScriptedAlarmEvaluator() { }
+ /// Returns an inactive alarm result for every evaluation (safe no-op behavior).
+ /// The alarm identifier (ignored).
+ /// The predicate expression (ignored).
+ /// The variable dependencies (ignored).
+ /// Always returns an inactive alarm result.
public ScriptedAlarmEvalResult Evaluate(string alarmId, string predicate, IReadOnlyDictionary dependencies)
=> ScriptedAlarmEvalResult.Ok(active: false);
}
diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Engines/IVirtualTagEvaluator.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Engines/IVirtualTagEvaluator.cs
index ce0d15e4..023b48cf 100644
--- a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Engines/IVirtualTagEvaluator.cs
+++ b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Engines/IVirtualTagEvaluator.cs
@@ -13,6 +13,10 @@ public interface IVirtualTagEvaluator
/// . Implementations must not throw — script failures
/// are reported via .
///
+ /// The unique identifier of the virtual tag being evaluated.
+ /// The expression string to evaluate.
+ /// Read-only dictionary of variable names to values for expression evaluation.
+ /// Result containing success flag, evaluated value, and optional failure reason.
VirtualTagEvalResult Evaluate(string virtualTagId, string expression, IReadOnlyDictionary dependencies);
}
@@ -21,7 +25,15 @@ public interface IVirtualTagEvaluator
public sealed record VirtualTagEvalResult(bool Success, object? Value, string? Reason)
{
public static readonly VirtualTagEvalResult NoChange = new(true, null, "no-change");
+
+ /// Creates a successful evaluation result with the given value.
+ /// The evaluated value.
+ /// A successful evaluation result.
public static VirtualTagEvalResult Ok(object? value) => new(true, value, null);
+
+ /// Creates a failed evaluation result with the given reason.
+ /// Description of the failure cause.
+ /// A failed evaluation result.
public static VirtualTagEvalResult Failure(string reason) => new(false, null, reason);
}
@@ -31,6 +43,11 @@ public sealed class NullVirtualTagEvaluator : IVirtualTagEvaluator
{
public static readonly NullVirtualTagEvaluator Instance = new();
private NullVirtualTagEvaluator() { }
+ /// Returns for every evaluation.
+ /// The virtual tag identifier (ignored).
+ /// The expression string (ignored).
+ /// The variable dependencies (ignored).
+ /// Always returns .
public VirtualTagEvalResult Evaluate(string virtualTagId, string expression, IReadOnlyDictionary dependencies)
=> VirtualTagEvalResult.NoChange;
}
diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Interfaces/IAdminOperationsClient.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Interfaces/IAdminOperationsClient.cs
index 3a099867..3957b121 100644
--- a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Interfaces/IAdminOperationsClient.cs
+++ b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Interfaces/IAdminOperationsClient.cs
@@ -9,5 +9,9 @@ namespace ZB.MOM.WW.OtOpcUa.Commons.Interfaces;
///
public interface IAdminOperationsClient
{
+ /// Starts a new deployment on the cluster-singleton admin operations actor.
+ /// The user or system identifier triggering the deployment.
+ /// The cancellation token.
+ /// A task representing the asynchronous operation containing the deployment start result.
Task StartDeploymentAsync(string createdBy, CancellationToken ct);
}
diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Interfaces/IClusterRoleInfo.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Interfaces/IClusterRoleInfo.cs
index 29c1dc1a..927c0754 100644
--- a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Interfaces/IClusterRoleInfo.cs
+++ b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Interfaces/IClusterRoleInfo.cs
@@ -10,11 +10,23 @@ namespace ZB.MOM.WW.OtOpcUa.Commons.Interfaces;
///
public interface IClusterRoleInfo
{
+ /// Gets the local cluster node identifier.
NodeId LocalNode { get; }
+ /// Gets the set of roles assigned to the local node.
IReadOnlySet LocalRoles { get; }
+ /// Checks if the local node has the specified role.
+ /// Role name to check.
+ /// True if the local node has the role; otherwise, false.
bool HasRole(string role);
+ /// Gets all nodes assigned to the specified role.
+ /// Role name to query.
+ /// List of node identifiers with the role.
IReadOnlyList MembersWithRole(string role);
+ /// Gets the leader node for the specified role, or null if no leader is elected.
+ /// Role name to query.
+ /// The leader node identifier, or null if no leader exists.
NodeId? RoleLeader(string role);
+ /// Occurs when the leader of a role changes.
event EventHandler? RoleLeaderChanged;
}
diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Interfaces/IFleetDiagnosticsClient.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Interfaces/IFleetDiagnosticsClient.cs
index cab512ac..262cf795 100644
--- a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Interfaces/IFleetDiagnosticsClient.cs
+++ b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Interfaces/IFleetDiagnosticsClient.cs
@@ -8,5 +8,8 @@ namespace ZB.MOM.WW.OtOpcUa.Commons.Interfaces;
///
public interface IFleetDiagnosticsClient
{
+ /// Gets diagnostics for the specified node.
+ /// The node ID to retrieve diagnostics for.
+ /// The cancellation token.
Task GetDiagnosticsAsync(NodeId nodeId, CancellationToken ct);
}
diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Interfaces/RoleLeaderChangedEventArgs.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Interfaces/RoleLeaderChangedEventArgs.cs
index 50fb8f12..2ccf85e3 100644
--- a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Interfaces/RoleLeaderChangedEventArgs.cs
+++ b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Interfaces/RoleLeaderChangedEventArgs.cs
@@ -2,9 +2,15 @@ using ZB.MOM.WW.OtOpcUa.Commons.Types;
namespace ZB.MOM.WW.OtOpcUa.Commons.Interfaces;
+/// Event arguments for role leader change notifications.
public sealed class RoleLeaderChangedEventArgs : EventArgs
{
+ /// Gets the role name that changed leadership.
public required string Role { get; init; }
+
+ /// Gets the previous leader node ID, or null if there was no previous leader.
public required NodeId? PreviousLeader { get; init; }
+
+ /// Gets the new leader node ID, or null if the role is now leaderless.
public required NodeId? NewLeader { get; init; }
}
diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Observability/OtOpcUaTelemetry.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Observability/OtOpcUaTelemetry.cs
index efb99090..1a284860 100644
--- a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Observability/OtOpcUaTelemetry.cs
+++ b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Observability/OtOpcUaTelemetry.cs
@@ -68,6 +68,7 @@ public static class OtOpcUaTelemetry
/// Starts a deploy span tagged with the deployment id. Caller disposes to close. Returns
/// null when no listener is attached so the call site stays cheap on undecorated builds.
///
+ /// The deployment identifier to tag the span with.
public static Activity? StartDeployApplySpan(string deploymentId)
{
var activity = ActivitySource.StartActivity("otopcua.deploy.apply", ActivityKind.Internal);
diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/OpcUa/DeferredAddressSpaceSink.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/OpcUa/DeferredAddressSpaceSink.cs
index 09ff634e..3bb7e934 100644
--- a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/OpcUa/DeferredAddressSpaceSink.cs
+++ b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/OpcUa/DeferredAddressSpaceSink.cs
@@ -18,20 +18,41 @@ public sealed class DeferredAddressSpaceSink : IOpcUaAddressSpaceSink
/// Swap in the production sink. Pass null to revert to the null sink
/// (used during graceful shutdown so post-stop writes don't hit a half-disposed manager).
+ /// The sink implementation to use, or null to use the null sink.
public void SetSink(IOpcUaAddressSpaceSink? sink) =>
_inner = sink ?? NullOpcUaAddressSpaceSink.Instance;
+ /// Writes a value to the OPC UA address space through the inner sink.
+ /// The node ID of the variable.
+ /// The value to write.
+ /// The OPC UA quality value.
+ /// The source timestamp in UTC.
public void WriteValue(string nodeId, object? value, OpcUaQuality quality, DateTime sourceTimestampUtc)
=> _inner.WriteValue(nodeId, value, quality, sourceTimestampUtc);
+ /// Writes an alarm state through the inner sink.
+ /// The node ID of the alarm condition.
+ /// Whether the alarm is active.
+ /// Whether the alarm has been acknowledged.
+ /// The source timestamp in UTC.
public void WriteAlarmState(string alarmNodeId, bool active, bool acknowledged, DateTime sourceTimestampUtc)
=> _inner.WriteAlarmState(alarmNodeId, active, acknowledged, sourceTimestampUtc);
+ /// Ensures a folder exists in the address space through the inner sink.
+ /// The node ID of the folder.
+ /// The node ID of the parent folder, or null for root.
+ /// The display name of the folder.
public void EnsureFolder(string folderNodeId, string? parentNodeId, string displayName)
=> _inner.EnsureFolder(folderNodeId, parentNodeId, displayName);
+ /// Ensures a variable exists in the address space through the inner sink.
+ /// The node ID of the variable.
+ /// The node ID of the parent folder, or null for root.
+ /// The display name of the variable.
+ /// The OPC UA data type of the variable.
public void EnsureVariable(string variableNodeId, string? parentFolderNodeId, string displayName, string dataType)
=> _inner.EnsureVariable(variableNodeId, parentFolderNodeId, displayName, dataType);
+ /// Rebuilds the address space through the inner sink.
public void RebuildAddressSpace() => _inner.RebuildAddressSpace();
}
diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/OpcUa/DeferredServiceLevelPublisher.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/OpcUa/DeferredServiceLevelPublisher.cs
index 092845cc..eb227979 100644
--- a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/OpcUa/DeferredServiceLevelPublisher.cs
+++ b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/OpcUa/DeferredServiceLevelPublisher.cs
@@ -12,8 +12,11 @@ public sealed class DeferredServiceLevelPublisher : IServiceLevelPublisher
private volatile IServiceLevelPublisher _inner = NullServiceLevelPublisher.Instance;
/// Swap the underlying publisher. Pass null to revert to the Null no-op.
+ /// The publisher implementation to use, or null to use the null publisher.
public void SetInner(IServiceLevelPublisher? inner) =>
_inner = inner ?? NullServiceLevelPublisher.Instance;
+ /// Publishes a service level value to the inner publisher.
+ /// The service level to publish.
public void Publish(byte serviceLevel) => _inner.Publish(serviceLevel);
}
diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/OpcUa/IOpcUaAddressSpaceSink.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/OpcUa/IOpcUaAddressSpaceSink.cs
index a4690e17..eb7b7c3a 100644
--- a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/OpcUa/IOpcUaAddressSpaceSink.cs
+++ b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/OpcUa/IOpcUaAddressSpaceSink.cs
@@ -9,9 +9,17 @@ namespace ZB.MOM.WW.OtOpcUa.Commons.OpcUa;
public interface IOpcUaAddressSpaceSink
{
/// Write a Variable node's current value + quality + source timestamp.
+ /// The OPC UA node ID of the variable.
+ /// The value to write.
+ /// The quality status of the value.
+ /// The source timestamp in UTC.
void WriteValue(string nodeId, object? value, OpcUaQuality quality, DateTime sourceTimestampUtc);
/// Write an alarm-condition Variable's active/acknowledged state.
+ /// The OPC UA node ID of the alarm.
+ /// Whether the alarm is active.
+ /// Whether the alarm has been acknowledged.
+ /// The source timestamp in UTC.
void WriteAlarmState(string alarmNodeId, bool active, bool acknowledged, DateTime sourceTimestampUtc);
///
@@ -20,6 +28,9 @@ public interface IOpcUaAddressSpaceSink
/// is null the folder is parented under the namespace
/// root. Idempotent: calling twice with the same id is safe.
///
+ /// The OPC UA node ID for the folder.
+ /// The parent folder node ID, or null for namespace root.
+ /// The display name for the folder.
void EnsureFolder(string folderNodeId, string? parentNodeId, string displayName);
///
@@ -29,6 +40,9 @@ public interface IOpcUaAddressSpaceSink
/// Used by Phase7Applier to materialise Galaxy / SystemPlatform tags ahead of any
/// driver-side subscribe so OPC UA clients can browse them. Idempotent.
///
+ /// The OPC UA node ID for the variable.
+ /// The parent folder node ID, or null for namespace root.
+ /// The display name for the variable.
/// OPC UA built-in type name ("Boolean" / "Int32" / "Float" / etc.).
void EnsureVariable(string variableNodeId, string? parentFolderNodeId, string displayName, string dataType);
@@ -49,9 +63,19 @@ public sealed class NullOpcUaAddressSpaceSink : IOpcUaAddressSpaceSink
{
public static readonly NullOpcUaAddressSpaceSink Instance = new();
private NullOpcUaAddressSpaceSink() { }
+
+ ///
public void WriteValue(string nodeId, object? value, OpcUaQuality quality, DateTime sourceTimestampUtc) { }
+
+ ///
public void WriteAlarmState(string alarmNodeId, bool active, bool acknowledged, DateTime sourceTimestampUtc) { }
+
+ ///
public void EnsureFolder(string folderNodeId, string? parentNodeId, string displayName) { }
+
+ ///
public void EnsureVariable(string variableNodeId, string? parentFolderNodeId, string displayName, string dataType) { }
+
+ ///
public void RebuildAddressSpace() { }
}
diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/OpcUa/IServiceLevelPublisher.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/OpcUa/IServiceLevelPublisher.cs
index 67f66e03..c464670a 100644
--- a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/OpcUa/IServiceLevelPublisher.cs
+++ b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/OpcUa/IServiceLevelPublisher.cs
@@ -8,6 +8,8 @@ namespace ZB.MOM.WW.OtOpcUa.Commons.OpcUa;
///
public interface IServiceLevelPublisher
{
+ /// Publishes the service level value to the OPC UA Server object.
+ /// The service level value (0-255).
void Publish(byte serviceLevel);
}
@@ -17,6 +19,11 @@ public sealed class NullServiceLevelPublisher : IServiceLevelPublisher
{
public static readonly NullServiceLevelPublisher Instance = new();
private NullServiceLevelPublisher() { }
+
+ /// Gets the last published service level value.
public byte LastPublished { get; private set; }
+
+ /// Records the service level value without publishing.
+ /// The service level value (0-255).
public void Publish(byte serviceLevel) => LastPublished = serviceLevel;
}
diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Types/CorrelationId.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Types/CorrelationId.cs
index da7894e1..fbf9dc06 100644
--- a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Types/CorrelationId.cs
+++ b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Types/CorrelationId.cs
@@ -2,9 +2,16 @@ namespace ZB.MOM.WW.OtOpcUa.Commons.Types;
public readonly record struct CorrelationId(Guid Value)
{
+ /// Creates a new CorrelationId with a randomly generated GUID.
public static CorrelationId NewId() => new(Guid.NewGuid());
+ ///
public override string ToString() => Value.ToString("N");
+ /// Parses a lowercase hex string without hyphens into a CorrelationId.
+ /// The string to parse.
public static CorrelationId Parse(string s) => new(Guid.ParseExact(s, "N"));
+ /// Attempts to parse a lowercase hex string without hyphens into a CorrelationId.
+ /// The string to parse, or null.
+ /// The resulting CorrelationId if parsing succeeds.
public static bool TryParse(string? s, out CorrelationId id)
{
if (Guid.TryParseExact(s, "N", out var g)) { id = new CorrelationId(g); return true; }
diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Types/DeploymentId.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Types/DeploymentId.cs
index 8d74194b..657f4e18 100644
--- a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Types/DeploymentId.cs
+++ b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Types/DeploymentId.cs
@@ -2,9 +2,22 @@ namespace ZB.MOM.WW.OtOpcUa.Commons.Types;
public readonly record struct DeploymentId(Guid Value)
{
+ /// Creates a new deployment ID with a random GUID.
+ /// A new DeploymentId.
public static DeploymentId NewId() => new(Guid.NewGuid());
+
+ ///
public override string ToString() => Value.ToString("N");
+
+ /// Parses a deployment ID from a hex string without hyphens.
+ /// The hex string to parse.
+ /// The parsed DeploymentId.
public static DeploymentId Parse(string s) => new(Guid.ParseExact(s, "N"));
+
+ /// Attempts to parse a deployment ID from a hex string without hyphens.
+ /// The hex string to parse, or null.
+ /// The parsed DeploymentId if successful, or default.
+ /// True if parsing succeeded; false otherwise.
public static bool TryParse(string? s, out DeploymentId id)
{
if (Guid.TryParseExact(s, "N", out var g)) { id = new DeploymentId(g); return true; }
diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Types/ExecutionId.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Types/ExecutionId.cs
index 7920a66d..d8b6bfff 100644
--- a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Types/ExecutionId.cs
+++ b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Types/ExecutionId.cs
@@ -2,9 +2,22 @@ namespace ZB.MOM.WW.OtOpcUa.Commons.Types;
public readonly record struct ExecutionId(Guid Value)
{
+ /// Creates a new execution ID with a randomly generated GUID.
+ /// A new ExecutionId instance.
public static ExecutionId NewId() => new(Guid.NewGuid());
+
+ ///
public override string ToString() => Value.ToString("N");
+
+ /// Parses the specified string into an ExecutionId in format N.
+ /// The string to parse.
+ /// The parsed ExecutionId.
public static ExecutionId Parse(string s) => new(Guid.ParseExact(s, "N"));
+
+ /// Tries to parse the specified string into an ExecutionId in format N.
+ /// The string to parse, or null.
+ /// The parsed ExecutionId, or default if parsing fails.
+ /// true if parsing succeeded; otherwise, false.
public static bool TryParse(string? s, out ExecutionId id)
{
if (Guid.TryParseExact(s, "N", out var g)) { id = new ExecutionId(g); return true; }
diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Types/NodeId.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Types/NodeId.cs
index 273f7a3f..e1251a4c 100644
--- a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Types/NodeId.cs
+++ b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Types/NodeId.cs
@@ -7,11 +7,22 @@ namespace ZB.MOM.WW.OtOpcUa.Commons.Types;
///
public readonly record struct NodeId(string Value)
{
+ ///
public override string ToString() => Value;
+
+ /// Parses a string into a NodeId.
+ /// The string to parse.
+ /// A new NodeId instance.
+ /// Thrown when the string is null, empty, or whitespace.
public static NodeId Parse(string s) =>
string.IsNullOrWhiteSpace(s)
? throw new ArgumentException("NodeId value cannot be empty.", nameof(s))
: new NodeId(s);
+
+ /// Attempts to parse a string into a NodeId.
+ /// The string to parse.
+ /// The parsed NodeId if successful.
+ /// True if the parse succeeded; otherwise false.
public static bool TryParse(string? s, out NodeId id)
{
if (!string.IsNullOrWhiteSpace(s)) { id = new NodeId(s); return true; }
diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Types/RevisionHash.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Types/RevisionHash.cs
index 30440eb9..0180becd 100644
--- a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Types/RevisionHash.cs
+++ b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/Types/RevisionHash.cs
@@ -6,11 +6,24 @@ namespace ZB.MOM.WW.OtOpcUa.Commons.Types;
///
public readonly record struct RevisionHash(string Value)
{
+ ///
public override string ToString() => Value;
+ ///
+ /// Parses a string into a .
+ ///
+ /// The string to parse.
+ /// A instance.
+ /// Thrown if the input is null, empty, or whitespace.
public static RevisionHash Parse(string s) =>
string.IsNullOrWhiteSpace(s)
? throw new ArgumentException("RevisionHash value cannot be empty.", nameof(s))
: new RevisionHash(s);
+ ///
+ /// Attempts to parse a string into a .
+ ///
+ /// The string to parse.
+ /// The parsed hash, or default if parsing fails.
+ /// True if parsing succeeded; otherwise false.
public static bool TryParse(string? s, out RevisionHash hash)
{
if (!string.IsNullOrWhiteSpace(s)) { hash = new RevisionHash(s); return true; }
diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/DesignTimeDbContextFactory.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/DesignTimeDbContextFactory.cs
index 402a0f0f..183ca972 100644
--- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/DesignTimeDbContextFactory.cs
+++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/DesignTimeDbContextFactory.cs
@@ -17,6 +17,9 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration;
///
public sealed class DesignTimeDbContextFactory : IDesignTimeDbContextFactory
{
+ /// Creates a new DbContext instance for design-time operations.
+ /// Command-line arguments (unused).
+ /// The configured DbContext instance.
public OtOpcUaConfigDbContext CreateDbContext(string[] args)
{
var connection = Environment.GetEnvironmentVariable("OTOPCUA_CONFIG_CONNECTION");
diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ClusterNode.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ClusterNode.cs
index 5c95ec95..c7368c93 100644
--- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ClusterNode.cs
+++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ClusterNode.cs
@@ -6,13 +6,16 @@ public sealed class ClusterNode
/// Stable per-machine logical ID, e.g. "LINE3-OPCUA-A".
public required string NodeId { get; set; }
+ /// The unique identifier of the cluster this node belongs to.
public required string ClusterId { get; set; }
/// Machine hostname / IP.
public required string Host { get; set; }
+ /// The OPC UA server port (default 4840).
public int OpcUaPort { get; set; } = 4840;
+ /// The dashboard HTTP port (default 8081).
public int DashboardPort { get; set; } = 8081;
///
@@ -32,15 +35,21 @@ public sealed class ClusterNode
///
public string? DriverConfigOverridesJson { get; set; }
+ /// Gets or sets a value indicating whether this node is enabled.
public bool Enabled { get; set; } = true;
+ /// Gets or sets the timestamp when this node was last seen.
public DateTime? LastSeenAt { get; set; }
+ /// Gets or sets the timestamp when this node was created.
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
+ /// Gets or sets the username of who created this node.
public required string CreatedBy { get; set; }
// Navigation
+ /// Gets or sets the cluster this node belongs to.
public ServerCluster? Cluster { get; set; }
+ /// Gets or sets the credentials associated with this node.
public ICollection Credentials { get; set; } = [];
}
diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ClusterNodeCredential.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ClusterNodeCredential.cs
index c6824ea7..6a767e9a 100644
--- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ClusterNodeCredential.cs
+++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ClusterNodeCredential.cs
@@ -8,22 +8,30 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Entities;
///
public sealed class ClusterNodeCredential
{
+ /// Gets or sets the credential identifier.
public Guid CredentialId { get; set; }
+ /// Gets or sets the node identifier this credential binds to.
public required string NodeId { get; set; }
+ /// Gets or sets the credential kind (login, certificate, etc.).
public required CredentialKind Kind { get; set; }
- /// Login name / cert thumbprint / SID / gMSA name.
+ /// Gets or sets the credential value (login name / cert thumbprint / SID / gMSA name).
public required string Value { get; set; }
+ /// Gets or sets a value indicating whether the credential is enabled.
public bool Enabled { get; set; } = true;
+ /// Gets or sets the date/time when the credential was last rotated.
public DateTime? RotatedAt { get; set; }
+ /// Gets or sets the date/time when the credential was created.
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
+ /// Gets or sets the user who created the credential.
public required string CreatedBy { get; set; }
+ /// Gets or sets the related cluster node.
public ClusterNode? Node { get; set; }
}
diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ConfigAuditLog.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ConfigAuditLog.cs
index 627d5eeb..386a34ca 100644
--- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ConfigAuditLog.cs
+++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ConfigAuditLog.cs
@@ -6,21 +6,28 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Entities;
///
public sealed class ConfigAuditLog
{
+ /// Gets or sets the unique audit log identifier.
public long AuditId { get; set; }
+ /// Gets or sets the timestamp of the audit event.
public DateTime Timestamp { get; set; } = DateTime.UtcNow;
+ /// Gets or sets the principal (user or service) that initiated the event.
public required string Principal { get; set; }
/// DraftCreated | DraftEdited | Published | RolledBack | NodeApplied | CredentialAdded | CredentialDisabled | ClusterCreated | NodeAdded | ExternalIdReleased | CrossClusterNamespaceAttempt | OpcUaAccessDenied | …
public required string EventType { get; set; }
+ /// Gets or sets the cluster identifier associated with the event, if applicable.
public string? ClusterId { get; set; }
+ /// Gets or sets the node identifier associated with the event, if applicable.
public string? NodeId { get; set; }
+ /// Gets or sets the generation identifier associated with the event, if applicable.
public long? GenerationId { get; set; }
+ /// Gets or sets additional event details in JSON format.
public string? DetailsJson { get; set; }
///
diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ConfigEdit.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ConfigEdit.cs
index 237fcb1c..4a73f338 100644
--- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ConfigEdit.cs
+++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ConfigEdit.cs
@@ -7,21 +7,27 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Entities;
///
public sealed class ConfigEdit
{
+ /// Gets the unique identifier for this edit.
public Guid EditId { get; init; } = Guid.NewGuid();
+ /// Gets the type of entity that was edited.
public required string EntityType { get; init; }
+ /// Gets the identifier of the entity that was edited.
public Guid EntityId { get; init; }
- /// JSON payload of the column-name → new-value pairs touched by this edit.
+ /// Gets the JSON payload of the column-name → new-value pairs touched by this edit.
public required string FieldsJson { get; init; }
- /// Optional correlation across edits inside a single admin operation.
+ /// Gets the optional correlation identifier across edits inside a single admin operation.
public Guid? ExecutionId { get; init; }
+ /// Gets the username of the user who performed the edit.
public required string EditedBy { get; init; }
+ /// Gets the UTC timestamp when the edit was performed.
public DateTime EditedAtUtc { get; init; } = DateTime.UtcNow;
+ /// Gets the node identifier of the admin instance that performed the edit.
public required string SourceNode { get; init; }
}
diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/Deployment.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/Deployment.cs
index 8a4afacc..19d83728 100644
--- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/Deployment.cs
+++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/Deployment.cs
@@ -10,21 +10,30 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Entities;
///
public sealed class Deployment
{
+ /// Gets or sets the unique deployment identifier.
public Guid DeploymentId { get; init; } = Guid.NewGuid();
+ /// Gets or sets the revision hash of the deployment artifact.
public required string RevisionHash { get; init; }
+ /// Gets or sets the deployment status.
public DeploymentStatus Status { get; set; } = DeploymentStatus.Dispatching;
+ /// Gets or sets the name of the user who created the deployment.
public required string CreatedBy { get; init; }
+ /// Gets or sets the UTC timestamp when the deployment was created.
public DateTime CreatedAtUtc { get; init; } = DateTime.UtcNow;
+ /// Gets or sets the serialized artifact blob containing the configuration.
public byte[] ArtifactBlob { get; init; } = Array.Empty();
+ /// Gets or sets the row version for optimistic concurrency control.
public byte[] RowVersion { get; set; } = Array.Empty();
+ /// Gets or sets the failure reason if the deployment failed.
public string? FailureReason { get; set; }
+ /// Gets or sets the UTC timestamp when the deployment was sealed.
public DateTime? SealedAtUtc { get; set; }
}
diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/Device.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/Device.cs
index 736cef38..0fca1d16 100644
--- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/Device.cs
+++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/Device.cs
@@ -3,15 +3,27 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Entities;
/// Per-device row for multi-device drivers (Modbus, AB CIP). Optional for single-device drivers.
public sealed class Device
{
+ ///
+ /// Gets or sets the unique database row identifier for the device.
+ ///
public Guid DeviceRowId { get; set; }
+ ///
+ /// Gets or sets the device identifier.
+ ///
public required string DeviceId { get; set; }
/// Logical FK to .
public required string DriverInstanceId { get; set; }
+ ///
+ /// Gets or sets the device name.
+ ///
public required string Name { get; set; }
+ ///
+ /// Gets or sets a value indicating whether the device is enabled.
+ ///
public bool Enabled { get; set; } = true;
/// Schemaless per-driver-type device config (host, port, unit ID, slot, etc.).
diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/DriverHostStatus.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/DriverHostStatus.cs
index 440d1cee..7b1eb167 100644
--- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/DriverHostStatus.cs
+++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/DriverHostStatus.cs
@@ -39,6 +39,7 @@ public sealed class DriverHostStatus
///
public required string HostName { get; set; }
+ /// Gets or sets the current connectivity state of the host.
public DriverHostState State { get; set; } = DriverHostState.Unknown;
/// Timestamp of the last state transition (not of the most recent heartbeat).
diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/DriverInstance.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/DriverInstance.cs
index 39276223..09c40868 100644
--- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/DriverInstance.cs
+++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/DriverInstance.cs
@@ -3,10 +3,13 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Entities;
/// One driver instance in a cluster's generation. JSON config is schemaless per-driver-type.
public sealed class DriverInstance
{
+ /// Gets or sets the row ID for this driver instance.
public Guid DriverInstanceRowId { get; set; }
+ /// Gets or sets the unique driver instance identifier.
public required string DriverInstanceId { get; set; }
+ /// Gets or sets the cluster ID this driver instance belongs to.
public required string ClusterId { get; set; }
///
@@ -15,11 +18,13 @@ public sealed class DriverInstance
///
public required string NamespaceId { get; set; }
+ /// Gets or sets the friendly name of this driver instance.
public required string Name { get; set; }
/// Galaxy | ModbusTcp | AbCip | AbLegacy | S7 | TwinCat | Focas | OpcUaClient
public required string DriverType { get; set; }
+ /// Gets or sets a value indicating whether this driver instance is enabled.
public bool Enabled { get; set; } = true;
/// Schemaless per-driver-type JSON config. Validated against registered JSON schema at draft-publish time (decision #91).
@@ -46,5 +51,6 @@ public sealed class DriverInstance
/// Optimistic concurrency token for last-write-wins detection in the v2 live-edit model.
public byte[] RowVersion { get; set; } = Array.Empty();
+ /// Gets or sets the related server cluster for navigation.
public ServerCluster? Cluster { get; set; }
}
diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/DriverInstanceResilienceStatus.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/DriverInstanceResilienceStatus.cs
index 445b84b2..b057222a 100644
--- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/DriverInstanceResilienceStatus.cs
+++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/DriverInstanceResilienceStatus.cs
@@ -15,7 +15,9 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Entities;
///
public sealed class DriverInstanceResilienceStatus
{
+ /// Gets or sets the driver instance identifier.
public required string DriverInstanceId { get; set; }
+ /// Gets or sets the host name.
public required string HostName { get; set; }
/// Most recent time the circuit breaker for this (instance, host) opened; null if never.
diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/Equipment.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/Equipment.cs
index d4cd5e6d..dd1e8c79 100644
--- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/Equipment.cs
+++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/Equipment.cs
@@ -7,6 +7,7 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Entities;
///
public sealed class Equipment
{
+ /// Gets or sets the row identifier for this equipment.
public Guid EquipmentRowId { get; set; }
///
@@ -43,19 +44,29 @@ public sealed class Equipment
// OPC UA Companion Spec OPC 40010 Machinery Identification fields (decision #139).
// All nullable so equipment can be added before identity is fully captured.
+ /// Gets or sets the manufacturer name for this equipment.
public string? Manufacturer { get; set; }
+ /// Gets or sets the model number or designation for this equipment.
public string? Model { get; set; }
+ /// Gets or sets the serial number for this equipment.
public string? SerialNumber { get; set; }
+ /// Gets or sets the hardware revision level for this equipment.
public string? HardwareRevision { get; set; }
+ /// Gets or sets the software revision level for this equipment.
public string? SoftwareRevision { get; set; }
+ /// Gets or sets the year of construction for this equipment.
public short? YearOfConstruction { get; set; }
+ /// Gets or sets the asset location information for this equipment.
public string? AssetLocation { get; set; }
+ /// Gets or sets the manufacturer URI for this equipment.
public string? ManufacturerUri { get; set; }
+ /// Gets or sets the device manual URI for this equipment.
public string? DeviceManualUri { get; set; }
/// Nullable hook for future schemas-repo template ID (decision #112).
public string? EquipmentClassRef { get; set; }
+ /// Gets or sets whether this equipment is enabled.
public bool Enabled { get; set; } = true;
/// Optimistic concurrency token for last-write-wins detection in the v2 live-edit model.
diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/EquipmentImportBatch.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/EquipmentImportBatch.cs
index c3b65f8c..bd37b7d2 100644
--- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/EquipmentImportBatch.cs
+++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/EquipmentImportBatch.cs
@@ -17,15 +17,31 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Entities;
///
public sealed class EquipmentImportBatch
{
+ /// Gets or sets the unique identifier for this batch.
public Guid Id { get; set; }
+
+ /// Gets or sets the cluster identifier.
public required string ClusterId { get; set; }
+
+ /// Gets or sets the user name who created this batch.
public required string CreatedBy { get; set; }
+
+ /// Gets or sets the UTC timestamp when this batch was created.
public DateTime CreatedAtUtc { get; set; }
+
+ /// Gets or sets the total number of rows staged in this batch.
public int RowsStaged { get; set; }
+
+ /// Gets or sets the number of rows accepted in this batch.
public int RowsAccepted { get; set; }
+
+ /// Gets or sets the number of rows rejected in this batch.
public int RowsRejected { get; set; }
+
+ /// Gets or sets the UTC timestamp when this batch was finalised, or null if still in staging.
public DateTime? FinalisedAtUtc { get; set; }
+ /// Gets or sets the collection of staged rows in this batch.
public ICollection Rows { get; set; } = [];
}
@@ -37,32 +53,74 @@ public sealed class EquipmentImportBatch
///
public sealed class EquipmentImportRow
{
+ /// Gets or sets the unique identifier for this row.
public Guid Id { get; set; }
+
+ /// Gets or sets the parent batch identifier.
public Guid BatchId { get; set; }
+
+ /// Gets or sets the line number in the source file.
public int LineNumberInFile { get; set; }
+
+ /// Gets or sets a value indicating whether this row was accepted.
public bool IsAccepted { get; set; }
+
+ /// Gets or sets the reason this row was rejected, if applicable.
public string? RejectReason { get; set; }
// Required (decision #117)
+ /// Gets or sets the Z tag identifier.
public required string ZTag { get; set; }
+
+ /// Gets or sets the machine code.
public required string MachineCode { get; set; }
+
+ /// Gets or sets the SAP identifier.
public required string SAPID { get; set; }
+
+ /// Gets or sets the equipment identifier.
public required string EquipmentId { get; set; }
+
+ /// Gets or sets the equipment UUID.
public required string EquipmentUuid { get; set; }
+
+ /// Gets or sets the equipment name.
public required string Name { get; set; }
+
+ /// Gets or sets the UNS area name.
public required string UnsAreaName { get; set; }
+
+ /// Gets or sets the UNS line name.
public required string UnsLineName { get; set; }
// Optional (decision #139 — OPC 40010 Identification)
+ /// Gets or sets the manufacturer name.
public string? Manufacturer { get; set; }
+
+ /// Gets or sets the equipment model.
public string? Model { get; set; }
+
+ /// Gets or sets the serial number.
public string? SerialNumber { get; set; }
+
+ /// Gets or sets the hardware revision.
public string? HardwareRevision { get; set; }
+
+ /// Gets or sets the software revision.
public string? SoftwareRevision { get; set; }
+
+ /// Gets or sets the year of construction.
public string? YearOfConstruction { get; set; }
+
+ /// Gets or sets the asset location.
public string? AssetLocation { get; set; }
+
+ /// Gets or sets the manufacturer URI.
public string? ManufacturerUri { get; set; }
+
+ /// Gets or sets the device manual URI.
public string? DeviceManualUri { get; set; }
+ /// Gets or sets the parent batch.
public EquipmentImportBatch? Batch { get; set; }
}
diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ExternalIdReservation.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ExternalIdReservation.cs
index cd4c7897..934e9135 100644
--- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ExternalIdReservation.cs
+++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ExternalIdReservation.cs
@@ -9,10 +9,13 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Entities;
///
public sealed class ExternalIdReservation
{
+ /// Gets or sets the unique reservation identifier.
public Guid ReservationId { get; set; }
+ /// Gets or sets the kind of reservation (ZTag or SAPID).
public required ReservationKind Kind { get; set; }
+ /// Gets or sets the reserved external ID value.
public required string Value { get; set; }
/// The equipment that owns this reservation. Stays bound even when equipment is disabled.
@@ -21,16 +24,21 @@ public sealed class ExternalIdReservation
/// First cluster to publish this reservation.
public required string ClusterId { get; set; }
+ /// Gets or sets the timestamp when the reservation was first published.
public DateTime FirstPublishedAt { get; set; } = DateTime.UtcNow;
+ /// Gets or sets the identifier of the user or system that first published the reservation.
public required string FirstPublishedBy { get; set; }
+ /// Gets or sets the timestamp of the most recent publication.
public DateTime LastPublishedAt { get; set; } = DateTime.UtcNow;
/// Non-null when explicitly released by FleetAdmin (audit-logged, requires reason).
public DateTime? ReleasedAt { get; set; }
+ /// Gets or sets the identifier of the user or system that released the reservation.
public string? ReleasedBy { get; set; }
+ /// Gets or sets the reason for releasing the reservation.
public string? ReleaseReason { get; set; }
}
diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/Namespace.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/Namespace.cs
index c22b7895..55f53433 100644
--- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/Namespace.cs
+++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/Namespace.cs
@@ -8,24 +8,30 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Entities;
///
public sealed class Namespace
{
+ /// Gets or sets the row identifier for this namespace.
public Guid NamespaceRowId { get; set; }
/// Stable logical ID, e.g. "LINE3-OPCUA-equipment". Globally unique in v2.
public required string NamespaceId { get; set; }
+ /// Gets or sets the cluster identifier.
public required string ClusterId { get; set; }
+ /// Gets or sets the namespace kind.
public required NamespaceKind Kind { get; set; }
/// E.g. "urn:zb:warsaw-west:equipment". Unique fleet-wide per generation.
public required string NamespaceUri { get; set; }
+ /// Gets or sets a value indicating whether the namespace is enabled.
public bool Enabled { get; set; } = true;
+ /// Gets or sets optional notes about the namespace.
public string? Notes { get; set; }
/// Optimistic concurrency token for last-write-wins detection in the v2 live-edit model.
public byte[] RowVersion { get; set; } = Array.Empty();
+ /// Gets or sets the associated server cluster.
public ServerCluster? Cluster { get; set; }
}
diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/NodeAcl.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/NodeAcl.cs
index a69287be..537dfa4b 100644
--- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/NodeAcl.cs
+++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/NodeAcl.cs
@@ -8,14 +8,19 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Entities;
///
public sealed class NodeAcl
{
+ /// Gets or sets the database row ID for this ACL entry.
public Guid NodeAclRowId { get; set; }
+ /// Gets or sets the logical ID of this ACL entry.
public required string NodeAclId { get; set; }
+ /// Gets or sets the cluster ID for this ACL entry.
public required string ClusterId { get; set; }
+ /// Gets or sets the LDAP group for this ACL entry.
public required string LdapGroup { get; set; }
+ /// Gets or sets the scope kind for this ACL entry.
public required NodeAclScopeKind ScopeKind { get; set; }
/// NULL when = ; otherwise the scoped entity's logical ID.
@@ -24,6 +29,7 @@ public sealed class NodeAcl
/// Bitmask of . Stored as int in SQL.
public required NodePermissions PermissionFlags { get; set; }
+ /// Gets or sets optional notes for this ACL entry.
public string? Notes { get; set; }
/// Optimistic concurrency token for last-write-wins detection in the v2 live-edit model.
diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/NodeDeploymentState.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/NodeDeploymentState.cs
index 0a53094e..95375733 100644
--- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/NodeDeploymentState.cs
+++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/NodeDeploymentState.cs
@@ -10,20 +10,29 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Entities;
///
public sealed class NodeDeploymentState
{
+ /// Gets or sets the cluster node identifier.
public required string NodeId { get; init; }
+ /// Gets or sets the deployment identifier.
public Guid DeploymentId { get; init; }
+ /// Gets or sets the deployment status on this node.
public NodeDeploymentStatus Status { get; set; } = NodeDeploymentStatus.Applying;
+ /// Gets or sets the UTC timestamp when the deployment application started.
public DateTime StartedAtUtc { get; set; } = DateTime.UtcNow;
+ /// Gets or sets the UTC timestamp when the deployment was successfully applied, or null if not yet applied.
public DateTime? AppliedAtUtc { get; set; }
+ /// Gets or sets the failure reason if the deployment failed, or null if successful.
public string? FailureReason { get; set; }
+ /// Gets or sets the row version for optimistic concurrency control.
public byte[] RowVersion { get; set; } = Array.Empty();
+ /// Gets or sets the cluster node entity reference.
public ClusterNode? Node { get; set; }
+ /// Gets or sets the deployment entity reference.
public Deployment? Deployment { get; set; }
}
diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/PollGroup.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/PollGroup.cs
index 5d6c99b5..4220c3f8 100644
--- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/PollGroup.cs
+++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/PollGroup.cs
@@ -3,14 +3,19 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Entities;
/// Driver-scoped polling group. Tags reference it via .
public sealed class PollGroup
{
+ /// Gets or sets the database row identifier for the polling group.
public Guid PollGroupRowId { get; set; }
+ /// Gets or sets the unique identifier for the polling group.
public required string PollGroupId { get; set; }
+ /// Gets or sets the driver instance that owns this polling group.
public required string DriverInstanceId { get; set; }
+ /// Gets or sets the display name of the polling group.
public required string Name { get; set; }
+ /// Gets or sets the poll interval in milliseconds.
public int IntervalMs { get; set; }
/// Optimistic concurrency token for last-write-wins detection in the v2 live-edit model.
diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/Script.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/Script.cs
index 056340eb..17fa3ad9 100644
--- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/Script.cs
+++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/Script.cs
@@ -16,6 +16,7 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Entities;
///
public sealed class Script
{
+ /// Gets or sets the script row identifier.
public Guid ScriptRowId { get; set; }
/// Stable logical id. Globally unique in v2.
diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ScriptedAlarm.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ScriptedAlarm.cs
index cb5d1710..b53aab4d 100644
--- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ScriptedAlarm.cs
+++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ScriptedAlarm.cs
@@ -16,6 +16,7 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Entities;
///
public sealed class ScriptedAlarm
{
+ /// Gets or sets the database row identifier for this scripted alarm.
public Guid ScriptedAlarmRowId { get; set; }
/// Stable logical id — drives AlarmConditionType.ConditionName. Globally unique in v2.
@@ -52,6 +53,7 @@ public sealed class ScriptedAlarm
///
public bool Retain { get; set; } = true;
+ /// Gets or sets a value indicating whether this alarm is enabled.
public bool Enabled { get; set; } = true;
/// Optimistic concurrency token for last-write-wins detection in the v2 live-edit model.
diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ScriptedAlarmState.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ScriptedAlarmState.cs
index d0d78373..c199ac63 100644
--- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ScriptedAlarmState.cs
+++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ScriptedAlarmState.cs
@@ -45,13 +45,16 @@ public sealed class ScriptedAlarmState
/// Operator-supplied ack comment. Null if no comment or never acked.
public string? LastAckComment { get; set; }
+ /// Gets or sets the UTC timestamp of the last acknowledgment.
public DateTime? LastAckUtc { get; set; }
/// User who last confirmed.
public string? LastConfirmUser { get; set; }
+ /// Gets or sets the operator-supplied confirm comment. Null if no comment or never confirmed.
public string? LastConfirmComment { get; set; }
+ /// Gets or sets the UTC timestamp of the last confirmation.
public DateTime? LastConfirmUtc { get; set; }
/// JSON array of operator comments, append-only (GxP audit).
diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ServerCluster.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ServerCluster.cs
index 159bb79b..c05e5b36 100644
--- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ServerCluster.cs
+++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/ServerCluster.cs
@@ -11,6 +11,7 @@ public sealed class ServerCluster
/// Stable logical ID, e.g. "LINE3-OPCUA".
public required string ClusterId { get; set; }
+ /// Gets or sets the display name for the server cluster.
public required string Name { get; set; }
/// UNS level 1. Canonical org value: "zb" per decision #140.
@@ -19,23 +20,33 @@ public sealed class ServerCluster
/// UNS level 2, e.g. "warsaw-west".
public required string Site { get; set; }
+ /// Gets or sets the number of nodes in the cluster.
public byte NodeCount { get; set; }
+ /// Gets or sets the redundancy mode for the cluster.
public required RedundancyMode RedundancyMode { get; set; }
+ /// Gets or sets a value indicating whether the cluster is enabled.
public bool Enabled { get; set; } = true;
+ /// Gets or sets optional notes about the cluster.
public string? Notes { get; set; }
+ /// Gets or sets the UTC timestamp when the cluster was created.
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
+ /// Gets or sets the user who created the cluster.
public required string CreatedBy { get; set; }
+ /// Gets or sets the UTC timestamp when the cluster was last modified.
public DateTime? ModifiedAt { get; set; }
+ /// Gets or sets the user who last modified the cluster.
public string? ModifiedBy { get; set; }
// Navigation
+ /// Gets or sets the collection of cluster nodes.
public ICollection Nodes { get; set; } = [];
+ /// Gets or sets the collection of namespaces in the cluster.
public ICollection Namespaces { get; set; } = [];
}
diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/Tag.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/Tag.cs
index ec2f8225..889e9d7f 100644
--- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/Tag.cs
+++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/Tag.cs
@@ -9,12 +9,24 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Entities;
///
public sealed class Tag
{
+ ///
+ /// Gets or sets the unique database row identifier for the tag.
+ ///
public Guid TagRowId { get; set; }
+ ///
+ /// Gets or sets the tag identifier.
+ ///
public required string TagId { get; set; }
+ ///
+ /// Gets or sets the driver instance identifier for this tag.
+ ///
public required string DriverInstanceId { get; set; }
+ ///
+ /// Gets or sets the device identifier.
+ ///
public string? DeviceId { get; set; }
///
@@ -23,6 +35,9 @@ public sealed class Tag
///
public string? EquipmentId { get; set; }
+ ///
+ /// Gets or sets the tag name.
+ ///
public required string Name { get; set; }
/// Only used when is NULL (SystemPlatform namespace).
@@ -31,11 +46,17 @@ public sealed class Tag
/// OPC UA built-in type name (Boolean / Int32 / Float / etc.).
public required string DataType { get; set; }
+ ///
+ /// Gets or sets the access level for this tag.
+ ///
public required TagAccessLevel AccessLevel { get; set; }
/// Per decisions #44–45 — opt-in for write retry eligibility.
public bool WriteIdempotent { get; set; }
+ ///
+ /// Gets or sets the poll group identifier for batching read/write operations.
+ ///
public string? PollGroupId { get; set; }
/// Register address / scaling / poll group / byte-order / etc. — schemaless per driver type.
diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/UnsArea.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/UnsArea.cs
index 36fad95d..889da2d9 100644
--- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/UnsArea.cs
+++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/UnsArea.cs
@@ -3,19 +3,24 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Entities;
/// UNS level-3 segment. Generation-versioned per decision #115.
public sealed class UnsArea
{
+ /// Gets or sets the unique row identifier.
public Guid UnsAreaRowId { get; set; }
+ /// Gets or sets the UNS area identifier.
public required string UnsAreaId { get; set; }
+ /// Gets or sets the cluster identifier.
public required string ClusterId { get; set; }
/// UNS level 3 segment: matches ^[a-z0-9-]{1,32}$ OR equals literal _default.
public required string Name { get; set; }
+ /// Gets or sets optional notes for the area.
public string? Notes { get; set; }
/// Optimistic concurrency token for last-write-wins detection in the v2 live-edit model.
public byte[] RowVersion { get; set; } = Array.Empty();
+ /// Gets or sets the associated server cluster.
public ServerCluster? Cluster { get; set; }
}
diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/UnsLine.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/UnsLine.cs
index d95e7d16..ee990fbf 100644
--- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/UnsLine.cs
+++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/UnsLine.cs
@@ -3,8 +3,10 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Entities;
/// UNS level-4 segment. Generation-versioned per decision #115.
public sealed class UnsLine
{
+ /// Gets or sets the unique row identifier for this UNS line.
public Guid UnsLineRowId { get; set; }
+ /// Gets or sets the unique identifier for this UNS line.
public required string UnsLineId { get; set; }
/// Logical FK to .
@@ -13,6 +15,7 @@ public sealed class UnsLine
/// UNS level 4 segment: matches ^[a-z0-9-]{1,32}$ OR equals literal _default.
public required string Name { get; set; }
+ /// Gets or sets optional notes describing this UNS line.
public string? Notes { get; set; }
/// Optimistic concurrency token for last-write-wins detection in the v2 live-edit model.
diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/VirtualTag.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/VirtualTag.cs
index bf160cc2..5957dba9 100644
--- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/VirtualTag.cs
+++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/Entities/VirtualTag.cs
@@ -20,9 +20,10 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.Entities;
///
public sealed class VirtualTag
{
+ /// Gets or sets the database row ID (primary key).
public Guid VirtualTagRowId { get; set; }
- /// Stable logical id. Globally unique in v2.
+ /// Gets or sets the stable logical identifier, globally unique in v2.
public required string VirtualTagId { get; set; }
/// Logical FK to — owner of this virtual tag.
@@ -43,9 +44,10 @@ public sealed class VirtualTag
/// Timer re-evaluation cadence in milliseconds. null = no timer.
public int? TimerIntervalMs { get; set; }
- /// Per plan decision #10 — checkbox to route this tag's values through IHistoryWriter.
+ /// Gets or sets a value indicating whether this tag's values should be historized.
public bool Historize { get; set; }
+ /// Gets or sets a value indicating whether this virtual tag is enabled.
public bool Enabled { get; set; } = true;
/// Optimistic concurrency token for last-write-wins detection in the v2 live-edit model.
diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/LocalCache/GenerationSealedCache.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/LocalCache/GenerationSealedCache.cs
index 78408c97..a64ddf3a 100644
--- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/LocalCache/GenerationSealedCache.cs
+++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/LocalCache/GenerationSealedCache.cs
@@ -31,6 +31,8 @@ public sealed class GenerationSealedCache
/// Root directory for all clusters' sealed caches.
public string CacheRoot => _cacheRoot;
+ /// Initializes a new instance of the GenerationSealedCache class.
+ /// The root directory for the cache.
public GenerationSealedCache(string cacheRoot)
{
ArgumentException.ThrowIfNullOrWhiteSpace(cacheRoot);
@@ -43,6 +45,9 @@ public sealed class GenerationSealedCache
/// mark the file read-only, then atomically publish the CURRENT pointer. Existing
/// sealed files for prior generations are preserved (prune separately).
///
+ /// The generation snapshot to seal.
+ /// The cancellation token.
+ /// A task representing the asynchronous operation.
public async Task SealAsync(GenerationSnapshot snapshot, CancellationToken ct = default)
{
ArgumentNullException.ThrowIfNull(snapshot);
@@ -88,6 +93,9 @@ public sealed class GenerationSealedCache
/// (first-boot-no-snapshot case) or when the sealed file is corrupt. Never silently
/// falls back to a prior generation.
///
+ /// The cluster ID to read the snapshot for.
+ /// The cancellation token.
+ /// A task representing the asynchronous operation containing the generation snapshot.
public Task ReadCurrentAsync(string clusterId, CancellationToken ct = default)
{
ArgumentException.ThrowIfNullOrWhiteSpace(clusterId);
@@ -135,6 +143,8 @@ public sealed class GenerationSealedCache
}
/// Return the generation id the CURRENT pointer points at, or null if no pointer exists.
+ /// The cluster ID to get the current generation ID for.
+ /// The generation ID, or null if no pointer exists.
public long? TryGetCurrentGenerationId(string clusterId)
{
ArgumentException.ThrowIfNullOrWhiteSpace(clusterId);
@@ -165,6 +175,11 @@ public sealed class GenerationSealedCache
/// Sealed cache is unreachable — caller must fail closed.
public sealed class GenerationCacheUnavailableException : Exception
{
+ /// Initializes a new instance of the GenerationCacheUnavailableException class.
+ /// The error message.
public GenerationCacheUnavailableException(string message) : base(message) { }
+ /// Initializes a new instance of the GenerationCacheUnavailableException class with an inner exception.
+ /// The error message.
+ /// The inner exception.
public GenerationCacheUnavailableException(string message, Exception inner) : base(message, inner) { }
}
diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/LocalCache/GenerationSnapshot.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/LocalCache/GenerationSnapshot.cs
index 9d67ce4f..b883719d 100644
--- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/LocalCache/GenerationSnapshot.cs
+++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/LocalCache/GenerationSnapshot.cs
@@ -7,9 +7,14 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.LocalCache;
///
public sealed class GenerationSnapshot
{
+ /// Gets or sets the auto-generated LiteDB ID.
public int Id { get; set; } // LiteDB auto-ID
+ /// Gets or sets the cluster identifier.
public required string ClusterId { get; set; }
+ /// Gets or sets the generation identifier.
public required long GenerationId { get; set; }
+ /// Gets or sets the time this snapshot was cached.
public required DateTime CachedAt { get; set; }
+ /// Gets or sets the JSON-serialized payload content.
public required string PayloadJson { get; set; }
}
diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/LocalCache/ILocalConfigCache.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/LocalCache/ILocalConfigCache.cs
index a4cca538..fc92d9ec 100644
--- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/LocalCache/ILocalConfigCache.cs
+++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/LocalCache/ILocalConfigCache.cs
@@ -13,7 +13,18 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration.LocalCache;
///
public interface ILocalConfigCache
{
+ /// Retrieves the most recent generation snapshot for the specified cluster.
+ /// The cluster identifier.
+ /// The cancellation token.
+ /// The most recent generation snapshot, or null if none exists.
Task GetMostRecentAsync(string clusterId, CancellationToken ct = default);
+ /// Stores a generation snapshot in the local cache.
+ /// The generation snapshot to store.
+ /// The cancellation token.
Task PutAsync(GenerationSnapshot snapshot, CancellationToken ct = default);
+ /// Removes old generations, keeping only the most recent N.
+ /// The cluster identifier.
+ /// The number of latest generations to keep.
+ /// The cancellation token.
Task PruneOldGenerationsAsync(string clusterId, int keepLatest = 10, CancellationToken ct = default);
}
diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/LocalCache/LiteDbConfigCache.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/LocalCache/LiteDbConfigCache.cs
index 8c04b2d5..39e5dfb4 100644
--- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/LocalCache/LiteDbConfigCache.cs
+++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/LocalCache/LiteDbConfigCache.cs
@@ -20,6 +20,8 @@ public sealed class LiteDbConfigCache : ILocalConfigCache, IDisposable
// page-level write, not the find-then-insert window.
private readonly SemaphoreSlim _writeGate = new(initialCount: 1, maxCount: 1);
+ /// Initializes a new instance of the class.
+ /// Path to the LiteDB database file.
public LiteDbConfigCache(string dbPath)
{
// LiteDB can be tolerant of header-only corruption at construction time (it may overwrite
@@ -43,6 +45,9 @@ public sealed class LiteDbConfigCache : ILocalConfigCache, IDisposable
}
}
+ /// Gets the most recent snapshot for the specified cluster.
+ /// The cluster ID.
+ /// Cancellation token.
public Task GetMostRecentAsync(string clusterId, CancellationToken ct = default)
{
ct.ThrowIfCancellationRequested();
@@ -53,6 +58,9 @@ public sealed class LiteDbConfigCache : ILocalConfigCache, IDisposable
return Task.FromResult(snapshot);
}
+ /// Stores a snapshot in the cache.
+ /// The snapshot to store.
+ /// Cancellation token.
public async Task PutAsync(GenerationSnapshot snapshot, CancellationToken ct = default)
{
ct.ThrowIfCancellationRequested();
@@ -81,6 +89,10 @@ public sealed class LiteDbConfigCache : ILocalConfigCache, IDisposable
}
}
+ /// Removes old generation snapshots, keeping only the latest ones.
+ /// The cluster ID.
+ /// Number of latest generations to keep.
+ /// Cancellation token.
public Task PruneOldGenerationsAsync(string clusterId, int keepLatest = 10, CancellationToken ct = default)
{
ct.ThrowIfCancellationRequested();
@@ -97,6 +109,7 @@ public sealed class LiteDbConfigCache : ILocalConfigCache, IDisposable
return Task.CompletedTask;
}
+ /// Releases all resources used by the cache.
public void Dispose()
{
_writeGate.Dispose();
diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/LocalCache/ResilientConfigReader.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/LocalCache/ResilientConfigReader.cs
index d628565d..d6c72bf1 100644
--- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/LocalCache/ResilientConfigReader.cs
+++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/LocalCache/ResilientConfigReader.cs
@@ -27,6 +27,12 @@ public sealed class ResilientConfigReader
private readonly ResiliencePipeline _pipeline;
private readonly ILogger _logger;
+ /// Initializes a resilient config reader with the given cache and options.
+ /// The sealed cache for fallback.
+ /// The stale config flag to manage.
+ /// The logger instance.
+ /// The timeout for central fetch (default 2s).
+ /// The number of retries (default 3).
public ResilientConfigReader(
GenerationSealedCache cache,
StaleConfigFlag staleFlag,
@@ -71,6 +77,9 @@ public sealed class ResilientConfigReader
@"(?ix)\b(Password|Pwd|User\s*Id|Uid|AccessToken|Authorization|Api[-_]?Key)\s*=\s*[^;,)\s]*",
RegexOptions.Compiled);
+ /// Redacts sensitive credential information from a message.
+ /// The message to scrub.
+ /// The message with redacted credentials.
internal static string ScrubSecrets(string? message)
{
if (string.IsNullOrEmpty(message)) return message ?? string.Empty;
@@ -80,10 +89,15 @@ public sealed class ResilientConfigReader
}
///
- /// Execute through the resilience pipeline. On full failure
- /// (post-retry), reads the sealed cache for and passes the
- /// snapshot to to extract the requested shape.
+ /// Executes a central fetch through the resilience pipeline. On full failure
+ /// (post-retry), reads the sealed cache and extracts the requested shape.
///
+ /// The type of configuration to read.
+ /// The cluster ID to fetch for.
+ /// Function to fetch from central DB.
+ /// Function to extract the config from a snapshot.
+ /// Cancellation token.
+ /// The configuration of type T.
public async ValueTask ReadAsync(
string clusterId,
Func> centralFetch,
diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/OtOpcUaConfigDbContext.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/OtOpcUaConfigDbContext.cs
index 06ef21f7..97747fe1 100644
--- a/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/OtOpcUaConfigDbContext.cs
+++ b/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/OtOpcUaConfigDbContext.cs
@@ -12,39 +12,69 @@ namespace ZB.MOM.WW.OtOpcUa.Configuration;
public sealed class OtOpcUaConfigDbContext(DbContextOptions options)
: DbContext(options), IDataProtectionKeyContext
{
+ /// Gets the DbSet of server clusters.
public DbSet ServerClusters => Set();
+ /// Gets the DbSet of cluster nodes.
public DbSet ClusterNodes => Set();
+ /// Gets the DbSet of cluster node credentials.
public DbSet ClusterNodeCredentials => Set();
+ /// Gets the DbSet of namespaces.
public DbSet Namespaces => Set();
+ /// Gets the DbSet of UNS areas.
public DbSet UnsAreas => Set();
+ /// Gets the DbSet of UNS lines.
public DbSet UnsLines => Set();
+ /// Gets the DbSet of driver instances.
public DbSet DriverInstances => Set();
+ /// Gets the DbSet of devices.
public DbSet Devices => Set();
+ /// Gets the DbSet of equipment.
public DbSet Equipment => Set();
+ /// Gets the DbSet of tags.
public DbSet Tags => Set();
+ /// Gets the DbSet of poll groups.
public DbSet PollGroups => Set();
+ /// Gets the DbSet of node ACLs.
public DbSet NodeAcls => Set();
+ /// Gets the DbSet of configuration audit logs.
public DbSet ConfigAuditLogs => Set();
+ /// Gets the DbSet of external ID reservations.
public DbSet ExternalIdReservations => Set();
+ /// Gets the DbSet of driver host statuses.
public DbSet DriverHostStatuses => Set();
+ /// Gets the DbSet of driver instance resilience statuses.
public DbSet DriverInstanceResilienceStatuses => Set();
+ /// Gets the DbSet of LDAP group role mappings.
public DbSet LdapGroupRoleMappings => Set();
+ /// Gets the DbSet of equipment import batches.
public DbSet EquipmentImportBatches => Set();
+ /// Gets the DbSet of equipment import rows.
public DbSet EquipmentImportRows => Set();
+ /// Gets the DbSet of scripts.
public DbSet