Current language support for protocols
The tables below list the drivers that actually ship with each language implementation. A protocol only appears as supported where a driver exists and is registered with that implementation’s driver manager - a protocol specification on its own is not enough.
| Protocol | C | C# | Go | Java | Python |
|---|---|---|---|---|---|
AB-Ethernet |
|||||
ADS /AMS |
|||||
BACnet/IP |
|||||
CAN (raw) |
|||||
CANopen |
|||||
CBus |
|||||
ctrlX |
|||||
DF1 |
|||||
EtherNet/IP |
|||||
EtherNet/IP - Logix |
|||||
Firmata |
|||||
IEC-60870 |
|||||
KNXnet/IP |
|||||
Modbus (TCP/RTU/ASCII) |
|||||
OPC-UA |
|||||
Open-Protocol (Torque-Tools) |
|||||
PLC4X (Proxy-Protocol) |
|||||
Profinet |
|||||
S7 |
|||||
Simulated |
|||||
SLMP (MELSEC) |
|||||
UMAS |
Legend: - Implemented and usable - Partially implemented - see the notes below - Not implemented |
Notes on the partially implemented drivers:
-
AB-Ethernet reads and offers polled subscriptions in both Java and Go; neither writes.
-
BACnet/IP (Java) passively receives broadcast traffic and exposes it as subscriptions; it does not read or write properties. The Go driver is the complete one: it reads and writes properties, discovers devices and subscribes to COV notifications.
-
CAN (raw) (Java) writes and subscribes; there is no read support.
-
CBus (Java) is a skeleton that connects but implements no operations. The Go driver is the complete one.
-
ctrlX (Java) answers pings; that is the only operation it completes. Discovery is offered by the driver, but
CtrlXPlcDiscoverer.discoverWithHandleris an unimplemented TODO that returnsnullinstead of a future, so a discovery request fails rather than finding anything. Its read, write and subscribe builders are not implemented either, and although the connection carries browse code, browsing does not work yet. -
Firmata writes and subscribes in both Java and Go; neither reads. A board is driven and monitored, never polled.
-
IEC 60870-5-104 subscribes only, in both Java and Go, because the protocol is push driven: the RTU sends unsolicited ASDUs once the session is started, so there is nothing to read or write. The Go driver keeps the IEC quality descriptors alongside each value, so a reading the RTU marked invalid, blocked, substituted or not-topical does not arrive looking like a good one.
-
KNXnet/IP (C#) is the only driver in plc4net and has not kept pace with the other implementations.
-
OPC-UA (Go) reads, writes and subscribes over an unencrypted channel, but that is where it ends: only
securityPolicy=Noneactually works, browsing is not implemented, and messages are not chunked, so a request or response larger than a single chunk fails. The Java driver implements the six security policies, browsing and chunking. -
Open-Protocol (Java) is a skeleton that connects but implements no operations.
-
Profinet (Java) discovers devices and browses the submodules of a connected device; neither of the two Java drivers has read or write support. Only the newer
profinet-ngdriver is part ofplc4j-driver-all; the olderprofinetdriver is still in the code base but is not bundled. Inprofinet-nga subscription request completes the PROFINET connect handshake, but the subscription response future is deliberately left incomplete andonRegisterConsumerthrowsUnsupportedOperationException, so no cyclic data ever reaches an application. The unbundledprofinetdriver does implement that path - it completes the subscription response, registers consumers per subscription handle and dispatches aPlcSubscriptionEventfor every incoming cyclic frame - so the subscribe entry below, which describes what ships, does not apply to it. -
SLMP addresses the word devices
D,WandRonly, in both Java and Go. That is the scope the driver was written to rather than a port gap - the bit devices and the wider MELSEC command set are not implemented in either language. -
UMAS (Go) refuses
DATEandTIME_OF_DAYtags rather than answering them: the Go data item parser has no case for those field names yet, so the bytes would parse to no value. Every other data type reads and writes. Note also that UMAS ships no test data in any language, so both drivers are verified against each other rather than against a captured exchange.
DF1 has a protocol specification in the repository, and plc4go additionally ships the generated message model for it, but no language implementation has a driver: there is nothing that can open a DF1 connection. DF1 command messages also appear inside the AB-Ethernet model, which is where that protocol is actually used today.
Features
The table below lists which operations each driver actually implements. It describes plc4j, because that is the most complete implementation; the other languages support a subset. An operation is listed as supported where the driver implements it - drivers report their own metadata inconsistently, so this table follows the code rather than the metadata.
| Protocol | Discovery | Browse | Read | Write | Subscribe | Ping |
|---|---|---|---|---|---|---|
AB-Ethernet |
||||||
ADS /AMS |
||||||
BACnet/IP |
||||||
CAN (raw) |
||||||
CANopen |
||||||
CBus |
||||||
ctrlX |
||||||
EtherNet/IP |
||||||
EtherNet/IP - Logix |
||||||
Firmata |
||||||
IEC-60870 |
||||||
KNXnet/IP |
||||||
Modbus TCP |
||||||
Modbus RTU / ASCII |
||||||
OPC-UA |
||||||
Open-Protocol (Torque-Tools) |
||||||
PLC4X (Proxy-Protocol) |
||||||
Profinet ( |
||||||
S7 |
||||||
Simulated |
||||||
SLMP (MELSEC) |
||||||
UMAS |
Legend: - Implemented by the driver - Emulated: the protocol has no native support, so PLC4X provides it - Not implemented |
Protocols such as Modbus have no notion of a subscription - a client has to poll. Drivers for those
protocols extend PollingSubscriptionConnectionBase, which turns a subscription request into a
polling loop and emits change events from it, so application code can use the same subscription API
everywhere. This is what the yellow subscription entries above mean; the traffic on the wire is
still a sequence of reads. AB-Ethernet, EtherNet/IP (including Logix), Modbus, SLMP and UMAS work
this way.
The Logix driver reuses the EtherNet/IP connection, so it supports the same operations, but it does
not expose device discovery. Modbus discovery is likewise a TCP-only feature: only ModbusTcpDriver
offers a discovery request builder, so the serial RTU and ASCII flavors cannot discover devices.
S7 discovery uses PROFINET DCP and needs the optional pcap4j runtime (and libpcap on the host) to be
installed.
A read or write request always carries a set of tags, so there is no separate "single value" and "multiple values" support: a driver that can read can read any number of tags in one request. How efficiently it does so differs - some drivers split a request into several PLC requests and merge the responses.