C++ Based OPC UA Client/Server/PubSub SDK  1.8.3.628
OPC UA Data Types

The following page describes the concepts for OPC UA data types.

Overview and built-in DataTypes

OPC UA variables, methods and events are used to exchange application specific data as variable value, method arguments or event fields. Such application specific data can use different DataTypes. The ValueRank is defined in addition to indicate if the DataType is used as scalar value (-1), as array (1) or as multidimensional array (>1).

DataTypes are exposed as nodes in the server address space. These nodes build a type hierarchy with the BaseDataType as root of the DataType hierarchy.

The NodeId of the DataType nodes is used to indicate the DataType of a variable in the DataType attribute of the variable. Also the DataType of an event field or a method argument is indicated with the NodeId of the DataType.

OPC UA Data Type hierarchy

OPC UA defines 24 so called built-in DataTypes. These built-in DataTypes are either simple DataTypes like Boolean, floating point types, integer types, string or they are structures like NodeId that are used in OPC UA services.

Built-in DataTypeDescription
Boolean A value that is either TRUE or FALSE
SByte One byte signed integer between −128 and 127 inclusive.
Byte One byte unsigned integer in the range of 0 to 255 inclusive.
Int16 Two byte (16-bit) signed integer between −32 768 and 32 767 inclusive.
UInt16 Two byte (16-bit) unsigned integer in the range of 0 to 65 535 inclusive.
Int32 Four byte (32-bit) signed integer between −2 147 483 648 and 2 147 483 647 inclusive.
UInt32 Four byte (32-bit) unsigned integer in the range of 0 to 4 294 967 295 inclusive.
Int64 Eight byte (64-bit) signed integer between −9 223 372 036 854 775 808 and 9 223 372 036 854 775 807 inclusive.
UInt64 Eight byte (64-bit) unsigned integer in the range of 0 to 18 446 744 073 709 551 615 inclusive.
Float Four byte floating point value that adheres to the ISO/IEC/IEEE 60559:2011 single precision data type definition.
Double Eight byte floating point value that adheres to the ISO/IEC/IEEE 60559:2011 double precision data type definition.
String Unicode character string that should exclude control characters that are not white-spaces.
DateTime Date and time represented as 64-bit signed integer which represents the number of 100 nanosecond intervals since January 1, 1601 (UTC).
Guid 128-bit Globally Unique Identifier.
ByteString Sequence of Byte values with length information.
XmlElement DataType used to transport XML elements.
ExtensionObject Used to transport structure DataTypes. The ExtensionObject contains the encoding NodeId of the structure DataType and the structure as blob encoded in the requested format.
NodeId Globally unique identifier for a Node in the OPC UA server address space. See OPC UA NodeIds for more details. The DataType is mainly used in OPC UA services.
ExpandedNodeId Extended NodeId used to refer to Nodes in other OPC UA Servers. The DataType is mainly used in OPC UA services.
StatusCode Four byte numerical value that is used to report the overall result of an operation performed by an OPC UA server. StatusCodes are defined by the OPC UA specification. Application specific StatusCodes are not allowed. The DataType is mainly used in OPC UA services.
QualifiedName Qualified name that consists of a name and a namespace. The name part of the QualifiedName is restricted to 512 characters. The DataType is mainly used in OPC UA services.
LocalizedText Localized text that consists of the text in a locale-specific translation and the identifier for the locale. The DataType is mainly used in OPC UA services.
DataValue Structure used to transport values of variables together with a StatusCode and timestamps. The DataType is only used in OPC UA services.
DiagnosticInfo Structure used to provide additional optional diagnostic information for an operation performed by an OPC UA server. The DataType is only used in OPC UA services.

Transport of values for different DataTypes

The built-in DataTypes are transported on the wire in a Variant union. This includes arrays or multidimensional arrays of the built-in DataTypes.

The BuiltInType is an enumeration with the values 0 (NULL) to 25. The BuiltInType UInt32 has the value 7 in this enumeration.

