using CliFx; using CliFx.Attributes; using CliFx.Infrastructure; using Serilog; namespace ZB.MOM.WW.OtOpcUa.Driver.Cli.Common; /// /// Shared base for every driver test-client command (Modbus / AB CIP / AB Legacy / S7 / /// TwinCAT). Carries the options that are meaningful regardless of protocol — verbose /// logging + the standard timeout — plus helpers every command implementation wants: /// Serilog configuration + cancellation-token capture. /// /// /// /// Each driver CLI sub-classes this with its own protocol-specific base (e.g. /// ModbusCommandBase) that adds host/port/unit-id + a BuildDriver() /// factory. That second layer is the point where the driver's {Driver}DriverOptions /// type plugs in; keeping it out of this common base lets each driver CLI stay a thin /// executable with no dependency on the other drivers' projects. /// /// /// Why a shared base at all — without this every CLI re-authored the same ~40 lines /// of Serilog wiring + cancel-token plumbing + verbose flag. /// /// public abstract class DriverCommandBase : ICommand { /// /// Enable Serilog debug-level output. Leave off for clean one-line-per-call output; /// switch on when diagnosing a connect / PDU-framing / retry problem. /// [CommandOption("verbose", Description = "Enable verbose/debug Serilog output")] public bool Verbose { get; init; } /// /// Request-level timeout used by the driver's Initialize / Read / /// Write / probe calls. Defaults per-protocol (Modbus: 2s, AB: 5s, S7: 5s, /// TwinCAT: 5s) — each driver CLI overrides this property with the appropriate /// [CommandOption] default. /// public abstract TimeSpan Timeout { get; init; } public abstract ValueTask ExecuteAsync(IConsole console); /// /// Configures the process-global Serilog logger. Commands call this at the top of /// so driver-internal Log.Logger writes land on the /// same sink as the CLI's operator-facing output. /// protected void ConfigureLogging() { var config = new LoggerConfiguration(); if (Verbose) config.MinimumLevel.Debug().WriteTo.Console(); else config.MinimumLevel.Warning().WriteTo.Console(); Log.Logger = config.CreateLogger(); } }