Auto: s7-c3 — per-tag scan group / publish rate

Closes #296
This commit is contained in:
Joseph Doherty
2026-04-26 01:03:00 -04:00
parent ca3d4bf581
commit 162c82b8d9
6 changed files with 736 additions and 26 deletions

View File

@@ -122,6 +122,23 @@ public sealed class S7DriverOptions
/// non-<see cref="TsapMode.Auto"/> mode.
/// </summary>
public ushort? RemoteTsap { get; init; }
/// <summary>
/// PR-S7-C3 — per-tag scan-group → publishing-interval map. When a tag declares a
/// <see cref="S7TagDefinition.ScanGroup"/>, <see cref="S7Driver.SubscribeAsync"/>
/// resolves its publishing rate by looking the group up in this dictionary; tags
/// without a group, or with a group not present here, fall back to the
/// subscription-default <c>publishingInterval</c> argument. Keys are matched
/// case-insensitively. See <c>docs/v2/s7.md</c> "Per-tag scan groups" section.
/// </summary>
/// <remarks>
/// The driver still owns one <c>Plc</c> connection serialized through the per-driver
/// <c>_gate</c>, so partitioning into N poll loops does NOT parallelise wire-level
/// reads — every partition queues against the same semaphore. Operator value is
/// decoupling tick cadence: a 100 ms HMI tag isn't blocked behind a 10 s slow-poll
/// batch any more, because the slow batch's <c>Task.Delay</c> isn't holding the gate.
/// </remarks>
public IReadOnlyDictionary<string, TimeSpan>? ScanGroupIntervals { get; init; }
}
/// <summary>
@@ -227,6 +244,15 @@ public sealed class S7ProbeOptions
/// they need bespoke layout handling and are tracked as a follow-up. Capped at 8000 to
/// keep the byte-range request inside a single S7 PDU envelope.
/// </param>
/// <param name="ScanGroup">
/// PR-S7-C3 — optional scan-group identifier. When set, <c>SubscribeAsync</c> looks up
/// the group's publishing interval in <see cref="S7DriverOptions.ScanGroupIntervals"/>
/// and partitions the input tag list so all tags sharing that interval poll together
/// in a dedicated background loop. Tags with no <c>ScanGroup</c>, or with a group not
/// present in the map, fall back to the subscription's default publishing interval
/// (legacy single-rate behaviour). Group names are matched case-insensitively. See
/// <c>docs/v2/s7.md</c> "Per-tag scan groups" section.
/// </param>
public sealed record S7TagDefinition(
string Name,
string Address,
@@ -234,7 +260,8 @@ public sealed record S7TagDefinition(
bool Writable = true,
int StringLength = 254,
bool WriteIdempotent = false,
int? ElementCount = null);
int? ElementCount = null,
string? ScanGroup = null);
public enum S7DataType
{