Add Heidenhain LSV2 read-only driver #803

Closed
opened 2026-11-10 14:20:10 -05:00 by dohertj2 · 1 comment
Owner

Request

Add a native read-only Heidenhain LSV2 driver to lmxopcua, using the existing Java implementation in ignitionoee as the protocol and behavior reference. Integrate it with the existing .NET driver, configuration, discovery, health, and OPC UA infrastructure.

Java reference

Scope

  • Native LSV2 TCP transport (default port 19000), without a Java/Python runtime or vendor SDK dependency.
  • Configurable endpoint, timeouts, polling groups, bounded alarms, and securely stored credentials for INSPECT and optional DNC/DATA access. Honor controller permissions and per-read denials.
  • Typed read-only OPC UA data for controller identity, execution/program state, program names/line, overrides, axis names/positions, tools, alarms, capabilities, and configured PLC/DATA scalar bindings.
  • Preserve raw controller enums and units; leave OEE mappings to consumers. Keep experimental duration selectors disabled by default until their semantics are validated.
  • Serialized controller transactions, cached OPC reads, bounded reconnect/backoff, and explicit quality/status handling for unsupported, denied, malformed, and type-mismatched reads. Invalidate all remote values on communication loss and recover after reconnect.
  • Preserve the Java reference's PLC element/byte-count rules, address bounds, DATA type/range checks, and observed Boolean FF encoding.

Read-only boundary

Expose no writable OPC nodes. Enforce a payload-aware outbound command allowlist for the required logins and read requests. Exclude program/PLC/parameter/file writes, arbitrary commands, keyboard or motion control, privilege changes, and security/license bypasses.

Acceptance criteria

  • Driver is registered and configurable through the existing lmxopcua infrastructure; document configuration, supported addresses, namespace, and limitations.
  • Port relevant protocol fixtures and regression coverage from the Java tests, including framing, decoding, bounds, permission failures, read-only enforcement, and reconnect/stale-value behavior.
  • Verify browse/read/subscribe, OPC write rejection, controller-side outbound restrictions, and outage/recovery through the .NET server.
  • Complete and retain live commissioning evidence for the .NET implementation; Java validation is reference evidence, not proof of the port.

The Java v0.20.3 artifact was validated on 2026-11-03 against four real iTNC 530 controls. DATA reads worked on three; raw R_MB reads remained permission-denied on all four. Other controller families, successful raw-memory decoding, physical units/HMI comparisons, experimental timer semantics, and sustained fleet/load operation remain separate validation gates.

## Request Add a native read-only Heidenhain LSV2 driver to lmxopcua, using the existing Java implementation in ignitionoee as the protocol and behavior reference. Integrate it with the existing .NET driver, configuration, discovery, health, and OPC UA infrastructure. ## Java reference - [Java driver source (v0.20.3 reference commit)](https://gitea.dohertylan.com/dohertj2/ignitionoee/src/commit/d1dda0a53d3c701761272b3dfe22044d0fe06023/modules/drivers/gateway/src/main/java/com/zb/mom/driver/heidenhain) - [Java driver tests](https://gitea.dohertylan.com/dohertj2/ignitionoee/src/commit/d1dda0a53d3c701761272b3dfe22044d0fe06023/modules/drivers/gateway/src/test/java/com/zb/mom/driver/heidenhain) - [Driver documentation](https://gitea.dohertylan.com/dohertj2/ignitionoee/src/commit/d1dda0a53d3c701761272b3dfe22044d0fe06023/modules/drivers/README.md#heidenhain-lsv2-v0203) - [LSV2 wire reference](https://gitea.dohertylan.com/dohertj2/ignitionoee/src/commit/d1dda0a53d3c701761272b3dfe22044d0fe06023/docs/reference/heidenhain-lsv2.md) - [Design and read-only boundaries](https://gitea.dohertylan.com/dohertj2/ignitionoee/src/commit/d1dda0a53d3c701761272b3dfe22044d0fe06023/docs/superpowers/specs/2026-11-03-heidenhain-lsv2-design.md) - [Final v0.20.3 real-controller validation evidence](https://gitea.dohertylan.com/dohertj2/ignitionoee/src/branch/main/docs/recipes/evidence/heidenhain-final-0.20.3-2026-11-03/README.md) - [Commissioning checklist and remaining validation gates](https://gitea.dohertylan.com/dohertj2/ignitionoee/src/branch/main/docs/recipes/heidenhain-lsv2-validation.md) ## Scope - Native LSV2 TCP transport (default port 19000), without a Java/Python runtime or vendor SDK dependency. - Configurable endpoint, timeouts, polling groups, bounded alarms, and securely stored credentials for INSPECT and optional DNC/DATA access. Honor controller permissions and per-read denials. - Typed read-only OPC UA data for controller identity, execution/program state, program names/line, overrides, axis names/positions, tools, alarms, capabilities, and configured PLC/DATA scalar bindings. - Preserve raw controller enums and units; leave OEE mappings to consumers. Keep experimental duration selectors disabled by default until their semantics are validated. - Serialized controller transactions, cached OPC reads, bounded reconnect/backoff, and explicit quality/status handling for unsupported, denied, malformed, and type-mismatched reads. Invalidate all remote values on communication loss and recover after reconnect. - Preserve the Java reference's PLC element/byte-count rules, address bounds, DATA type/range checks, and observed Boolean FF encoding. ## Read-only boundary Expose no writable OPC nodes. Enforce a payload-aware outbound command allowlist for the required logins and read requests. Exclude program/PLC/parameter/file writes, arbitrary commands, keyboard or motion control, privilege changes, and security/license bypasses. ## Acceptance criteria - [ ] Driver is registered and configurable through the existing lmxopcua infrastructure; document configuration, supported addresses, namespace, and limitations. - [ ] Port relevant protocol fixtures and regression coverage from the Java tests, including framing, decoding, bounds, permission failures, read-only enforcement, and reconnect/stale-value behavior. - [ ] Verify browse/read/subscribe, OPC write rejection, controller-side outbound restrictions, and outage/recovery through the .NET server. - [ ] Complete and retain live commissioning evidence for the .NET implementation; Java validation is reference evidence, not proof of the port. The Java v0.20.3 artifact was validated on 2026-11-03 against four real iTNC 530 controls. DATA reads worked on three; raw R_MB reads remained permission-denied on all four. Other controller families, successful raw-memory decoding, physical units/HMI comparisons, experimental timer semantics, and sustained fleet/load operation remain separate validation gates.
Author
Owner

