
샘플(노드 구조, 메시지 흐름)
현재 구성한 노드의 구조는 아래와 같습니다.
Objects
└─ Factory
└─ LINE1
└─ EQP1
├─ Status (UInt16) // 설비 상태 코드
├─ Temperature (Double) // 온도 값
├─ LastUpdate (DateTime) // 마지막 갱신 시각(UTC)
├─ Seq (UInt32) // 증가 시퀀스
└─ RawMessage (String) // 원문 메시지(선택)
일반적인 Message Flow(TCP, Client-Server)는 아래와 같습니다.
# Message Flow (TCP, Client–Server
User PLM MES OPC UA Server PLC
| | | | |
| 1.Change | | | |
|---------->| | | |
| | 2.Notify | | |
| |----------->| | |
| | (Change, | | |
| | SEQ=1001) | | |
| | | 3.Validate SEQ | |
| | | | |
| | | 4.ACK | |
| |<-----------| | |
| | | (ACK,1001) | |
| | | | |
| | | 5.Write Params | |
| | |---------------> | |
| | | (CMD, SEQ=2001) | |
| | | | 6.Apply |
| | | |-------------->|
| | | | |
| | | | 7.ACK |
| | |<--------------- | |
| | | (ACK,2001) | |
일반적인 Message Flow(Pub/Sub)는 아래와 같습니다.
# Message Flow (Pub/Sub)
User PLM Event Bus / OPC UA PubSub MES PLC
| | | | |
| 1.Change | | | |
|---------->| | | |
| | 2.Publish | | |
| |---------------> | | |
| | (Event, | | |
| | SEQ=3001) | | |
| | | 3.Deliver | |
| | |----------------------> | |
| | | (Event, SEQ=3001) | |
| | | | 4.ACK* |
| | | <----------------------| |
| | | (ACK,3001) | |
| | | | |
| | | 5.Deliver | |
| | |-------------------------------> |
| | | (Event, SEQ=3001) |
메시지 전송 트리거
[이벤트 발생 기반 전송]
특정 상태 변화나 이벤트가 발생할 때마다 메시지를 보내는 방식입니다.
특정 상태 코드(Status) 또는 온도(Temperature)가 임계치를 넘는 등 유의미한 변화가 있을 때 PLC의 OPCUA 서버는 해당 값들을 업데이트하고, 이를 MES 클라이언트가 Sub으로 감지하여 처리합니다.(Polling 없이 Sub으로 실시간 감지 가능)
[주기적/배치 전송]
특정 주기 또는 공정 단계 완료 시점 등에 정기적으로 메시지를 묶어 보내는 방식입니다. 실시간성은 떨어지지만, MES에서
수집하여 일괄 처리하거나 네트워크 부하를 조절할 때 유용합니다.
메시지 내용 및 데이터 모델
메시지의 데이터 구조는 양측 시스템 모두에 의미 있고 확장 가능하도록 설계해야 합니다.
현재 구성한 노드는 아래와 같습니다.
Status (UInt16): 설비 상태 코드 (예: 가동/정지/에러 등의 코드)
Temperature (Double): 현재 온도 값 (프로세스 변수 예시)
LastUpdate (DateTime): 해당 데이터셋이 갱신된 시각 (UTC 기준)
Seq (UInt32): 메시지 시퀀스 번호 (증가하는 고유 ID)
RawMessage (String): 원문 메시지 (선택 사항, 필요 시 구조화된 문자열 또는 JSON 등)
추가로 고려해볼 사항입니다.
[메시지 타입 식별자]
- Microsoft Azure OPC UA Connector의 메시지 헤더에는 type이나 subject 필드로 메시지 종류와 대상 자산을 구분하고, sequence 필드로 메시지 일렬번호를 제공하고 있습니다.
OPC UA Message
├─ header
│ ├─ type // 메시지 종류 (telemetry | event | alarm | command)
│ ├─ subject // 대상 자산 (site/line/equipment/tag)
│ ├─ sequence // 메시지 일련번호 (증가값), 자산에 메시지가 하나 발행될 때 생성
│ ├─ timestamp // 이벤트 발생 시각 (UTC)
│ └─ source // OPC-UA 서버 또는 Endpoint
│
└─ body
├─ nodeId // OPC-UA NodeId
├─ value // 실제 값
├─ dataType // OPC-UA DataType
├─ quality // StatusCode (Good/Bad/Uncertain)
└─ meta // 확장 정보 (선택)
------------------------------------------------------------------------
{
"header": {
"type": "telemetry",
"subject": "factory1/lineA/eqp01/temperature",
"sequence": 102345,
"timestamp": "2026-01-23T01:15:30Z",
"source": "opc.tcp://10.0.0.5:4840"
},
"body": {
"nodeId": "ns=2;s=Factory.LineA.EQP01.Temperature",
"value": 72.4,
"dataType": "Double",
"quality": "Good",
"meta": {
"unit": "C",
"samplingIntervalMs": 1000
}
}
}
# 배열
{
"header": {
"type": "telemetry",
"subject": "factory1/lineA/eqp01/sensors",
"sequence": 33012,
"timestamp": "2026-01-23T01:15:40Z",
"source": "opc.tcp://10.0.0.5:4840"
},
"body": {
"nodeId": "ns=2;s=Factory.LineA.EQP01.SensorArray",
"dataType": "Structure[]",
"value": [
{ "sensorId": "T1", "value": 72.4 },
{ "sensorId": "P1", "value": 1.02 }
],
"quality": "Good"
}
}
[설비 라인 식별 정보]
- 지금은 subject 값으로 line, eqp 정보를 알 수 있지만, object가 많아지면 msg 항목에 추가 시켜도 좋습니다.
[여러 데이터 포인트 묶음]
- 데이터 덩어리가 아닌 개체로 표현
- 관련 데이터를 묶어, 설비의 의미를 구조로 표현하는 것
Objects
└─ Factory
└─ LineA
└─ EQP01
├─ Status (Object)
│ ├─ Temperature
│ ├─ Pressure
│ └─ RunState
│
└─ StatusData (Structure)
└─ { temperature, pressure, runState, alarm }
메시지 순서 보장과 유실 검출
신뢰성 있는 MES-PLC 통신을 위해선느 메시지의 순서가 보장되고, 누락된 메시지를 감지하는 메커니즘이 필요합니다. OPCUA 자체도 전송 계층에서 순서 제어와 누락 검출 기능을 일부 제공합니다.
내용 초반에 노드 구성을 보면 Seq 노드가 응용 레벨 시퀀스 번호입니다. 이 번호를 활용하여 다음과 같은 전략을 구현할 수 있습니다.
- 메시지 순서 부여: PLC는 새로운 메시지 생성할 때마다 Seq 값을 1씩 증가시켜 붙입니다. MES에서 Seq 값을 확인해 누락된 것을 확인할 수 있습니다.
- 핸드셰이크 설계: ACK 메커니즘을 토입하면 더욱 신뢰성 있는 구성이 가능합니다. https://cache.industry.siemens.com/dl/files/835/109814835/att_1140017/v2/109814835_SiemensInformationModelKit_DOC_v3_0_en.pdf#:~:text=SequenceNo%20UInt32%20Unique%20sequence%20number,for%20this%20handshake%20interface%2C%20to

