Files
lmxopcua/docs/drivers/TwinCAT.md

5.0 KiB
Raw Blame History

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.

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:

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 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