using CliFx.Attributes; using CliFx.Infrastructure; using ZB.MOM.WW.OtOpcUa.Driver.Cli.Common; namespace ZB.MOM.WW.OtOpcUa.Driver.AbCip.Cli.Commands; /// /// Read one Logix tag by symbolic path. Operator specifies --tag + --type; /// the CLI synthesises a one-tag driver config, reads once, prints the snapshot, shuts /// down. UDT / Structure reads are out of scope here — those need the member layout /// declared, which belongs in a real driver config. /// [Command("read", Description = "Read a single Logix tag by symbolic path.")] public sealed class ReadCommand : AbCipCommandBase { [CommandOption("tag", 't', Description = "Logix symbolic path. Controller scope: 'Motor01_Speed'. Program scope: " + "'Program:Main.Motor01_Speed'. Array element: 'Recipe[3]'. UDT member: " + "'Motor01.Speed'.", IsRequired = true)] public string TagPath { get; init; } = default!; [CommandOption("type", Description = "Bool / SInt / Int / DInt / LInt / USInt / UInt / UDInt / ULInt / Real / LReal / " + "String / Dt / Structure (default DInt).")] public AbCipDataType DataType { get; init; } = AbCipDataType.DInt; public override async ValueTask ExecuteAsync(IConsole console) { ConfigureLogging(); var ct = console.RegisterCancellationHandler(); var tagName = SynthesiseTagName(TagPath, DataType); var tag = new AbCipTagDefinition( Name: tagName, DeviceHostAddress: Gateway, TagPath: TagPath, DataType: DataType, Writable: false); var options = BuildOptions([tag]); await using var driver = new AbCipDriver(options, DriverInstanceId); try { await driver.InitializeAsync("{}", ct); var snapshot = await driver.ReadAsync([tagName], ct); await console.Output.WriteLineAsync(SnapshotFormatter.Format(TagPath, snapshot[0])); } finally { await driver.ShutdownAsync(CancellationToken.None); } } /// /// Tag-name key the driver uses internally. The path + type pair is already unique /// so we use them verbatim — keeps tag-level diagnostics readable without mangling. /// internal static string SynthesiseTagName(string tagPath, AbCipDataType type) => $"{tagPath}:{type}"; }