The DataType NodeIds for the BuiltInType has the same numeric identifier in namespace 0 (OPC UA). Therefore the BuiltInType enumeration value equals the numeric identifier of the DataType NodeIds for the built-in DataTypes. If the numeric identifier of a NodeId is not in namespace 0 and is bigger than 25, it is not a built-in DataType.

The BuiltInType enumeration value for UInt32 is 7, the NodeId for the DataType UInt32 is i=0 (namespace 0 with numeric identifier 7).

Any other OPC UA or application defined DataType can be transported using one of these built-in DataTypes. This is described in the next section.

Application specific DataTypes

Any subtype of simple types like Duration (subtype of Double) is represented as the corresponding built-in type on the wire.

There are three DataTypes (Enumerations, OptionSets and Structures), where application specific sub-types define the semantic of the DataType and its values. The data is transported as one of the built-in DataTypes but the client need to read additional information from the server type system to get the semantic.

Semantic of application specific DataTypes

Enumeration DataTypes are transported as 32 bit signed integer built-in DataType. The name of the different enumeration values are exposed as EnumStrings property of the Enumeration DataType.

OptionSet DataTypes (bit masks) are transported as one of the unsigned integer built-in DataTypes. The name of the bits in the bit mask is exposed as OptionSetValues property of the OptionSet DataType.

Structure DataTypes are transported with the special built-in DataType ExtensionObject. An ExtensionObject contains the encoding NodeId of the structure DataType and the structure as blob encoded in the requested format e.g. OPC UA Binary.

The encoding NodeId is provided by an object of type DataTypeEncodingType. This object is referenced by the structure DataType with a non-hierarchical HasEncoding reference. The browse name of this object for OPC UA Binary encoding is 'Default Binary'. A server may support other encodings like JSON encoding. In this case, the server references more than one encoding object from the structure DataType node.

The fields of the structure DataType are described by the value of the DataTypeDefinition attribute of the structure DataType node (e.g. MyStruct).

DataTypeDefinition Attribute

The DataTypeDefinition attribute was introduced in OPC UA 1.04 and provides a simplified option to get access to the meta-data of a structure DataType. It is also provided for Enumeration and OptionSet DataTypes.

The DataTypeDefinition Attribute contains either a structureDefinition or an EnumDefinition. The following table contains the description of the SsructureDefinition DataType.

Fields of the structureDefinition DataType

Structure field nameStructure field DataTypeDescription
DefaultEncodingId NodeId The NodeId of the default DataTypeEncoding for the DataType. The default depends on the message encoding, Default Binary for UA Binary encoding, Default JSON for JSON encoding and Default XML for XML encoding.
BaseDataType NodeId The NodeId of the direct super-type of the DataType. This might be the abstract structure or the Union DataType.
StructureType Enum StructureType An enumeration that specifies the type of structure defined by the DataType. Options are structure (A structure without optional fields), structureWithOptionalFields (A structure with optional fields) and Union (A Union DataType). Only one of the fields defined for the data type is encoded into a value if the data type is a Union.
Fields StructureField [] The list of fields that make up the data type. This definition assumes the structure has a sequential layout. For structures derived from another structure DataType this list starts with the fields of the BaseDataType followed by the fields of this StructureDefinition.

Fields of the StructureField DataType

Structure field nameStructure field DataTypeDescription
Name String A name for the field that is unique within the StructureDefinition.
Description LocalizedText A localized description of the field.
DataType NodeId The NodeId of the DataType for the field.
ValueRank Int32 The value rank for the field. It shall be Scalar (-1) or a fixed rank Array (>=1).
ArrayDimensions UInt32[] This field specifies the maximum supported length of each dimension. If the maximum is unknown the value shall be 0. The number of elements shall be equal to the value of the valueRank field. This field shall be null if valueRank ≤ 0. The maximum number of elements of an array transferred on the wire is 2147483647 (max Int32).
MaxStringLength UInt32 If the DataType field is a String or ByteString then this field specifies the maximum supported length. If the maximum is unknown the value shall be 0. If the DataType field is not a String or ByteString the value shall be 0. If the valueRank is greater than 0 this field applies to each element of the array.

