561b0f9ea9
Closes #242
97 lines
4.6 KiB
C#
97 lines
4.6 KiB
C#
using CliFx.Attributes;
|
|
using ZB.MOM.WW.OtOpcUa.Driver.Cli.Common;
|
|
|
|
namespace ZB.MOM.WW.OtOpcUa.Driver.AbCip.Cli;
|
|
|
|
/// <summary>
|
|
/// Base for every AB CIP CLI command. Carries the libplctag endpoint options
|
|
/// (<c>--gateway</c> + <c>--family</c>) and exposes <see cref="BuildOptions"/> so each
|
|
/// command can synthesise an <see cref="AbCipDriverOptions"/> from CLI flags + its own
|
|
/// tag list.
|
|
/// </summary>
|
|
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;
|
|
|
|
/// <summary>
|
|
/// PR abcip-3.2 — pin the device's CIP addressing mode for this CLI invocation.
|
|
/// Auto / Symbolic / Logical. Defaults to <see cref="AddressingMode.Auto"/> (resolves
|
|
/// to Symbolic until a future PR plumbs auto-detection). Logical against an
|
|
/// unsupported family (Micro800) silently falls back to Symbolic with a logged
|
|
/// warning, so passing <c>--addressing-mode Logical</c> across a mixed-family
|
|
/// fleet is safe.
|
|
/// </summary>
|
|
[CommandOption("addressing-mode", Description =
|
|
"CIP addressing mode: Auto / Symbolic / Logical (default Auto, resolves to " +
|
|
"Symbolic). Logical uses CIP Symbol Object instance IDs after a one-time @tags " +
|
|
"walk; unsupported on Micro800 (silent fallback to Symbolic with warning).")]
|
|
public AddressingMode AddressingMode { get; init; } = AddressingMode.Auto;
|
|
|
|
/// <summary>
|
|
/// PR abcip-5.1 — partner gateway URI for HSBY (Hot-Standby) paired chassis. When
|
|
/// supplied, every CLI command auto-enables HSBY role probing on the device options
|
|
/// so subcommands like <c>hsby-status</c> + diagnostics surface the active chassis
|
|
/// without extra flags. Unset for non-redundant deployments.
|
|
/// </summary>
|
|
[CommandOption("partner", Description =
|
|
"Partner gateway URI for ControlLogix HSBY pair (e.g. ab://10.0.0.6/1,0). When " +
|
|
"set, the driver runs a second role-probe loop and the hsby-status command can " +
|
|
"surface which chassis is currently Active. Optional.")]
|
|
public string? Partner { get; init; }
|
|
|
|
/// <inheritdoc />
|
|
public override TimeSpan Timeout
|
|
{
|
|
get => TimeSpan.FromMilliseconds(TimeoutMs);
|
|
init { /* driven by TimeoutMs */ }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Build an <see cref="AbCipDriverOptions"/> 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.
|
|
/// </summary>
|
|
protected AbCipDriverOptions BuildOptions(IReadOnlyList<AbCipTagDefinition> tags) => new()
|
|
{
|
|
Devices = [new AbCipDeviceOptions(
|
|
HostAddress: Gateway,
|
|
PlcFamily: Family,
|
|
DeviceName: $"cli-{Family}",
|
|
AddressingMode: AddressingMode,
|
|
// PR abcip-5.1 — surface --partner through the device options so commands that
|
|
// use BuildOptions can take advantage of HSBY role probing without subclassing.
|
|
// Hsby auto-enables only when a partner was actually supplied; pre-5.1 invocations
|
|
// (no --partner) see exactly the legacy options shape.
|
|
PartnerHostAddress: Partner,
|
|
Hsby: string.IsNullOrWhiteSpace(Partner) ? null : new AbCipHsbyOptions
|
|
{
|
|
Enabled = true,
|
|
ProbeInterval = TimeSpan.FromSeconds(2),
|
|
})],
|
|
Tags = tags,
|
|
Timeout = Timeout,
|
|
Probe = new AbCipProbeOptions { Enabled = false },
|
|
EnableControllerBrowse = false,
|
|
EnableAlarmProjection = false,
|
|
};
|
|
|
|
/// <summary>
|
|
/// Short instance id used in Serilog output so operators running the CLI against
|
|
/// multiple gateways in parallel can distinguish the logs.
|
|
/// </summary>
|
|
protected string DriverInstanceId => $"abcip-cli-{Gateway}";
|
|
}
|