Beckhoff ADS (community)
Input for Beckhoff's ADS protocol. Supports batch reading and notifications. Beckhoff recommends limiting notifications to approximately 500 to avoid overloading the controller. This input only supports symbols and not direct addresses.
This plugin is community supported only. If you encounter any issues, check out the original repository for more information, or ask around in our Discord.
input:
ads:
cycleTime: 1000 # Optional, default: 1000
hostAMS: auto # Optional, default: auto
intervalTime: 1000 # Optional, default: 1000
logLevel: disabled # Optional, default: disabled
maxDelay: 100 # Optional, default: 100
readType: notification # Optional, default: notification
routeHostAddress: 192.168.1.123 # Optional, auto detected. Usually required when using docker.
routePassword: "1" # Optional, default: "". Required if using automatic UDP route registration on the PLC
routeUsername: Administrator # Optional, default: "". Required if using automatic UDP route registration on the PLC
runtimePort: 801 # Optional, default: 801 for old TwinCAT 2
symbols:
- MAIN.MYTRIGGER:0:10 # variable in the main program with 0ms max delay and 10ms cycle time
- MAIN.myInt # variable in the main program, uses default maxDelay and cycleTime
- ".superDuperInt" # global variable (must start with `.`)
targetAMS: 5.3.12.111.1.1 # Required, AMS net ID of the target.
targetIP: 192.168.3.70 # Required, IP address of the Beckhoff PLC
targetPort: 48898 # Optional, default: 48898
transmissionMode: serverOnChange # Optional, default: serverOnChange
upperCase: true # Optional, default: trueConnection to ADS
When connecting to an ADS device you connect to a router which then routes the traffic to the correct device using the AMS net ID. There are basically 3 ways for setting up the connection:
TwinCAT Connection Manager: Use the TwinCAT connection manager locally on the host, scan for the device and add a connection using the correct credentials for the PLC.
Static route on PLC: Log in to the PLC using the TwinCAT system manager and add a static route from the PLC to the client. This is the preferred way when using benthos on a Kubernetes cluster since you have no good way of installing the connection manager.
Automatic route registration (UDP): Use the
routeUsernameandroutePasswordconfig fields to have the plugin automatically register a route on the PLC before connecting. See the Route Registration section below.
Docker and Kubernetes
ADS works from inside Docker containers with default bridge networking — no host_network, no port forwarding, and no open ports are needed. All ADS traffic (requests, responses, and notifications) flows over a single outbound TCP connection to port 48898. The PLC never initiates connections back to the client; it sends all responses and notifications on the same TCP socket the client opened.
The only requirement is that the hostAMS value matches a route registered on the PLC. When running in Docker with bridge networking:
routeHostAddressmust be set to the Docker host's IP on the PLC network (e.g.192.168.1.50). This tells the PLC which IP address to associate with the route. If left empty, it auto-detects the container's bridge IP which is not routable from the PLC.hostAMScan be set explicitly torouteHostAddress+.1.1(e.g.192.168.1.50.1.1), or left asauto— when route registration is configured withrouteHostAddress,autowill correctly derive the AMS NetID fromrouteHostAddressinstead of the container's bridge IP.A route must exist on the PLC for the
hostAMSNetID. This can be added manually in TwinCAT System Manager, or automatically via therouteUsername/routePasswordconfig fields.hostPortis optional (default 10500). It is a logical AMS port used in protocol headers, not a network port. Any value works.
Option A: Automatic route registration (recommended)
The plugin registers a route on the PLC automatically via UDP before connecting. No manual PLC configuration needed:
You can also set hostAMS explicitly if you prefer:
Option B: Static route on PLC
If you prefer not to use automatic registration, add a static route on the PLC via TwinCAT System Manager pointing to the Docker host's IP. Then configure hostAMS to match — no routeUsername/routePassword needed:
Option C: host_network or macvlan
When the container has a routable IP on the PLC network, hostAMS: auto works without routeHostAddress:
Configuration Parameters
targetIP
Yes
—
IP address of the Beckhoff PLC
targetAMS
Yes
—
AMS net ID of the target
targetPort
No
48898
Port of the target internal gateway
runtimePort
No
801
Runtime port of PLC system, 800–899. TwinCAT 2 uses 800–850 (usually 801), TwinCAT 3 uses 851–899 (usually 851)
hostAMS
No
auto
Host AMS net ID. Usually the IP address + .1.1. Must match a route on the PLC. auto derives it from routeHostAddress if set, otherwise from the outbound connection's local IP
hostPort
No
10500
AMS source port used in protocol headers. This is a logical port, not a network port. Any arbitrary value works
readType
No
notification
Read type for the symbols. interval polls at intervalTime; notification uses PLC push updates (see Interval vs Notification)
maxDelay
No
100
Default max delay for sending notifications in ms. Maximum time after value change before PLC must send the notification
cycleTime
No
1000
Default cycle time for notification handler in ms. How often the PLC scans for changes. Use a low value for triggers that are only true/false for 1 PLC cycle
intervalTime
No
1000
Interval time between reads in ms (only used when readType is interval)
requestTimeout
No
5000
Timeout for individual ADS requests in ms. Increase for slow PLCs or large symbol tables
transmissionMode
No
serverOnChange
Notification transmission mode. Only applies when readType is notification. Options: serverOnChange, serverCycle, serverOnChange2, serverCycle2 (see Transmission Modes)
upperCase
No
true
Convert symbol names to all uppercase. Often necessary for TwinCAT 2 PLCs
logLevel
No
disabled
Log level for ADS connection (disabled, error, warn, info, debug, trace). At debug/trace, ADS error codes show human-readable descriptions
routeUsername
No
""
Username for automatic UDP route registration on the PLC. If set, a route is registered before connecting (see Route Registration)
routePassword
No
""
Password for automatic UDP route registration on the PLC
routeHostAddress
No
""
IP address the PLC associates with the route. Required in Docker bridge networking (set to Docker host's IP). When hostAMS is auto, the AMS NetID is also derived from this. Auto-detected from outbound connection if empty (only correct with host_network or macvlan)
Symbols Format
Symbols are specified in the format function.variable:maxDelay:cycleTime:
MAIN.MYBOOL— variable in the main program, uses default maxDelay and cycleTimeMAIN.MYTRIGGER:0:10— variable in the main program with 0ms max delay and 10ms cycle time.superDuperInt— global variable (must start with.)
Transmission Modes
Note:
transmissionModeonly applies whenreadTypeisnotification. When usingreadType: interval, the plugin sends plain ADS Read commands to the PLC at each interval — no notification mechanism is involved, andtransmissionModeis ignored.
The transmissionMode field controls how the PLC's internal notification handler sends updates back to the client. The available modes are:
serverOnChange
4
(Default) The PLC scans for changes at the configured cycleTime interval and sends a notification only when the value has changed. This is the most efficient mode for most use cases.
serverCycle
3
The PLC sends the current value at every cycleTime interval, regardless of whether the value has changed. Useful when you need a constant data stream or heartbeat.
serverOnChange2
6
Enhanced version of serverOnChange available on newer TwinCAT 3 firmware. Supports more efficient internal handling on the PLC side. Automatically falls back to serverOnChange on older PLCs.
serverCycle2
5
Enhanced version of serverCycle available on newer TwinCAT 3 firmware. Same behavior as serverCycle but with improved internal efficiency. Automatically falls back to serverCycle on older PLCs.
Choosing a mode:
Use
serverOnChange(default) for event-driven data where you only care about changesUse
serverCyclewhen you need periodic snapshots regardless of changesThe
2variants (serverOnChange2,serverCycle2) can be used safely on any PLC — the plugin automatically detects older PLCs and falls back to the v1 equivalent
Interval vs Notification
The interval and notification read types can produce similar-looking results (periodic data), but they work differently under the hood:
interval: The client polls the PLC — sends an ADS Read request for each symbol at everyintervalTimeinterval. Simple, no PLC notification overhead, and not subject to the ~500-notification limit.notification+serverOnChange: The PLC pushes data only when a value changes. Most efficient for event-driven data. Subject to the ~500-notification limit per connection.notification+serverCycle: The PLC pushes data at everycycleTimeinterval regardless of changes. Similar result tointervalbut PLC-driven — more precise timing with no request/response overhead per cycle. Subject to the ~500-notification limit.
Aspect
interval
notification + serverOnChange
notification + serverCycle
Who drives
Client polls
PLC pushes on change
PLC pushes on timer
Network per cycle
Request + response
Push only
Push only
Sends unchanged values
Yes
No
Yes
Timing precision
Subject to network latency
PLC real-time task
PLC real-time task
PLC notification limit
No limit
~500 max
~500 max
Best for
Large symbol lists, simple setup
Event-driven data (most use cases)
Precise periodic sampling
Route Registration
The plugin can automatically register a route on the PLC using the Beckhoff UDP route protocol (port 48899). This removes the need to manually add routes in the TwinCAT System Manager.
How it works:
Before establishing the TCP connection, the plugin sends a UDP route registration packet to port 48899 on the PLC
The packet tells the PLC: "Associate AMS NetID X with IP address Y"
The PLC adds this as a runtime route (may not be visible in TwinCAT System Manager)
The normal ADS TCP connection is then established over port 48898
Setting routeUsername activates automatic route registration. If route registration fails (e.g. UDP response lost due to NAT), the plugin logs a warning and still attempts the TCP connection — the route may have been created despite the missing response.
Parameters:
routeUsername/routePassword: PLC administrator credentials. Same as used in TwinCAT System Manager to add routesrouteHostAddress: The IP address the PLC associates with this client. In Docker with bridge networking, this must be set to the Docker host's IP on the PLC network. WhenhostAMSisauto, the AMS NetID is derived from this address. Auto-detected if empty (only correct withhost_networkor macvlan)
Network requirements:
UDP port 48899 must be reachable on the PLC from the client (for route registration)
TCP port 48898 must be reachable on the PLC from the client (outbound — works through any NAT)
Reconnection
The plugin automatically reconnects when the TCP connection is lost (e.g. network cable unplugged, PLC restart). Aggressive TCP keepalive probes detect dead connections within ~13 seconds. On reconnect, the plugin:
Re-establishes the TCP connection (retries indefinitely with 5s interval)
Reloads the symbol table from the PLC
Re-subscribes all notification handles
No manual intervention is needed.
Output
This outputs for each address a single message with the payload being the value that was read. To distinguish messages, you can use meta("symbol_name") in a following benthos bloblang processor.
Testing
Tested and verified:
CX7000, TwinCAT 3
Notifications from Docker container with bridge networking (no host_network)
Automatic UDP route registration from Docker bridge networking
Static route with explicit hostAMS (no route registration)
Reconnection after network loss with automatic notification re-subscribe
Sum/batch commands for read, add notification, and delete notification
CX1020, TwinCAT 2
Read batches, Add notifications, different cycle times and max delay
Different datatypes, INT, INT16, UINT, DINT, BOOL, STRUCT, and more
Automatic fallback from sum commands to individual calls
Automatic fallback from v2 transmission modes to v1
Reconnection after network loss with automatic notification re-subscribe
Last updated

