Auto: twincat-1.4 — whole-array reads
Surface int[]? ArrayDimensions on TwinCATTagDefinition + thread it through ITwinCATClient.ReadValueAsync / WriteValueAsync. When non-null + non-empty, AdsTwinCATClient issues a single ADS read against the symbol with clrType.MakeArrayType() and returns the flat 1-D CLR Array; for IEC TIME / DATE / DT / TOD element types we project per-element to the native TimeSpan / DateTime so consumers see consistent types regardless of rank. DiscoverAsync surfaces IsArray=true + ArrayDim=product(dims) onto DriverAttributeInfo via a new ResolveArrayShape helper. Multi-dim shapes flatten to the product on the wire — DriverAttributeInfo.ArrayDim is single-uint today and the OPC UA layer reflects rank via its own metadata. Native ADS notification subscriptions skip whole-array tags so the OPC UA layer falls through to a polled snapshot — the per-element AdsNotificationEx callback shape doesn't fit a flat array. Whole-array WRITES are out of scope for this PR — AdsTwinCATClient.WriteValueAsync returns BadNotSupported when ArrayDimensions is set. Tests: TwinCATArrayReadTests covers ResolveArrayShape (null / empty / single-dim / multi-dim flatten / non-positive defensive), DiscoverAsync emitting IsArray + ArrayDim for declared array tags, single-dim + multi-dim fake-client read fan-out, and the BadNotSupported gate on whole-array writes. Existing 137 unit tests still pass — total now 143. Closes #308
This commit is contained in:
@@ -22,22 +22,29 @@ public interface ITwinCATClient : IDisposable
|
||||
/// <summary>
|
||||
/// Read a symbolic value. Returns a boxed .NET value matching the requested
|
||||
/// <paramref name="type"/>, or <c>null</c> when the read produced no data; the
|
||||
/// <c>status</c> tuple member carries the mapped OPC UA status (0 = Good).
|
||||
/// <c>status</c> tuple member carries the mapped OPC UA status (0 = Good). When
|
||||
/// <paramref name="arrayDimensions"/> is non-null + non-empty, the symbol is treated
|
||||
/// as a whole-array read and the boxed value is a flat 1-D CLR
|
||||
/// <see cref="Array"/> sized to <c>product(arrayDimensions)</c>.
|
||||
/// </summary>
|
||||
Task<(object? value, uint status)> ReadValueAsync(
|
||||
string symbolPath,
|
||||
TwinCATDataType type,
|
||||
int? bitIndex,
|
||||
int[]? arrayDimensions,
|
||||
CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Write a symbolic value. Returns the mapped OPC UA status for the operation
|
||||
/// (0 = Good, non-zero = error mapped via <see cref="TwinCATStatusMapper"/>).
|
||||
/// <paramref name="arrayDimensions"/> mirrors <see cref="ReadValueAsync"/>; PR-1.4
|
||||
/// ships read-only whole-array support so writers may surface <c>BadNotSupported</c>.
|
||||
/// </summary>
|
||||
Task<uint> WriteValueAsync(
|
||||
string symbolPath,
|
||||
TwinCATDataType type,
|
||||
int? bitIndex,
|
||||
int[]? arrayDimensions,
|
||||
object? value,
|
||||
CancellationToken cancellationToken);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user