using CliFx.Attributes;
using ZB.MOM.WW.OtOpcUa.Driver.Cli.Common;
namespace ZB.MOM.WW.OtOpcUa.Driver.AbCip.Cli;
///
/// Base for every AB CIP CLI command. Carries the libplctag endpoint options
/// (--gateway + --family) and exposes so each
/// command can synthesise an from CLI flags + its own
/// tag list.
///
public abstract class AbCipCommandBase : DriverCommandBase
{
[CommandOption("gateway", 'g', Description =
"Canonical AB CIP gateway: ab://host[:port]/cip-path. Port defaults to 44818 " +
"(EtherNet/IP). cip-path is family-specific: ControlLogix / CompactLogix need " +
"'1,0' to reach slot 0 of the CPU chassis; Micro800 takes an empty path; " +
"GuardLogix typically '1,0' same as ControlLogix.",
IsRequired = true)]
public string Gateway { get; init; } = default!;
[CommandOption("family", 'f', Description =
"ControlLogix / CompactLogix / Micro800 / GuardLogix (default ControlLogix).")]
public AbCipPlcFamily Family { get; init; } = AbCipPlcFamily.ControlLogix;
[CommandOption("timeout-ms", Description = "Per-operation timeout in ms (default 5000).")]
public int TimeoutMs { get; init; } = 5000;
///
public override TimeSpan Timeout
{
get => TimeSpan.FromMilliseconds(TimeoutMs);
init { /* driven by TimeoutMs */ }
}
///
/// Build an with the device + tag list a subclass
/// supplies. Probe + alarm projection are disabled — CLI runs are one-shot; the
/// probe loop would race the operator's own reads.
///
protected AbCipDriverOptions BuildOptions(IReadOnlyList tags) => new()
{
Devices = [new AbCipDeviceOptions(
HostAddress: Gateway,
PlcFamily: Family,
DeviceName: $"cli-{Family}")],
Tags = tags,
Timeout = Timeout,
Probe = new AbCipProbeOptions { Enabled = false },
EnableControllerBrowse = false,
EnableAlarmProjection = false,
};
///
/// Short instance id used in Serilog output so operators running the CLI against
/// multiple gateways in parallel can distinguish the logs.
///
protected string DriverInstanceId => $"abcip-cli-{Gateway}";
}