Files
lmxopcua/docs/v3/twincat-backlog.md
T
Joseph Doherty 664ff75ee2 fix(twincat): #645 live gate — sum-read never worked on hardware; TC2 diagnostics fallback
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
2026-10-08 21:17:44 -04:00

4.9 KiB
Raw Blame History

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

  1. 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<IgIoSumReadEntity> (see AdsTwinCATClient.CreateSumRead); fixed and pinned by TwinCATSumReadConstructionTests.

  2. 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).

  3. 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.

  4. 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.