docs(twincat): native array notifications, sub-range / size-cap rules, live TC2 gate record

Removes the 'use UseNativeNotifications=false for arrays' workaround and
documents the raw-bytes array model shared by poll and notification: element
checks, STRING arrays, multi-dim flattening, 0-based publication, leading
sub-range for a shorter arrayLength, refusals (struct/UDT arrays, too long,
scalar over array), the 128 KiB native cap (BadOutOfRange), the bit-path fix,
and the 2026-10-07 read-only live gate on Z33856 / Z33733.
This commit is contained in:
Joseph Doherty
2026-10-07 14:56:03 -04:00
parent 313946e6ea
commit 1982af8155
5 changed files with 129 additions and 26 deletions
@@ -263,10 +263,10 @@ 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).
// An array-typed tag (def.ArrayLength != null) reads the array as raw bytes and decodes
// it with TwinCATArrayCodec — the same decode a native array notification runs — into 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.
var (value, status) = await client.ReadValueAsync(
symbolName, def.DataType, parsed?.BitIndex, def.ArrayLength, cancellationToken)
.ConfigureAwait(false);