Every node in an OPC UA server has a NodeId: a namespace index and an identifier, written as ns=2;s=LineA.Temperature. The identifier is one of four types, numeric (i=), string (s=), GUID (g=) or opaque bytes (b=). A client such as a SCADA system or a gateway connects to an endpoint of the server and uses NodeIds to read, write or subscribe.
An OPC UA integration that reads the right value today can read the wrong one after a server update, because the identity it stored was not the one that lasts. An OPC UA server holds an address space: a set of nodes that describe equipment, its values and how they relate. A reliable integration identifies each value by its NodeId and namespace, and keeps the value's status and timestamps with it. This guide explains each of those identities, and how to accept one point before you add a hundred.
This guide is part of the OPC UA and MQTT series. It covers the usual session-based client and server exchange, not OPC UA PubSub.
OPC UA client vs server
The OPC Foundation's overview (Part 1) separates the two roles. The server owns the address space and offers services on it. The client connects and uses those services. One application can be both: a gateway can read a PLC's server as a client, and offer its own server to a SCADA system. Those are two interfaces, and each needs its own specification and test. A wrapper that puts a UA server in front of an older OPC DA server is a common case; the OPC DA migration guide covers it.
Check each service that the project needs separately: Browse, Read, Write, subscriptions (monitored items), method calls and historical access. A successful read of one scalar value proves only that read works for that node and that user.
Endpoint URLs and security
An endpoint URL such as opc.tcp://plc-line-a.example:4840/UA/Process identifies a connection, not a value. opc.tcp is the binary protocol over TCP. Port 4840 is the port that IANA registers for OPC UA over TCP, but many servers listen on another one, so copy the URL that the server reports. Each endpoint advertises, as its EndpointDescription:
- a security policy, the set of algorithms;
- a message security mode: None, Sign or SignAndEncrypt;
- the user token types it accepts: anonymous, user name and password, or certificate.
Two separate trust decisions follow. The client and the server must trust each other's application certificates. The server must then authorise the user. Trusting a certificate does not authorise a user, and a TCP connection that opens proves neither. Record the endpoint, the security policy and mode, the user identity and where each certificate is trusted.
NodeIds and namespaces
A NodeId identifies one node. Part 3 of the specification (OPC 10000-3, 8.2) gives it three parts: a namespace index (a UInt16), an identifier type and the identifier. Part 6 (OPC 10000-6, 5.1.12) defines the string form ns=<index>;<type>=<identifier>. There are four identifier types:
| Identifier type | Prefix | Example | Rules |
|---|---|---|---|
| Numeric | i= | ns=3;i=1001 | An unsigned integer. The nodes that the OPC Foundation defines are numeric: i=2258 is the server's current time |
| String | s= | ns=2;s=LineA.Temperature | Up to 4,096 characters, with no control characters |
| GUID | g= | ns=4;g=09087e75-8e5e-499b-954f-f2a9603db28a | 32 hexadecimal digits in the 8-4-4-4-12 form |
| Opaque | b= | ns=5;b=M/RbKBsRVkePCePcx24oRA== | Bytes written in Base64, up to 4,096 bytes, in a format that the server defines |
Namespace 0 is the OPC UA namespace, http://opcfoundation.org/UA/, and its NodeIds are written without ns=, as in i=2258. Index 1 is reserved for the server's own local namespace (OPC 10000-5, 6.3.1). The namespaces of a device's information model or a PLC's tags start at index 2 or higher. Part 6 also allows the URI in place of the index, as in nsu=urn:example:process-model;s=LineA.Temperature, but older clients and tools do not accept that form.
The namespace index is a position in the server's NamespaceArray, and each position holds a namespace URI. The URI is the stable name. The index can change when the server's configuration or firmware changes. Part 5 forbids a server to change or delete entries while a client has a session open and recommends that it only append new ones, but it allows that a change can be unavoidable, so a client should check the indexes when it starts a session:
Record the namespace URI with every NodeId in the point list. After any change to the server, check the NamespaceArray before you trust the old indexes.
A display name and a browse path are not NodeIds either. Use them to find a node, then record its NodeId.
The value, its status and its timestamps
A read returns a DataValue, which Part 4 defines. Keep all of it:
| Field | What it tells you |
|---|---|
| Value | The value, of the node's data type: scalar, array or structure |
| StatusCode | Good, Uncertain or Bad, with a reason |
| SourceTimestamp | When the value was measured or changed at its source, if the server knows |
| ServerTimestamp | When the server last knew the value to be current |
Rules for using them:
- Check the status first. A Bad value is not a measurement. Agree a rule for Uncertain.
- Keep the two timestamps apart. A steady value can keep an old source timestamp while the server confirms it again and again. "No change for an hour" does not mean "no communication for an hour".
- Check the data type. Record the declared type and whether it is an array. A UInt64 counter is valid in OPC UA but can lose precision in software that stores numbers as 64-bit floats.
- Know which timestamp your collector keeps. Some collectors record the server or source timestamp; others record their own read time. The timestamp guide explains the difference.
Accept one point, then expand
For the first point, write down the endpoint, security settings, user, namespace URI, NodeId, data type, unit, any scaling and the read interval. Then:
- Compare the value with an independent reference while it changes.
- Record the status code and the timestamps at the server, at the collector and at the final destination.
- Stop the source, or the connection, with approval. The data must show a gap or a Bad or Uncertain status, not an old value with a new timestamp.
- Restart the collector, and check that it reads the same node again.
- Read a node that does not exist, and one that the user may not read. Each must fail clearly, not return another node's value.
Test writes separately, with the equipment owner's approval and an independent check of the physical result.
OPC UA with Edge
Edge on the ZGW-20 Gateway is an OPC UA client. It connects to an endpoint with the security policy and mode that the server offers (None, Sign or SignAndEncrypt), as an anonymous user, with a user name or with a certificate. It reads each variable node on a schedule, from once a second to once a day, and applies any multiplier and offset. Edge addresses each node by its full NodeId string, up to 512 characters, including the namespace index. Copy the NodeId from the server's address space, because a browse name alone is not an address, and check the index after any server change. Each value is timestamped when Edge reads it.
Common questions
What is a NodeId in OPC UA?
The identifier of a node in a server's address space. It has a namespace index and an identifier, which can be a number, a string, a GUID or bytes. For example, ns=2;s=LineA.Temperature is the string identifier LineA.Temperature in namespace 2.
What is an OPC UA namespace?
A group of node identifiers, named by a URI. The server lists its namespaces in its NamespaceArray, and a NodeId refers to a namespace by its position in that array. The URI is stable; the position (the index) can change when the server's configuration changes.
What is the difference between an OPC UA client and server?
The server owns the address space and offers services on it. The client connects and uses those services to browse, read, write or subscribe. One application can be both, for example a gateway that reads a PLC's server as a client and offers its own server to SCADA.
What does an OPC UA status code mean?
Every value that a server returns has a status code: Good, Uncertain or Bad, with a reason. A Bad value must not be used as a measurement. Uncertain values need a rule agreed for the project.
What does ns=2;s= mean in an OPC UA NodeId?
ns=2 is the namespace index, position 2 in the server's NamespaceArray. s= says that the identifier that follows is a string. The other identifier types are i= for a number, g= for a GUID and b= for opaque bytes in Base64. A NodeId in namespace 0, such as i=2258, is written without ns=.
Can the namespace index of a NodeId change?
Yes. OPC 10000-5 forbids a server to change or delete namespace table entries while a client has a session open, and recommends that servers only append new entries. It also allows that a change can be unavoidable, so a client should check the indexes when it starts a session. The namespace URI does not change.