This standard defines three data encodings: OPC UA Binary, OPC UA XML and OPC UA JSON. It describes how to construct Messagesusing each of these encodings.

All OPC UA DataEncodingsare based on rules that are defined for a standard set of built-in types. These built-in types are then used to construct structures, arrays and Messages. The built-in types are described in Table 1.

Table 1– Built-in Data Types

ID

Name

Description

1

Boolean

A two-state logical value (true or false).

2

SByte

An integer value between −128 and 127 inclusive.

3

Byte

An integer value between 0 and 255 inclusive.

4

Int16

An integer value between −32 768 and 32 767 inclusive.

5

UInt16

An integer value between 0 and 65 535 inclusive.

6

Int32

An integer value between −2 147 483 648 and 2 147 483 647 inclusive.

7

UInt32

An integer value between 0 and 4 294 967 295 inclusive.

8

Int64

An integer value between −9 223 372 036 854 775 808 and 9 223 372 036 854 775 807 inclusive.

9

UInt64

An integer value between 0 and 18 446 744 073 709 551 615 inclusive.

10

Float

An IEEE single precision (32 bit) floating point value.

11

Double

An IEEE double precision (64 bit) floating point value.

12

String

A sequence of Unicode characters.

13

DateTime

An instance in time.

14

Guid

A 16-byte value that can be used as a globally unique identifier.

15

ByteString

A sequence of octets.

16

XmlElement

An XML element.

17

NodeId

An identifier for a node in the address space of an OPC UA Server.

18

ExpandedNodeId

A NodeId that allows the namespace URI to be specified instead of an index.

19

StatusCode

A numeric identifier for an error or condition that is associated with a value or an operation.

20

QualifiedName

A name qualified by a namespace.

21

LocalizedText

Human readable text with an optional locale identifier.

22

ExtensionObject

A structure that contains an application specific data type that may not be recognized by the receiver.

23

DataValue

A data value with an associated status code and timestamps.

24

Variant

A union of all of the types specified above.

25

DiagnosticInfo

A structure that contains detailed error and diagnostic information associated with a StatusCode.

Most of these data types are the same as the abstract types defined in OPC 10000-3and OPC 10000-4. However, the ExtensionObjectand Varianttypes are defined in this standard. In addition, this standard defines a representation for the Guidtype defined in OPC 10000-3.

A Guidis a 16-byte globally unique identifier with the layout shown in Table 2.

Table 2– Guid structure

Component

Data Type

Data1

UInt32

Data2

UInt16

Data3

UInt16

Data4

Byte [8]

Guidvalues may be represented as a string in this form:

<Data1>-<Data2>-<Data3>-<Data4[0:1]>-<Data4[2:7]>

Where Data1 is 8 characters wide, Data2 and Data3 are 4 characters wide and each Bytein Data4 is 2 characters wide. Each value is formatted as a hexadecimal number with padded zeros. A typical Guidvalue would look like this when formatted as a string:

C496578A-0DFE-4B8F-870A-745238C6AEAE

A ByteStringis structurally the same as a one-dimensional array of Byte.It is represented as a distinct built-in data type because it allows encoders to optimize the transmission of the value. However, some DevelopmentPlatforms will not be able to preserve the distinction between a ByteStringand a one-dimensional array of Byte.

If a decoderfor DevelopmentPlatform cannot preserve the distinction it shall convert all one-dimensional arrays of Byteto ByteStrings.

Each element in a one-dimensional array of ByteStringcan have a different length which means is structurally different from a two-dimensional array of Byte where the length of each dimension is the same. This means decoders shall preserve the distinction between two or more dimension arrays of Byteand one or more dimension arrays of ByteString.

If a DevelopmentPlatform does not supportunsigned integers, then it will have to represent ByteStringsas arrays of SByte. In this case, the requirements for Bytewould then apply to SByte.

An ExtensionObject is a container for any Structured DataTypeswhich cannot be encoded as one of the other built-in data types. The ExtensionObject contains a complex value serialized as a sequence of bytes or as an XML element. It also contains an identifier which indicates what data it contains and how it is encoded.

