Merge branch 'worktree-agent-a6ace38a85443d6d6' into heidenhain-pylsv2-parity
This commit is contained in:
@@ -66,7 +66,7 @@ enums, so the numeric-enum form/factory trap cannot occur):
|
||||
| `TimeoutMs` | 5000 | 100–60000; connect + per-transaction deadline |
|
||||
| `Access.TelemetryEnabled` | true | Off = no `R_RI` requests at all |
|
||||
| `Access.DncLoginEnabled` | true | Optional DNC login; a refusal never blocks reads permitted under INSPECT |
|
||||
| `Access.DataEnabled` | false | Opt-in DATA login, attempted only when a `DATA:` binding exists (iTNC only) |
|
||||
| `Access.DataEnabled` | false | Opt-in DATA login, attempted only when a `DATA:` binding exists, and only on an iTNC 530 ([Control families](#control-families)) |
|
||||
| `Access.InspectPassword` / `DncPassword` / `DataPassword` | — | **References only** (below) |
|
||||
| `Polling.StatusMs` / `CustomMs` / `SlowMs` | 1000 / 1000 / 10000 | each 100–3600000 |
|
||||
| `Polling.AlarmMs` | 2000 | 100–3600000; the alarm walk behind `ALARM:` conditions — only for a control carrying an `ALARM:` tag ([Alarm conditions](#alarm-conditions-alarm-gitea-831)) |
|
||||
@@ -120,7 +120,7 @@ SSH subsystem.
|
||||
|
||||
| Folder | Leaves (type) | Source | Group |
|
||||
|---|---|---|---|
|
||||
| `Controller` | `Model`, `NcVersion`, `PlcVersion`, `Options` (String) | `R_VR` (4 or 5 fields; SPLC skipped; empty options preserved) | Slow |
|
||||
| `Controller` | `Model`, `NcVersion`, `PlcVersion`, `Options`, `Family` (String) | `R_VR` (4 or 5 fields; SPLC skipped; empty options preserved). `Family` is classified locally from `Model` — no extra request ([Control families](#control-families)) | Slow |
|
||||
| `Status` | `ExecutionState` (Int32), `ProgramState` (Int32) — raw native enums | `R_RI 23`, `26` | Status |
|
||||
| `Program` | `Main`, `Current` (String), `Line` (Int64) | `R_RI 24` | Status |
|
||||
| `Overrides` | `Feed`, `Spindle`, `Rapid` (Float64, percent) | `R_RI 25` (uint32 hundredths) | Status |
|
||||
@@ -156,6 +156,55 @@ truncates or wraps — otherwise `BadTypeMismatch`.
|
||||
|
||||
At most 256 PLC/DATA bindings per control (excess are skipped and reported on `/hosts`).
|
||||
|
||||
## Control families
|
||||
|
||||
`R_VR`'s model field is classified once, in one place — `HeidenhainControlFamilies.Classify` (Contracts project,
|
||||
`HeidenhainControlFamily`) — with pyLSV2's rule (MIT; `dat_cls.py` `VersionInfo.control`): strip spaces, compare
|
||||
case-insensitively by prefix, `ITNC530` first. The result is published on the **`Controller/Family`** String leaf
|
||||
(member name: `ITnc530`, `Tnc`, `Tnc7`, `Lathe`, `MillPlus`, `LegacyTnc`, `Unknown`), included in the Test-Connect
|
||||
probe message (`TNC640 (Tnc) NC …`) and the `/hosts` diagnostics bag (`<host>.family`). It costs no request: it is
|
||||
derived from the `R_VR` reply the session already reads. `Controller/Model` keeps the raw string.
|
||||
|
||||
The only code-level gate pyLSV2 applies to a request this driver makes is **DATA**: `read_data_path` returns early
|
||||
on anything but an iTNC (`client.py` "does not work on non iTNC controls"). So a `DATA:` binding on any other family
|
||||
— and on an `Unknown` model — is `BadNotSupported` with `Capabilities/DataLogin = Unsupported`, and **the DATA login
|
||||
is never sent**. (Scope is pyLSV2's other iTNC-only gate; this driver has no scope.) Every other feature is
|
||||
attempted on every family and settled by the control's own reply: `T_ER_UNKNOWN_TELE` (22) ⇒ `Unsupported`, asked
|
||||
once per session, then suppressed; an access refusal ⇒ `AccessDenied`. No family pre-gates a selector — pyLSV2
|
||||
records those as "observations, not guarantees" (`docs/protocol.rst`), and a pre-gate would hide data a newer NC
|
||||
version serves.
|
||||
|
||||
| Family (`Controller/Family`) | Models (`R_VR` prefix) | Evidence | What the reference says | Driver behaviour |
|
||||
|---|---|---|---|---|
|
||||
| `ITnc530` | `iTNC530` / `iTNC 530` | **Hardware-proven** — four Hermle iTNC 530 (NC 340490 03/04, 606420 03; `evidence/heidenhain-live-2026-11-11.md`) | pyLSV2 `MILL_OLD`; DATA + scope iTNC-only; tool (51), alarms (27/28) and timers (30–34) served | All features attempted; DATA allowed (opt-in) |
|
||||
| `Tnc` | `TNC640`, `TNC620`, `TNC320`, `TNC128` | Per pyLSV2, hardware-unproven | `MILL_NEW`. TNC 640 NC 340590 10 SP2: 27/28/51 and 30–34 → `T_ER_UNKNOWN_TELE`; 25/26 need DNC; 24 serves the program under INSPECT with block number 0 | `Tool/*`, `Alarms/*`, `ALARM:` conditions and `Timers/*` read `Unsupported` after one refused request; without DNC `Overrides/*` and `Status/ProgramState` are `AccessDenied` and `Program/Line` reads the control's raw 0. DATA `Unsupported`, not sent |
|
||||
| `Tnc7` | `TNC7` | Per pyLSV2, hardware-unproven | `TNC7` — "behaves just a bit different again"; only keyboard/key functions are flagged (not used here) | Reply-driven (no selector observations recorded); DATA `Unsupported` |
|
||||
| `Lathe` | `CNCPILOT640`, `MANUALPLUS` | Per pyLSV2, hardware-unproven | `LATHE_NEW`; protocol table: no tool (51), no error messages (27/28) | Those features settle `Unsupported` from the reply; DATA `Unsupported` |
|
||||
| `MillPlus` | `MILLPLUS` (e.g. `MillPlusIT V600`) | Per pyLSV2, hardware-unproven | `MILLPLUS`; "not officially supported by any other Heidenhain tool" | Reply-driven; DATA `Unsupported` |
|
||||
| `LegacyTnc` | `TNC426`, `TNC430` | **No reference** (pyLSV2 reports these `UNKNOWN`) | — | Named for the leaf only; reply-driven; DATA `Unsupported` |
|
||||
| `Unknown` | anything else | — | pyLSV2 `UNKNOWN` | Reply-driven; DATA `Unsupported` |
|
||||
|
||||
Decoding is family-independent per pyLSV2: `R_VR` is 4 or 5 NUL-separated fields on every family (`client.py`
|
||||
`_read_version`), `R_PR` is 120 or 124 bytes with one layout (`misc.py` `decode_system_parameters`), and the `R_RI`
|
||||
decoders for 22–28/51 carry no family branch. The simulator exercises every family in both `R_VR` shapes, both
|
||||
`R_PR` lengths and the read-only wire set (`Simulator/ControlProfiles.cs`, `HeidenhainControlFamilyTests`) — that is
|
||||
evidence for the classification and the gates, **not** for any non-iTNC control's real replies.
|
||||
|
||||
**Open, needs real hardware or a request this driver deliberately does not send:**
|
||||
|
||||
- **Buffer size.** pyLSV2 negotiates 512–4096-byte telegrams with `C_CC` from `R_PR`'s max block length; `C_CC` is
|
||||
a configuration command, outside the allowlist. We stay at the un-negotiated legacy frame on every family (pyLSV2's own default
|
||||
is 256 bytes, so a control is expected to fit replies to it); a reply over 255 bytes is a transport error
|
||||
(`Oversized LSV2 response`), never a truncated value.
|
||||
- **Encrypted passwords.** pyLSV2's `R_PR` exposes a password-encryption key and notes TNC 640 sends some login
|
||||
passwords encrypted (scope). Whether a password-protected DNC/DATA login on a `Tnc`/`Tnc7` needs that is unknown;
|
||||
INSPECT and DNC with an empty password are unaffected.
|
||||
- **Which family sends the 5-field `R_VR`**, and whether `R_RI 20/21` (TNC 640 axis config/physical names, outside
|
||||
our selector allowlist) would be a better axes source there.
|
||||
- **Selector availability per NC version** on `Tnc`/`Tnc7`/`Lathe`/`MillPlus` (the table above is one TNC 640
|
||||
observation plus pyLSV2's test-suite gating), the `R_RI 22` axis encoding, override/tool units, and whether
|
||||
`R_MB` is granted under INSPECT on any non-iTNC family.
|
||||
|
||||
## Alarm conditions (`ALARM:`, Gitea #831)
|
||||
|
||||
The control exposes one flat active-alarm list (`R_RI 27` first, `28` next — class, group, number, text; only refusal
|
||||
@@ -333,7 +382,9 @@ No real control was available for this port. Still open:
|
||||
|
||||
- **.NET commissioning evidence** on a real control (the LiveIntegration gate) — browse/types/arrays through a
|
||||
real OPC UA client, OPC write refusal, network interruption + recovery quality, bounded traffic under load.
|
||||
- Controller families/versions other than iTNC 530 (TNC 320/430/640) — unproven even in the Java reference.
|
||||
- Controller families/versions other than iTNC 530 (TNC 640/620/320/128, TNC7, CNC PILOT/MANUALplus, MillPlus,
|
||||
TNC 426/430) — see the [Control families](#control-families) matrix; everything there except iTNC 530 is per
|
||||
pyLSV2 only.
|
||||
- Successful raw **`R_MB`** decoding and its Boolean encoding (denied on all four tested controls).
|
||||
- Physical units of axis positions / tool geometry vs. the HMI; experimental timer semantics (selectors 30–34).
|
||||
- DNC/DATA permission matrices per control; sustained fleet/load operation.
|
||||
|
||||
Reference in New Issue
Block a user