시퀀스 번호는 메시지의 순서를 추적하고 유실 여부를 판단하는 핵심 장치입니다. OPCUA 통신 자체가 TCP 기반이라 전송된 메시지는 순서를 유지하지만, 네트워크 장애나 구독 지연 등으로 인해 어떤 메시지가 전달되지 못하는 상황에 대비해야 합니다. 가능하다면, Seq와 ACK를 활용하여 검증하는 것을 권장합니다.
재기동/장애 시 복구 전략
예외 상황에서 데이터를 어떻게 복구하고 흐름을 재개할지 대비해야 합니다.
[세션 재연결 및 구독 복원]
대부분의 OPCUA 클라이언트 SDK는 세션 끊김을 감지하면 자동으로 재연결 및 sub 복구 기능을 제공하거나, 그렇지 않으면 재구독 로직을 구현해야 합니다. 재연결 후 초기에 한 번 현재 값들을 읽어서 PLC 상태를 동기화하는 것도 좋습니다.
[시퀀스 동기화]
재연결 시 MES는 현재 PLC의 Seq 값을 읽고, 자신이 마지막으로 처리한 Seq와 비교해야 합니다. 통신 장애로 인해 MES.Seq=50이고 PLC.Seq=55이면, 51~54에 대한 누락 메시지 처리 방안에 대해 정리해야 합니다.
- 단순 로그: 누락된 번호를 기록하고, 운영자가 별도로 확인합니다.
- 데이터베이스/이력 복구: PLC가 중단 후 발생한 메시지를 메모리나 파일에 보관해두었다며, MES가 재연결 후 전송을 받습니다. OPCUA-Historical Access / Events / History Read 기능이 관련있습니다.
[미처리 메시지 처리]
장애 직전에 송신되었으나 미처 Ack 받지 못한 메시지가 있을 수 있습니다. MES → PLC로 보낸 경우 PLC가 해당 명령을 수행했는지 불확실하고, PLC → MES인 경우 MES가 처리 못 했을 수 있습니다. 핸드셰이크를 도입해쑈다면, 재연결 시 Ack 불일치로 파악하여 재전송이 가능하지만, 단순 구조에서는 이 부분을 고려해야 합니다. 일반적으로 MES에서는 중요 트랜잭션은 응답을 받을 때까지 재시도하거나, PLC쪽에서는 중복 수신에 대비하여 동일한 Seq의 메시지가 다시 와도 한 번만 처리하도록 만들어 두는 것이 안전합니다.