Structured DataTypesare represented in a Serveraddress space as sub-types of the Structure DataType. The DataEncodingsavailable for any given Structured DataTypesare represented as a DataTypeEncoding Objectin the Server AddressSpace. The NodeIdfor the DataTypeEncoding Objectis the identifier stored in the ExtensionObject. OPC 10000-3describes how DataTypeEncoding Nodesare related to other Nodesof the AddressSpace.

Serverimplementers should use namespace qualified numeric NodeIdsfor any DataTypeEncoding Objectsthey define. This will minimize the overhead introduced by packing Structured DataType values into an ExtensionObject.

ExtensionObjects and Variantsallow unlimited nesting which could result in stack overflow errors even if the message size is less than the maximum allowed. Decoders shall support at least 100 nesting levels. Decoders shall report an error if the number of nesting levels exceeds what it supports.

A Variantis a union of all built-in data types including an ExtensionObject. Variantscan also contain arrays of any of these built-in types. Variantsare used to store any value or parameter with a data type of BaseDataType or one of its subtypes.

Variantscan be empty. An empty Variantis described as having a null value and should be treated like a null column in a SQL database. A null value in a Variantmay not be the same as a null value for data types that support nulls such as Strings. Some DevelopmentPlatforms may not be able to preserve the distinction between a null for a DataTypeand a null for a Variant, therefore, applications shall not rely on this distinction. This requirement also means that if an Attributesupports the writing of a null value it shall also support writing of an empty Variant and vice versa.

Variantscan contain arrays of Variantsbut they cannot directly contain another Variant.

DiagnosticInfo types only have meaning when returned in a response message with an associated StatusCodeand table of strings. As a result,Variantscannot contain instances ofDiagnosticInfo.

Valuesof Attributesare always returned in instances of DataValues. Therefore, the DataTypeof an Attributecannot be a DataValue. Variantscan contain DataValuewhen used in other contexts such as Method Argumentsor PubSub Messages. The Variantin a DataValuecannot, directly or indirectly, contain another DataValue.

Variableswith a DataTypeof BaseDataTypeare mapped to a Variant, however, the ValueRankand ArrayDimensions Attributesplace restrictions on what is allowed in the Variant. For example, if the ValueRankis Scalarthen the Variantmay only contain scalar values.

ExtensionObjects and Variantsallow unlimited nesting which could result in stack overflow errors even if the message size is less than the maximum allowed. Decoders shall support at least 100 nesting levels. Decoders shall report an error if the number of nesting levels exceeds what it supports.

A Decimal is a high-precision signed decimal number. It consists of an arbitrary precision integer unscaled value and an integer scale. The scale is the power of ten that is applied to the unscaled value.

A Decimalhas the fields described in Table 3.

Table 3– Layout of Decimal

Field

Type

Description

TypeId

NodeId

The identifier for the Decimal DataType.

Encoding

Byte

This value is always 1.

Length

Int32

The length of the Decimal.If the length is less than or equal to 0 then the Decimalvalue is 0.

Scale

Int16

A signed integer representing the power of ten used to scale the value.

i.e. the decimal number of the value * 10-scale

The integer is encoded starting with the least significant bit.

Value

Byte [*]

A 2-complement signed integer representing the unscaled value.

The number of bits is inferred from the length of the length field.

If the number of bits is 0 then the value is 0.

The integer is encoded with the least significant byte first.

When a Decimalis encoded in a Variantthe built-in type is set to ExtensionObject. Decoders that do not understand the Decimaltype shall treat it like any other unknown Structureand pass it on to the application. Decoders that do understand the Decimalcan parse the value and use any construct that is suitable for the DevelopmentPlatform.

If a Decimalis embedded in another Structurethen the DataTypeDefinitionfor the field shall specify the NodeIdof the Decimal Nodeas the DataType. If a Serverpublishes an OPC Binary type description for the Structurethen the type description shall set the DataTypefor the field to ExtensionObject.