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

73 lines
4.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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<IgIoSumReadEntity>` (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.