Sum-read (#310): batches a poll's reads per device into sum commands capped at sumReadMaxItems, per-item ADS errors mapped per tag, falls back to individual reads when the target refuses the command. Diagnostics (#314): ADS state, app name, online-change count, task cycle/exec/jitter via IDriverDiagnostics. Re-implemented against the current raw-byte read path (stranded auto/driver-gaps commits predate it). Sum-write not ported. Unit tests only; live gate pending a route. Claude-Session: https://claude.ai/code/session_01Ef2ozxS7QPanGT8uoATbTe
This commit is contained in:
+39
-1
@@ -185,9 +185,47 @@ notifications; `DInt` over a `STRING(80)` → `BadTypeMismatch` in both paths wi
|
||||
the rest of the subscription Good. No PLC value held a genuine non-ASCII string
|
||||
to exercise Windows-1252 live — that rule is unit-tested only.
|
||||
|
||||
## Sum-read and diagnostics (Gitea #645)
|
||||
|
||||
Two items ported from the stranded `auto/driver-gaps` branch (#310, #314), re-implemented against the
|
||||
current raw-byte read path rather than cherry-picked (the branch predates the type guard, the string codec
|
||||
and the array codec). Unit-tested against the fake client only; the live gate is read-only and pending a
|
||||
route (see `docs/v3/twincat-backlog.md`).
|
||||
|
||||
### Sum-read (opt-in)
|
||||
|
||||
`useSumRead: true` (default **off**) batches a poll's reads for one device into ADS sum-read commands
|
||||
(`IndexGroup 0xF080`) of at most `sumReadMaxItems` symbols (default 200) instead of one round-trip per tag.
|
||||
TC2 CE 2.11 support for the sum command is unverified, hence opt-in.
|
||||
|
||||
- The client plans each item exactly as a single read does — symbol from the Beckhoff symbol cache, declared
|
||||
type checked by `TwinCATTypeGuard` — and then reads the raw bytes at the symbol's index group / offset in
|
||||
one command, decoding with the same `TwinCATArrayCodec` (a scalar is a one-element array). A type-mismatched
|
||||
item gets `BadTypeMismatch` without joining the batch; a bit-indexed BOOL and a handle-addressed symbol
|
||||
(`0xF005`) are read individually inside the call.
|
||||
- Per-item ADS error codes map to that tag only (`MapAdsError`); the overall code is the command's.
|
||||
- **Fallback.** If the target refuses the command as a whole (overall ADS 1792–1798: service / group /
|
||||
offset / size not supported) the client throws `TwinCATSumReadRefusedException`; the driver logs once,
|
||||
marks the device `SumReadUnsupported`, and re-reads that batch with individual reads. The flag is sticky
|
||||
until the driver is re-initialised. A comms-level failure is **not** a refusal: that chunk goes
|
||||
`BadCommunicationError` and the next poll tries the sum command again.
|
||||
- A one-item chunk is just a single read. Sum-**write** is not implemented (writes stay per-tag).
|
||||
|
||||
### `/hosts` diagnostics (`IDriverDiagnostics`)
|
||||
|
||||
The driver implements the optional `IDriverDiagnostics` bag (the S7 `NegotiatedPduSize` precedent, #640),
|
||||
so these ride the health snapshot to `/hosts` — deliberately not synthetic raw tags. Sampled once per
|
||||
healthy probe tick: ADS device state (`ReadState`), and `TwinCAT_SystemInfoVarList` `_AppInfo.AppName`,
|
||||
`_AppInfo.OnlineChangeCnt`, `_TaskInfo[1].CycleTime`, `_TaskInfo[1].LastExecTime` (100 ns ticks).
|
||||
Keys: `TwinCAT.AdsState`, `.AppName`, `.OnlineChangeCnt`, `.CycleTimeMs`, `.LastExecTimeMs`, `.JitterMs`
|
||||
(last exec − cycle; positive = the task overran). Several devices prefix `TwinCAT.<DeviceName or host>.`;
|
||||
the host caps the bag at 16 entries. Times are rounded to 0.1 ms because the bag's digest is in the
|
||||
publish fingerprint. Each symbol is best-effort: a runtime that does not export one (older TC2) keeps the
|
||||
others, and a symbol answering "not found" is not re-asked until the client is rebuilt.
|
||||
|
||||
## Capability surface
|
||||
|
||||
`TwinCATDriver : IDriver, IReadable, IWritable, ITagDiscovery, ISubscribable, IHostConnectivityProbe, IPerCallHostResolver, IRediscoverable`
|
||||
`TwinCATDriver : IDriver, IReadable, IWritable, ITagDiscovery, ISubscribable, IHostConnectivityProbe, IPerCallHostResolver, IRediscoverable, ISkippedTagReporter, IDriverDiagnostics`
|
||||
(`src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.TwinCAT/TwinCATDriver.cs`).
|
||||
|
||||
| Capability | Path | Notes |
|
||||
|
||||
+52
-18
@@ -5,27 +5,61 @@ The v2 TwinCAT driver is considered solid: 28 integration tests (14 `[TwinCATFac
|
||||
three latent driver bugs shaken out (notification cycle units, `STRING(N)` mapper,
|
||||
bit-indexed BOOL path). Further work is deferred.
|
||||
|
||||
Archived from `docs/drivers/TwinCAT-Test-Fixture.md` § Follow-up candidates.
|
||||
Archived from `docs/drivers/TwinCAT-Test-Fixture.md` § Follow-up candidates. Refreshed 2026-10-08
|
||||
(Gitea #612 / #645); live-validation results live in `docs/drivers/TwinCAT.md` § "Live validation".
|
||||
|
||||
## Deferred items
|
||||
## Hardware available (as of 2026-10-08)
|
||||
|
||||
1. **TC2 coverage** — spin up a TC2 runtime (Windows CE IPC or legacy XAR)
|
||||
and run the same suite; any delta surfaces. Blocked on hardware.
|
||||
The Elma cleaner fleet (25 presses, 23 live) is the only real TwinCAT hardware in reach, and it is
|
||||
**production — strictly read-only**:
|
||||
|
||||
2. **Notification coalescing under load** — run the subscribe test while
|
||||
the PLC cycle is saturated (bump `lineSim` complexity, watch for
|
||||
dropped notifications). Doable on current rig; deferred as lower
|
||||
priority than v3 feature work.
|
||||
| Press | Runtime | AMS | Notes |
|
||||
|---|---|---|---|
|
||||
| 22 presses (e.g. Z33856 `10.201.45.236.1.1`, Z33733 `5.25.53.46.1.1`) | **TC2 2.11 on WinCE 6.0** | port **801** | read-validated 2026-10-07 |
|
||||
| **Z35474** (`5.118.56.93.1.1`, 10.201.23.227) | **TC3 3.1.4024** (Win NT 10) | port **851** | the **only TC3 press**; "Plc30 App" |
|
||||
| TCBSD fixture `10.100.0.128` (`41.169.163.43.1.1:851`) | TC3 | 851 | not a press; unreachable from the Mac |
|
||||
|
||||
3. **Multi-hop AMS route** — add a test behind an IPC gateway with a
|
||||
chained route entry. Blocked on hardware (gateway IPC).
|
||||
Access facts: ADS is TCP 48898. The driver sends no AddRoute (routes are provisioned out of band) and has
|
||||
no IP field, so a host needs a local AMS router — TwinCAT XAR, or `Beckhoff.TwinCAT.Ads.TcpRouter` hosted
|
||||
in-process (the driver csproj does not reference TcpRouter; the 2026-10-07 run used a scratch harness).
|
||||
The Mac reaches the presses directly over the VPN. **The PLC routes left by earlier tooling are STALE:**
|
||||
they name the Mac's old VPN IP (10.181.198.189), and the Mac is now 10.181.207.140, so a source NetId of
|
||||
`10.181.207.140.1.1` has no route on any press. We must not AddRoute on production, so the **live gate for
|
||||
this backlog is deferred pending a user-approved route** (owner refreshes the route, or the user approves
|
||||
reusing the old source NetId). Nothing below that says "live" has been run against TC3.
|
||||
|
||||
4. **License-rotation automation** — XAR's 7-day trial expires on
|
||||
schedule. Either automate `TcActivate.exe /reactivate` via a scheduled
|
||||
task on the VM (not officially supported; reportedly works for some
|
||||
TC3 builds), or buy a paid runtime license (~$1k one-time per runtime
|
||||
per CPU) to kill the rotation. Ops item, not code.
|
||||
## Status of the original items
|
||||
|
||||
5. **Lab rig** — cheapest IPC (CX7000 / CX9020) on a dedicated network;
|
||||
the only route that covers TC2 + real EtherCAT I/O timing + cycle
|
||||
jitter under CPU load. Blocked on hardware + budget.
|
||||
1. **TC2 coverage — DONE (read side).** No longer "blocked on hardware": the 2026-10-07 Elma run
|
||||
(TwinCAT 2.11) verified browse, scalar/array/string reads and native notifications on TC2. What is
|
||||
still unverified there: sum-read support (see item 6) and anything that writes.
|
||||
|
||||
2. **Notification coalescing under load** — run the subscribe test while the PLC cycle is saturated.
|
||||
Needs the TCBSD fixture (loading a production press is out of the question) and the `GVL_Perf` /
|
||||
`FB_PerfChurn` fixture project from the stranded `auto/driver-gaps` branch. Fixture-gated.
|
||||
|
||||
3. **Multi-hop AMS route** — a test behind an IPC gateway with a chained route entry. No hardware.
|
||||
|
||||
4. **License-rotation automation** — XAR's 7-day trial expires on schedule. Ops item, not code.
|
||||
|
||||
5. **Lab rig** — cheapest IPC on a dedicated network; the only route that covers real EtherCAT I/O
|
||||
timing and cycle jitter under CPU load. Blocked on hardware + budget.
|
||||
|
||||
## Added by #612 / #645
|
||||
|
||||
6. **ADS sum-read (#310) — code DONE, live gate pending.** Opt-in `useSumRead` / `sumReadMaxItems`
|
||||
(see `docs/drivers/TwinCAT.md` § "Sum-read"). Unit-tested against the fake client only. Live gate
|
||||
(read-only, valid on a press): enable on Z33856 / Z33733 (TC2) and Z35474 (TC3), compare a batched poll
|
||||
to individual reads value-for-value, and record whether TC2 CE 2.11 answers or refuses the sum command
|
||||
(either outcome is a result — a refusal must fall back cleanly). Needs the route above.
|
||||
|
||||
7. **Driver diagnostics (#314) — code DONE, live gate pending.** ADS state, app name, online-change
|
||||
count, task cycle time, last exec time and jitter on the `/hosts` diagnostics bag. Live gate: confirm
|
||||
`TwinCAT_SystemInfoVarList._TaskInfo[1]` resolves on TC2 2.11 (the driver tolerates its absence).
|
||||
|
||||
8. **Flat vs VirtualTree browse on TC3 (#612)** — open. Only Z35474 is TC3; read-only symbol-table
|
||||
upload in both modes, compare leaf sets. Add a `SymbolsLoadMode` option only if Flat drops struct
|
||||
members. Needs the route. (Flat on TC2 already proved fine: 45,083 / 42,666 variables.)
|
||||
|
||||
9. **Discovered struct/FB member writes (#612)** — deferred: writes, never on a press; fixture-only.
|
||||
Likewise **sum-write** was deliberately NOT ported from the stranded branch.
|
||||
|
||||
Reference in New Issue
Block a user