86f3fc2733
Closes #271
82 lines
3.8 KiB
C#
82 lines
3.8 KiB
C#
using CliFx.Attributes;
|
|
using ZB.MOM.WW.OtOpcUa.Driver.Cli.Common;
|
|
|
|
namespace ZB.MOM.WW.OtOpcUa.Driver.FOCAS.Cli;
|
|
|
|
/// <summary>
|
|
/// Base for every FOCAS CLI command. Carries the CNC endpoint options
|
|
/// (host / port / series) + exposes <see cref="BuildOptions"/> so each command
|
|
/// can synthesise a <see cref="FocasDriverOptions"/> with one device + one tag.
|
|
/// </summary>
|
|
public abstract class FocasCommandBase : DriverCommandBase
|
|
{
|
|
[CommandOption("cnc-host", 'h', Description =
|
|
"CNC IP address or hostname. FOCAS-over-EIP listens on port 8193 by default.",
|
|
IsRequired = true)]
|
|
public string CncHost { get; init; } = default!;
|
|
|
|
[CommandOption("cnc-port", 'p', Description = "FOCAS TCP port (default 8193).")]
|
|
public int CncPort { get; init; } = 8193;
|
|
|
|
[CommandOption("series", 's', Description =
|
|
"CNC series: Unknown / Zero_i_D / Zero_i_F / Zero_i_MF / Zero_i_TF / Sixteen_i / " +
|
|
"Thirty_i / ThirtyOne_i / ThirtyTwo_i / PowerMotion_i (default Unknown).")]
|
|
public FocasCncSeries Series { get; init; } = FocasCncSeries.Unknown;
|
|
|
|
[CommandOption("timeout-ms", Description = "Per-operation timeout in ms (default 2000).")]
|
|
public int TimeoutMs { get; init; } = 2000;
|
|
|
|
/// <summary>
|
|
/// Plan PR F4-d (issue #271) — optional CNC connection-level password emitted
|
|
/// via <c>cnc_wrunlockparam</c> on connect. Required only by controllers that
|
|
/// gate <c>cnc_wrparam</c> + selected reads behind a password switch.
|
|
/// PASSWORD INVARIANT: never logged. The CLI's Serilog config does not
|
|
/// include this option in any console / file destructure; the redaction is
|
|
/// enforced at the <see cref="FocasDeviceOptions"/> layer (record's
|
|
/// overridden <c>ToString</c>).
|
|
/// </summary>
|
|
[CommandOption("cnc-password", Description =
|
|
"Optional CNC connection password emitted via cnc_wrunlockparam on connect. " +
|
|
"Required by controllers that gate parameter writes behind a password switch.")]
|
|
public string? CncPassword { get; init; }
|
|
|
|
/// <inheritdoc />
|
|
public override TimeSpan Timeout
|
|
{
|
|
get => TimeSpan.FromMilliseconds(TimeoutMs);
|
|
init { /* driven by TimeoutMs */ }
|
|
}
|
|
|
|
/// <summary>Canonical FOCAS host-address string, shape <c>focas://host:port</c>.</summary>
|
|
protected string HostAddress => $"focas://{CncHost}:{CncPort}";
|
|
|
|
/// <summary>
|
|
/// Build a <see cref="FocasDriverOptions"/> with the CNC target this base collected
|
|
/// + the tag list a subclass supplies. Probe disabled; the default
|
|
/// <see cref="FwlibFocasClientFactory"/> attempts <c>Fwlib32.dll</c> P/Invoke, which
|
|
/// throws <see cref="DllNotFoundException"/> at first call when the DLL is absent —
|
|
/// surfaced through the driver as <c>BadCommunicationError</c>. Pass
|
|
/// <paramref name="writesEnabled"/> = <c>true</c> to bypass the F4-a driver-level
|
|
/// write gate for the lifetime of this CLI invocation (issue #268).
|
|
/// </summary>
|
|
protected FocasDriverOptions BuildOptions(
|
|
IReadOnlyList<FocasTagDefinition> tags, bool writesEnabled = false) => new()
|
|
{
|
|
Devices = [new FocasDeviceOptions(
|
|
HostAddress: HostAddress,
|
|
DeviceName: $"cli-{CncHost}:{CncPort}",
|
|
Series: Series,
|
|
OverrideParameters: null,
|
|
// PR F4-d (issue #271) — thread the CLI's --cnc-password through to
|
|
// the driver. Null when the operator didn't supply the flag — the
|
|
// driver short-circuits the unlock call in that case.
|
|
Password: CncPassword)],
|
|
Tags = tags,
|
|
Timeout = Timeout,
|
|
Probe = new FocasProbeOptions { Enabled = false },
|
|
Writes = new FocasWritesOptions { Enabled = writesEnabled },
|
|
};
|
|
|
|
protected string DriverInstanceId => $"focas-cli-{CncHost}:{CncPort}";
|
|
}
|