Auto: twincat-4.1 — nested UDT browse via online type walker
Closes #315
This commit is contained in:
@@ -28,6 +28,56 @@ sessions. Pick one:
|
||||
The CLI compiles + runs without a router, but every wire call fails with a
|
||||
transport error until one is reachable.
|
||||
|
||||
## UDT decomposition
|
||||
|
||||
PR 4.1 (issue #315) replaces the old "skip non-atomic symbols" behaviour
|
||||
of `BrowseSymbolsAsync` with a recursive type walker
|
||||
(`TwinCATTypeWalker`). When the OtOpcUa server's TwinCAT driver runs
|
||||
discovery with `EnableControllerBrowse=true`, struct / UDT / function-block
|
||||
typed symbols flatten into one OPC UA variable per atomic leaf. Browse
|
||||
addresses use the same dotted-instance form the PLC exposes:
|
||||
|
||||
| PLC declaration | OPC UA browse paths surfaced |
|
||||
|---|---|
|
||||
| `MAIN.bStart : BOOL` | `MAIN.bStart` |
|
||||
| `GVL.stMotor : ST_Motor` | `GVL.stMotor.bRunning`, `GVL.stMotor.nState`, `GVL.stMotor.rTemperature`, … |
|
||||
| `GVL.aRecipe : ARRAY[1..10] OF DINT` | `GVL.aRecipe[1]` … `GVL.aRecipe[10]` |
|
||||
| `GVL.aPairs : ARRAY[0..2] OF ST_Pair` | `GVL.aPairs[0].nCount`, `GVL.aPairs[0].rValue`, `GVL.aPairs[1].…` |
|
||||
| `GVL.aBig : ARRAY[1..5000] OF DINT` | `GVL.aBig` (single whole-array root — over the cap) |
|
||||
|
||||
The CLI's `read` / `write` / `subscribe` commands take dotted paths
|
||||
directly:
|
||||
|
||||
```powershell
|
||||
# Read a struct member
|
||||
otopcua-twincat-cli read -n 192.168.1.40.1.1 -s GVL.stMotor.rTemperature -t Real
|
||||
|
||||
# Read an array element
|
||||
otopcua-twincat-cli read -n 192.168.1.40.1.1 -s "GVL.aRecipe[3]" -t DInt
|
||||
```
|
||||
|
||||
### Array expansion bound
|
||||
|
||||
`TwinCATDriverOptions.MaxArrayExpansion` (default `1024`) caps how many
|
||||
elements an array contributes to the discovered address space. Arrays
|
||||
whose total element count exceeds the cap surface as a single
|
||||
whole-array root with `IsArrayRoot=true` instead of one variable per
|
||||
element. Raise the bound when operators routinely care about individual
|
||||
elements of large recipe / lookup tables; lower it to keep discovery
|
||||
cheap for symbol tables that ship multi-thousand-element scratch
|
||||
arrays. Pre-declared whole-array tags from the `Tags` config bypass the
|
||||
walker entirely — set `ArrayDimensions` on a `TwinCATTagDefinition` to
|
||||
keep array reads on the existing PR 1.4 read-array path.
|
||||
|
||||
### Cycle / depth guard
|
||||
|
||||
The walker tracks the visited-type set + a hard depth cap of 8 levels
|
||||
so a self-pointer (`POINTER TO ST_Self`) or pathological alias chain
|
||||
terminates rather than spinning. POINTER / REFERENCE members are
|
||||
skipped at the type-graph level — surfacing them would require
|
||||
dereferencing through the AMS routing layer which has its own access
|
||||
patterns.
|
||||
|
||||
## Common flags
|
||||
|
||||
| Flag | Default | Purpose |
|
||||
|
||||
@@ -57,6 +57,14 @@ All three gated on `TWINCAT_TARGET_HOST` + `TWINCAT_TARGET_NETID` env
|
||||
vars; skip cleanly via `[TwinCATFact]` when the VM isn't reachable or
|
||||
vars are unset.
|
||||
|
||||
PR 4.1 / #315 adds `TwinCATUdtBrowseTests.Driver_browses_UDT_tree_and_flattens_to_atomic_leaves`
|
||||
which exercises `TwinCATDriver.DiscoverAsync` end-to-end against the
|
||||
`GVL_Plant` UDT fixture. Asserts the discovery surface emits one OPC UA
|
||||
variable per atomic leaf and folds `aAlarmRecords[1..2000]` into a
|
||||
single `IsArrayRoot` placeholder when the element count exceeds the
|
||||
default 1024-element cap (UDT per-member coverage; see
|
||||
`TwinCatProject/README.md §Complex hierarchy` for the supporting DUTs).
|
||||
|
||||
### Unit
|
||||
|
||||
- `TwinCATAmsAddressTests` — `ads://<netId>:<port>` parsing + routing
|
||||
@@ -66,6 +74,14 @@ vars are unset.
|
||||
- `TwinCATSymbolPathTests` — symbol-path routing for nested struct members
|
||||
- `TwinCATSymbolBrowserTests` — `ITagDiscovery.DiscoverAsync` via
|
||||
`ReadSymbolsAsync` (#188) + system-symbol filtering
|
||||
- `TwinCATTypeWalkerTests` — PR 4.1 / #315 nested-UDT decomposition:
|
||||
atomic / single-level struct / nested struct / array-of-atomic
|
||||
(in / over `MaxArrayExpansion`) / array-of-struct / alias chain /
|
||||
pointer skip / self-referencing struct depth-cap / per-leaf
|
||||
`MaxArrayExpansion` honored / ReadOnly propagation. Stub `IDataType`
|
||||
/ `IStructType` / `IArrayType` / `IMember` / `IDimensionCollection`
|
||||
trees built in-test so the walker is exercised without
|
||||
`Beckhoff.TwinCAT.Ads`-internal ctors.
|
||||
- `TwinCATNativeNotificationTests` — `AddDeviceNotification` (#189)
|
||||
registration, callback-delivery-to-`OnDataChange` wiring, unregister on
|
||||
unsubscribe
|
||||
|
||||
Reference in New Issue
Block a user