A DataSetMessage is produced by a DataSetWriter and contains list of name/value pairs which are specified by the PublishedDataSet associated with the DataSetWriter. The contents of the DataSetMessage are formally described by a DataSetMetaData Object. A DataSetMessage is a JSON object with the fields defined in Table 185.
A key frame DataSetMessage or an event based DataSetMessage contains name and value for all fields of the DataSet.
A delta frame DataSetMessage contains only name and value for the changed fields.
DataSetWriters may periodically provide keep-alive messages which are DataSetMessages without any Payload field.
Table 185 – JSON DataSetMessage definition
|
Name |
Type |
Description |
|
DataSetWriterId |
UInt16 |
An identifier for DataSetWriter which created the DataSetMessage. The presence of the value depends on the setting in the JsonDataSetMessageContentMask. It is unique within the scope of a Publisher. |
|
DataSetWriterName |
String |
The name of the DataSetWriter which created the DataSetMessage. The presence of the value depends on the setting in the JsonDataSetMessageContentMask. |
|
PublisherId |
String |
A unique identifier for the Publisher. It identifies the source of the message. The presence of the value depends on the setting in the JsonDataSetMessageContentMask. The source is the PublisherId on a PubSubConnection (see 6.2.7.1). If the PublisherId is a UInteger, the UInteger value is converted to a String without leading zeros. The value shall be omitted if the NetworkMessage header is present. |
|
WriterGroupName |
String |
The name of the WriterGroup which created the DataSetMessage. The presence of the value depends on the setting in the JsonDataSetMessageContentMask. The value shall be omitted if the WriterGroupName is contained in the NetworkMessage header. |
|
SequenceNumber |
UInt32 |
Sequence number for each new DataSetMessage as defined in 7.2.3. The presence of the value depends on the setting in the JsonDataSetMessageContentMask. For the DataSetMessage MessageType “ua-keepalive”, the sequence number provides the next expected sequence number for the DataSetWriter. |
|
MetaDataVersion |
ConfigurationVersionDataType |
The version of the DataSetMetaData which describes the contents of the Payload. The presence of the value depends on the setting in the JsonDataSetMessageContentMask. |
|
MinorVersion |
VersionTime |
The minor version of the DataSetMetaData which describes the contents of the Payload. The presence of the value depends on the setting in the JsonDataSetMessageContentMask. The value shall be omitted if the MetaDataVersion is contained in the DataSetMessage header. |
|
Timestamp |
DateTime |
The time the DataSetMessage was created. The presence of the value depends on the setting in the JsonDataSetMessageContentMask. |
|
Status |
StatusCode |
The overall status of the DataSetMessage. The dependencies to the status of DataSet fields are defined in Table 35. The presence of the value depends on the setting in the JsonDataSetMessageContentMask. |
|
MessageType |
String |
Possible values are “ua-keyframe”, “ua-deltaframe”, “ua-event” and “ua-keepalive”. The presence of the value depends on the setting in the JsonDataSetMessageContentMask. If the MessageType is “ua-keepalive” but the DataSetMessage header is disabled in JsonDataSetMessageContentMask, this results in an empty JSON object sent for the DataSetMessage. |
|
Payload |
Object |
A JSON object containing the name-value pairs specified by the PublishedDataSet. The format of the value depends on the DataType of the field and the flags specified by the DataSetFieldContentMask. The detailed rules for creating the DataSetMessage status and DataSet field content are defined in Table 35. For MessageType “ua-event”, only Variant or RawData encoding shall be allowed. If bits for DataValue encoding are set, the Variant encoding shall be used. This value is always present. |
All fields with a concrete DataType are encoded using VerboseEncoding if FieldEncoding1 is FALSE and CompactEncoding if FieldEncoding1 is TRUE. See the OPC UA JSON Data encodings defined in OPC 10000-6.
The fields in the DataSetMessage are specified by the DataSetFieldContentMask in the DataSetWriter parameters.
The format of the field values in the Payload depend on the setting of the DataSetFieldContentMask, the FieldEncoding1 and the FieldEncoding2 flag in the DataSetMessageContentMask. The resulting JSON encoding is defined in Table 112. The FieldEncoding2 flag should always be set to true to omit the deprecated JSON encodings.
If the DataSetFieldContentMask is 0x0 or 0x20 (only the RawData flag is set), the DataSetMessage fields are encoded as Variant. Otherwise the fields are encoded as DataValue. If the MessageType is “ua-event”, the DataSetFieldContentMask shall be 0x0 or 0x20.
OPC 10000-6 defines two DataEncodings: CompactEncoding and VerboseEncoding. They have the same structure except VerboseEncoding includes default values.
The main use case for the VerboseEncoding is the payload of DataSetMessages. The VerboseEncoding and the following rules for DataSet field encoding ensure that Subscribers without OPC UA knowledge get messages without OPC UA specific information for normal use cases. At the same time, the rules for special cases and abstract data types ensure that OPC UA aware Subscribers can fully reverse the payload to OPC UA DataTypes if they have access to the DataSetMetaData of the Publisher. The rules for the special cases are defined in 7.2.5.4.3. VerboseEncoding is the recommended default encoding for DataSetMessages.
This specification defines a DataSet field encoding for the VerboseEncoding which simplifies the encoding of Variants and ExtensionObjects by omitting UaType and UaTypeId fields with concrete DataType defined in the FieldMetaData. In this case the Variants at the top level are collapsed. Therefore the DataSet fields in a DataSetMessage for VerboseEncoding are encoded like the fields of a Structure where the fields are described by the FieldMetaData. This includes fields with Enumeration DataTypes which are encoded using verbose Enumeration with the definition in the FieldMetaData.
The additional simplification for VerboseEncoding only applies to the first level of the DataSet fields. For the nested fields in structure DataSet fields, the rules of VerboseEncoding defined in OPC 10000-6 apply.
The following example shows a DataSetMessage with VerboseEncoding and DataSet fields without field specific status and timestamps.
{
"PublisherId":"MyPublisher",
"DataSetWriterId":102,
"SequenceNumber":25460,
"MinorVersion":672341762,
"Timestamp":"2021-09-27T18:45:19.555Z",
"Payload":
{
"LocationName":"Building A",
"Coordinate":
{
"X":1,
"Y":0.2
}
}
}
The following example shows a DataSetMessage with VerboseEncoding and DataSet fields with field specific status and timestamps. Status is omitted if the Code is 0.
{
"PublisherId":"MyPublisher",
"DataSetWriterId":102,
"SequenceNumber":68468,
"MinorVersion":672341762,
"Timestamp":"2021-09-27T18:45:19.555Z",
"Payload":
{
"LocationName":
{
"Value":"Building A",
"Status":{"Code":1073741824,"Symbol":"Uncertain"},
"SourceTimestamp":"2021-09-27T11:32:38.349925Z"
},
"Coordinate":
{
"Value":
{
"X":1,
"Y":0.2
},
"SourceTimestamp":"2021-09-27T11:32:38.349925Z"
}
}
}
By default, DataSet fields can only be decoded to the original DataType by inferring the schema from the JSON message or if the DataSetMetaData describing the DataSet fields is available (i.e. from the DataSetMetaData messages).
Additional information in the payload is required to fully reverse the payload to the original DataTypes for DataSet fields in the following cases where the DataSetMetaData is insufficient to unambiguously decode the messages.
- DataSet fields with BuiltInType ExtensionObject and a value which is a subtype of the DataType in the FieldMetaData. The UaTypeId is needed to decode the value.
- DataSet fields with BuiltInType Variant. The UaType is needed to decode the value.
- DataSet fields with abstract ValueRank values of Any (-2) or OneOrMoreDimensions (0)
Note that the same problem exists when a field of a nested Structure has DataType BaseDataType or AllowSubTypes =TRUE.
If RawData =FALSE, then the Publisher always includes the full Variant with the UaType or ExtensionObject with UaTypeId when encoding these fields at the top level or within a nested Structure.
If RawData =TRUE the Publisher will encode the Variant but not include the UaTypeId and UaType which means OPC UA DataSetReaders are not able to determine the DataTypes of the original values. If DataSetMetaData contains abstract types and RawData =TRUE is configured, OPC UA DataSetReaders may go into Error state.
Table 186 provides examples of Variant VerboseEncoding field encoding with the different RawData settings. The ValueRank configured for the DataSet field is Scalar if no other ValueRank is mentioned in the description.
Table 187 provides examples of DataValue VerboseEncoding field encoding for RawData=FALSE. For RawData=TRUE the UaType and UaTypeId fields are skipped as shown in Table 186.
Table 186 – DataSet field Variant VerboseEncoding examples
|
Description |
DataType |
RawData = TRUE |
RawData = FALSE |
|
Simple scalar Int32 |
Int32 |
1234 |
1234 |
|
Simple scalar String |
String |
"Apple" |
"Apple" |
|
BaseDataType |
BaseDataType |
{ "Value": "Apple" } |
{ "UaType": 12, "Value": "Apple" } |
|
Structure, no subtypes used |
Structure XInt32 YString |
{ "X": 1234, "Y": "Ring" } |
{ "X": 1234, "Y": "Ring" } |
|
Structure using subtype of the DataType in the FieldMetaData |
Structure XInt32 YString ZDouble |
{ "X": 1234, "Y": "Ring", "Z": 4.56 } |
{ "UaTypeId": "i=3456", "X": 1234, "Y": "Ring", "Z": 4.56 }(a) |
|
Nested structure with BaseDataType field |
Structure XInt32 SStructure A Double B BaseDataType |
{ "X": 1234, "S": { "A": 7.8, "B": { "Value":"Apple" } } } |
{ "X": 1234, "S": { "A": 7.8, "B": { "UaType": 12, "Value":"Apple" } } } |
|
Nested structure with AllowSubtypes = FALSE |
Structure XInt32 SStructure A Double B String |
{ "X": 1234, "S": { "A": 7.8, "B": "Apple" } } |
{ "X": 1234, "S": { "A": 7.8, "B": "Apple" } } |
|
Nested structure with AllowSubtypes = TRUE |
Structure XInt32 SStructure allow ST A Double B String |
{ "X": 1234 "S": { "A": 7.8, "B": "Apple" } } |
{ "X": 1234 "S": { "UaTypeId": "i=5678", "A": 7.8, "B": "Apple" } }(a) |
|
ValueRank = OneDimension |
Int32 [ ] |
[1,2,3,4] |
[1,2,3,4] |
|
ValueRank = TwoDimensions |
Int32 [ ] [ ] |
{ "Value": [1,2,3,4], "Dimensions": [2,2] } |
{ "Value": [1,2,3,4], "Dimensions": [2,2] } |
|
ValueRank = ScalarOrOneDimension |
Int32 |
11 |
11 |
|
ValueRank = ScalarOrOneDimension |
Int32 [ ] |
[1,2,3,4] |
[1,2,3,4] |
|
ValueRank = OneOrTwoDimensions |
Int32 [ ] |
{ "Value": [1,2,3,4] } |
{ "Value": [1,2,3,4] } |
|
ValueRank = OneOrTwoDimensions |
Int32 [ ] [ ] |
{ "Value": [1,2,3,4], "Dimensions": [2,2] } |
{ "Value": [1,2,3,4], "Dimensions": [2,2] } |
|
ValueRank = Any |
Int32 |
{ "Value": 11 } |
{ "Value": 11 } |
|
ValueRank = Any |
Int32 [ ] |
{ "Value": [1,2,3,4] } |
{ "Value": [1,2,3,4] } |
|
ValueRank = Any |
Int32 [ ] [ ] |
{ "Value": [1,2,3,4], "Dimensions": [2,2] } |
{ "Value": [1,2,3,4], "Dimensions": [2,2] } |
|
Structure with array |
Structure XInt32 [ ] YString |
{ "X": [1,2,3,4], "Y": "Ring" } |
{ "X": [1,2,3,4], "Y": "Ring" } |
|
Structure with multidimensional array |
Structure XInt32 [ ] [ ] YString |
{ "X": { "Array": [1,2,3,4] "Dimensions":[2,2] }, "Y": "Ring" } |
{ "X": { "Array": [1,2,3,4] "Dimensions":[2,2] }, "Y": "Ring" } |
|
Enumeration |
ServerStatusDataType |
"Suspended_3" |
"Suspended_3" |
|
(a)The NodeIds used in the example for UaTypeId are fictional NodeIds out of the OPC UA namespace to reduce the string length for readability of the examples. |
|||
Table 187 – DataSet field DataValue VerboseEncoding examples
|
Description |
DataType |
RawData = FALSE |
|
Simple scalar Int32 |
Int32 |
{ "Value": 1234, "SourceTimestamp": "2025-05-26T11:20:07.951Z" } |
|
Simple scalar String |
String |
{ "Value": "Apple", "SourceTimestamp": "2025-05-26T11:20:07.951Z" } |
|
BaseDataType |
BaseDataType |
{ "UaType": 12, "Value": "Apple", "SourceTimestamp": "2025-05-26T11:20:07.951Z" } |
|
Structure, no subtypes used |
Structure XInt32 YString |
{ "Value": { "X": 1234, "Y": "Ring", } } |
|
Structure using subtype of the DataType in the FieldMetaData |
Structure XInt32 YString ZDouble |
{ "Value": { "UaTypeId": "nsu=http://xy.de/types;i=123", "X": 1234, "Y": "Ring", "Z": 4.56 } } |