feat(cli): add enable/disable condition commands (H4 client path)

This commit is contained in:
Joseph Doherty
2026-06-19 01:48:21 -04:00
parent eb328e5761
commit 88d5ba45bf
10 changed files with 488 additions and 0 deletions
@@ -461,6 +461,50 @@ public sealed class OpcUaClientService : IOpcUaClientService
return StatusCodes.Good;
}
/// <inheritdoc />
public Task<StatusCode> EnableAsync(string conditionNodeId, CancellationToken ct = default) =>
CallEnableDisableAsync(conditionNodeId, enabling: true, ct);
/// <inheritdoc />
public Task<StatusCode> DisableAsync(string conditionNodeId, CancellationToken ct = default) =>
CallEnableDisableAsync(conditionNodeId, enabling: false, ct);
/// <summary>
/// Shared body for the H4 Enable/Disable client path. Invokes the OPC UA Part 9 ConditionType
/// <c>Enable</c>/<c>Disable</c> method (no input arguments) on the condition object node, mirroring
/// the <see cref="AcknowledgeAlarmAsync"/> convention: the methods live on the <c>.Condition</c>
/// child node, and a bad call result surfaces as the returned <see cref="StatusCode"/> rather than
/// escaping as an uncaught <see cref="ServiceResultException"/>.
/// </summary>
/// <param name="conditionNodeId">The condition node associated with the alarm.</param>
/// <param name="enabling"><c>true</c> to invoke Enable; <c>false</c> to invoke Disable.</param>
/// <param name="ct">The cancellation token that aborts the request.</param>
private async Task<StatusCode> CallEnableDisableAsync(string conditionNodeId, bool enabling, CancellationToken ct)
{
ThrowIfDisposed();
ThrowIfNotConnected();
// Enable/Disable live on the same .Condition child node as Acknowledge/Confirm.
var conditionObjId = conditionNodeId.EndsWith(".Condition")
? NodeId.Parse(conditionNodeId)
: NodeId.Parse(conditionNodeId + ".Condition");
var methodId = enabling ? MethodIds.ConditionType_Enable : MethodIds.ConditionType_Disable;
try
{
await _session!.CallMethodAsync(conditionObjId, methodId, [], ct);
}
catch (ServiceResultException ex)
{
Logger.Warning(ex, "Failed to {Operation} alarm on {ConditionId} (status {Status})",
enabling ? "enable" : "disable", conditionNodeId, ex.StatusCode);
return ex.StatusCode;
}
Logger.Debug("{Operation} alarm on {ConditionId}", enabling ? "Enabled" : "Disabled", conditionNodeId);
return StatusCodes.Good;
}
/// <inheritdoc />
public async Task<IReadOnlyList<DataValue>> HistoryReadRawAsync(
NodeId nodeId, DateTime startTime, DateTime endTime, int maxValues = 1000, CancellationToken ct = default)