using CliFx.Attributes; using CliFx.Exceptions; using CliFx.Infrastructure; using Opc.Ua; using ZB.MOM.WW.OtOpcUa.Client.CLI.Helpers; using ZB.MOM.WW.OtOpcUa.Client.Shared; namespace ZB.MOM.WW.OtOpcUa.Client.CLI.Commands; [Command("confirm", Description = "Confirm an acknowledged alarm condition (OPC UA Part 9 two-stage acknowledgment)")] public class ConfirmCommand : CommandBase { /// /// Creates the confirm command used to confirm an acknowledged OPC UA condition from the terminal. /// /// The factory that creates the shared client service for the command run. public ConfirmCommand(IOpcUaClientServiceFactory factory) : base(factory) { } /// /// Gets the condition node ID of the alarm event to confirm. /// [CommandOption("node", 'n', Description = "Condition node ID of the alarm to confirm", IsRequired = true)] public string NodeId { get; init; } = default!; /// /// Gets the event ID (hex-encoded) returned by the server in the alarm notification. /// [CommandOption("event-id", 'e', Description = "EventId from the alarm notification (hex-encoded byte array)", IsRequired = true)] public string EventId { get; init; } = default!; /// /// Gets the operator comment to include with the confirmation. /// [CommandOption("comment", 'c', Description = "Operator comment for the confirmation")] public string Comment { get; init; } = string.Empty; /// public override async ValueTask ExecuteAsync(IConsole console) { ConfigureLogging(); try { NodeIdParser.ParseRequired(NodeId); } catch (Exception ex) when (ex is FormatException or ArgumentException) { throw new CommandException($"Invalid --node value: {ex.Message}"); } byte[] eventId; try { eventId = Convert.FromHexString(EventId); } catch (FormatException ex) { throw new CommandException($"Invalid --event-id value: {ex.Message} (expected hex-encoded bytes, e.g. 0A1B2C)"); } IOpcUaClientService? service = null; try { var ct = console.RegisterCancellationHandler(); (service, _) = await CreateServiceAndConnectAsync(ct); var statusCode = await service.ConfirmAlarmAsync(NodeId, eventId, Comment, ct); if (StatusCode.IsGood(statusCode)) await console.Output.WriteLineAsync($"Confirm successful: {NodeId}"); else await console.Output.WriteLineAsync($"Confirm failed: {statusCode}"); } finally { if (service != null) { await service.DisconnectAsync(); service.Dispose(); } } } }