协议
下面的表格列出了每种语言实现中实际随附发布的驱动程序。只有当某个协议存在驱动程序并已在该实现的驱动管理器中注册时,才会被标记为支持——仅有一份协议规范本身是不够的。
| 协议 | C | C# | Go | Java | Python |
|---|---|---|---|---|---|
| AB-Ethernet | |||||
| ADS /AMS | |||||
| BACnet/IP | |||||
| CAN(原始) | |||||
| 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(代理协议) | |||||
| Profinet | |||||
| S7 | |||||
| Simulated | |||||
| SLMP(MELSEC) | |||||
| UMAS |
图例:
- 已实现且可用 - 部分实现——参见下方说明 - 未实现
关于部分实现的驱动程序的说明:
- AB-Ethernet 在 Java 和 Go 中均可读取并提供轮询订阅,但两者都不支持写入。
- BACnet/IP(Java)被动接收广播流量,并将其作为订阅暴露出来;它既不读取也不写入属性。Go 驱动才是功能完整的:它能读写属性、发现设备并订阅 COV 通知。
- CAN(raw)(Java)支持写入和订阅,不支持读取。
- CBus(Java)只是一个骨架,能建立连接但未实现任何操作。Go 驱动才是功能完整的。
- ctrlX(Java)能响应 ping,这是它唯一完成的操作。驱动提供了发现功能,但
CtrlXPlcDiscoverer.discoverWithHandler是一个未实现的 TODO,返回的是null而不是一个 future,因此发现请求只会失败,什么也找不到。它的读取、写入和订阅构建器同样未实现,而且尽管连接中带有浏览代码,浏览目前也无法工作。 - Firmata 在 Java 和 Go 中均可写入和订阅,但两者都不支持读取。它只用于驱动和监控一块开发板,而不做轮询。
- IEC 60870-5-104 在 Java 和 Go 中都仅支持订阅,因为该协议是推送驱动的:会话一旦建立,RTU 就会主动发送 ASDU,因此既没有东西可读,也没有东西可写。Go 驱动在每个值旁边保留了 IEC 质量描述符,因此 RTU 标记为无效、被阻塞、被替换或非当前的读数,不会以良好读数的样子呈现出来。
- KNXnet/IP(C#)是 plc4net 中唯一的驱动,没有跟上其他实现的进度。
- OPC-UA(Go)可以在未加密的通道上进行读取、写入和订阅,但仅此而已:只有
securityPolicy=None真正可用,浏览未实现,消息也不分块,因此超过单个分块的请求或响应会失败。Java 驱动实现了六种安全策略、浏览和分块。 - Open-Protocol(Java)只是一个骨架,能建立连接但未实现任何操作。
- Profinet(Java)能发现设备并浏览已连接设备的子模块;两个 Java 驱动都不支持读取和写入。只有较新的
profinet-ng驱动属于plc4j-driver-all;较旧的profinet驱动仍在代码库中,但未被打包发布。在profinet-ng中,订阅请求会完成 PROFINET 连接握手,但订阅响应的 future 被刻意留为未完成状态,且onRegisterConsumer会抛出UnsupportedOperationException,因此周期性数据永远不会到达应用。未打包的profinet驱动确实实现了这条路径——它会完成订阅响应、按订阅句柄注册消费者,并为每一个到来的周期性帧分发一个PlcSubscriptionEvent——所以下面描述实际发布内容的订阅条目并不适用于它。 - SLMP 在 Java 和 Go 中都仅访问字设备
D、W和R。这是驱动设计时的目标范围,而非移植上的缺口——位设备和更完整的 MELSEC 命令集在两种语言中都未实现。 - UMAS(Go)对
DATE和TIME_OF_DAY标签拒绝响应而非作出应答:Go 的数据项解析器还没有针对这些字段名的分支,否则这些字节会解析不出任何值。其他所有数据类型都支持读写。还要注意,UMAS 在任何语言中都没有附带测试数据,因此两个驱动是相互验证的,而不是与抓取到的真实报文交互进行验证。
DF1 在仓库中提供了协议规范,plc4go 还额外附带了由此生成的消息模型,但没有任何语言实现提供了对应的驱动:没有任何组件能够打开 DF1 连接。DF1 命令消息也会出现在 AB-Ethernet 模型中,该协议实际上正是在今天这个位置被使用的。
功能特性
下表列出了每个驱动实际实现了哪些操作。它描述的是 plc4j,因为这是最完整的实现;其他语言只支持其中的一个子集。当驱动实现了某项操作时,该操作就会被列为已支持——驱动对自身元数据的报告并不一致,因此本表遵循的是代码而非元数据。
| 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 (profinet-ng) | ||||||
| S7 | ||||||
| Simulated | ||||||
| SLMP (MELSEC) | ||||||
| UMAS |
图例:
- 由驱动实现 - 模拟:该协议没有原生支持,因此由 PLC4X 提供 - 未实现
Modbus 之类协议没有订阅的概念——客户端只能轮询。这些协议的驱动会扩展 PollingSubscriptionConnectionBase,它把订阅请求转化为轮询循环,并从中产生变更事件,从而使应用程序代码在任何地方都能使用同一套订阅 API。这正是上文黄色订阅条目所表示的含义;线路上的流量仍然是一连串的读取操作。AB-Ethernet、EtherNet/IP(包括 Logix)、Modbus、SLMP 和 UMAS 都以这种方式工作。
Logix 驱动复用了 EtherNet/IP 连接,因此它支持相同的操作,但不提供设备发现功能。Modbus 的发现功能同样仅限于 TCP:只有 ModbusTcpDriver 提供了发现请求构造器,所以串口的 RTU 和 ASCII 模式无法发现设备。S7 的发现功能使用 PROFINET DCP,需要安装可选的 pcap4j 运行时(以及主机上的 libpcap)。
读取或写入请求总是携带一组标签,因此不存在单独的"单值"与"多值"支持:能够读取的驱动就可以在一次请求中读取任意数量的标签。差别只在于效率——有些驱动会把一个请求拆分为多个 PLC 请求,再把响应合并起来。
评论
登录后参与评论
KnowForge