콘텐츠로 이동
무료 평가 시작

정보 모델

OPC UA 서버는 데이터를 주소 공간(address space)으로 공개합니다. 주소 공간은 노드(node)와 노드 사이의 참조(reference)로 이루어진 그래프입니다. 클라이언트는 이 그래프를 탐색(Browse)하고, 노드의 속성(attribute)을 읽고 쓰고, 메서드(method)를 호출합니다. 주소 공간 모델은 Part 3, 표준 노드와 타입은 Part 5에서 정의합니다.

모든 노드는 NodeClass 하나에 속합니다. NodeClass는 노드가 가지는 속성의 종류를 정합니다(Part 3, 5절 Standard NodeClasses).

NodeClass 값 용도
Object 1 장비, 폴더처럼 다른 노드를 묶는 객체
Variable 2 값을 가진 노드. 데이터 변수와 속성(property)이 있습니다.
Method 4 호출할 수 있는 함수
ObjectType 8 Object의 타입 정의
VariableType 16 Variable의 타입 정의
ReferenceType 32 참조의 종류
DataType 64 값의 데이터 타입
View 128 주소 공간의 부분 집합

값은 Browse 결과의 NodeClass 필드에 그대로 나타납니다. 예를 들어 PDComm 예제의 Browse 출력에서 Variable은 2, Method는 4입니다.

노드의 정보는 속성으로 읽습니다. 속성마다 숫자 ID가 있습니다(AttributeId). 자주 쓰는 속성은 다음과 같습니다.

AttributeId 이름 설명
1 NodeId 노드 식별자
2 NodeClass 위 표의 값
3 BrowseName 탐색 경로에 쓰는 이름(QualifiedName). 2:Simulator.Double처럼 네임스페이스 인덱스가 붙습니다.
4 DisplayName 사람이 읽는 이름(LocalizedText)
12 EventNotifier 이벤트를 구독할 수 있는지 나타내는 비트
13 Value 변수의 값
14 DataType 값의 데이터 타입 NodeId
15 ValueRank -1이면 스칼라, 1 이상이면 배열 차원
17 AccessLevel 읽기·쓰기·이력 접근 가능 여부 비트
20 Historizing 서버가 값의 이력을 저장하는지 여부

Read 서비스는 노드와 AttributeId의 쌍을 받습니다. AttributeId를 지정하지 않는 API는 대부분 Value(13)를 읽습니다. PDComm 시뮬레이터의 read 동작도 기본값이 13입니다.

NodeId는 네임스페이스 인덱스(namespace index)와 식별자(identifier)로 이루어집니다(Part 3, NodeId 데이터 타입). 식별자 형식은 네 가지입니다.

형식 텍스트 표기 예
숫자(Numeric) i= i=85, ns=2;i=1001
문자열(String) s= ns=2;s=Simulator.Double
GUID g= ns=1;g=09087e75-8e5e-499b-954f-f2a9603db28a
바이트 문자열(ByteString) b= ns=1;b=M/RbKBsRVkePCePcx24oRA==

네임스페이스 인덱스 0은 생략합니다. i=85는 ns=0;i=85와 같습니다.

네임스페이스 인덱스는 서버의 NamespaceArray 변수(i=2255)에 있는 URI 목록의 위치입니다. 인덱스 0은 항상 http://opcfoundation.org/UA/입니다. 인덱스 1은 서버 자신의 URI입니다. 그 뒤는 응용 프로그램 네임스페이스입니다. PDComm 시뮬레이터에서 i=2255를 읽으면 다음 값이 나옵니다.

["http://opcfoundation.org/UA/","urn:pdcomm:opcua:server","urn:pdcomm:opcua:nodes"]

PDComm SDK의 메모리 서버와 시뮬레이터는 응용 노드를 인덱스 2(urn:pdcomm:opcua:nodes)에 둡니다. 인덱스는 서버마다 다를 수 있습니다. 다른 서버에 연결할 때는 NamespaceArray를 읽어 URI로 인덱스를 찾습니다.

참조는 방향이 있는 연결입니다. 원본 노드에서 대상 노드로 향하는 방향을 순방향(forward), 반대를 역방향(inverse)이라고 합니다. 참조의 종류는 ReferenceType 노드로 정의합니다(Part 3, 7절 Standard ReferenceTypes).

ReferenceType NodeId 의미
HierarchicalReferences i=33 계층 참조 전체의 상위 타입. Browse의 기본 필터로 씁니다.
Organizes i=35 폴더가 노드를 정리함
HasComponent i=47 객체가 구성 요소를 가짐
HasProperty i=46 노드가 속성 변수를 가짐
HasTypeDefinition i=40 인스턴스와 타입 정의를 연결

