[s7] S7 — Multi-variable PDU packing #362

Merged
dohertj2 merged 1 commits from auto/s7/PR-S7-B1 into auto/driver-gaps 2026-04-25 21:06:57 -04:00
Owner

Summary

Multi-variable PDU packing for S7 — replaces per-tag Plc.ReadAsync loop with Plc.ReadMultipleVarsAsync batching.

  • S7ReadPacker.cs (new) static helper:
    • Classifies tags as packable / fallback / unknown.
    • Builds S7.Net.Types.DataItem with VarType, Count, DB, StartByteAdr, BitAdr.
    • Computes PDU item budget: (pduSize - 18) / 12, capped at 19 items per call.
    • Bin-packs preserving caller order.
  • S7Driver.ReadAsync — classifies inputs into unknown / packable / fallback. Packable batches dispatch via Plc.ReadMultipleVarsAsync; decodes each DataItem.Value back to per-tag snapshots. Falls back to per-tag ReadOneAsync on batch-level failure so one bad tag doesn't poison the rest of the batch.
  • Arrays, strings, dates, 64-bit ints, UDT-shaped types remain on the existing per-tag path (variable-width or special encoding).

Test plan

  • dotnet build src/ZB.MOM.WW.OtOpcUa.Driver.S7 — clean (0 / 0)
  • dotnet test tests/ZB.MOM.WW.OtOpcUa.Driver.S7.Tests163 / 163 passed (14 new in S7ReadPackerTests: item-budget math, bin-packing 100 items into ≤6 batches, packability classification across all S7DataType values, DataItem field mapping (DB / area / VarType / BitAdr), value reinterpret (signed Int16/Int32 from unsigned wire))
  • Integration tests — Snap7-server fixture supports it; not exercised in this PR

🤖 Auto-generated by the Mode-B execution loop. Closes #292.

Closes #292

## Summary Multi-variable PDU packing for S7 — replaces per-tag `Plc.ReadAsync` loop with `Plc.ReadMultipleVarsAsync` batching. - **`S7ReadPacker.cs`** (new) static helper: - Classifies tags as packable / fallback / unknown. - Builds `S7.Net.Types.DataItem` with `VarType`, `Count`, `DB`, `StartByteAdr`, `BitAdr`. - Computes PDU item budget: `(pduSize - 18) / 12`, capped at **19 items** per call. - Bin-packs preserving caller order. - **`S7Driver.ReadAsync`** — classifies inputs into unknown / packable / fallback. Packable batches dispatch via `Plc.ReadMultipleVarsAsync`; decodes each `DataItem.Value` back to per-tag snapshots. Falls back to per-tag `ReadOneAsync` on **batch-level** failure so one bad tag doesn't poison the rest of the batch. - Arrays, strings, dates, 64-bit ints, UDT-shaped types remain on the existing per-tag path (variable-width or special encoding). ## Test plan - [x] `dotnet build src/ZB.MOM.WW.OtOpcUa.Driver.S7` — clean (0 / 0) - [x] `dotnet test tests/ZB.MOM.WW.OtOpcUa.Driver.S7.Tests` — **163 / 163 passed** (14 new in `S7ReadPackerTests`: item-budget math, bin-packing 100 items into ≤6 batches, packability classification across all `S7DataType` values, `DataItem` field mapping (DB / area / VarType / BitAdr), value reinterpret (signed Int16/Int32 from unsigned wire)) - [ ] Integration tests — Snap7-server fixture supports it; not exercised in this PR 🤖 Auto-generated by the Mode-B execution loop. Closes #292. Closes #292
dohertj2 added 1 commit 2026-04-25 21:06:53 -04:00
Replaces the per-tag Plc.ReadAsync loop in S7Driver.ReadAsync with a
batched ReadMultipleVarsAsync path. Scalar fixed-width tags (Bool, Byte,
Int16/UInt16, Int32/UInt32, Float32, Float64) are bin-packed into ≤18-item
batches at the default 240-byte PDU using S7.Net.Types.DataItem; arrays,
strings, dates, 64-bit ints, and UDT-shaped types stay on the legacy
ReadOneAsync path. On batch-level failure each tag in the batch falls
back to ReadOneAsync so good tags still produce values and the offender
gets its per-item StatusCode (BadDeviceFailure / BadCommunicationError).

100 scalar reads now coalesce into ≤6 PDU round-trips instead of 100.

Closes #292
dohertj2 merged commit 5432c49364 into auto/driver-gaps 2026-04-25 21:06:57 -04:00
dohertj2 deleted branch auto/s7/PR-S7-B1 2026-04-25 21:06:58 -04:00
Sign in to join this conversation.