bd6c0b4d3d
Add missing <returns>/<param>/<summary>/<typeparam> tags and clean up misused inheritdoc across 481 files so the documented API surface is complete. Documentation-only (zero code lines changed). The 131 remaining findings are inheritdoc-style warnings deliberately left to preserve hand-written implementation rationale (plan-decision notes, race-condition explanations).
65 lines
2.7 KiB
C#
65 lines
2.7 KiB
C#
using CliFx.Attributes;
|
|
using CliFx.Infrastructure;
|
|
using ZB.MOM.WW.OtOpcUa.Driver.Cli.Common;
|
|
|
|
namespace ZB.MOM.WW.OtOpcUa.Driver.AbLegacy.Cli.Commands;
|
|
|
|
/// <summary>
|
|
/// Read one PCCC address (N7:0, F8:0, B3:0/3, L19:0, ST17:0, T4:0.ACC, etc.).
|
|
/// </summary>
|
|
[Command("read", Description = "Read a single PCCC file address.")]
|
|
public sealed class ReadCommand : AbLegacyCommandBase
|
|
{
|
|
/// <summary>Gets the PCCC file address to read.</summary>
|
|
[CommandOption("address", 'a', Description =
|
|
"PCCC file address. File letter implies storage; bit-within-word via slash " +
|
|
"(B3:0/3 or N7:0/5). Sub-element access for timers/counters/controls uses " +
|
|
"dot notation (T4:0.ACC, C5:0.PRE, R6:0.LEN).",
|
|
IsRequired = true)]
|
|
public string Address { get; init; } = default!;
|
|
|
|
/// <summary>Gets the data type of the address.</summary>
|
|
[CommandOption("type", 't', Description =
|
|
"Bit / Int / Long / Float / AnalogInt / String / TimerElement / CounterElement / " +
|
|
"ControlElement (default Int).")]
|
|
public AbLegacyDataType DataType { get; init; } = AbLegacyDataType.Int;
|
|
|
|
/// <inheritdoc />
|
|
public override async ValueTask ExecuteAsync(IConsole console)
|
|
{
|
|
ConfigureLogging();
|
|
var ct = console.RegisterCancellationHandler();
|
|
|
|
var tagName = SynthesiseTagName(Address, DataType);
|
|
var tag = new AbLegacyTagDefinition(
|
|
Name: tagName,
|
|
DeviceHostAddress: Gateway,
|
|
Address: Address,
|
|
DataType: DataType,
|
|
Writable: false);
|
|
var options = BuildOptions([tag]);
|
|
|
|
// Plain `var driver`: explicit ShutdownAsync(CancellationToken.None) in the
|
|
// finally is the deliberate teardown path; combining it with `await using`
|
|
// (which itself calls ShutdownAsync) would tear the driver down twice.
|
|
var driver = new AbLegacyDriver(options, DriverInstanceId);
|
|
try
|
|
{
|
|
await driver.InitializeAsync("{}", ct);
|
|
var snapshot = await driver.ReadAsync([tagName], ct);
|
|
await console.Output.WriteLineAsync(SnapshotFormatter.Format(Address, snapshot[0]));
|
|
}
|
|
finally
|
|
{
|
|
await driver.ShutdownAsync(CancellationToken.None);
|
|
}
|
|
}
|
|
|
|
/// <summary>Tag-name key the driver uses internally. Address+type is already unique.</summary>
|
|
/// <param name="address">The PCCC file address.</param>
|
|
/// <param name="type">The data type of the address.</param>
|
|
/// <returns>A combined tag name string in the form <c>address:type</c>.</returns>
|
|
internal static string SynthesiseTagName(string address, AbLegacyDataType type)
|
|
=> $"{address}:{type}";
|
|
}
|