using CliFx.Attributes; using CliFx.Infrastructure; using ZB.MOM.WW.OtOpcUa.Driver.Cli.Common; namespace ZB.MOM.WW.OtOpcUa.Driver.TwinCAT.Cli.Commands; /// /// Probes a TwinCAT runtime: opens an ADS session, reads one symbol, prints driver health. /// Use this first after configuring a new AMS route — it'll surface "no route" / /// "port unreachable" / "AMS router down" errors up-front before you bring the OtOpcUa /// server near the endpoint. /// [Command("probe", Description = "Verify the TwinCAT runtime is reachable and a sample symbol reads.")] public sealed class ProbeCommand : TwinCATTagCommandBase { /// Gets the symbol path to probe in the TwinCAT runtime. [CommandOption("symbol", 's', Description = "Symbol path to probe. System-global examples: " + "'TwinCAT_SystemInfoVarList._AppInfo.OnlineChangeCnt', 'MAIN.bRunning'. " + "User-project: a GVL or program variable.", IsRequired = true)] public string SymbolPath { get; init; } = default!; /// Gets the data type to use for reading the symbol. [CommandOption("type", 't', Description = "Bool / SInt / USInt / Int / UInt / DInt / UDInt / LInt / ULInt / Real / LReal / " + "String / WString / Time / Date / DateTime / TimeOfDay (default DInt).")] public TwinCATDataType DataType { get; init; } = TwinCATDataType.DInt; /// public override async ValueTask ExecuteAsync(IConsole console) { Validate(); ConfigureLogging(); var ct = console.RegisterCancellationHandler(); var probeTag = new TwinCATTagDefinition( Name: "__probe", DeviceHostAddress: Gateway, SymbolPath: SymbolPath, DataType: DataType, Writable: false); var options = BuildOptions([probeTag]); await using var driver = new TwinCATDriver(options, DriverInstanceId); try { await driver.InitializeAsync("{}", ct); var snapshot = await driver.ReadAsync(["__probe"], ct); var health = driver.GetHealth(); await console.Output.WriteLineAsync($"AMS: {AmsNetId}:{AmsPort}"); await console.Output.WriteLineAsync($"Health: {health.State}"); if (health.LastError is { } err) await console.Output.WriteLineAsync($"Last error: {err}"); await console.Output.WriteLineAsync(); await console.Output.WriteLineAsync(SnapshotFormatter.Format(SymbolPath, snapshot[0])); } finally { await driver.ShutdownAsync(CancellationToken.None); FlushLogging(); } } }