PROFINET 드라이버
개요
PROFINET IO — 산업용 이더넷 기반 fieldbus. 2026-07 네이티브 재작성 — 옛 Apache PLC4j profinet 위임은 제거되었습니다(PLC4X profinet 은 raw Ethernet(EtherType 0x8892, libpcap 전제) + canRead()=false 라 엣지에서 connect 자체가 예외로 죽었음). 지금은 plantpulse-plc-protocol 의 자체 acyclic Read-Implicit(DCE/RPC over UDP 34964) 구현(ProfinetPLC)을 사용합니다 — AR(Connect) 없이 ARUUID=0 으로 record 를 읽는 서비스(I&M 데이터 등 엔지니어링 툴 경로)라 폴링 수집기에 정합.
| 항목 | 값 |
|---|---|
opc_type | PROFINET |
| 구현 클래스 | plantpulse.driver.protocol.profinet.ProfinetDriver |
| 라이브러리 | 자체 네이티브 (plantpulse-plc-protocol 의 profinet — DCE/RPC Read-Implicit) |
| 상속 | BaseProtocolDriver (PLC4j 아님) |
| 기본 포트 | 34964 (PROFINET CM DCE/RPC, UDP) |
| 상태 | 안정 (acyclic record 폴링) |
| read | OK (Read-Implicit, acyclic record) |
| write | ❌ (읽기 전용 — Write record 미구현) |
| 보안 | 없음 |
본 드라이버는 acyclic record 폴링 전용입니다. 사이클릭 IO 교환(RT/IRT, L2 raw Ethernet)은 미지원 — RT 가 필요하면 raw-ethernet(pcap, CAP_NET_RAW) 트랙이 별도로 필요합니다. GSDML 파일도 쓰지 않습니다(record 좌표 직접 지정).
클래스 구조
BaseProtocolDriver
└── ProfinetDriver — connect() 에서 ProfinetPLC(host, port) 생성 (UDP connectionless)
UDP 는 connectionless 라 핸드셰이크가 없습니다 — 라이브니스는 read 실패 시 무효화(AB-ETH/BACnet 패턴). 요청→응답 왕복은 ProfinetPLC 안에서 직렬화(one outstanding request)되고, 응답은 activityUuid + sequenceNumber 에코 검증으로 stale 을 거부합니다.
OPC 등록 옵션
| 필드 | 의미 | 기본 |
|---|---|---|
opc_agent_ip | PROFINET 디바이스 IP | 192.168.1.30 |
opc_agent_port | UDP 포트 | 34964 (0 이면 자동) |
options.read-timeout | 응답 타임아웃 (ms) | 3000 |
options.api | PROFINET API 번호 | 0 |
옛 폼의 gsd-directory / dap-id / ip-address 옵션은 네이티브가 받지 않습니다(제거됨). record 좌표는 태그 주소로 직접 지정합니다.
태그 plc_address 형식 (신규 계약)
<slot>:<subslot>:<index>[:<TYPE>]
index: 10진 또는0x16진 (예: I&M0 =0xAFF0)TYPE(기본WORD):WORD(u16) /INT(i16) /DINT(i32) /DWORD(u32) /REAL(float32) /BOOL/STRING[n](기본 n=32). record data 는 big-endian.
| 표기 | 의미 |
|---|---|
0:1:0x0001:REAL | slot0 / subslot1 의 record 0x0001 을 float32 로 |
0:1:2 | record 2 를 WORD(u16) 로 — TYPE 생략 |
0:1:0xAFF0:STRING[32] | I&M0 영역 문자열 |
support / 미지원
- read: DCE/RPC Read-Implicit (acyclic record) — OK.
- write: 미지원 —
isWriteSupported() = false,write()는 항상false. (Write record 는 후속.) - 사이클릭 IO (RT/IRT): 미지원 — record 폴링 전용.
- DCP discovery / 자동 IP 설정: 미지원 — IP 직접 지정.
- PROFIsafe / PROFIenergy profile: 미지원.
curl 등록 예시
curl -X POST http://<edge-host>/api/v1/opc \
-H "Content-Type: application/json" \
-d '{
"opc_id": "OPC_PROFINET_IO1",
"opc_type": "PROFINET",
"opc_name": "PN Device 1",
"opc_agent_ip": "192.168.1.30",
"opc_agent_port": "34964",
"site_id": "SITE_00001",
"auto_collect": true,
"timecycle": 1000,
"options": { "read-timeout": "3000" },
"tag_list": [
{"tag_id":"OPC_PROFINET_IO1_T01","tag_name":"Rec1","plc_address":"0:1:0x0001:REAL","data_type":"Float"},
{"tag_id":"OPC_PROFINET_IO1_T02","tag_name":"Rec2","plc_address":"0:1:2:WORD","data_type":"Integer"}
]
}'
참고
- Profinet IO — IEC 61158-6-10 / IEC 61784. Read-Implicit = CM opnum 5.
- 코드:
plantpulse-edge-driver/src/plantpulse/driver/protocol/profinet/ProfinetDriver.java+plantpulse-plc-protocol의profinet패키지. - 운영: S7 PLC 메모리 값 수집이 목적이면 S7 (ISO-on-TCP) 드라이버가 더 보편적 — 본 드라이버는 PROFINET 디바이스의 record(I&M 등) 폴링용.