주소 공간의 출발점은 Objects 폴더(i=85)입니다. Objects 아래에는 서버 상태를 담는 Server 객체(i=2253)와 응용 프로그램 객체가 있습니다. PDComm 시뮬레이터의 주소 공간은 다음과 같습니다.

Objects (i=85)
├── Server (i=2253) Organizes
└── Simulator (ns=2;s=Simulator) Organizes
├── Simulator.Boolean Variable HasComponent
├── Simulator.Int32 Variable
├── Simulator.Double Variable Historizing
├── Simulator.String Variable
├── Simulator.Counter Variable read-only, historizing
├── Simulator.Protected Variable authenticated users only
├── Simulator.AlarmSource Variable drives Simulator.Alarm
├── Simulator.Add Method Double + Double
└── Simulator.Delay Method holds the server for N ms

SDK 예제 서버(opcua_server)는 Objects 아래에 Value(ns=2;i=1001), Limit(ns=2;i=1002), Protected(ns=2;i=1003) 변수를 둡니다.

Object와 Variable은 타입 정의를 가집니다. 폴더는 FolderType(i=61), 일반 데이터 변수는 BaseDataVariableType(i=63)의 인스턴스입니다. 타입은 상속 계층을 이룹니다. 이벤트 타입과 알람 타입도 같은 방식으로 정의합니다(Part 5, Part 9).

변수 값의 타입은 DataType 속성으로 나타냅니다. 기본 데이터 타입(built-in type)은 UA Binary에서 Variant의 타입 번호로 인코딩됩니다(Part 6, 5.2절 OPC UA Binary).

타입 번호 데이터 타입 DataType NodeId
1 Boolean i=1
6 Int32 i=6
7 UInt32 i=7
10 Float i=10
11 Double i=11
12 String i=12
13 DateTime i=13
15 ByteString i=15
17 NodeId i=17
21 LocalizedText i=21
22 ExtensionObject i=22

ExtensionObject는 구조체 값을 담습니다. 구조체의 인코딩 NodeId가 앞에 붙고 그 뒤에 본문이 옵니다. 서비스 요청과 응답 메시지도 같은 원리로 인코딩 NodeId로 시작합니다.

변수의 Value 속성을 읽고 쓸 수 있는지는 AccessLevel 비트로 나타냅니다.

비트 이름 의미
0x01 CurrentRead 현재 값을 읽을 수 있음
0x02 CurrentWrite 현재 값을 쓸 수 있음
0x04 HistoryRead 이력을 읽을 수 있음
0x08 HistoryWrite 이력을 바꿀 수 있음

시뮬레이터의 Simulator.Double은 AccessLevel이 15(0x0F)입니다. UserAccessLevel은 세션의 사용자에 따라 달라질 수 있습니다. PDComm 서버는 공개하지 않은 변수에 익명 세션이 접근하면 BadUserAccessDenied를 돌려줍니다.

Read 응답과 구독 알림은 값을 DataValue로 전달합니다. DataValue는 다음 필드로 이루어집니다.

필드 설명
Value 값(Variant)
StatusCode 값의 품질. 없으면 Good입니다.
SourceTimestamp 값이 원천에서 바뀐 시각
ServerTimestamp 서버가 값을 받은 시각

각 필드는 있을 수도 없을 수도 있습니다. UA Binary에서는 첫 바이트의 마스크 비트가 어떤 필드가 있는지 알려 줍니다.

StatusCode는 32비트 값입니다. 상위 2비트가 심각도(severity)입니다.

상위 비트 심각도 예
00 Good 0x00000000 Good, 0x00A50000 GoodNoData
01 Uncertain 0x40000000 Uncertain
10 Bad 0x803B0000 BadNotWritable, 0x801F0000 BadUserAccessDenied, 0x80340000 BadNodeIdUnknown

최상위 비트(0x80000000)가 켜져 있으면 실패입니다. PDComm 예제는 이 비트로 실패를 판단합니다. 하위 16비트에는 추가 정보 비트가 있습니다. 예를 들어 이력 값의 0x00000408은 Good이면서 같은 시각에 값이 더 있음을 나타냅니다.

OPC UA 응답에는 StatusCode가 두 단계로 있습니다.

  • 서비스 결과(serviceResult): 요청 전체의 결과입니다. 요청 자체가 거부되면 서버는 ServiceFault 응답을 보냅니다.
  • 작업 결과(operation result): 요청 안의 항목마다 붙는 결과입니다.

예를 들어 읽기 전용 변수에 쓰면 서비스 결과는 Good이고 항목 결과만 BadNotWritable입니다. PDComm C 예제는 두 값을 service=0x00000000 status=0x803b0000처럼 함께 출력합니다. StatusCode 목록은 StatusCode 오류 목록에서 찾습니다.

서비스에서 클라이언트가 노드에 접근하는 순서를 살펴봅니다.