OPC UA Custom DataTypes: Resolving Binary-Only Values

Jason IP3 min read
OPC / OPC UAOther ManufacturerTechnical Reference
Licensed PE Working through this on a live machine? A Maine-licensed engineer can take it from here — included with IMD hardware, by the hour for everything else. Book an engineer

A Java OPC UA client can read a custom structured DataType exposed by a C# server. The client must either know the structure in advance or discover its definition through the server's DataTypeDictionaries. A client that performs neither step can expose the value only as an undecoded binary body.

Why the custom structure appears as binary

The variable is an instance of BaseDataVariableType whose DataType is a developer-defined structure containing fields such as UInt32 and String. Its binary-encoded value is carried with a TypeId identifying the structure's binary encoding. The TypeId alone does not describe the fields, so the client needs matching structure information before it can interpret the body.

Client capability Result
The custom structured DataType is already known The client uses its registered structure definition to decode the binary body.
The client reads and interprets DataTypeDictionaries The client discovers the structure and decodes it generically.
Neither capability is implemented The value remains binary even though the server exposes a custom DataType.

Metadata chain required for generic decoding

Under Types → DataTypes → OPC Binary, the children represent DataTypeDictionaries for binary encoding. Each dictionary value is a ByteString containing descriptions of custom structures.

The custom DataType node has a HasEncoding reference to an encoding node with the BrowseName Default Binary. That node's NodeId is the BinaryEncodingId and is also the TypeId carried by the encoded ExtensionObject. A HasDescription reference connects the encoding node to a Description node that is a component of the relevant DataTypeDictionary. The Description value identifies the DataType name within that dictionary.

Implement the Java client decoding path

  1. Browse the children of OPC Binary, read the DataTypeDictionary values, and parse their structure descriptions.
  2. Browse the custom DataType node through HasEncoding to its Default Binary node.
  3. Record the encoding node's NodeId as the BinaryEncodingId and follow HasDescription to obtain the structure name in the dictionary.
  4. When an ExtensionObject arrives, use its TypeId to locate the mapped structure definition.
  5. Decode the binary body according to that definition and present the resulting fields instead of the raw bytes.

If the Java client library does not implement this discovery and mapping logic, register the structured type in the client instead. Changing only the display layer cannot decode the value because it still lacks the field definition.

Verify server and client interoperability

Confirm that the server exposes the dictionary, the custom DataType's HasEncoding reference, the Default Binary node, and its HasDescription link. Then compare the ExtensionObject TypeId with the encoding node's NodeId and verify that the Description value resolves to a parsed dictionary entry. Finally, assign known UInt32 and String field values at the server and confirm that the Java client returns those fields and values rather than a binary body.

The server is not limited to predefined DataTypes solely because the client uses another programming language. Compatibility depends on whether the server publishes the required type metadata and whether the client can consume that metadata or already knows the custom structure.

FAQ

Can a Java OPC UA client read a custom DataType from a C# server?

Yes. The client must either have the structured DataType registered in advance or read the server's DataTypeDictionaries and map the ExtensionObject TypeId to the discovered structure.

Why does my OPC UA client show an ExtensionObject as binary?

The client has the encoded body but lacks usable structure information. Check whether it parses the dictionaries under Types → DataTypes → OPC Binary and follows HasEncoding and HasDescription.

How do I identify the correct structure for an OPC UA TypeId?

Match the ExtensionObject TypeId to the NodeId of the DataType's Default Binary encoding node. Follow that node's HasDescription reference to find the DataType name within the relevant dictionary.

Back to blog