Skip to main content

write complex values

This tutorial covers how to write complex OPC UA data types including arrays, structures, extension objects, and custom data types using the OPC UA Write Node. Complex data types allow you to work with sophisticated industrial data structures that go beyond simple numeric and string values.

Understanding how to handle complex types is essential for advanced OPC UA applications that deal with structured data, configuration objects, and specialized industrial protocols.

Prerequisites

OPC UA Complex Variant Overview

Array Types

OPC UA supports several array formats:

  • Scalar: Single value (not an array)
  • Array: One-dimensional array [1, 2, 3]
  • Matrix: Multi-dimensional array with dimensions

Structure Types

  • Built-in Structures: Predefined OPC UA structures
  • Custom Structures: User-defined structured data types
  • Extension Objects: Complex objects with custom encoding

Data Type Categories

  1. Primitive Arrays: Arrays of basic types
  2. Structured Data: Complex objects with multiple fields
  3. Union Types: Data that can be one of several types
  4. Enumeration Arrays: Arrays of enumerated values

Writing Array Data Types

Simple Arrays

Numeric Arrays

// Integer array
msg = {
payload: {
dataType: "Int32",
value: [10, 20, 30, 40, 50],
arrayType: "Array"
},
nodeId: "ns=2;s=IntegerArray"
};

// Double array
msg = {
payload: {
dataType: "Double",
value: [1.1, 2.2, 3.3, 4.4],
arrayType: "Array"
},
nodeId: "ns=2;s=DoubleArray"
};

// Boolean array
msg = {
payload: {
dataType: "Boolean",
value: [true, false, true, false],
arrayType: "Array"
},
nodeId: "ns=2;s=BooleanArray"
};

String Arrays

msg = {
payload: {
dataType: "String",
value: ["Recipe1", "Recipe2", "Recipe3"],
arrayType: "Array"
},
nodeId: "ns=2;s=RecipeList"
};

Multi-Dimensional Arrays

// 2D Matrix (3x3)
msg = {
payload: {
dataType: "Double",
value: [
1.0, 2.0, 3.0,
4.0, 5.0, 6.0,
7.0, 8.0, 9.0
],
arrayType: "Matrix",
dimensions: [3, 3] // 3 rows, 3 columns
},
nodeId: "ns=2;s=Matrix3x3"
};

// 3D Array (2x2x2)
msg = {
payload: {
dataType: "Int32",
value: [1, 2, 3, 4, 5, 6, 7, 8],
arrayType: "Matrix",
dimensions: [2, 2, 2]
},
nodeId: "ns=2;s=Cube2x2x2"
};

Dynamic Arrays with Function Node

// Generate array data dynamically
const size = flow.get("arraySize") || 10;
const dataArray = [];

for (let i = 0; i < size; i++) {
dataArray.push(Math.random() * 100);
}

msg = {
payload: {
dataType: "Double",
value: dataArray,
arrayType: "Array"
},
nodeId: "ns=2;s=DynamicArray"
};

return msg;

Writing Structured Data

Simple Structures

// Equipment status structure
msg = {
payload: {
dataType: "ExtensionObject",
value: {
TypeId: "ns=2;i=1001", // Structure type identifier
Body: {
equipmentId: "PUMP_001",
status: "Running",
temperature: 65.5,
pressure: 2.3,
lastMaintenance: new Date("2024-01-15T10:00:00Z"),
isOnline: true
}
}
},
nodeId: "ns=2;s=EquipmentStatus"
};

Configuration Structures

// Process configuration object
msg = {
payload: {
dataType: "ExtensionObject",
value: {
TypeId: "ns=2;i=2001",
Body: {
ProcessName: "Heating Process",
Parameters: {
TargetTemperature: 150.0,
HeatingRate: 5.0,
HoldTime: 3600,
CoolingRate: 2.0
},
Alarms: {
HighTempAlarm: 180.0,
LowTempAlarm: 140.0,
PressureAlarm: 10.0
},
Safety: {
EmergencyShutdown: true,
AutoRestart: false,
MaxCycles: 100
}
}
}
},
nodeId: "ns=2;s=ProcessConfig"
};

Recipe Data Structures

// Manufacturing recipe
msg = {
payload: {
dataType: "ExtensionObject",
value: {
TypeId: "ns=2;i=3001",
Body: {
RecipeId: "RCP_001",
RecipeName: "Standard Mix",
Version: "1.2",
Ingredients: [
{
Name: "Component A",
Quantity: 50.0,
Unit: "kg",
Tolerance: 2.0
},
{
Name: "Component B",
Quantity: 25.0,
Unit: "kg",
Tolerance: 1.0
}
],
Steps: [
{
StepNumber: 1,
Action: "Heat",
Parameter: 80.0,
Duration: 1800,
Description: "Heat to 80°C for 30 minutes"
},
{
StepNumber: 2,
Action: "Mix",
Parameter: 500.0,
Duration: 600,
Description: "Mix at 500 RPM for 10 minutes"
}
]
}
}
},
nodeId: "ns=2;s=ActiveRecipe"
};

Working with Custom Data Types

Enumeration Types

// Status enumeration
const StatusEnum = {
STOPPED: 0,
STARTING: 1,
RUNNING: 2,
STOPPING: 3,
ERROR: 4
};

msg = {
payload: {
value: StatusEnum.RUNNING
},
nodeId: "ns=2;s=MachineStatus"
};

// Or with string representation
msg = {
payload: {
value: "Running"
},
nodeId: "ns=2;s=MachineStatusText"
};

Advanced Complex Type Scenarios

1. Array of Structures

// Array containing multiple structured objects
msg = {
payload: {
dataType: "ExtensionObject",
value: [
{
TypeId: "ns=2;i=6001",
Body: {
alarmId: "ALM_001",
severity: "High",
message: "Temperature too high",
timestamp: new Date("2024-01-15T10:30:00Z"),
acknowledged: false
}
},
{
TypeId: "ns=2;i=6001",
Body: {
alarmId: "ALM_002",
severity: "Medium",
message: "Pressure low",
timestamp: new Date("2024-01-15T10:32:00Z"),
acknowledged: true
}
}
],
arrayType: "Array"
},
nodeId: "ns=2;s=ActiveAlarms"
};