Atlas Copco Open Protocol 드라이버
개요
Atlas Copco 의 Open Protocol Specification (벤더 공개 PDF) 기반 자체 자바 구현. 토크 컨트롤러 / 체결 결과 수집을 단일 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 는 외부 Node.js 프로세스를 spawn 했지만,
OpenProtocolJavaDriver 는 순수 자바 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-padded, 예 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 (수신 timeout 시 자동 송신) |
송신 (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 (오른쪽 공백 padding) |
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-padding → 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