The ADS route enables communication with Beckhoff TwinCAT PLCs and systems using the ADS (Automation Device Specification) protocol. It supports automatic symbol discovery, bidirectional communication, and complex data types including arrays and structures.
ADS provides direct, high-performance access to TwinCAT variables. The AutoDiscovery feature can automatically find and expose all PLC symbols as MQTT topics.
The ADS route is on beta testing. It is planned for a future release.
DEFINE ROUTE BeckhoffPLC WITH TYPE ADS ADD ADS_CONFIG WITH LOCAL_NET_ID "192.168.1.10.1.1" WITH LOCAL_ROUTE_TO_TARGET "CX_12345" WITH TARGET_NET_ID "192.168.1.100.1.1" WITH TARGET_IP "192.168.1.100" WITH TARGET_PORT 851 WITH TARGET_ROUTE_TO_LOCAL "MQTTBridge" ADD MAPPING ProcessData WITH EVERY 500 MILLISECONDS ADD TAG Temperature WITH ADDRESS "GVL_Process.rTemperature" WITH DATA_TYPE "REAL" WITH SOURCE_TOPIC "plc/temperature"
ADD ADS_CONFIG WITH LOCAL_NET_ID "192.168.1.10.1.1" WITH LOCAL_ROUTE_TO_TARGET "PlcRoute" WITH TARGET_NET_ID "192.168.1.100.1.1" WITH TARGET_IP "192.168.1.100" WITH TARGET_PORT 851 WITH TARGET_ROUTE_TO_LOCAL "MQTTServer" WITH TARGET_USER "Administrator" WITH TARGET_PASSWORD "1" WITH TIMEOUT 5000
DEFINE ROUTE BeckhoffAutoDiscover WITH TYPE ADS ADD ADS_CONFIG WITH LOCAL_NET_ID "192.168.1.10.1.1" WITH LOCAL_ROUTE_TO_TARGET "CX_Route" WITH TARGET_NET_ID "192.168.1.100.1.1" WITH TARGET_IP "192.168.1.100" WITH TARGET_PORT 851 WITH TARGET_ROUTE_TO_LOCAL "MQTTBridge" WITH AUTO_DISCOVERY "true" WITH DISCOVERY_BASE_TOPIC "beckhoff/plc" WITH DISCOVERY_FILTER_INCLUDES "GVL_*" WITH DISCOVERY_FILTER_EXCLUDES "*_Internal*" WITH DISCOVERY_DEFAULT_CYCLE 500 WITH DISCOVERY_MAX_DEPTH 3
For on-demand ADS operations (not polling), use the EVENT syntax. Publish a message to SOURCE_TOPIC to trigger the operation; the route executes it and publishes the result to DESTINATION_TOPIC.
DEFINE ROUTE TwinCATBasic WITH TYPE ADS ADD ADS_CONFIG WITH LOCAL_NET_ID "192.168.1.10.1.1" WITH LOCAL_ROUTE_TO_TARGET "CX_Route" WITH TARGET_NET_ID "192.168.1.100.1.1" WITH TARGET_IP "192.168.1.100" WITH TARGET_PORT 851 WITH TARGET_ROUTE_TO_LOCAL "MQTTBridge" ADD MAPPING ProcessVariables WITH EVERY 500 MILLISECONDS ADD TAG Temperature WITH ADDRESS "GVL_Process.rTemperature" WITH ADDRESS_TYPE "SYMBOL" WITH DATA_TYPE "REAL" WITH SOURCE_TOPIC "plc/process/temperature" WITH UNIT "°C" ADD TAG Pressure WITH ADDRESS "GVL_Process.rPressure" WITH ADDRESS_TYPE "SYMBOL" WITH DATA_TYPE "REAL" WITH SOURCE_TOPIC "plc/process/pressure" WITH UNIT "bar" ADD TAG RunningState WITH ADDRESS "GVL_Process.bRunning" WITH ADDRESS_TYPE "SYMBOL" WITH DATA_TYPE "BOOL" WITH SOURCE_TOPIC "plc/process/running"
Automatically discover and expose all GVL variables:
DEFINE ROUTE TwinCATAutoDiscover WITH TYPE ADS ADD ADS_CONFIG WITH LOCAL_NET_ID "192.168.1.10.1.1" WITH LOCAL_ROUTE_TO_TARGET "CX_Route" WITH TARGET_NET_ID "192.168.1.100.1.1" WITH TARGET_IP "192.168.1.100" WITH TARGET_PORT 851 WITH TARGET_ROUTE_TO_LOCAL "MQTTBridge" WITH AUTO_DISCOVERY "true" WITH DISCOVERY_BASE_TOPIC "twincat" WITH DISCOVERY_FILTER_INCLUDES "GVL_Production.*,GVL_Process.*" WITH DISCOVERY_FILTER_EXCLUDES "*_Debug*,*_Test*" WITH DISCOVERY_DEFAULT_CYCLE 500 WITH DISCOVERY_MAX_DEPTH 2 WITH DISCOVERY_PARALLEL_READING "true" WITH DISCOVERY_BATCH_SIZE 100
Read process values and write setpoints:
DEFINE ROUTE TwinCATControl WITH TYPE ADS ADD ADS_CONFIG WITH LOCAL_NET_ID "192.168.1.10.1.1" WITH LOCAL_ROUTE_TO_TARGET "CX_Route" WITH TARGET_NET_ID "192.168.1.100.1.1" WITH TARGET_IP "192.168.1.100" WITH TARGET_PORT 851 WITH TARGET_ROUTE_TO_LOCAL "MQTTBridge" ADD MAPPING ControlLoop WITH EVERY 200 MILLISECONDS ADD TAG ProcessValue WITH ADDRESS "GVL_Control.rPV" WITH DATA_TYPE "REAL" WITH SOURCE_TOPIC "control/pv" WITH UNIT "°C" ADD TAG Setpoint WITH ADDRESS "GVL_Control.rSP" WITH DATA_TYPE "REAL" WITH SOURCE_TOPIC "control/sp" WITH WRITABLE "true" WITH DESTINATION_TOPIC "control/sp/write" WITH MIN_VALUE 0 WITH MAX_VALUE 100 ADD TAG Output WITH ADDRESS "GVL_Control.rOutput" WITH DATA_TYPE "REAL" WITH SOURCE_TOPIC "control/output" WITH UNIT "%" ADD TAG AutoMode WITH ADDRESS "GVL_Control.bAutoMode" WITH DATA_TYPE "BOOL" WITH SOURCE_TOPIC "control/auto" WITH WRITABLE "true" WITH DESTINATION_TOPIC "control/auto/write"
Read array values:
DEFINE ROUTE TwinCATArrays WITH TYPE ADS ADD ADS_CONFIG WITH LOCAL_NET_ID "192.168.1.10.1.1" WITH LOCAL_ROUTE_TO_TARGET "CX_Route" WITH TARGET_NET_ID "192.168.1.100.1.1" WITH TARGET_IP "192.168.1.100" WITH TARGET_PORT 851 WITH TARGET_ROUTE_TO_LOCAL "MQTTBridge" ADD MAPPING ArrayData WITH EVERY 1 SECOND ADD TAG TemperatureArray WITH ADDRESS "GVL_Data.arTemperatures" WITH DATA_TYPE "ARRAY" WITH ARRAY_ELEMENT_TYPE "REAL" WITH ARRAY_SIZE 10 WITH SOURCE_TOPIC "plc/temperatures" WITH PUBLISH_MODE "JSON" ADD TAG StatusBits WITH ADDRESS "GVL_Data.arStatus" WITH DATA_TYPE "ARRAY" WITH ARRAY_ELEMENT_TYPE "BOOL" WITH ARRAY_SIZE 16 WITH SOURCE_TOPIC "plc/status"
Read structured data:
DEFINE ROUTE TwinCATStruct WITH TYPE ADS ADD ADS_CONFIG WITH LOCAL_NET_ID "192.168.1.10.1.1" WITH LOCAL_ROUTE_TO_TARGET "CX_Route" WITH TARGET_NET_ID "192.168.1.100.1.1" WITH TARGET_IP "192.168.1.100" WITH TARGET_PORT 851 WITH TARGET_ROUTE_TO_LOCAL "MQTTBridge" ADD MAPPING StructData WITH EVERY 500 MILLISECONDS ADD TAG MachineData WITH ADDRESS "GVL_Machine.stMachineData" WITH DATA_TYPE "STRUCT" WITH STRUCT_FIELD_DEFINITIONS "Speed:0:REAL:4,Current:4:REAL:4,Status:8:INT:2,ErrorCode:10:WORD:2" WITH SOURCE_TOPIC "plc/machine" WITH PUBLISH_MODE "JSON"
Continuous monitoring with on-demand read and write events in the same route:
DEFINE ROUTE FullADSSetup WITH TYPE ADS ADD ADS_CONFIG WITH LOCAL_NET_ID "192.168.1.10.1.1" WITH LOCAL_ROUTE_TO_TARGET "CX_Route" WITH TARGET_NET_ID "192.168.1.100.1.1" WITH TARGET_IP "192.168.1.100" WITH TARGET_PORT 851 WITH TARGET_ROUTE_TO_LOCAL "MQTTBridge" ADD MAPPING ProcessVariables WITH EVERY 500 MILLISECONDS ADD TAG Temperature WITH ADDRESS "GVL_Process.rTemperature" WITH ADDRESS_TYPE "SYMBOL" WITH DATA_TYPE "REAL" WITH SOURCE_TOPIC "plc/temperature" WITH UNIT "°C" ADD TAG Pressure WITH ADDRESS "GVL_Process.rPressure" WITH ADDRESS_TYPE "SYMBOL" WITH DATA_TYPE "REAL" WITH SOURCE_TOPIC "plc/pressure" WITH UNIT "bar" ADD EVENT ReadSymbol WITH SOURCE_TOPIC "ads/commands/read" WITH DESTINATION_TOPIC "ads/responses/read" WITH QUERY "{operation: READ, symbol: GVL_Process.rOutput, data_type: REAL}" ADD EVENT WriteSetpoint WITH SOURCE_TOPIC "ads/commands/write" WITH DESTINATION_TOPIC "ads/responses/write" WITH QUERY "{operation: WRITE, symbol: GVL_Control.rSP, data_type: REAL, value: 0}"
The MAPPING continuously reads temperature and pressure. To trigger an on-demand read of the output value, publish any message to ads/commands/read. To write a setpoint, publish to ads/commands/write.