본문으로 건너뛰기

OPC-UA 드라이버

개요

OPC Unified Architecture (IEC 62541) 기반 산업 데이터 표준 프로토콜.

항목
opc_typeOPCUA
구현 클래스plantpulse.driver.protocol.opcua.OPCUA_34_Driver
라이브러리Eclipse Milo (milo-sdk-client)
read
write❌ (Phase 3 / Sparkplug NCMD 와 함께)
보안Username/Password, Anonymous

Kepware, Matrikon, Prosys 등 대부분의 OPC-UA 서버와 호환됩니다.


OPC 등록 폼

필드의미예시
opc_agent_ipOPC-UA 서버 IP192.168.0.40
opc_agent_portOPC-UA 서버 TCP 포트49320 (Kepware 기본)
timecycle폴링 주기 (ms)1000
options.servernameendpoint 끝의 서버명(Kepware 면 비움)
options.username인증 사용자kopens
options.password인증 패스워드***
options.discoverydiscovery endpoint 사용 여부false (true 면 endpoints 자동 검색)

생성되는 endpoint URL 형식:

opc.tcp://<opc_agent_ip>:<opc_agent_port>/<servername>

username + password 가 모두 있으면 UsernameProvider, 없으면 AnonymousProvider 사용.


태그 plc_address 형식

OPC-UA 표준 NodeId 표기. 예:

표기의미
ns=2;s=Simulator.Sine1namespace 2, string identifier Simulator.Sine1
ns=2;i=1234numeric identifier 1234
ns=3;g=09087e75-8e5e-499b-954f-f2a8624db28aGUID identifier
ns=2;b=Mb=opaque (bytestring) identifier

Kepware 의 경우 보통 ns=2;s=<Channel>.<Device>.<Tag> 형식.


data_type / format 매핑

OPC-UA 변수 노드의 Value 를 String 으로 캐스팅 후 반환합니다. data_type 은 후속 단계 (PLCValueFomula, Sparkplug 발행 등) 가 캐스팅에 사용합니다.

data_type동작
Float / Double숫자 그대로
Int / Integer / Int32 / Short / Long숫자 그대로
Boolean / Booltrue/false 문자열
String / TextUTF-8 문자열
DateTimeISO 문자열

format 은 OPC-UA 에서는 일반적으로 사용하지 않습니다. 후처리 수식이 필요하면 fomula 사용.


흔한 에러 + 해결

메시지 / 증상원인해결
connection refused서버 미가동, 포트 차단telnet <ip> <port> 로 통신 확인
Bad_UserAccessDeniedusername/password 오류, 익명 비허용서버측 사용자 등록 또는 anonymous 활성화
Bad_SecurityChecksFailed보안 정책 미스매치서버에서 None / Basic256Sha256 등 정책 확인. Phase 1 은 MessageSecurityMode.None 우선
endpointUrl 미스매치discovery=false 인데 서버가 다른 호스트네임 반환discovery=true 로 두거나 hosts 파일에 매핑
값이 항상 0 / nullNodeId 오타, namespace 번호 불일치UA Expert 등 클라이언트로 같은 NodeId read 검증

curl 등록 예시

curl -X POST http://<edge-host>/api/v1/opc \
-H "Content-Type: application/json" \
-d '{
"opc_id": "OPC_UA_Kepware",
"opc_type": "OPCUA",
"opc_name": "Kepware",
"opc_agent_ip": "192.168.0.40",
"opc_agent_port": "49320",
"site_id": "SITE_00001",
"auto_collect": true,
"timecycle": 1000,
"options": {
"username": "kopens",
"password": "***",
"discovery": "false"
},
"tag_list": [
{
"tag_id": "OPC_UA_Kepware_TAG_00001",
"tag_name": "Sine1",
"plc_address": "ns=2;s=Simulator.Sine1",
"data_type": "Float",
"description": "Sine wave"
},
{
"tag_id": "OPC_UA_Kepware_TAG_00002",
"tag_name": "Random1",
"plc_address": "ns=2;s=Simulator.Random1",
"data_type": "Integer"
}
]
}'

값 read:

curl -s http://<edge-host>/api/v1/tag/OPC_UA_Kepware_TAG_00001/value | jq

참고: Kepware 빠른 설정 가이드

  1. Kepware Server → Project → 채널 추가 (예: Simulator).
  2. 디바이스 추가 (예: Simulator) → 모델 = 16 Bit Device.
  3. 태그 추가 → Sine1, type Float, scan rate 100ms 등.
  4. Project Properties → OPC UA → Server Endpoint 에서 포트 49320 활성화.
  5. Anonymous 또는 사용자 계정 활성화.