Sequence
- 메시지에 붙은 고유한 번호
- 이 메시지가 몇 번째인가?를 식별하기 위한 값
- 메시지 중복 판단 / 순서 보장
- Seq만으로는 "처리되었는지" 알 수 없음
ACK(Acknowledgement)
- 이 Seq 메시지를 정상 처리했다 라는 응답
- 송신자가 안심하고 다음 단계로 넘어가게 하는 신호
- ACK는 수진자가 전송
- ACK 없으면 처리 여부 불확실
MES → PLC
SEQ: 101, 102, 103 ...
PLC → MES
ACK: seq=101
요약하면, 재기동/장애 시에는 세션 복구 → 시퀀스 동기화 확인 → 누락 데이터 검토의 단계를 거칩니다. OPCUA의 내재된 신뢰성 기능을 활용하고, 추가로 응용단에서 시퀀스 비교를 통한 누락 검출 및 로그를 시행하면 한층 견고한 통신을 구현활 수 있습니다.
MES-PLC 양방향 통신의 중요성
MES → PLC 명령이나 설정값을 보내고, PLC → MES 로 생산 실적이나 이벤트를 보내는 것 모두 원활해야 제조 실행 시스템이 제대로 가능합니다. 시나리오를 예로 정리해보았습니다.
MES → PLC
- 생산 지시 다운로드, 레시피 파라미터 전송, 설비 제어 명령(가동/정지 등) 등을 MES에서 PLC로 내보낼 수 있어야 합니다.
- OPCUA에서는 이를 위해 MES에서 PLC의 변수를 Write하거나 OPCUA 메서드를 호출하는 방식이 일반적입니다.
- 메서드는 하나의 호출로 여러 파라미터(구조체 형태)를 전달하고 실행 겨로가를 돌려받을 수 있습니다.
PLC → MES
- 설비에서 발생하는 이벤트, 알람 등은 OPCUA 서버가 값 변경이나 Event 발생을 통해 MES로 전달해야 합니다.
- Seq 증가와 노드 업데이트 매커니즘이 바로 이 방향의 통신을 담당합니다.
PLC ↔ MES
- PLC에서 설비 알람을 MES로 전송합니다.
- MES에서 담당자가 알람을 확인/해제하면, PLC에 전달하여 PLC도 알람 acknowledge를 완료하는 형태가 됩니다.
단순 구현과 향후 확장성 고려
현재 요구를 단순하고 확실하게 충족하면서도 미래의 확장에 대비해야 합니다.
[과도한 오버엔지니어링 지양]
초기 단계부터 복잡한 시나리오를 구현하려 하면 개발과 유지보수가 어려워질 수 있습니다. 간략한 구조에서 Seq/Ack 태그만으로 메모리 버퍼에 데이터를 안전하게 주고받게 구성할 수 있습니다. https://cache.industry.siemens.com/dl/files/835/109814835/att_1140017/v2/109814835_SiemensInformationModelKit_DOC_v3_0_en.pdf#:~:text=The%20client%20checks%20for%20available,it%20is%20ready%20to%20receive

