Skip to main content

Atlas Copco Open Protocol Driver

Overview

A proprietary Java implementation based on Atlas Copco's Open Protocol Specification (vendor-published PDF). It handles torque controller / tightening result collection entirely within a single JVM, eliminating the dependency on an external Node.js runner / NDJSON pipe.

ItemValue
opc_typeOP (native)
Implementation classplantpulse.driver.protocol.op.OpenProtocolJavaDriver
Library(none — proprietary implementation. Atlas Copco OP spec)
readGood (subscription cache based)
writeGood (isWriteSupported() = true) — only certain MIDs
Default port4545
SecurityNone (direct TCP)
Differences from the older OPDriver

The legacy OPDriver in the same package spawned an external Node.js process, whereas OpenProtocolJavaDriver runs on a pure Java socket + receiver thread, which simplifies deployment. Use this driver for new registrations.


Class / Structure

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) → subscribe to the main MIDs (0060, 0070) → start receiverThread.


Wire Format Summary

LLLL MMMM RRR x SS PP CC m n | <body ASCII> | NUL(0x00)
└ 4 4 3 1 2 2 2 1 1 = 20 byte 헤더
FieldLengthMeaning
LLLL4Total length (header 20 + body, NUL excluded)
MMMM4MID (0-padded, e.g. 0061)
RRR3revision
NoAck1' ' (ack required) / '1' (no-ack)
SS2StationID
PP2SpindleID
CC2Sequence
m1MsgNum
n1MsgTotal

All fields are ASCII (US-ASCII). Messages are terminated with \0.


Main MIDs

Receive (subscription)

MIDMeaning
0001 → 0002Communication start / handshake
0060 → 0061Last tightening result subscription / data. Acked with 0062 on receipt
0070 → 0071Alarm subscription / alarm data
9999Keep-alive (sent automatically on receive timeout)

Send (write support)

ConstantMIDActionbody
MID_SELECT_PSET0018Select Pset4-char ASCII
MID_SELECT_JOB0038Select Job2-char ASCII
MID_DISABLE_TOOL0042Disable toolempty string
MID_ENABLE_TOOL0043Enable toolempty string
MID_SET_VEHICLE_ID0050Set Vehicle ID25-char ASCII (right-padded with spaces)
MID_ABORT_TIGHTEN0127Abort tighteningempty string

For write acks, when receiverLoop receives MID 0005 (accepted) / 0004 (error) it triggers pendingWriteAck.complete(...), and write() waits via future.get(DEFAULT_WRITE_ACK_TIMEOUT_MS=5000ms, ...).


Tag Address Format

NotationMeaning
0061:resultDataThe resultData field of MID 0061 (tightening result)
0061Full raw message of the MID
0071:alarmCodealarmCode of the alarm message
61Automatic 4-digit 0-padding → 0061

read() only returns the cache of lastByMID, so the polling interval (timecycle) has no bearing on PLC load.

Write address aliases (case-insensitive): pset, job, select-job, vehicle-id / vehicleid, disable / disable-tool, enable / enable-tool, abort / abort-tightening, or the MID:0018, MID0018, 0018, 18 forms.


Supported / Not Supported

  • ✅ Handshake / keep-alive / automatic re-subscription
  • ✅ MID 0061 / 0071 cache (raw + extraction of the first few fields)
  • ✅ Write MID 0018 / 0038 / 0042 / 0043 / 0050 / 0127 (synchronous ack wait)
  • ❌ Per-MID detailed field parsers (currently only __raw__ + data — later phase)
  • ❌ spindleId routing for multi-spindle controllers
  • ❌ Security/authentication (not present in Open Protocol itself)

Test Coverage

test/java/plantpulse/driver/protocol/op/

ClassTest count
OPDriverTest9 (legacy driver)
OpenProtocolJavaDriverTest10
OpenProtocolSpecTest15
OpenProtocolWriteTest31

65 tests in total.


References

  • Atlas Copco Open Protocol Specification (vendor-published PDF)
  • Code: src/plantpulse/driver/protocol/op/OpenProtocolJavaDriver.java