Skip to content
Start free evaluation

Information model

An OPC UA server exposes its data as an address space: a graph of nodes connected by references. Clients browse the graph, read and write node attributes and call methods. Part 3 defines the address space model; Part 5 defines the standard nodes and types.

Every node belongs to exactly one NodeClass, which decides the attributes the node has (Part 3, section 5, Standard NodeClasses).

NodeClass Value Used for
Object 1 Devices, folders and other nodes that group nodes
Variable 2 Nodes that hold a value: data variables and properties
Method 4 Callable functions
ObjectType 8 Type definitions of Objects
VariableType 16 Type definitions of Variables
ReferenceType 32 Kinds of references
DataType 64 Data types of values
View 128 Subsets of the address space

The value appears as-is in the NodeClass field of a Browse result. In the output of the PDComm browse example, Variable is 2 and Method is 4.

You read a node’s information through its attributes. Each attribute has a numeric AttributeId. These are the ones you’ll use most:

AttributeId Name Description
1 NodeId The node’s identifier
2 NodeClass A value from the table above
3 BrowseName The name used in browse paths (QualifiedName), prefixed with its namespace index, as in 2:Simulator.Double
4 DisplayName Human-readable name (LocalizedText)
12 EventNotifier Bits that tell whether you can subscribe to the node’s events
13 Value A variable’s value
14 DataType NodeId of the value’s data type
15 ValueRank -1 for a scalar; 1 or more for the number of array dimensions
17 AccessLevel Bits for read, write and history access
20 Historizing Whether the server stores the value’s history

The Read service takes pairs of a node and an AttributeId. APIs that don’t ask for an AttributeId usually read Value (13); the read action of the PDComm simulator also defaults to 13.

A NodeId combines a namespace index and an identifier (Part 3, the NodeId data type). There are four identifier types:

Type Text form Example
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==

Namespace index 0 is omitted: i=85 is the same as ns=0;i=85.

The namespace index is a position in the URI list held by the server’s NamespaceArray variable (i=2255). Index 0 is always http://opcfoundation.org/UA/, index 1 is the server’s own URI, and application namespaces follow. Reading i=2255 from the PDComm simulator returns:

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

The PDComm SDK in-memory server and the simulator both put application nodes at index 2 (urn:pdcomm:opcua:nodes). Indexes can differ between servers, so when you connect to another server, read its NamespaceArray and look the index up by URI.

A reference is a directed link. Following it from the source node to the target is the forward direction; the opposite is the inverse direction. ReferenceType nodes define the kinds of references (Part 3, section 7, Standard ReferenceTypes).

ReferenceType NodeId Meaning
HierarchicalReferences i=33 Supertype of all hierarchical references; the usual Browse filter
Organizes i=35 A folder organizes a node
HasComponent i=47 An object has a component
HasProperty i=46 A node has a property variable
HasTypeDefinition i=40 Links an instance to its type definition

The Objects folder (i=85) is where browsing starts. Below it are the Server object (i=2253), which holds the server’s status, and the application’s objects. The PDComm simulator’s address space looks like this:

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

The SDK example server (opcua_server) puts three variables under Objects: Value (ns=2;i=1001), Limit (ns=2;i=1002) and Protected (ns=2;i=1003).

Objects and Variables have type definitions. A folder is an instance of FolderType (i=61); a plain data variable is an instance of BaseDataVariableType (i=63). Types form an inheritance hierarchy, and event and alarm types are defined the same way (Part 5, Part 9).

The DataType attribute gives the type of a variable’s value. Built-in types are encoded in UA Binary by their Variant type number (Part 6, section 5.2, OPC UA Binary):

Type number Data type 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

An ExtensionObject carries a structure: the structure’s encoding NodeId comes first, followed by the body. Service request and response messages follow the same rule and start with an encoding NodeId.

The AccessLevel bits tell whether you can read and write a variable’s Value:

Bit Name Meaning
0x01 CurrentRead The current value can be read
0x02 CurrentWrite The current value can be written
0x04 HistoryRead The history can be read
0x08 HistoryWrite The history can be changed

Simulator.Double in the simulator has AccessLevel 15 (0x0F). UserAccessLevel can differ by session user: PDComm servers return BadUserAccessDenied when an anonymous session touches a variable that isn’t public.

Read responses and subscription notifications deliver values as DataValues, which have these fields:

Field Description
Value The value (a Variant)
StatusCode Quality of the value; Good when absent
SourceTimestamp When the value changed at its source
ServerTimestamp When the server received the value

Each field is optional. In UA Binary, mask bits in the first byte say which fields follow.

A StatusCode is a 32-bit value whose two top bits give the severity:

Top bits Severity Examples
00 Good 0x00000000 Good, 0x00A50000 GoodNoData
01 Uncertain 0x40000000 Uncertain
10 Bad 0x803B0000 BadNotWritable, 0x801F0000 BadUserAccessDenied, 0x80340000 BadNodeIdUnknown

If the top bit (0x80000000) is set, the operation failed; the PDComm examples test that bit. The low 16 bits carry extra information. For example, a history value with status 0x00000408 is Good and tells you that more values exist at the same timestamp.

OPC UA responses carry StatusCodes at two levels:

  • Service result (serviceResult): the result of the whole request. If the server rejects the request itself, it answers with a ServiceFault.
  • Operation result: one result per item in the request.

For example, a write to a read-only variable has a Good service result and a BadNotWritable operation result. The PDComm C examples print both, as in service=0x00000000 status=0x803b0000. Look codes up in the StatusCode catalog.

Services shows the sequence a client follows to reach these nodes.