# TwinCAT driver — v3 backlog The v2 TwinCAT driver is considered solid: 28 integration tests (14 `[TwinCATFact]` + 16-case `[TwinCATTheory]`) running live against the TCBSD fixture, 110 unit tests, 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. Refreshed 2026-10-08 (Gitea #612 / #645); live-validation results live in `docs/drivers/TwinCAT.md` § "Live validation". ## Hardware available (as of 2026-10-08) The Elma cleaner fleet (25 presses, 23 live) is the only real TwinCAT hardware in reach, and it is **production — strictly read-only**: | 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 | 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. **Routes (2026-10-08, hw2 live gate):** with the user's approval, an `oee-tagdump-mac` route for the Mac's current VPN IP (`10.181.201.108.1.1`) was added to **Z35474** (TC3) and **Z34834** (TC2, `5.69.178.220.1.1`, 10.201.45.197) by UDP-48899 AddRoute with the factory login. ⚠️ A same-name AddRoute does **not** replace on either runtime: both presses now carry TWO `oee-tagdump-mac` entries — the stale `10.181.198.189.1.1` and the new one (route table read back over ADS, port 10000 / IG 803). Removing the stale one needs an ADS write and was not done. Every other press still has only the stale route, so it refuses the Mac; the VPN IP changes again ⇒ the routes go stale again. ## Status of the original items 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) — DONE, live-gated 2026-10-08** on Z35474 (TC3) and Z34834 (TC2 2.11): 59 real symbols (BOOL/INT/UINT/DINT/UDINT/USINT/REAL/LREAL/STRING/TIME + 7 value-converted pairs), sum vs single bracketed by two single passes, `sumReadMaxItems` 8 (≥ 7 chunks) and 200: identical status on every tag, identical value on every tag that did not move between passes; poll 59 tags in ~0.35–0.66 s vs ~2.7 s. **TC2 CE 2.11 answers the sum command** (no refusal, no fallback). The gate found the shipped path broken — every chunk `BadCommunicationError` because Beckhoff's `SumRead` constructor throws `InvalidCastException` for a `List` (see `AdsTwinCATClient.CreateSumRead`); fixed and pinned by `TwinCATSumReadConstructionTests`. 7. **Driver diagnostics (#314) — DONE, live-gated 2026-10-08** (opt-in `diagnosticsEnabled`). TC3 Z35474: all six keys from `TwinCAT_SystemInfoVarList` (`AppName=Port_851`, cycle 5.0 ms, exec 0.1 ms). TC2 Z34834 has **no** `TwinCAT_SystemInfoVarList`; the driver now falls back to `.SYSTEMINFO.PROJECTNAME` / `.ONLINECHANGECOUNT` and `.SYSTEMTASKINFOARR[1].CYCLETIME` / `.LASTEXECTIME` (all six keys live: cycle 20.0 ms, exec 0.6 ms). 8. **Flat vs VirtualTree browse on TC3 (#612) — DONE, keep Flat.** Z35474: Flat 3,384 roots → 10,770 leaves, every struct root carried SubSymbols (0 without); VirtualTree 1,027 roots → 1,459 leaves, a strict subset (it loses array-of-struct element members such as `.L_Axis[10].IN._AT.*`). The driver's `DiscoverAsync` returned 10,628 variables. No `SymbolsLoadMode` option is needed. 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.