[OPCUA 표준 기능 활용]
가능한 한 OPCUA 표준 케커니즘을 활용하는 것이 좋습니다.
- 연결 유지(Keep-Alive)
- 자동 재연결
- 데드밴드(Deadband)를 통한 잡음 필터링
- 히스토리 데이터 저장
- ...
[확장 시나리오 대비]
향후 더 많은 장비가 추가되거나, 메시지 종류가 다양해질 것으로 대비하여 모델을 일반화하면 좋습니다. OPCUA의 네임스페이스와 노드 구조를 체계적으로 설계해 두면, MES 쪽에서도 Browse 경로나 Node ID 패턴을 통해 동적으로 장비를 추가해나가기 수월합니다.
[테스트 및 모니터링 도구]
자동화된 통합 테스트를 만들어 다양한 시나리오에서 메시지 흐름을 검증해야 합니다.
다음 시간
소캣, opc 어떤 통신이던 queue에 쌓아놓고 처리하는 설계가 필요할 것 같다
[AI Prompt]
너는 OPCUA, MES 전문가이다.
전문가 의견으로 판단해줘.
나는 MES를 다루는 엔지니어이다.
OPCUA에 대한 아주 기본적인 사항은 마무리한 것으로 보인다.
#다음작업으로 실제 메시지 흐름을 설계해보고 싶다.
나의 생각에 대해 부족한 부분이 있으면 의견부탁한다.
#구축완료한환경 :
- 하나의 윈도우 PC에 OPC-UA 서버 구동 완료
- 하나의 윈도우 PC에 OPC-UA 클라이언트 구동 완료
- 서버와 클라이언트 연동 완료
- 서버의 uanodesetimport.xml에 Node 추가(bjects → Factory → Line → PLC → Message)
- PLC 역할의 메시지 전달 로직 수행, 2개
- uaexpert에서 Message Value 값 수정 가능 확인
- 노드 구조
Objects
└─ Factory
└─ LINE1
└─ EQP1
├─ Status (UInt16) // 설비 상태 코드
├─ Temperature (Double) // 온도 값
├─ LastUpdate (DateTime) // 마지막 갱신 시각(UTC)
├─ Seq (UInt32) // 증가 시퀀스
└─ RawMessage (String) // 원문 메시지(선택)
- 테스트 PLC 코드로 테그값 변경 완료
- StressTest 진행
Write 부하 테스트 수행, 10개 서비스 구동 중
Subscription 서비스 10개, 서비스당 4개 노드 구독
- Stress 테스트 종료
- Pub/Sub에 대한 개념 이해
#다음작업
- 메시지 언제 보낼 것인가 (이벤트 기준)
- 메시지 무엇을 담을 것인가 (데이터 모델)
- 메시지 순서/유실을 어떻게 판단할 것인가 (Sequence)
- 재기동/장애 시 어떻게 복구할 것인가
#DO
- 코딩 외적으로 필요한 부분은 주석으로 설명
#DO NOT
- 의미 없는 코드 작성
- 오버 엔지니어링 금지
'IT 제조' 카테고리의 다른 글
| 협동로봇 입문 교육 후기 – 두산로보틱스 초급 과정 솔직 정리 (0) | 2026.02.09 |
|---|---|
| 제조 공정 분석 1 - LCD, MES (0) | 2026.02.03 |
| OPC-UA 실습 4 - Pub/Sub 아키텍처 (0) | 2026.01.21 |
| OPC-UA 실습 3 - 가상 환경, Message, StressTest, Pub/Sub (1) | 2026.01.21 |
| OPC-UA 실습 2 - PLC 테스트 코드 → OPCUA 서버 → 클라이언트(Uaexpert) 확인 (0) | 2026.01.19 |