To encode or decode data in or from an ExtensionObject, the application needs to have the list of fields in the structure DataType. If a structure field has a built-in DataType, the corresponding encoding or decoding can be used. If a structure field is again a structure, the fields of this structure must be decoded with the rules for the contained built-in DataType.

DataType Dictionary (deprecated)

The older and deprecated way to expose the description of structure DataTypes in an OPC UA server address space is a DataTypeDictionary.

DataType Dictionary

The DataTypeDictionary is a XML file that is provided by a variable of type DataTypeDictionaryType. The value of the variable contains the XML document. In the example above, this is the variable with the name 'MyDictionary'.

The following example shows a dictionary XML file with two structure DataTypes.

<opc:TypeDictionary xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tns="http://yourorganisation.org/StructExample/" DefaultByteOrder="LittleEndian" xmlns:opc="http://opcfoundation.org/BinarySchema/" xmlns:ua="http://opcfoundation.org/UA/" TargetNamespace="http://yourorganisation.org/StructExample/">
<opc:Import Namespace="http://opcfoundation.org/UA/"/>
<opc:StructuredType BaseType="ua:ExtensionObject" Name="MyStruct">
<opc:Field TypeName="opc:Double" Name="Field_A"/>
<opc:Field TypeName="opc:Int32" Name="Field_B"/>
</opc:StructuredType>
<opc:StructuredType BaseType="ua:ExtensionObject" Name="MyStruct2">
<opc:Field TypeName="opc:Double" Name="Field1"/>
<opc:Field TypeName="opc:Double" Name="Field2"/>
</opc:StructuredType>
</opc:TypeDictionary>

The list of DataTypeDictionaries for OPC UA Binary encoding can be found below Types > DataTypes > OPC Binary.

The relation of a structure DataType to a DataTypeDictionary is created by a chain of OPC UA References from the

  • Structure DataType Node (MyStruct) following the non-hierarchical HasEncoding reference forward to the
  • Encoding Object with the name 'Default Binary' following the non-hierarchical HasDescription reference forward to the
  • DataTypeDescriptionType variable (MyStruct) following the hierarchical HasComponent reference in inverse direction to the
  • Dictionary variable (MyDictionary)

The value of the DataTypeDescriptionType variable matches the name of the structure DataType description in the XML document that is the value of the Dictionary variable. This is normally also the name of the DataType Node and the name of the DataTypeDescriptionType variable.

Client side handling of structure DataTypes

An OPC UA client that is able to handle structure DataTypes must build a type cache to do the time consuming discovery of the DataType description only once during a working Session with an OPC UA server. After the creation of a new Session, the type cache must be updated.

For each structure DataType, the cache consists of two NodeIds and the DataType description

  • NodeId of the DataType Node (used for lookup if the DataType is known)
  • NodeId of the encoding Object Node (used for lookup if the encoding NodeId is known from a received ExtensionObject)
  • List of structure fields for decoding a received structure value from an ExtensionObject

One strategy is to read all descriptions after Session creation with the following steps

  • Recursively browse all DataType nodes starting from the structure DataType Node
  • For each structure DataType returned from Browse, read the DataTypeDefinition Attribute

If the DataTypeDefinition is present

  • Store the StructureDefinition with the field information necessary to decode the structure DataType
  • Add the DataType NodeId to the look-up table to reference the StructureDefinition
  • Add the encoding NodeId to the look-up table to reference the StructureDefinition. The encoding NodeId is part of the StructureDefinition (DefaultEncodingId)

If the DataTypeDefinition is not present

  • Browse and Read the DataTypeDictionaries below ‘OPC Binary’
  • Browse to the DataTypeDictionary variable through encoding Object and DataTypeDescription variable as described above
  • Store the StructureDefinition with the field information necessary to decode the structure DataType from the information in the related DataTypeDictionary XML document
  • Add the DataType NodeId to the look-up table to reference the StructureDefinition
  • Add the encoding NodeId to the look-up table to reference the StructureDefinition. The encoding NodeId is part of the browse results for finding the Dictionary

The next chapter describes the OPC UA Namespaces.