How-to guide
Node types
Work with method, file, data type, variable, and data item nodes, including analog values.
How-to guide
Node types
Call methods
Types usedOpcClientOpcNodeIdOpcCallMethod
The NodeId defines which method node the client calls. You pass the parameters a method expects when you call CallMethod or in the respective OpcCallMethod instance. Always specify the NodeId of the owner of the method first, then the NodeId of the method itself. The NodeId of the owner is the identifier of the object node or object type node that references the method through a HasComponent reference.
Call a single method node without parameters (the method has no IN arguments):
// The result array contains the values of the OUT arguments offered by the method.
object[] result = client.CallMethod(
"ns=2;s=Machine", /* NodeId of Owner Node */
"ns=2;s=Machine/StartMachine" /* NodeId of Method Node*/);'The result array contains the values of the OUT arguments offered by the method.
Dim result As Object() = client.CallMethod( _
"ns=2;s=Machine", _ 'NodeId of Owner Node
"ns=2;s=Machine/StartMachine") 'NodeId of Method NodeCall a single method node with parameters (the method has IN arguments):
// The result array contains the values of the OUT arguments offered by the method.
object[] result = client.CallMethod(
"ns=2;s=Machine", /* NodeId of Owner Node */
"ns=2;s=Machine/StopMachine", /* NodeId of Method Node */
"Job Change", /* Parameter 1: 'reason' */
10023, /* Parameter 2: 'reasonCode' */
DateTime.Now /* Parameter 3: 'scheduleDate' */);'The result array contains the values of the OUT arguments offered by the method.
Dim result As Object() = client.CallMethod( _
"ns=2;s=Machine", _ 'NodeId of Owner Node
"ns=2;s=Machine/StopMachine", _ 'NodeId of Method Node
"Job Change", _ 'Parameter 1: 'reason'
10023, _ 'Parameter 2: 'reasonCode'
DateTime.Now) 'Parameter 3: 'scheduleDate'Call multiple method nodes without parameters (the methods have no IN arguments):
OpcCallMethod[] commands = new OpcCallMethod[] {
new OpcCallMethod("ns=2;s=Machine", "ns=2;s=Machine/StopMachine"),
new OpcCallMethod("ns=2;s=Machine", "ns=2;s=Machine/ScheduleJob"),
new OpcCallMethod("ns=2;s=Machine", "ns=2;s=Machine/StartMachine")
};
// The result array contains the values of the OUT arguments offered by the methods.
object[][] results = client.CallMethods(commands);Dim commands As OpcCallMethod() = New OpcCallMethod() { _
New OpcCallMethod("ns=2;s=Machine", "ns=2;s=Machine/StopMachine"), _
New OpcCallMethod("ns=2;s=Machine", "ns=2;s=Machine/ScheduleJob"), _
New OpcCallMethod("ns=2;s=Machine", "ns=2;s=Machine/StartMachine") _
}
'The result array contains the values of the OUT arguments offered by the methods.
Dim results As Object()() = client.CallMethods(commands)Call multiple method nodes with parameters (the methods have IN arguments):
OpcCallMethod[] commands = new OpcCallMethod[] {
new OpcCallMethod(
"ns=2;s=Machine", /* NodeId of Owner Node */
"ns=2;s=Machine/StopMachine", /* NodeId of Method Node */
"Job Change", /* Parameter 1: 'reason' */
10023, /* Parameter 2: 'reasonCode' */
DateTime.Now /* Parameter 3: 'scheduleDate' */),
new OpcCallMethod(
"ns=2;s=Machine", /* NodeId of Owner Node */
"ns=2;s=Machine/ScheduleJob", /* NodeId of Method Node */
"MAN_F01_78910" /* Parameter 1: 'jobSerial' */),
new OpcCallMethod(
"ns=2;s=Machine", /* NodeId of Owner Node */
"ns=2;s=Machine/StartMachine", /* NodeId of Method Node */
10021 /* Parameter 1: 'reasonCode' */)
};
// The result array contains the values of the OUT arguments offered by the methods.
object[][] results = client.CallMethods(commands);Dim commands As OpcCallMethod() = New OpcCallMethod() { _
New OpcCallMethod( _
"ns=2;s=Machine", _ 'NodeId of Owner Node
"ns=2;s=Machine/StopMachine", _ 'NodeId of Method Node
"Job Change", _ 'Parameter 1: 'reason'
10023, _ 'Parameter 2: 'reasonCode'
DateTime.Now), _ 'Parameter 3: 'scheduleDate'
New OpcCallMethod( _
"ns=2;s=Machine", _ 'NodeId of Owner Node
"ns=2;s=Machine/ScheduleJob", _ 'NodeId of Method Node
"MAN_F01_78910"), _ 'Parameter 1: 'jobSerial'
New OpcCallMethod( _
"ns=2;s=Machine", _ 'NodeId of Owner Node
"ns=2;s=Machine/StartMachine", _ 'NodeId of Method Node
10021) _ 'Parameter 1: 'reasonCode'
}
'The result array contains the values of the OUT arguments offered by the methods.
Dim results As Object()() = client.CallMethods(commands)Call method nodes in a typed way: For methods without OUT arguments, OpcClient provides the CallAction method. For methods with OUT arguments, it provides the CallFunc method. The type parameters define the types of the IN arguments, and the last type parameter defines the type of the return value. The method returns the value of the first OUT argument:
// Call a method without IN and OUT arguments.
client.CallAction("ns=2;s=Machine", "ns=2;s=Machine/StartMachine");
// Call a method with two IN arguments and return the value of its first OUT argument.
int jobId = client.CallFunc<string, int, int>(
"ns=2;s=Machine",
"ns=2;s=Machine/StartJob",
"JOB001",
10023);'Call a method without IN and OUT arguments.
client.CallAction("ns=2;s=Machine", "ns=2;s=Machine/StartMachine")
'Call a method with two IN arguments and return the value of its first OUT argument.
Dim jobId As Integer = client.CallFunc(Of String, Integer, Integer)( _
"ns=2;s=Machine", _
"ns=2;s=Machine/StartJob", _
"JOB001", _
10023)File nodes
Nodes of the type FileType provide the content of a file, which the client accesses like a file in the file system. The page Read and write files describes how to read and write such files.
Query data types
Types usedOpcClientOpcNodeIdOpcNodeInfoOpcTypeNodeInfo
A server can provide a node that describes a data type defined by the server in more detail. The client might have to retrieve and process this information. Browsing is the easiest way to do this. For data type nodes, the SDK therefore provides a specialization of the OpcNodeInfo class: the OpcTypeNodeInfo class. Through its properties, the client retrieves additional information about the user-defined data type, for example, whether the data type is an enumeration. If it is, the client also retrieves the enum entries of this type:
var machineStatusNode = client.BrowseNode("ns=2;s=MachineStatus") as OpcTypeNodeInfo;
if (machineStatusNode != null && machineStatusNode.IsEnum) {
var members = machineStatusNode.GetEnumMembers();
foreach (var member in members)
Console.WriteLine(member.Name);
}Dim machineStatusNode = TryCast(client.BrowseNode("ns=2;s=MachineStatus"), OpcTypeNodeInfo)
If machineStatusNode IsNot Nothing AndAlso machineStatusNode.IsEnum Then
Dim members = machineStatusNode.GetEnumMembers()
For Each member In members
Console.WriteLine(member.Name)
Next
End IfVariables
Types usedOpcClientOpcNodeIdOpcNodeInfoOpcVariableNodeInfo
Working with variable nodes is often limited to reading and writing the Value attribute. This works the same way as for all nodes, see Read values and Write values. If the client needs more information than the value, it requests it from the server in one step by browsing. This includes, for example, DataType, AccessLevel, IsArray, ArrayDimensions, or IsHistorizing of the OpcVariableNodeInfo class. Separate requests with ReadNode are then not necessary. The following example shows this:
var machineStatusNode = client.BrowseNode("ns=2;s=Machine/Status") as OpcVariableNodeInfo;
if (machineStatusNode != null) {
Console.WriteLine($"AccessLevel: {machineStatusNode.AccessLevel}");
Console.WriteLine($"UserAccessLevel: {machineStatusNode.UserAccessLevel}");
...
}Dim machineStatusNode = TryCast(client.BrowseNode("ns=2;s=Machine/Status"), OpcVariableNodeInfo)
If machineStatusNode IsNot Nothing Then
Console.WriteLine("AccessLevel: {0}", machineStatusNode.AccessLevel)
Console.WriteLine("UserAccessLevel: {0}", machineStatusNode.UserAccessLevel)
...
End IfThe client can also continue browsing directly at the data type node that the variable node uses:
var dataTypeNode = machineStatusNode.DataType;
if (dataTypeNode.IsSystemType) {
...
}Dim dataTypeNode = machineStatusNode.DataType
If dataTypeNode.IsSystemType Then
...
End IfLarge binary values as a stream
Types usedOpcClientOpcNodeStream
The client reads variables with large ByteString values (for example, images, recipes, or logs) through an OpcNodeStream like a file, for example, with CopyTo. The stream first tries to read the whole value. If that fails, for example, because the value exceeds the data transfer limits, it reads the value in chunks through ranges of the value. The chunk size depends on MaxByteStringLength. The stream supports reading only and requires that the node allows reading (AccessLevel CurrentRead):
using (var source = new OpcNodeStream(client, "ns=2;s=Machine/Snapshot"))
using (var target = File.Create("snapshot.bin")) {
source.CopyTo(target);
}Using source = New OpcNodeStream(client, "ns=2;s=Machine/Snapshot")
Using target = IO.File.Create("snapshot.bin")
source.CopyTo(target)
End Using
End UsingData items
Data item nodes that a server provides as OpcDataItemNode extend a simple OpcDataVariableNode. They also mainly provide values. In addition, they supply further useful metadata. Most important is the "Definition" property, which is a property node below this node. It helps to interpret and process the data of the node correctly. Its vendor-specific value describes how the value of the node is determined. Apart from that, the operations from Read and write values also work for this specialization. The client reads "Definition" like any other child node, for example, through Child("Definition") when browsing or through ReadNode with the identifier of the property node.
Analog items
Types usedOpcClientOpcNodeIdOpcNodeInfoOpcAnalogItemNodeInfo
Analog items are a specialization of the data item node OpcDataItemNode. Their values are mainly analog. The additional properties InstrumentRange, EngineeringUnit, and EngineeringUnitRange describe them in more detail. InstrumentRange describes the value range of the analog data of the source. EngineeringUnit defines the unit of measure of the value the node provides. In normal operation, the determined value lies within the value range defined by the EngineeringUnitRange property. The unit of measure in the EngineeringUnit property follows UNECE Recommendation No. 20. These recommendations are based on the International System of Units (SI units). To make this additional information easier to process, the OpcAnalogItemNodeInfo class provides the corresponding interface when browsing:
var temperatureNode = client.BrowseNode("ns=2;s=Machine/Temperature") as OpcAnalogItemNodeInfo;
if (temperatureNode != null) {
Console.WriteLine($"InstrumentRange: {temperatureNode.InstrumentRange}");
Console.WriteLine($"EngineeringUnit: {temperatureNode.EngineeringUnit}");
Console.WriteLine($"EngineeringUnitRange: {temperatureNode.EngineeringUnitRange}");
}Dim temperatureNode = TryCast(client.BrowseNode("ns=2;s=Machine/Temperature"), OpcAnalogItemNodeInfo)
If temperatureNode IsNot Nothing Then
Console.WriteLine("InstrumentRange: {0}", temperatureNode.InstrumentRange)
Console.WriteLine("EngineeringUnit: {0}", temperatureNode.EngineeringUnit)
Console.WriteLine("EngineeringUnitRange: {0}", temperatureNode.EngineeringUnitRange)
End IfThe information contained in an OpcEngineeringUnitInfo describes a unit of measure from the UNECE table of units of measure. You can look up the possible units at the OPC Foundation: UNECE units of measure in OPC UA (currently unavailable). Alternatively, the MTConnect Institute also provides the UNECE table on GitHub: UNECE units of measure in OPC UA (MTConnect@GitHub).

