Files
lmxopcua/docs/drivers/TwinCAT.md

116 lines
5.0 KiB
Markdown
Raw Permalink 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 — operator guide
Beckhoff TwinCAT 2 / TwinCAT 3 ADS driver. Talks to the runtime via
`Beckhoff.TwinCAT.Ads` v6 (managed); requires a reachable AMS router on
the host (local TwinCAT XAR, the standalone `Beckhoff.TwinCAT.Ads.TcpRouter`
NuGet, or any Windows box with TwinCAT installed and an authorised AMS
route).
## Configuration surface
`TwinCATDriverOptions` (one instance supports N AMS targets, each a
`TwinCATDeviceOptions`). Wire format mirrors the C# class on the JSON
side — every `init`-only property round-trips through
`System.Text.Json` with the default options.
| Option | Type | Default | Notes |
| --- | --- | --- | --- |
| `Devices` | `TwinCATDeviceOptions[]` | `[]` | One entry per AMS target. |
| `Tags` | `TwinCATTagDefinition[]` | `[]` | Pre-declared symbol set. |
| `Probe.Enabled` | `bool` | `true` | Per-tick `ReadStateAsync` against the runtime. |
| `Probe.Interval` | `TimeSpan` | `5 s` | |
| `Timeout` | `TimeSpan` | `2 s` | Per-operation timeout. |
| `UseNativeNotifications` | `bool` | `true` | False = fall through to PollGroupEngine. |
| `EnableControllerBrowse` | `bool` | `false` | Walk symbol table on `DiscoverAsync`. |
| `MaxArrayExpansion` | `int` | `1024` | Per-element cutoff during nested-UDT browse. |
| `EnableAlarms` (PR 5.1) | `bool` | `false` | Opt-in TC3 EventLogger bridge — see "Alarms" below. |
## Alarms (TC3 EventLogger bridge, PR 5.1 / #316)
When `EnableAlarms=true`, the driver implements `IAlarmSource` by
opening a second `AdsClient` against AMS port **110**
(`AMSPORT_EVENTLOG`) and adding a device notification on
`ADSIGRP_TCEVENTLOG_ALARMS`. Subscribers receive `OnAlarmEvent`
notifications for every transition the EventLogger surfaces (raise /
clear / acknowledge).
### Decode caveat
Beckhoff doesn't ship a managed wrapper for `TcEventLogger` in the
regular `Beckhoff.TwinCAT.Ads` v6 NuGet — only the C++ TcCOM headers
exist. The driver therefore decodes the AMS-port-110 binary payload
manually. The current implementation is best-effort: event class GUIDs
and source names usually decode cleanly; some less-common fields may
surface as `"Unknown"` until a follow-up PR lands a complete decoder.
Spike output captured at
[`docs/v3/twincat-eventlogger-spike.md`](../v3/twincat-eventlogger-spike.md).
### Wire path
| Layer | What it does |
| --- | --- |
| Primary `AdsClient` | The existing per-device session against the PLC runtime port (default `851`) — handles reads / writes / native subscriptions. |
| Secondary `AdsClient` (alarms) | Opens against AMS port `110` on the same target NetId. Adds one device notification on `ADSIGRP_TCEVENTLOG_ALARMS` with a `length=...` payload covering the full alarm-list shape. |
| `ITwinCATAlarmGate` (driver-internal) | Decodes incoming notifications into `TwinCATAlarmEvent` records (`EventClass`, `Source`, `Severity`, `Message`, `OccurrenceUtc`, `Acked`). |
| `TwinCATAlarmSource` | Projects `TwinCATAlarmEvent` onto the driver-agnostic `IAlarmSource.OnAlarmEvent`. |
### Severity mapping (TC3 → OPC UA AC)
TC3 EventLogger severity is a 0255 `USINT`. The driver maps it onto
the four-bucket `AlarmSeverity` enum the OPC UA AC layer consumes:
| TC3 severity | `AlarmSeverity` |
| --- | --- |
| 064 | `Low` |
| 65128 | `Medium` |
| 129192 | `High` |
| 193255 | `Critical` |
### Acknowledge
`AcknowledgeAsync` round-trips through `ITwinCATAlarmGate.AcknowledgeAsync`,
which writes to the EventLogger ack index group. Best-effort — the wire
format isn't documented in managed code, so individual ack failures don't
poison the batch and the gate returns silently when the EventLogger isn't
configured.
### Disabling
`EnableAlarms=false` (default) returns a sentinel handle from
`SubscribeAlarmsAsync` and never opens the secondary `AdsClient`.
`OnAlarmEvent` simply never fires. Capability negotiation still works,
which is why the driver advertises `IAlarmSource` unconditionally.
## CLI
The `otopcua-twincat-cli` test client exposes an `alarms` subcommand
that wraps the bridge end-to-end:
```powershell
dotnet run --project src/ZB.MOM.WW.OtOpcUa.Driver.TwinCAT.Cli -- alarms `
--ams-net-id 5.23.91.23.1.1 --ams-port 851 `
--source Conveyor1.MotorOverload
```
See [`docs/Driver.TwinCAT.Cli.md`](../Driver.TwinCAT.Cli.md) for the
full CLI surface.
## Test coverage
- **Unit**: `TwinCATAlarmSourceTests` covers (a) feature-gating off vs.
on, (b) gate-event projection shape, (c) multi-event ordering, (d)
source-filter matching, (e) acknowledge round-trip, (f) JSON DTO
round-trip.
- **Integration**: `TwinCATAlarmIntegrationTests.Driver_raises_alarm_event_when_PLC_logs_event`
ships build-only in PR 5.1; the GVL + FB_AlarmHarness ship as XAE
stubs at `tests/.../TwinCatProject/PLC/`. Once the XAR project
imports them the test transitions skip → pass.
## See also
- [`docs/v3/twincat-eventlogger-spike.md`](../v3/twincat-eventlogger-spike.md)
— spike output for the managed-wrapper question
- [`docs/drivers/TwinCAT-Test-Fixture.md`](TwinCAT-Test-Fixture.md)
— coverage map + capability matrix
- [`docs/Driver.TwinCAT.Cli.md`](../Driver.TwinCAT.Cli.md) — CLI guide