// Shows how to write complex data with OPC UA Complex Data plug-in.
//
// Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
// OPC client and subscriber examples in C# on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-CSharp .
// Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
// a commercial license in order to use Online Forums, and we reply to every post.
using System;
using OpcLabs.BaseLib.DataTypeModel;
using OpcLabs.EasyOpc.UA;
using OpcLabs.EasyOpc.UA.ComplexData;
using OpcLabs.EasyOpc.UA.OperationModel;
namespace UADocExamples.ComplexData._EasyUAClient
{
class WriteValue
{
public static void Main1()
{
// Define which server and node we will work with.
UAEndpointDescriptor endpointDescriptor =
"opc.tcp://opcua.demo-this.com:51210/UA/SampleServer";
// or "http://opcua.demo-this.com:51211/UA/SampleServer" (currently not supported)
// or "https://opcua.demo-this.com:51212/UA/SampleServer/"
UANodeDescriptor nodeDescriptor =
"nsu=http://test.org/UA/Data/ ;i=10239"; // [ObjectsFolder]/Data.Static.Scalar.StructureValue
// Instantiate the client object.
var client = new EasyUAClient();
// Read a node which returns complex data.
// We know that this node returns complex data, so we can type cast to UAGenericObject.
Console.WriteLine("Reading...");
UAGenericObject genericObject;
try
{
genericObject = (UAGenericObject)client.ReadValue(endpointDescriptor, nodeDescriptor);
}
catch (UAException uaException)
{
Console.WriteLine("*** Failure: {0}", uaException.GetBaseException().Message);
return;
}
// Modify the data read.
// This node returns one of the two data types, randomly (this is not common, usually the type is fixed). The
// data types are sub-types of one common type which the data type of the node. We therefore use the data type
// ID in the returned UAGenericObject to detect which data type has been returned.
// For processing the internals of the data, refer to examples for GenericData and DataType classes.
// We know how the data is structured, and have hard-coded a logic that modifies certain values inside. It is
// also possible to discover the structure of the data type in the program, and write generic clients that can
// cope with any kind of complex data.
//
// Note that the code below is not fully robust - it will throw an exception if the data is not as expected.
Console.WriteLine("Modifying...");
Console.WriteLine(genericObject.DataTypeId);
if (genericObject.DataTypeId.NodeDescriptor.Match("nsu=http://test.org/UA/Data/ ;i=9440")) // ScalarValueDataType
{
// Negate the byte in the "ByteValue" field.
var structuredData = (StructuredData)genericObject.GenericData;
var byteValue = (PrimitiveData)structuredData.FieldData["ByteValue"];
byteValue.Value = (Byte)~((Byte)byteValue.Value);
Console.WriteLine(byteValue.Value);
}
else if (genericObject.DataTypeId.NodeDescriptor.Match("nsu=http://test.org/UA/Data/ ;i=9669")) // ArrayValueDataType
{
// Negate bytes at indexes 0 and 1 of the array in the "ByteValue" field.
var structuredData = (StructuredData)genericObject.GenericData;
var byteValue = (SequenceData)structuredData.FieldData["ByteValue"];
var element0 = (PrimitiveData)byteValue.Elements[0];
var element1 = (PrimitiveData)byteValue.Elements[1];
element0.Value = (Byte)~((Byte)element0.Value);
element1.Value = (Byte)~((Byte)element1.Value);
Console.WriteLine(element0.Value);
Console.WriteLine(element1.Value);
}
// Write the modified complex data back to the node.
// The data type ID in the UAGenericObject is borrowed without change from what we have read, so that the server
// knows which data type we are writing. The data type ID not necessary if writing precisely the same data type
// as the node has (not a subtype).
Console.WriteLine("Writing...");
try
{
client.WriteValue(endpointDescriptor, nodeDescriptor, genericObject);
}
catch (UAException uaException)
{
Console.WriteLine("*** Failure: {0}", uaException.GetBaseException().Message);
}
}
}
}
' Shows how to write complex data with OPC UA Complex Data plug-in.
'
' Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
' OPC client and subscriber examples in VB.NET on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-VBNET .
' Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
' a commercial license in order to use Online Forums, and we reply to every post.
Imports System
Imports OpcLabs.BaseLib.DataTypeModel
Imports OpcLabs.EasyOpc.UA
Imports OpcLabs.EasyOpc.UA.ComplexData
Imports OpcLabs.EasyOpc.UA.OperationModel
Namespace ComplexData._EasyUAClient
Friend Class WriteValue
Public Shared Sub Main1()
' Define which server we will work with.
Dim endpointDescriptor As UAEndpointDescriptor =
"opc.tcp://opcua.demo-this.com:51210/UA/SampleServer"
' or "http://opcua.demo-this.com:51211/UA/SampleServer" (currently not supported)
' or "https://opcua.demo-this.com:51212/UA/SampleServer/"
' Define which node we will work with.
Dim nodeDescriptor As UANodeDescriptor = _
"nsu=http://test.org/UA/Data/ ;i=10239" ' [ObjectsFolder]/Data.Static.Scalar.StructureValue
' Instantiate the client object.
Dim client = New EasyUAClient
' Read a node which returns complex data.
' We know that this node returns complex data, so we can type cast to UAGenericObject.
Console.WriteLine("Reading...")
Dim genericObject As UAGenericObject
Try
genericObject = CType(client.ReadValue(endpointDescriptor, nodeDescriptor), UAGenericObject)
Catch uaException As UAException
Console.WriteLine("*** Failure: {0}", uaException.GetBaseException.Message)
Exit Sub
End Try
' Modify the data read.
' This node returns one of the two data types, randomly (this is not common, usually the type is fixed). The
' data types are sub-types of one common type which the data type of the node. We therefore use the data type
' ID in the returned UAGenericObject to detect which data type has been returned.
' For processing the internals of the data, refer to examples for GenericData and DataType classes.
' We know how the data is structured, and have hard-coded a logic that modifies certain values inside. It is
' also possible to discover the structure of the data type in the program, and write generic clients that can
' cope with any kind of complex data.
'
' Note that the code below is not fully robust - it will throw an exception if the data is not as expected.
Console.WriteLine("Modifying...")
Console.WriteLine(genericObject.DataTypeId)
If genericObject.DataTypeId.NodeDescriptor.Match("nsu=http://test.org/UA/Data/ ;i=9440") Then ' ScalarValueDataType
' Negate the byte in the "ByteValue" field.
Dim structuredData = CType(genericObject.GenericData, StructuredData)
Dim byteValue = CType(structuredData.FieldData("ByteValue"), PrimitiveData)
byteValue.Value = CType(Not CType(byteValue.Value, Byte), Byte)
Console.WriteLine(byteValue.Value)
ElseIf genericObject.DataTypeId.NodeDescriptor.Match("nsu=http://test.org/UA/Data/ ;i=9669") Then ' ArrayValueDataType
' Negate bytes at indexes 0 and 1 of the array in the "ByteValue" field.
Dim structuredData = CType(genericObject.GenericData, StructuredData)
Dim byteValue = CType(structuredData.FieldData("ByteValue"), SequenceData)
Dim element0 = CType(byteValue.Elements(0), PrimitiveData)
Dim element1 = CType(byteValue.Elements(1), PrimitiveData)
element0.Value = CType(Not CType(element0.Value, Byte), Byte)
element1.Value = CType(Not CType(element1.Value, Byte), Byte)
Console.WriteLine(element0.Value)
Console.WriteLine(element1.Value)
End If
' Write the modified complex data back to the node.
' The data type ID in the UAGenericObject is borrowed without change from what we have read, so that the server
' knows which data type we are writing. The data type ID not necessary if writing precisely the same data type
' as the node has (not a subtype).
Console.WriteLine("Writing...")
Try
client.WriteValue(endpointDescriptor, nodeDescriptor, genericObject)
Catch uaException As UAException
Console.WriteLine("*** Failure: {0}", uaException.GetBaseException.Message)
Exit Sub
End Try
End Sub
End Class
End Namespace
// Shows how to write complex data with OPC UA Complex Data plug-in.
//
// Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
// OPC client and subscriber examples in Object Pascal (Delphi) on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-OP .
// Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
// a commercial license in order to use Online Forums, and we reply to every post.
class procedure WriteValue.Main;
var
ArrayValueDataType: _UANodeDescriptor;
ByteValue: _PrimitiveData;
ByteValue2: _SequenceData;
Client: _EasyUAClient;
Element0, Element1: _PrimitiveData;
EndpointDescriptor: string;
GenericObject: _UAGenericObject;
NodeDescriptor: string;
ScalarValueDataType: _UANodeDescriptor;
StructuredData: _StructuredData;
begin
// Define which server and node we will work with.
EndpointDescriptor :=
//'http://opcua.demo-this.com:51211/UA/SampleServer';
//'https://opcua.demo-this.com:51212/UA/SampleServer/';
'opc.tcp://opcua.demo-this.com:51210/UA/SampleServer';
NodeDescriptor := 'nsu=http://test.org/UA/Data/ ;i=10239'; // [ObjectsFolder]/Data.Static.Scalar.StructureValue
// Instantiate the client object
Client := CoEasyUAClient.Create;
// Read a node which returns complex data.
// We know that this node returns complex data, so we can type cast to UAGenericObject.
WriteLn('Reading...');
try
GenericObject := _UAGenericObject(IUnknown(Client.ReadValue(EndpointDescriptor, NodeDescriptor)));
except
on E: EOleException do
begin
WriteLn(Format('*** Failure: %s', [E.GetBaseException.Message]));
Exit;
end;
end;
// Modify the data read.
// This node returns one of the two data types, randomly (this is not common, usually the type is fixed). The
// data types are sub-types of one common type which the data type of the node. We therefore use the data type
// ID in the returned UAGenericObject to detect which data type has been returned.
// For processing the internals of the data, refer to examples for GenericData and DataType classes.
// We know how the data is structured, and have hard-coded a logic that modifies certain values inside. It is
// also possible to discover the structure of the data type in the program, and write generic clients that can
// cope with any kind of complex data.
//
// Note that the code below is not fully robust - it will throw an exception if the data is not as expected.
WriteLn('Modifying...');
WriteLn(GenericObject.DataTypeId.ToString);
ScalarValueDataType := CoUANodeDescriptor.Create;
ScalarValueDataType.NodeId.ExpandedText := 'nsu=http://test.org/UA/Data/ ;i=9440'; // ScalarValueDataType
if GenericObject.DataTypeId.NodeDescriptor.Match(ScalarValueDataType) then
begin
// Negate the byte in the "ByteValue" field.
StructuredData := IUnknown(GenericObject.GenericData) as _StructuredData;
ByteValue := IUnknown(StructuredData.FieldData['ByteValue']) as _PrimitiveData;
ByteValue.Value := Byte(not (Byte(byteValue.Value)));
WriteLn(ByteValue.Value);
end
else
begin
ArrayValueDataType := CoUANodeDescriptor.Create;
ArrayValueDataType.NodeId.ExpandedText := 'nsu=http://test.org/UA/Data/ ;i=9669'; // ArrayValueDataType
if GenericObject.DataTypeId.Nodedescriptor.Match(ArrayValueDataType) then
begin
// Negate bytes at indexes 0 and 1 of the array in the "ByteValue" field.
StructuredData := IUnknown(GenericObject.GenericData) as _StructuredData;
ByteValue2 := IUnknown(StructuredData.FieldData['ByteValue']) as _SequenceData;
Element0 := IUnknown(ByteValue2.Elements[0]) as _PrimitiveData;
Element1 := IUnknown(ByteValue2.Elements[1]) as _PrimitiveData;
Element0.Value := Byte(not (Byte(element0.Value)));
Element1.Value := Byte(not (Byte(element1.Value)));
WriteLn(Element0.Value);
WriteLn(Element1.Value);
end;
end;
// Write the modified complex data back to the node.
// The data type ID in the UAGenericObject is borrowed without change from what we have read, so that the server
// knows which data type we are writing. The data type ID not necessary if writing precisely the same data type
// as the node has (not a subtype).
WriteLn('Writing...');
try
Client.WriteValue(EndpointDescriptor, NodeDescriptor, GenericObject);
except
on E: EOleException do
begin
WriteLn(Format('*** Failure: %s', [E.GetBaseException.Message]));
Exit;
end;
end;
end;
// Shows how to write complex data with OPC UA Complex Data plug-in.
//
// Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
// OPC client and subscriber examples in PHP on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-PHP .
// Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
// a commercial license in order to use Online Forums, and we reply to every post.
// Define which server and node we will work with.
$EndpointDescriptor =
//"http://opcua.demo-this.com:51211/UA/SampleServer";
//"https://opcua.demo-this.com:51212/UA/SampleServer/";
"opc.tcp://opcua.demo-this.com:51210/UA/SampleServer";
$NodeDescriptor = "nsu=http://test.org/UA/Data/ ;i=10239"; // [ObjectsFolder]/Data.Static.Scalar.StructureValue
// Instantiate the client object
$Client = new COM("OpcLabs.EasyOpc.UA.EasyUAClient");
// Read a node which returns complex data.
// We know that this node returns complex data, so we can type cast to UAGenericObject.
printf("Reading...\n");
try
{
$GenericObject = $Client->ReadValue($EndpointDescriptor, $NodeDescriptor);
}
catch (com_exception $e)
{
printf("*** Failure: %s\n", $e->getMessage());
Exit();
}
// Modify the data read.
// This node returns one of the two data types, randomly (this is not common, usually the type is fixed). The
// data types are sub-types of one common type which the data type of the node. We therefore use the data type
// ID in the returned UAGenericObject to detect which data type has been returned.
// For processing the internals of the data, refer to examples for GenericData and DataType classes.
// We know how the data is structured, and have hard-coded a logic that modifies certain values inside. It is
// also possible to discover the structure of the data type in the program, and write generic clients that can
// cope with any kind of complex data.
//
// Note that the code below is not fully robust - it will throw an exception if the data is not as expected.
printf("Modifying...\n");
printf("%s\n", $GenericObject->DataTypeId);
$ScalarValueDataType = new COM("OpcLabs.EasyOpc.UA.UANodeDescriptor");
$ScalarValueDataType->NodeId->ExpandedText = "nsu=http://test.org/UA/Data/ ;i=9440"; // ScalarValueDataType
if ($GenericObject->DataTypeId->NodeDescriptor->Match($ScalarValueDataType)) {
// Negate the byte in the "ByteValue" field.
$StructuredData = $GenericObject->GenericData->AsStructuredData();
$ByteValue = $StructuredData->FieldData["ByteValue"]->AsPrimitiveData();
$ByteValue->Value = ~($ByteValue->Value) & 255;
printf("%s\n", $ByteValue->Value);
}
else {
$ArrayValueDataType = new COM("OpcLabs.EasyOpc.UA.UANodeDescriptor");
$ArrayValueDataType->NodeId->ExpandedText = "nsu=http://test.org/UA/Data/ ;i=9669"; // ArrayValueDataType
if ($GenericObject->DataTypeId->Nodedescriptor->Match($ArrayValueDataType)) {
// Negate bytes at indexes 0 and 1 of the array in the "ByteValue" field.
$StructuredData = $GenericObject->GenericData->AsStructuredData();
$ByteValue2 = $StructuredData->FieldData["ByteValue"]->AsSequenceData();
$Element0 = $ByteValue2->Elements[0]->AsPrimitiveData();
$Element1 = $ByteValue2->Elements[1]->AsPrimitiveData();
$Element0->Value = ~($Element0->Value) & 255;
$Element1->Value = ~($Element1->Value) & 255;
printf("%s\n", $Element0->Value);
printf("%s\n", $Element1->Value);
}
}
// Write the modified complex data back to the node.
// The data type ID in the UAGenericObject is borrowed without change from what we have read, so that the server
// knows which data type we are writing. The data type ID not necessary if writing precisely the same data type
// as the node has (not a subtype).
printf("Writing...\n");
try
{
$Client->WriteValue($EndpointDescriptor, $NodeDescriptor, $GenericObject);
}
catch (com_exception $e)
{
printf("Failure: %s\n", $e->getMessage());
Exit();
}
# Shows how to write complex data with OPC UA Complex Data plug-in.
#
# Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
# OPC client and subscriber examples in Python on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-Python .
# Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
# a commercial license in order to use Online Forums, and we reply to every post.
# The QuickOPC package is needed. Install it using "pip install opclabs_quickopc".
import opclabs_quickopc
# Import .NET namespaces.
from System import *
from OpcLabs.BaseLib.DataTypeModel import *
from OpcLabs.EasyOpc.UA import *
from OpcLabs.EasyOpc.UA.OperationModel import *
endpointDescriptor = UAEndpointDescriptor('opc.tcp://opcua.demo-this.com:51210/UA/SampleServer')
# or 'http://opcua.demo-this.com:51211/UA/SampleServer' (currently not supported)
# or 'https://opcua.demo-this.com:51212/UA/SampleServer/'
# [ObjectsFolder]/Data.Static.Scalar.StructureValue
nodeDescriptor = UANodeDescriptor('nsu=http://test.org/UA/Data/ ;i=10239')
# Instantiate the client object.
client = EasyUAClient()
# Read a node which returns complex data.
# We know that this node returns complex data, so we can type cast to UAGenericObject.
try:
print('Reading...')
genericObject = IEasyUAClientExtension.ReadValue(client, endpointDescriptor, nodeDescriptor)
except UAException as uaException:
print('*** Failure: ' + uaException.GetBaseException().Message)
exit()
# Modify the data read.
# This node returns one of the two data types, randomly (this is not common, usually the type is fixed). The
# data types are sub-types of one common type which the data type of the node. We therefore use the data type
# ID in the returned UAGenericObject to detect which data type has been returned.
#
# For processing the internals of the data, refer to examples for GenericData and DataType classes.
# We know how the data is structured, and have hard-coded a logic that modifies certain values inside. It is
# also possible to discover the structure of the data type in the program, and write generic clients that can
# cope with any kind of complex data.
#
# Note that the code below is not fully robust - it will throw an exception if the data is not as expected.
print ('Modifying...')
print(genericObject.DataTypeId)
if genericObject.DataTypeId.NodeDescriptor.Match(UANodeDescriptor('nsu=http://test.org/UA/Data/ ;i=9440')): # ScalarValueDataType
# Negate the byte in the "ByteValue" field.
structuredData = genericObject.GenericData
byteValue = structuredData.FieldData.get_Item('ByteValue') # PrimitiveData
byteValue.Value = (~byteValue.Value) & 0xFF
print(byteValue.Value)
elif genericObject.DataTypeId.NodeDescriptor.Match(UANodeDescriptor('nsu=http://test.org/UA/Data/ ;i=9669')): # ArrayValueDataType
# Negate bytes at indexes 0 and 1 of the array in the "ByteValue" field.
structuredData = genericObject.GenericData
byteValue = structuredData.FieldData.get_Item('ByteValue') # SequenceData
element0 = byteValue.Elements.get_Item(0) # PrimitiveData
element1 = byteValue.Elements.get_Item(1) # PrimitiveData
element0.Value = (~element0.Value) & 0xFF
element1.Value = (~element1.Value) & 0xFF
print(element0.Value)
print(element1.Value)
# Write the modified complex data back to the node.
# The data type ID in the UAGenericObject is borrowed without change from what we have read, so that the server
# knows which data type we are writing. The data type ID not necessary if writing precisely the same data type
# as the node has (not a subtype).
try:
print('Writing...')
IEasyUAClientExtension.WriteValue(client, endpointDescriptor, nodeDescriptor, genericObject)
except UAException as uaException:
print('*** Failure: ' + uaException.GetBaseException().Message)
print()
print('Finished.')