Read-only live gate on Elma presses Z35474 (TC3 3.1.4024) and Z34834 (TC2 2.11): - Sum-read: every chunk came back BadCommunicationError. Beckhoff's SumRead(IList<IgIoSumReadEntity>) ctor casts to IList<SumDataEntity>, which throws InvalidCastException for a List<> (only an array survives via covariance). The fake-client tests never built a real SumRead. New AdsTwinCATClient.CreateSumRead passes an array; TwinCATSumReadConstructionTests pins it (red on the List form) plus a falsifiability control on the library. After the fix: 59 tags, status identical everywhere, values identical on every non-moving tag, ~0.35-0.66 s vs ~2.7 s per poll; TC2 CE 2.11 answers sum reads. - An unexpected sum chunk failure now logs one Warning per device (it was invisible: the health message was overwritten by the next good read). - Diagnostics: TC2 has no TwinCAT_SystemInfoVarList; fall back to .SYSTEMINFO / .SYSTEMTASKINFOARR[1] once the TC3 name answers not-found (live: all six keys). - #612 browse: Flat verified on TC3 (10,770 leaves; VirtualTree 1,459 strict subset) — comment and docs updated, no load-mode option needed. Claude-Session: https://claude.ai/code/session_01Ef2ozxS7QPanGT8uoATbTe
4.9 KiB
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
-
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.
-
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_PerfChurnfixture project from the strandedauto/driver-gapsbranch. Fixture-gated. -
Multi-hop AMS route — a test behind an IPC gateway with a chained route entry. No hardware.
-
License-rotation automation — XAR's 7-day trial expires on schedule. Ops item, not code.
-
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
-
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,
sumReadMaxItems8 (≥ 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 chunkBadCommunicationErrorbecause Beckhoff'sSumReadconstructor throwsInvalidCastExceptionfor aList<IgIoSumReadEntity>(seeAdsTwinCATClient.CreateSumRead); fixed and pinned byTwinCATSumReadConstructionTests. -
Driver diagnostics (#314) — DONE, live-gated 2026-10-08 (opt-in
diagnosticsEnabled). TC3 Z35474: all six keys fromTwinCAT_SystemInfoVarList(AppName=Port_851, cycle 5.0 ms, exec 0.1 ms). TC2 Z34834 has noTwinCAT_SystemInfoVarList; the driver now falls back to.SYSTEMINFO.PROJECTNAME/.ONLINECHANGECOUNTand.SYSTEMTASKINFOARR[1].CYCLETIME/.LASTEXECTIME(all six keys live: cycle 20.0 ms, exec 0.6 ms). -
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'sDiscoverAsyncreturned 10,628 variables. NoSymbolsLoadModeoption is needed. -
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.