HART-IP 드라이버
개요
HART (Highway Addressable Remote Transducer) 의 IP 변형. 4-20 mA 산업 계측기를 IP 게이트웨이 경유로 디지털 read/write 한다. HCF 의 공개 HART-IP 사양 기반.
| 항목 | 값 |
|---|---|
opc_type | HART |
| 구현 클래스 | plantpulse.driver.protocol.hart.HARTDriver |
| 라이브러리 | 자체 자바 구현 (HCF spec 기반, 외부 라이브러리 의존 없음) |
| read | ✅ (cmd 1, 3, 13) |
| write | ✅ (cmd 6, 17, 18, 19, 22) |
| 보안 | 없음 (HART-IP spec 자체에 인증/암호화 없음) |
| 기본 포트 | 5094 (TCP) |
클래스 구조
| 클래스 | 역할 |
|---|---|
HARTDriver | 라이프사이클 / 주소 파서 / read·write 디스패치 / KeepAlive 스레드 |
HartIpHeader | 13-byte HART-IP 헤더 (version, type, id, status, sequence, byteCount BE) |
HartCommand | HART 명령 PDU 빌더 — preamble + 0x82 + 5-byte address + cmd + byteCount + data + XOR |
HartChecksum | longitudinal XOR (preamble 제외) |
HartDecode | float32 BE / packed-ASCII 6-bit 디코더, communication status 비트 해석 |
Wire 포맷
HART-IP 메시지 = 13-byte 헤더 + payload
byte 0 Version 1
byte 1 Message Type 0=Request 1=Response 2=Publish 3=NAK
byte 2 Message ID 0=Session-Init 1=Session-Close 2=KeepAlive 3=PDU
byte 3 Status / Error
byte 4-5 Sequence (BE)
byte 6-7 ByteCount (BE, 헤더 13 byte 포함)
byte 8-12 Reserved (0)
PDU payload (Message ID 3) =
Preamble(0xFF×N) + Start(0x82) + Address(5) + Command(1) + ByteCount(1) + Data(N) + XOR(1)
핸드셰이크: connect() 가 Session Init (master-type 1 byte + inactivity-close-time 4 byte BE)
송신 → Response 수신. 이후 KeepAlive 백그라운드 스레드가 주기적으로 Message ID 2 송신.
OPC 등록 옵션
| 필드 | 의미 | 디폴트 |
|---|---|---|
opc_agent_ip / opc_agent_port | 게이트웨이 IP / 포트 | (port 0이면 5094) |
options.master-type | primary / secondary | primary |
options.inactivity-ms | Session inactivity close time | 600000 (10 분) |
options.keepalive-ms | KeepAlive 송신 주기 | 30000 |
options.connect-timeout | TCP connect 타임아웃 | 5000 |
options.read-timeout | read SO 타임아웃 | 5000 |
태그 plc_address 형식
| 표기 | 의미 | 디코드 |
|---|---|---|
1 또는 1:pv | cmd 1 — Read PV | float32 BE (status 2 byte 이후 offset 3) |
3:0 ~ 3:3 또는 3:pv/sv/tv/qv | cmd 3 — PV/SV/TV/QV | 4 × float32 BE (간이 모델) |
13 또는 13:tag | cmd 13 — Tag 8 char | packed-ASCII (3 byte → 4 char) |
write 주소 (address.getValue() 와 함께):
| 표기 | 의미 | value 형식 |
|---|---|---|
6 / polling-address | cmd 6 — Write Polling Address | 0..63 정수 |
17 / message | cmd 17 — Write Message | 32-char packed-ASCII |
18 / tag / descriptor / date | cmd 18 — Tag/Descriptor/Date | tag|desc|DD/MM/YY 또는 sub-field 별 |
19 / final-assembly | cmd 19 — Final Assembly Number | 0..16777215 |
22 / long-tag | cmd 22 — Long Tag (32 byte ISO-Latin-1) | 임의 문자열 |
미지원 영역
- WirelessHART (HART 7) burst 모드, publish (Message Type 2) 비동기 수신.
- Cmd 0/cmd 50/cmd 9 등 device-discovery 류 — 추가 가능.
- Long-frame 외 Short-frame address.
- 5-byte device address 의 manufacturer/device-type 매칭 (현재는 zero-fill).
- Keepalive 응답 동기 처리 — 단순화로 keepalive 응답은 무시 (별 receiver thread + seq correlation 으로 보강 가능).
테스트 커버리지
test/java/plantpulse/driver/protocol/hart/
| 테스트 | 검증 |
|---|---|
HartIpHeaderTest | 13-byte 헤더 round-trip |
HartChecksumTest | XOR 알려진 vector |
HartCommandTest / HartCommandWriteTest | cmd 0/1/3/13/6/17/18/19/22 PDU 빌드 |
HartDecodeTest / HartEncodeTest | float32 BE, packed-ASCII (양방향), BCD date |
HARTDriverAddressTest / HARTDriverWriteTest | 주소 파서 + write 디스패치 |
HartSpecExtraTest | 추가 spec 적합성 |
참고
- HART-IP spec — FieldComm Group / HART Communication Foundation (회원 문서).
- 코드:
plantpulse-edge-driver/src/plantpulse/driver/protocol/hart/. - 운영 시 게이트웨이 (예: ABB AC500-eCo, Pepperl+Fuchs HART Multiplexer) 에서 TCP 5094 가 노출돼야 한다.