→ Edge 등록 폼:

필드
opc_agent_ipKepware 서버 IP
opc_agent_port49320
options.servername(비움)
options.username/password위에서 만든 계정
plc_addressns=2;s=Simulator.Simulator.Sine1

예제 모음 (데이터타입별)

OPC-UA 는 변수 노드의 값(Variant)을 String 으로 캐스팅 후 반환합니다. data_type 은 후처리 (PLCValueFomula, Sparkplug DataTypeMapper) 가 캐스팅에 사용. format 은 일반적으로 사용하지 않습니다.

Boolean

data_typeplc_address비고
Booleanns=2;s=Simulator.Boolean1Kepware Simulator 의 Boolean tag
Booleanns=2;s=PLC.Status.RunningKepware Channel.Device.Tag
Booleanns=2;i=1003numeric NodeId

16/32-bit 정수

data_typeplc_address비고
Integerns=2;s=Simulator.Random1Random integer 시뮬
Integerns=2;s=Simulator.Counter1Counter
Integerns=2;s=PLC.D100Kepware MELSEC 채널 노출

64-bit 정수

data_typeplc_address비고
Longns=2;s=Simulator.LongCounterUInt64 / Int64 노드
Longns=2;s=PLC.Cycle.Total누적 카운터

실수

data_typeplc_address비고
Floatns=2;s=Simulator.Sine1sine wave 시뮬
Floatns=2;s=Simulator.Ramp1ramp wave
Doublens=2;s=PLC.Pressure정밀 측정값

문자열

data_typeplc_address비고
Stringns=2;s=Simulator.User1.Name문자열 노드
Stringns=2;s=PLC.Recipe.Active레시피명

NodeId 형식별

identifier 타입plc_address
String (s=)ns=2;s=Simulator.Sine1
Numeric (i=)ns=2;i=1234
GUID (g=)ns=3;g=09087e75-8e5e-499b-954f-f2a8624db28a
Opaque (b=)ns=2;b=Mb=

Formula 활용

용도data_typefomula비고
단위 변환Float${VALUE}*0.001g → kg 등
영점 보정Float${VALUE}-${TAG_ZERO}다른 OPCUA 태그 참조 가능
형변환Float${VALUE}*1.0Integer → Float 강제
다항식Float${VALUE}*${VALUE}*0.0001비선형

curl 종합 예제 (모든 타입)

curl -X POST http://<edge-host>/api/v1/opc \
-H "Content-Type: application/json" \
-d '{
"opc_id": "OPC_UA_FULL",
"opc_type": "OPCUA",
"opc_name": "Kepware Full",
"opc_agent_ip": "192.168.0.40",
"opc_agent_port": "49320",
"site_id": "SITE_00001",
"auto_collect": true,
"timecycle": 1000,
"options": { "discovery": "false" },
"tag_list": [
{"tag_id":"OPC_UA_FULL_T01", "tag_name":"BoolTag", "plc_address":"ns=2;s=Simulator.Boolean1", "data_type":"Boolean"},
{"tag_id":"OPC_UA_FULL_T02", "tag_name":"IntTag", "plc_address":"ns=2;s=Simulator.Random1", "data_type":"Integer"},
{"tag_id":"OPC_UA_FULL_T03", "tag_name":"LongTag", "plc_address":"ns=2;s=Simulator.LongCounter", "data_type":"Long"},
{"tag_id":"OPC_UA_FULL_T04", "tag_name":"FloatTag", "plc_address":"ns=2;s=Simulator.Sine1", "data_type":"Float"},
{"tag_id":"OPC_UA_FULL_T05", "tag_name":"DoubleTag", "plc_address":"ns=2;s=PLC.Pressure", "data_type":"Double"},
{"tag_id":"OPC_UA_FULL_T06", "tag_name":"StringTag", "plc_address":"ns=2;s=Simulator.User1.Name", "data_type":"String"},
{"tag_id":"OPC_UA_FULL_T07", "tag_name":"NumIdTag", "plc_address":"ns=2;i=1234", "data_type":"Integer"},
{"tag_id":"OPC_UA_FULL_T08", "tag_name":"ScaledTag", "plc_address":"ns=2;s=Simulator.Sine1", "data_type":"Float", "fomula":"${VALUE}*100"}
]
}'