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.
Nodes and NodeClasses
Section titled “Nodes and NodeClasses”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.
Attributes
Section titled “Attributes”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.
NodeIds and namespaces
Section titled “NodeIds and namespaces”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.
References
Section titled “References”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 msThe 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).
Type system
Section titled “Type system”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.
Variables and access levels
Section titled “Variables and access levels”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.
DataValue
Section titled “DataValue”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.
StatusCode
Section titled “StatusCode”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.
Next steps
Section titled “Next steps”Services shows the sequence a client follows to reach these nodes.