Atlas Copco Open Protocol 驱动
概述
基于 Atlas Copco 的 Open Protocol Specification(厂商公开 PDF)的自研 Java 实现。在单一 JVM 内完成扭矩控制器 / 拧紧结果的采集,消除了对外部 Node.js runner / NDJSON pipe 的依赖。
| 项目 | 值 |
|---|---|
opc_type | OP (原生) |
| 实现类 | plantpulse.driver.protocol.op.OpenProtocolJavaDriver |
| 库 | (无 — 自研实现。Atlas Copco OP spec) |
| read | 良好 (基于订阅缓存) |
| write | 良好 (isWriteSupported() = true) — 仅部分 MID |
| 默认端口 | 4545 |
| 安全 | 无 (TCP 直连) |
OPDriver 的差异同一包中的旧版 OPDriver 会 spawn 外部 Node.js 进程,而
OpenProtocolJavaDriver 以纯 Java socket + receiver thread 运行,
部署更为简单。新增注册请使用本驱动。
类 / 结构
OpenProtocolJavaDriver (BaseProtocolDriver)
├── Socket — host:4545
├── receiverThread — daemon, "OP-Receiver-<opc_id>"
├── lastByMID — ConcurrentHashMap<MID4, Map<field,value>>
├── pendingWriteAck — CompletableFuture<String> (MID 0005/0004 단일-flight)
└── writeLock — synchronized (write 직렬화)
connect() → handshake (MID 0001 → 0002) → 订阅主要 MID (0060, 0070) → 启动 receiverThread。
wire 格式摘要
LLLL MMMM RRR x SS PP CC m n | <body ASCII> | NUL(0x00)
└ 4 4 3 1 2 2 2 1 1 = 20 byte 헤더
| 字段 | 长度 | 含义 |
|---|---|---|
| LLLL | 4 | 总长度 (头部 20 + body,不含 NUL) |
| MMMM | 4 | MID (0 填充,例 0061) |
| RRR | 3 | revision |
| NoAck | 1 | ' ' (要求 ack) / '1' (no-ack) |
| SS | 2 | StationID |
| PP | 2 | SpindleID |
| CC | 2 | Sequence |
| m | 1 | MsgNum |
| n | 1 | MsgTotal |
所有字段均为 ASCII (US-ASCII)。消息以 \0 结束。
主要 MID
接收 (订阅)
| MID | 含义 |
|---|---|
| 0001 → 0002 | 通信启动 / 握手 |
| 0060 → 0061 | 订阅最后一次拧紧结果 / 数据。接收时以 0062 进行 ack |
| 0070 → 0071 | 报警订阅 / 报警数据 |
| 9999 | Keep-alive (接收超时时自动发送) |
发送 (支持 write)
| 常量 | MID | 动作 | body |
|---|---|---|---|
MID_SELECT_PSET | 0018 | Select Pset | 4-char ASCII |
MID_SELECT_JOB | 0038 | Select Job | 2-char ASCII |
MID_DISABLE_TOOL | 0042 | Disable tool | 空字符串 |
MID_ENABLE_TOOL | 0043 | Enable tool | 空字符串 |
MID_SET_VEHICLE_ID | 0050 | Set Vehicle ID | 25-char ASCII (右侧空格填充) |
MID_ABORT_TIGHTEN | 0127 | Abort tightening | 空字符串 |
write ack 由 receiverLoop 在收到 MID 0005 (accepted) / 0004 (error) 时 pendingWriteAck.complete(...),
write() 则以 future.get(DEFAULT_WRITE_ACK_TIMEOUT_MS=5000ms, ...) 等待。
标签地址格式
| 表示 | 含义 |
|---|---|
0061:resultData | MID 0061 (拧紧结果) 的 resultData 字段 |
0061 | MID 的完整 raw 消息 |
0071:alarmCode | 报警消息的 alarmCode |
61 | 自动补足为 4 位 0 填充 → 0061 |
read() 仅返回 lastByMID 的缓存,因此轮询周期 (timecycle) 与 PLC 负载无关。
write 地址别名 (忽略大小写):pset、job、select-job、vehicle-id / vehicleid、
disable / disable-tool、enable / enable-tool、abort / abort-tightening,
或 MID:0018、MID0018、0018、18 格式。
支持 / 不支持
- ✅ Handshake / keep-alive / 自动重新订阅
- ✅ MID 0061 / 0071 缓存 (raw + 首部字段提取)
- ✅ Write MID 0018 / 0038 / 0042 / 0043 / 0050 / 0127 (同步等待 ack)
- ❌ 各 MID 的详细字段解析器 (当前仅
__raw__+data— 后续 phase) - ❌ Multi-spindle controller 的 spindleId 路由
- ❌ 安全/认证 (Open Protocol 本身不具备)
测试覆盖率
test/java/plantpulse/driver/protocol/op/
| 类 | 测试数 |
|---|---|
OPDriverTest | 9 (旧版 driver) |
OpenProtocolJavaDriverTest | 10 |
OpenProtocolSpecTest | 15 |
OpenProtocolWriteTest | 31 |
共 65 个测试。
参考
- Atlas Copco Open Protocol Specification (厂商公开 PDF)
- 代码:
src/plantpulse/driver/protocol/op/OpenProtocolJavaDriver.java