Auto: twincat-2.1 — ADS Sum-read / Sum-write

Closes #310
This commit is contained in:
Joseph Doherty
2026-04-25 21:43:32 -04:00
parent fa2fbb404d
commit 931049b5a7
11 changed files with 875 additions and 26 deletions
@@ -48,6 +48,38 @@ public interface ITwinCATClient : IDisposable
object? value,
CancellationToken cancellationToken);
/// <summary>
/// Bulk-read N scalar symbols in a single AMS request via Beckhoff's ADS Sum-command
/// family (IndexGroup <c>0xF080..0xF084</c>). The result is a parallel array preserving
/// <paramref name="reads"/> ordering — element <c>i</c>'s outcome maps to request <c>i</c>.
/// Empty input returns an empty result without a wire round-trip.
/// </summary>
/// <remarks>
/// <para>This is the throughput-optimised path used by <see cref="TwinCATDriver.ReadAsync"/>
/// to replace the per-tag <see cref="ReadValueAsync"/> loop — one ADS sum-read for N
/// symbols beats N individual round-trips by ~10× on the typical PLC link.</para>
///
/// <para>Whole-array reads + bit-extracted BOOL reads stay on the per-tag path because
/// the Sum-command surface only marshals scalars + bitIndex needs CLR-side post-processing.
/// Callers should pre-filter or fall back as appropriate.</para>
/// </remarks>
Task<IReadOnlyList<(object? value, uint status)>> ReadValuesAsync(
IReadOnlyList<TwinCATBulkReadItem> reads,
CancellationToken cancellationToken);
/// <summary>
/// Bulk-write N scalar symbols in a single AMS request via Beckhoff's
/// <c>SumWriteBySymbolPath</c>. Result is a parallel status array preserving
/// <paramref name="writes"/> ordering. Empty input returns an empty result.
/// </summary>
/// <remarks>
/// Whole-array writes + bit-RMW writes are not in scope for the bulk path — those continue
/// through the per-tag <see cref="WriteValueAsync"/> path. The driver layer pre-filters.
/// </remarks>
Task<IReadOnlyList<uint>> WriteValuesAsync(
IReadOnlyList<TwinCATBulkWriteItem> writes,
CancellationToken cancellationToken);
/// <summary>
/// Cheap health probe — returns <c>true</c> when the target's AMS state is reachable.
/// Used by <see cref="Core.Abstractions.IHostConnectivityProbe"/>'s probe loop.
@@ -105,3 +137,19 @@ public interface ITwinCATClientFactory
{
ITwinCATClient Create();
}
/// <summary>One element of an <see cref="ITwinCATClient.ReadValuesAsync"/> request — the symbol path
/// + the IEC type for marshalling. Strings carry an explicit <paramref name="StringLength"/> for
/// fixed-size <c>STRING(n)</c> declarations (defaults to <c>80</c> matching IEC 61131-3).</summary>
public sealed record TwinCATBulkReadItem(
string SymbolPath,
TwinCATDataType Type,
int StringLength = 80);
/// <summary>One element of an <see cref="ITwinCATClient.WriteValuesAsync"/> request.
/// Mirror of <see cref="TwinCATBulkReadItem"/> with the value to push.</summary>
public sealed record TwinCATBulkWriteItem(
string SymbolPath,
TwinCATDataType Type,
object? Value,
int StringLength = 80);