feat(twincat): 1-D array symbol read via ADS + IsArray discovery

This commit is contained in:
Joseph Doherty
2026-06-16 21:59:17 -04:00
parent 950069392c
commit 3e74239532
7 changed files with 341 additions and 14 deletions
@@ -227,8 +227,13 @@ public sealed class TwinCATDriver : IDriver, IReadable, IWritable, ITagDiscovery
var client = await EnsureConnectedAsync(device, cancellationToken).ConfigureAwait(false);
var parsed = TwinCATSymbolPath.TryParse(def.SymbolPath);
var symbolName = parsed?.ToAdsSymbolName() ?? def.SymbolPath;
// An array-typed tag (def.ArrayLength != null) drives a native 1-D ADS array read;
// the boxed result is an element-typed CLR array. Scalar tags pass null
// (scalar path) — bit-indexed BOOLs are inherently scalar so the client ignores
// arrayCount when a bitIndex is present (Phase 4c).
var (value, status) = await client.ReadValueAsync(
symbolName, def.DataType, parsed?.BitIndex, cancellationToken).ConfigureAwait(false);
symbolName, def.DataType, parsed?.BitIndex, def.ArrayLength, cancellationToken)
.ConfigureAwait(false);
results[i] = new DataValueSnapshot(value, status, now, now);
if (status == TwinCATStatusMapper.Good)
@@ -340,8 +345,10 @@ public sealed class TwinCATDriver : IDriver, IReadable, IWritable, ITagDiscovery
deviceFolder.Variable(tag.Name, tag.Name, new DriverAttributeInfo(
FullName: tag.Name,
DriverDataType: tag.DataType.ToDriverDataType(),
IsArray: false,
ArrayDim: null,
// A pre-declared tag with a positive ArrayLength is a 1-D array node; null
// (or non-positive) stays scalar (Phase 4c).
IsArray: tag.ArrayLength is > 0,
ArrayDim: tag.ArrayLength is > 0 ? (uint)tag.ArrayLength.Value : null,
SecurityClass: tag.Writable
? SecurityClassification.Operate
: SecurityClassification.ViewOnly,
@@ -367,8 +374,12 @@ public sealed class TwinCATDriver : IDriver, IReadable, IWritable, ITagDiscovery
discoveredFolder.Variable(sym.InstancePath, sym.InstancePath, new DriverAttributeInfo(
FullName: sym.InstancePath,
DriverDataType: dt.ToDriverDataType(),
IsArray: false,
ArrayDim: null,
// A discovered 1-D array symbol carries its element count in
// sym.ArrayLength (the browser reports the ELEMENT type as dt);
// multi-dim/unsupported arrays arrive with null ArrayLength → scalar
// (Phase 4c).
IsArray: sym.ArrayLength is > 0,
ArrayDim: sym.ArrayLength is > 0 ? (uint)sym.ArrayLength.Value : null,
SecurityClass: sym.ReadOnly
? SecurityClassification.ViewOnly
: SecurityClassification.Operate,