Implemented on master (merge 7af9c40e + fix 5bbe1e3c): native read-only Heidenhain LSV2 driver (Driver.Heidenhain + Contracts), no Java/Python/vendor SDK, all registration seams (factory, DriverTypeNames.Heidenhain, admin-node probe, deploy gates, /raw driver+device modals, typed tag editor, CSV, browse-commit), docs in docs/drivers/Heidenhain.md.

Read-only: no IWritable; deploy gate HeidenhainTagWritable + authoring refusals; a payload-aware outbound allowlist in the only frame builder (A_LG INSPECT/DNC/DATA; R_VR/R_PR empty; R_RI selectors 22–28, 30–34, 51; R_MB bounded/no wrap; R_DP zero-prefix + terminated path) — refused requests send zero bytes. Credentials: only secret:heidenhain/<name> or env:OTOPCUA_HEIDENHAIN_<NAME>, enforced in parser, save path, deploy gate, probe and at resolve time (closes a Test-Connect exfiltration path the review found; same class for other drivers → #815). Quality per refusal/unsupported/malformed/mismatch, all values BadNoCommunication on comms loss, bounded backoff. Experimental timer selectors off by default.

Independent review: read-only boundary and protocol port verified against the Java reference; 8 findings (2 medium credential issues) fixed. Tests: driver 194 (+2 live-hardware skips, golden vectors from the Java iTNC 530 captures), AdminUI 2023, Configuration 252, Core.Abstractions 565.

docker-dev live gate: first run found that the probe's eager ISecretResolver resolution crash-looped every central node at boot (Akka AuditWriterActorKey ordering) — fixed in 5bbe1e3c with a regression test. Re-run on 5bbe1e3c: all 6 items PASS (modals round-trip with string-named JSON; literal/out-of-namespace passwords refused and not persisted; Test Connect fails cleanly and fail-closed; tag access locked to Read with data type from the address; CSV ReadWrite/mismatch rows refused at commit; deploy sealed, nodes BadNoCommunication and BadNotWritable on write; /hosts DEGRADED with the right reason; no console errors or 500s).

Hardware-gated remainder → #829. Follow-ups: #830, #831.

Implemented on master (merge 7af9c40e + fix 5bbe1e3c): native read-only Heidenhain LSV2 driver (`Driver.Heidenhain` + Contracts), no Java/Python/vendor SDK, all registration seams (factory, `DriverTypeNames.Heidenhain`, admin-node probe, deploy gates, /raw driver+device modals, typed tag editor, CSV, browse-commit), docs in `docs/drivers/Heidenhain.md`. Read-only: no `IWritable`; deploy gate `HeidenhainTagWritable` + authoring refusals; a payload-aware outbound allowlist in the only frame builder (A_LG INSPECT/DNC/DATA; R_VR/R_PR empty; R_RI selectors 22–28, 30–34, 51; R_MB bounded/no wrap; R_DP zero-prefix + terminated path) — refused requests send zero bytes. Credentials: only `secret:heidenhain/<name>` or `env:OTOPCUA_HEIDENHAIN_<NAME>`, enforced in parser, save path, deploy gate, probe and at resolve time (closes a Test-Connect exfiltration path the review found; same class for other drivers → #815). Quality per refusal/unsupported/malformed/mismatch, all values BadNoCommunication on comms loss, bounded backoff. Experimental timer selectors off by default. Independent review: read-only boundary and protocol port verified against the Java reference; 8 findings (2 medium credential issues) fixed. Tests: driver 194 (+2 live-hardware skips, golden vectors from the Java iTNC 530 captures), AdminUI 2023, Configuration 252, Core.Abstractions 565. **docker-dev live gate:** first run found that the probe's eager `ISecretResolver` resolution crash-looped every central node at boot (Akka AuditWriterActorKey ordering) — fixed in 5bbe1e3c with a regression test. Re-run on 5bbe1e3c: all 6 items PASS (modals round-trip with string-named JSON; literal/out-of-namespace passwords refused and not persisted; Test Connect fails cleanly and fail-closed; tag access locked to Read with data type from the address; CSV ReadWrite/mismatch rows refused at commit; deploy sealed, nodes BadNoCommunication and BadNotWritable on write; /hosts DEGRADED with the right reason; no console errors or 500s). Hardware-gated remainder → #829. Follow-ups: #830, #831.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: dohertj2/lmxopcua#803