// This example shows different ways of constructing OPC UA node IDs.
//
// 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;
using OpcLabs.EasyOpc.UA;
using OpcLabs.EasyOpc.UA.AddressSpace;
using OpcLabs.EasyOpc.UA.AddressSpace.Parsing;
using OpcLabs.EasyOpc.UA.AddressSpace.Parsing.Extensions;
using OpcLabs.EasyOpc.UA.AddressSpace.Standard;
using OpcLabs.EasyOpc.UA.OperationModel;
namespace UACommonDocExamples._UANodeId
{
class _Construction
{
// A node ID specifies a namespace (either by an URI or by an index), and an identifier.
// The identifier can be numeric (an integer), string, GUID, or opaque.
public static void Main1()
{
// A node ID can be specified in string form (so-called expanded text).
// The code below specifies a namespace URI (nsu=...), and an integer identifier (i=...).
UANodeId nodeId1 = new UANodeId("nsu=http://test.org/UA/Data/ ;i=10853");
Console.WriteLine(nodeId1);
// Similarly, with a string identifier (s=...).
UANodeId nodeId2 = new UANodeId("nsu=http://test.org/UA/Data/ ;s=someIdentifier");
Console.WriteLine(nodeId2);
// Actually, "s=" can be omitted (not recommended, though).
UANodeId nodeId3 = new UANodeId("nsu=http://test.org/UA/Data/ ;someIdentifier");
Console.WriteLine(nodeId3);
// Notice that the output is normalized - the "s=" is added again.
// Similarly, with a GUID identifier (g=...).
UANodeId nodeId4 = new UANodeId("nsu=http://test.org/UA/Data/ ;g=BAEAF004-1E43-4A06-9EF0-E52010D5CD10");
Console.WriteLine(nodeId4);
// Notice that the output is normalized - uppercase letters in the GUI are converted to lowercase, etc.
// Similarly, with an opaque identifier (b=..., in Base64 encoding).
UANodeId nodeId5 = new UANodeId("nsu=http://test.org/UA/Data/ ;b=AP8=");
Console.WriteLine(nodeId5);
// Namespace index can be used instead of namespace URI. The server is allowed to change the namespace
// indices between sessions (except for namespace 0), and for this reason, you should avoid the use of
// namespace indices, and rather use the namespace URIs whenever possible.
UANodeId nodeId6 = new UANodeId("ns=2;i=10853");
Console.WriteLine(nodeId6);
// Namespace index can be also specified together with namespace URI. This is still safe, but may be
// a bit quicker to perform, because the client can just verify the namespace URI instead of looking
// it up.
UANodeId nodeId7 = new UANodeId("nsu=http://test.org/UA/Data/ ;ns=2;i=10853");
Console.WriteLine(nodeId7);
// When neither namespace URI nor namespace index are given, the node ID is assumed to be in namespace
// with index 0 and URI "http://opcfoundation.org/UA/", which is reserved by OPC UA standard. There are
// many standard nodes that live in this reserved namespace, but no nodes specific to your servers will
// be in the reserved namespace, and hence the need to specify the namespace with server-specific nodes.
UANodeId nodeId8 = new UANodeId("i=2254");
Console.WriteLine(nodeId8);
// If you attempt to pass in a string that does not conform to the syntax rules,
// a UANodeIdFormatException is thrown.
try
{
UANodeId nodeId9 = new UANodeId("nsu=http://test.org/UA/Data/ ;i=notAnInteger");
Console.WriteLine(nodeId9);
}
catch (UANodeIdFormatException nodeIdFormatException)
{
Console.WriteLine($"*** Failure {nodeIdFormatException.Message}");
}
// There is a parser object that can be used to parse the expanded texts of node IDs.
UANodeIdParser nodeIdParser10 = new UANodeIdParser();
UANodeId nodeId10 = nodeIdParser10.Parse("nsu=http://test.org/UA/Data/ ;i=10853");
Console.WriteLine(nodeId10);
// The parser can be used if you want to parse the expanded text of the node ID but do not want
// exceptions be thrown.
UANodeIdParser nodeIdParser11 = new UANodeIdParser();
IStringParsingError stringParsingError =
nodeIdParser11.TryParse("nsu=http://test.org/UA/Data/ ;i=notAnInteger", out UANodeId nodeId11);
if (stringParsingError is null)
Console.WriteLine(nodeId11);
else
Console.WriteLine($"*** Failure: {stringParsingError.Message}");
// You can also use the parser if you have node IDs where you want the default namespace be different
// from the standard "http://opcfoundation.org/UA/".
UANodeIdParser nodeIdParser12 = new UANodeIdParser("http://test.org/UA/Data/");
UANodeId nodeId12 = nodeIdParser12.Parse("i=10853");
Console.WriteLine(nodeId12);
// The namespace URI string (or the namespace index, or both) and the identifier can be passed to the
// constructor separately.
UANodeId nodeId13 = new UANodeId("http://test.org/UA/Data/", 10853);
Console.WriteLine(nodeId13);
// You can create a "null" node ID. Such node ID does not actually identify any valid node in OPC UA, but
// is useful as a placeholder or as a starting point for further modifications of its properties.
UANodeId nodeId14 = new UANodeId();
Console.WriteLine(nodeId14);
// Properties of a node ID can be modified individually. The advantage of this approach is that you do
// not have to care about syntax of the node ID expanded text.
UANodeId nodeId15 = new UANodeId();
nodeId15.NamespaceUriString = "http://test.org/UA/Data/";
nodeId15.Identifier = 10853;
Console.WriteLine(nodeId15);
// The same as above, but using an object initializer list.
UANodeId nodeId16 = new UANodeId
{
NamespaceUriString = "http://test.org/UA/Data/",
Identifier = 10853
};
Console.WriteLine(nodeId16);
// If you know the type of the identifier upfront, it is safer to use typed properties that correspond
// to specific types of identifier. Here, with an integer identifier.
UANodeId nodeId17 = new UANodeId();
nodeId17.NamespaceUriString = "http://test.org/UA/Data/";
nodeId17.NumericIdentifier = 10853;
Console.WriteLine(nodeId17);
// Similarly, with a string identifier.
UANodeId nodeId18 = new UANodeId();
nodeId18.NamespaceUriString = "http://test.org/UA/Data/";
nodeId18.StringIdentifier = "someIdentifier";
Console.WriteLine(nodeId18);
// Similarly, with a GUID identifier.
UANodeId nodeId19 = new UANodeId();
nodeId19.NamespaceUriString = "http://test.org/UA/Data/";
nodeId19.GuidIdentifier = Guid.Parse("BAEAF004-1E43-4A06-9EF0-E52010D5CD10");
Console.WriteLine(nodeId19);
// If you have GUID in its string form, the node ID object can parse it for you.
UANodeId nodeId20 = new UANodeId();
nodeId20.NamespaceUriString = "http://test.org/UA/Data/";
nodeId20.GuidIdentifierString = "BAEAF004-1E43-4A06-9EF0-E52010D5CD10";
Console.WriteLine(nodeId20);
// And, with an opaque identifier.
UANodeId nodeId21 = new UANodeId();
nodeId21.NamespaceUriString = "http://test.org/UA/Data/";
nodeId21.OpaqueIdentifier = new byte[] {0x00, 0xFF};
Console.WriteLine(nodeId21);
// Assigning an expanded text to a node ID parses the value being assigned and sets all corresponding
// properties accordingly.
UANodeId nodeId22 = new UANodeId();
nodeId22.ExpandedText = "nsu=http://test.org/UA/Data/ ;i=10853";
Console.WriteLine(nodeId22);
// There is an implicit conversion from a string (representing the expanded text) to a node ID.
// You can therefore use the expanded text (string) in place of any node ID object directly.
UANodeId nodeId23 = "nsu=http://test.org/UA/Data/ ;i=10853";
Console.WriteLine(nodeId23);
// There is a copy constructor as well, creating a clone of an existing node ID.
UANodeId nodeId24a = new UANodeId("nsu=http://test.org/UA/Data/ ;i=10853");
Console.WriteLine(nodeId24a);
UANodeId nodeId24b = new UANodeId(nodeId24a);
Console.WriteLine(nodeId24b);
// We have provided static classes with properties that correspond to all standard nodes specified by
// OPC UA. You can simply refer to these node IDs in your code.
// The class names are UADataTypeIds, UAMethodIds, UAObjectIds, UAObjectTypeIds, UAReferenceTypeIds,
// UAVariableIds and UAVariableTypeIds.
UANodeId nodeId25 = UAObjectIds.TypesFolder;
Console.WriteLine(nodeId25);
// When the UANodeId equals to one of the standard nodes, it is output in the shortened form - as the standard
// name only.
// You can also refer to any standard node using its name (in a string form).
// Note that assigning a non-existing standard name is not allowed, and throws ArgumentException.
UANodeId nodeId26 = new UANodeId();
nodeId26.StandardName = "TypesFolder";
Console.WriteLine(nodeId26);
// When you browse for nodes in the OPC UA server, every returned node element contains a node ID that
// you can use further.
var client27 = new EasyUAClient();
try
{
UANodeElementCollection nodeElementCollection27 = client27.Browse(
"opc.tcp://opcua.demo-this.com:51210/UA/SampleServer",
UAObjectIds.Server,
new UABrowseParameters(UANodeClass.All, new[] { UAReferenceTypeIds.References }));
if (nodeElementCollection27.Count != 0)
{
UANodeId nodeId27 = nodeElementCollection27[0].NodeId;
Console.WriteLine(nodeId27);
}
}
catch (UAException uaException)
{
Console.WriteLine("Failure: {0}", uaException.GetBaseException().Message);
}
// As above, but using a constructor that takes a node element as an input.
var client28 = new EasyUAClient();
try
{
UANodeElementCollection nodeElementCollection28 = client28.Browse(
"opc.tcp://opcua.demo-this.com:51210/UA/SampleServer",
UAObjectIds.Server,
new UABrowseParameters(UANodeClass.All, new[] { UAReferenceTypeIds.References }));
if (nodeElementCollection28.Count != 0)
{
UANodeId nodeId28 = new UANodeId(nodeElementCollection28[0]);
Console.WriteLine(nodeId28);
}
}
catch (UAException uaException)
{
Console.WriteLine("Failure: {0}", uaException.GetBaseException().Message);
}
// Or, there is an explicit conversion from a node descriptor as well.
var client29 = new EasyUAClient();
try
{
UANodeElementCollection nodeElementCollection29 = client29.Browse(
"opc.tcp://opcua.demo-this.com:51210/UA/SampleServer",
UAObjectIds.Server,
new UABrowseParameters(UANodeClass.All, new[] { UAReferenceTypeIds.References }));
if (nodeElementCollection29.Count != 0)
{
UANodeId nodeId29 = (UANodeId) nodeElementCollection29[0];
Console.WriteLine(nodeId29);
}
}
catch (UAException uaException)
{
Console.WriteLine("Failure: {0}", uaException.GetBaseException().Message);
}
}
}
}
' This example shows different ways of constructing OPC UA node IDs.
'
' 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
Imports OpcLabs.EasyOpc.UA
Imports OpcLabs.EasyOpc.UA.AddressSpace
Imports OpcLabs.EasyOpc.UA.AddressSpace.Parsing
Imports OpcLabs.EasyOpc.UA.AddressSpace.Parsing.Extensions
Imports OpcLabs.EasyOpc.UA.AddressSpace.Standard
Namespace _UANodeId
Friend Class _Construction
Public Shared Sub Main1()
' A node ID can be specified in string form (so-called expanded text).
' The code below specifies a namespace URI (nsu=...), and an integer identifier (i=...).
Dim nodeId1 = New UANodeId("nsu=http://test.org/UA/Data/ ;i=10853")
Console.WriteLine(nodeId1)
' Similarly, with a string identifier (s=...).
Dim nodeId2 = New UANodeId("nsu=http://test.org/UA/Data/ ;s=someIdentifier")
Console.WriteLine(nodeId2)
' Actually, "s=" can be omitted (not recommended, though)
Dim nodeId3 = New UANodeId("nsu=http://test.org/UA/Data/ ;someIdentifier")
Console.WriteLine(nodeId3)
' Similarly, with a GUID identifier (g=...)
Dim nodeId4 = New UANodeId("nsu=http://test.org/UA/Data/ ;g=BAEAF004-1E43-4A06-9EF0-E52010D5CD10")
Console.WriteLine(nodeId4)
' Similarly, with an opaque identifier (b=..., in Base64 encoding).
Dim nodeId5 = New UANodeId("nsu=http://test.org/UA/Data/ ;b=AP8=")
Console.WriteLine(nodeId5)
' Namespace index can be used instead of namespace URI. The server is allowed to change the namespace
' indices between sessions, and for this reason, you should avoid the use of namespace indices, and
' rather use the namespace URIs whenever possible.
Dim nodeId6 = New UANodeId("ns=2;i=10853")
Console.WriteLine(nodeId6)
' Namespace index can be also specified together with namespace URI. This is still safe, but may be
' a bit quicker to perform, because the client can just verify the namespace URI instead of looking
' it up.
Dim nodeId7 = New UANodeId("nsu=http://test.org/UA/Data/ ;ns=2;i=10853")
Console.WriteLine(nodeId7)
' When neither namespace URI nor namespace index are given, the node ID is assumed to be in namespace
' with index 0 and URI "http://opcfoundation.org/UA/", which is reserved by OPC UA standard. There are
' many standard nodes that live in this reserved namespace, but no nodes specific to your servers will
' be in the reserved namespace, and hence the need to specify the namespace with server-specific nodes.
Dim nodeId8 = New UANodeId("i=2254")
Console.WriteLine(nodeId8)
' If you attempt to pass in a string that does not conform to the syntax rules,
' a UANodeIdFormatException is thrown.
Try
Dim nodeId9 = New UANodeId("nsu=http://test.org/UA/Data/ ;i=notAnInteger")
Console.WriteLine(nodeId9)
Catch nodeIdFormatException As UANodeIdFormatException
Console.WriteLine(nodeIdFormatException.Message)
End Try
' There is a parser object that can be used to parse the expanded textx of node IDs.
Dim nodeIdParser10 = New UANodeIdParser()
Dim nodeId10 = nodeIdParser10.Parse("nsu=http://test.org/UA/Data/ ;i=10853")
Console.WriteLine(nodeId10)
' The parser can be used if you want to parse the expanded text of the node ID but do not want
' exceptions be thrown.
Dim nodeIdParser11 = New UANodeIdParser()
Dim nodeId11 As UANodeId = Nothing
Dim stringParsingError As IStringParsingError =
nodeIdParser11.TryParse("nsu=http://test.org/UA/Data/ ;i=notAnInteger", nodeId11)
If stringParsingError Is Nothing Then
Console.WriteLine(nodeId11)
Else
Console.WriteLine(stringParsingError.Message)
End If
' You can also use the parser if you have node IDs where you want the default namespace be different
' from the standard "http://opcfoundation.org/UA/".
Dim nodeIdParser12 = New UANodeIdParser("http://test.org/UA/Data/")
Dim nodeId12 = nodeIdParser12.Parse("i=10853")
Console.WriteLine(nodeId12)
' The namespace URI string (or the namespace index, or both) and the identifier can be passed to the
' constructor separately.
Dim nodeId13 = New UANodeId("http://test.org/UA/Data/", 10853)
Console.WriteLine(nodeId13)
' You can create a "null" node ID. Such node ID does not actually identify any valid node in OPC UA, but
' is useful as a placeholder or as a starting point for further modifications of its properties.
Dim nodeId14 = New UANodeId()
Console.WriteLine(nodeId14)
' Properties of a node ID can be modified individually. The advantage of this approach is that you do
' not have to care about syntax of the node ID expanded text.
Dim nodeId15 = New UANodeId()
nodeId15.NamespaceUriString = "http://test.org/UA/Data/"
nodeId15.Identifier = 10853
Console.WriteLine(nodeId15)
' The same as above, but using an object initializer list.
Dim nodeId16 = New UANodeId With
{
.NamespaceUriString = "http://test.org/UA/Data/",
.Identifier = 10853
}
Console.WriteLine(nodeId16)
' If you know the type of the identifier upfront, it is safer to use typed properties that correspond
' to specific types of identifier. Here, with an integer identifier.
Dim nodeId17 = New UANodeId()
nodeId17.NamespaceUriString = "http://test.org/UA/Data/"
nodeId17.NumericIdentifier = 10853
Console.WriteLine(nodeId17)
' Similarly, with a string identifier.
Dim nodeId18 = New UANodeId()
nodeId18.NamespaceUriString = "http://test.org/UA/Data/"
nodeId18.StringIdentifier = "someIdentifier"
Console.WriteLine(nodeId18)
' Similarly, with a GUID identifier.
Dim nodeId19 = New UANodeId()
nodeId19.NamespaceUriString = "http://test.org/UA/Data/"
nodeId19.GuidIdentifier = Guid.Parse("BAEAF004-1E43-4A06-9EF0-E52010D5CD10")
Console.WriteLine(nodeId19)
' If you have GUID in its string form, the node ID object can parse it for you.
Dim nodeId20 = New UANodeId()
nodeId20.NamespaceUriString = "http://test.org/UA/Data/"
nodeId20.GuidIdentifierString = "BAEAF004-1E43-4A06-9EF0-E52010D5CD10"
Console.WriteLine(nodeId20)
' And, with an opaque identifier.
Dim nodeId21 = New UANodeId()
nodeId21.NamespaceUriString = "http://test.org/UA/Data/"
nodeId21.OpaqueIdentifier = {&H0, &HFF}
Console.WriteLine(nodeId21)
' Assigning an expanded text to a node ID parses the value being assigned and sets all corresponding
' properties accordingly.
Dim nodeId22 = New UANodeId()
nodeId22.ExpandedText = "nsu=http://test.org/UA/Data/ ;i=10853"
Console.WriteLine(nodeId22)
' There is an implicit conversion from a string (representing the expanded text) to a node ID.
' You can therefore use the expanded text (string) in place of any node ID object directly.
Dim nodeId23 = "nsu=http://test.org/UA/Data/ ;i=10853"
Console.WriteLine(nodeId23)
' There is a copy constructor as well, creating a clone of an existing node ID.
Dim nodeId24a = New UANodeId("nsu=http://test.org/UA/Data/ ;i=10853")
Console.WriteLine(nodeId24a)
Dim nodeId24b = New UANodeId(nodeId24a)
Console.WriteLine(nodeId24b)
' We have provided static classes with properties that correspond to all standard nodes specified by
' OPC UA. You can simply refer to these node IDs in your code.
' The class names are UADataTypeIds, UAMethodIds, UAObjectIds, UAObjectTypeIds, UAReferenceTypeIds,
' UAVariableIds and UAVariableTypeIds.
Dim nodeId25 = UAObjectIds.TypesFolder
Console.WriteLine(nodeId25)
' You can also refer to any standard node using its name (in a string form).
' Note that assigning a non-existing standard name is not allowed, and throws ArgumentException.
Dim nodeId26 = New UANodeId()
nodeId26.StandardName = "TypesFolder"
Console.WriteLine(nodeId26)
' When you browse for nodes in the OPC UA server, every returned node element contains a node ID that
' you can use further.
Dim client27 = New EasyUAClient()
Dim nodeElementCollection27 = client27.Browse(
"opc.tcp://opcua.demo-this.com:51210/UA/SampleServer",
UAObjectIds.Server,
New UABrowseParameters(UANodeClass.All, {UAReferenceTypeIds.References}))
Dim nodeId27 = nodeElementCollection27(0).NodeId
Console.WriteLine(nodeId27)
' As above, but using a constructor that takes a node element as an input.
Dim client28 = New EasyUAClient()
Dim nodeElementCollection28 = client28.Browse(
"opc.tcp://opcua.demo-this.com:51210/UA/SampleServer",
UAObjectIds.Server,
New UABrowseParameters(UANodeClass.All, {UAReferenceTypeIds.References}))
Dim nodeId28 = New UANodeId(nodeElementCollection28(0))
Console.WriteLine(nodeId28)
' Or, there is an explicit conversion from a node element as well.
Dim client29 = New EasyUAClient()
Dim nodeElementCollection29 = client29.Browse(
"opc.tcp://opcua.demo-this.com:51210/UA/SampleServer",
UAObjectIds.Server,
New UABrowseParameters(UANodeClass.All, {UAReferenceTypeIds.References}))
Dim nodeId29 = CType(nodeElementCollection29(0), UANodeId)
Console.WriteLine(nodeId29)
End Sub
End Class
End Namespace
// This example shows different ways of constructing OPC UA node IDs.
//
// 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 _Construction.Main;
var
BrowseParameters: _UABrowseParameters;
Client27: _EasyUAClient;
EndpointDescriptor: _UAEndpointDescriptor;
NodeId1, NodeId2, NodeId3, NodeId4, NodeId5, NodeId6, NodeId7, NodeId8, NodeId9, NodeId10,
NodeId11, NodeId12, NodeId14, NodeId15, NodeId17, NodeId18,
NodeId20, NodeId21, NodeId26, NodeId27,
ServerNodeId, ReferencesNodeId: OpcLabs_EasyOpcUA_TLB._UANodeId;
NodeId11Result: OleVariant;
NodeIdParser10, NodeIdParser11, NodeIdParser12: _UANodeIdParser;
NodeElements27: _UANodeElementCollection;
OpaqueIdentifier21: Variant;
ServerNodeDescriptor: _UANodeDescriptor;
StringParsingError: _StringParsingError;
begin
// A node ID specifies a namespace (either by an URI or by an index), and an identifier.
// The identifier can be numeric (an integer), string, GUID, or opaque.
// A node ID can be specified in string form (so-called expanded text).
// The code below specifies a namespace URI (nsu=...), and an integer identifier (i=...).
// Assigning an expanded text to a node ID parses the value being assigned and sets all corresponding
// properties accordingly.
NodeId1 := CoUANodeId.Create;
NodeId1.ExpandedText := 'nsu=http://test.org/UA/Data/ ;i=10853';
WriteLn(NodeId1.ToString);
// Similarly, with a string identifier (s=...).
NodeId2 := CoUANodeId.Create;
NodeId2.ExpandedText := 'nsu=http://test.org/UA/Data/ ;s=someIdentifier';
WriteLn(NodeId2.ToString);
// Actually, "s=" can be omitted (not recommended, though)
NodeId3 := CoUANodeId.Create;
NodeId3.ExpandedText := 'nsu=http://test.org/UA/Data/ ;someIdentifier';
WriteLn(NodeId3.ToString);
// Notice that the output is normalized - the "s=" is added again.
// Similarly, with a GUID identifier (g=...)
NodeId4 := CoUANodeId.Create;
NodeId4.ExpandedText := 'nsu=http://test.org/UA/Data/ ;g=BAEAF004-1E43-4A06-9EF0-E52010D5CD10';
WriteLn(NodeId4.ToString);
// Notice that the output is normalized - uppercase letters in the GUI are converted to lowercase, etc.
// Similarly, with an opaque identifier (b=..., in Base64 encoding).
NodeId5 := CoUANodeId.Create;
NodeId5.ExpandedText := 'nsu=http://test.org/UA/Data/ ;b=AP8=';
WriteLn(NodeId5.ToString);
// Namespace index can be used instead of namespace URI. The server is allowed to change the namespace
// indices between sessions (except for namespace 0), and for this reason, you should avoid the use of
// namespace indices, and rather use the namespace URIs whenever possible.
NodeId6 := CoUANodeId.Create;
NodeId6.ExpandedText := 'ns=2;i=10853';
WriteLn(NodeId6.ToString);
// Namespace index can be also specified together with namespace URI. This is still safe, but may be
// a bit quicker to perform, because the client can just verify the namespace URI instead of looking
// it up.
NodeId7 := CoUANodeId.Create;
NodeId7.ExpandedText := 'nsu=http://test.org/UA/Data/ ;ns=2;i=10853';
WriteLn(NodeId7.ToString);
// When neither namespace URI nor namespace index are given, the node ID is assumed to be in namespace
// with index 0 and URI "http://opcfoundation.org/UA/", which is reserved by OPC UA standard. There are
// many standard nodes that live in this reserved namespace, but no nodes specific to your servers will
// be in the reserved namespace, and hence the need to specify the namespace with server-specific nodes.
NodeId8 := CoUANodeId.Create;
NodeId8.ExpandedText := 'i=2254';
WriteLn(NodeId8.ToString);
// If you attempt to pass in a string that does not conform to the syntax rules,
// a UANodeIdFormatException is thrown.
NodeId9 := CoUANodeId.Create;
try
NodeId9.ExpandedText := 'nsu=http://test.org/UA/Data/ ;i=notAnInteger';
WriteLn(NodeId9.ToString);
except
on E: EOleException do
begin
WriteLn(Format('*** Failure: %s', [E.BaseException.Message]));
end;
end;
// There is a parser object that can be used to parse the expanded texts of node IDs.
NodeIdParser10 := CoUANodeIdParser.Create;
NodeId10 := NodeIdParser10.Parse('nsu=http://test.org/UA/Data/ ;i=10853', False);
WriteLn(NodeId10.ToString);
// The parser can be used if you want to parse the expanded text of the node ID but do not want
// exceptions be thrown.
NodeIdParser11 := CoUANodeIdParser.Create;
StringParsingError := NodeIdParser11.TryParse('nsu=http://test.org/UA/Data/ ;i=notAnInteger', False, NodeId11Result);
if StringParsingError = nil then
begin
NodeId11 := IUnknown(NodeId11Result) as OpcLabs_EasyOpcUA_TLB._UANodeId;
WriteLn(NodeId11.ToString);
end
else
WriteLn(Format('*** Failure: %s', [StringParsingError.Message]));
// You can also use the parser if you have node IDs where you want the default namespace be different
// from the standard "http://opcfoundation.org/UA/".
NodeIdParser12 := CoUANodeIdParser.Create;
NodeIdParser12.DefaultNamespaceUriString := 'http://test.org/UA/Data/';
NodeId12 := NodeIdParser12.Parse('i=10853', False);
WriteLn(NodeId12.ToString);
// You can create a "null" node ID. Such node ID does not actually identify any valid node in OPC UA, but
// is useful as a placeholder or as a starting point for further modifications of its properties.
NodeId14 := CoUANodeId.Create;
WriteLn(NodeId14.ToString);
// Properties of a node ID can be modified individually. The advantage of this approach is that you do
// not have to care about syntax of the node ID expanded text.
NodeId15 := CoUANodeId.Create;
NodeId15.NamespaceUriString := 'http://test.org/UA/Data/';
NodeId15.Identifier := 10853;
WriteLn(NodeId15.ToString);
// If you know the type of the identifier upfront, it is safer to use typed properties that correspond
// to specific types of identifier. Here, with an integer identifier.
NodeId17 := CoUANodeId.Create;
NodeId17.NamespaceUriString := 'http://test.org/UA/Data/';
NodeId17.NumericIdentifier := 10853;
WriteLn(NodeId17.ToString);
// Similarly, with a string identifier.
NodeId18 := CoUANodeId.Create;
NodeId18.NamespaceUriString := 'http://test.org/UA/Data/';
NodeId18.StringIdentifier := 'someIdentifier';
WriteLn(NodeId18.ToString);
// If you have GUID in its string form, the node ID object can parse it for you.
NodeId20 := CoUANodeId.Create;
NodeId20.NamespaceUriString := 'http://test.org/UA/Data/';
NodeId20.GuidIdentifierString := 'BAEAF004-1E43-4A06-9EF0-E52010D5CD10';
WriteLn(NodeId20.ToString);
// And, with an opaque identifier.
NodeId21 := CoUANodeId.Create;
NodeId21.NamespaceUriString := 'http://test.org/UA/Data/';
// OpaqueIdentifier21 := VarArrayCreate ([0, 1], varByte);
OpaqueIdentifier21 := VarArrayCreate ([0, 1], varVariant);
OpaqueIdentifier21[0] := $00;
OpaqueIdentifier21[1] := $FF;
NodeId21.OpaqueIdentifier := PSafeArray (TVarData (OpaqueIdentifier21).VArray);
WriteLn(NodeId21.ToString);
// We have built-in a list of all standard nodes specified by OPC UA. You can simply refer to these node IDs in your code.
// You can refer to any standard node using its name (in a string form).
// Note that assigning a non-existing standard name is not allowed, and throws ArgumentException.
NodeId26 := CoUANodeId.Create;
NodeId26.StandardName := 'TypesFolder';
WriteLn(NodeId26.ToString);
// When the UANodeId equals to one of the standard nodes, it is output in the shortened form - as the standard name only.
// When you browse for nodes in the OPC UA server, every returned node element contains a node ID that
// you can use further.
Client27 := CoEasyUAClient.Create;
EndpointDescriptor := CoUAEndpointDescriptor.Create;
EndpointDescriptor.UrlString := 'http://opcua.demo-this.com:51211/UA/SampleServer';
// Browse from the Server node.
ServerNodeId := CoUANodeId.Create;
ServerNodeId.StandardName := 'Server';
ServerNodeDescriptor := CoUANodeDescriptor.Create;
ServerNodeDescriptor.NodeId := ServerNodeId;
// Browse all References.
ReferencesNodeId := CoUANodeId.Create;
ReferencesNodeId.StandardName := 'References';
BrowseParameters := CoUABrowseParameters.Create;
BrowseParameters.NodeClasses := UANodeClass_All; // this is the default, anyway
BrowseParameters.ReferenceTypeIds.Add(ReferencesNodeId);
try
NodeElements27 := Client27.Browse(EndpointDescriptor, ServerNodeDescriptor, BrowseParameters);
if NodeElements27.Count <> 0 then
begin
NodeId27 := NodeElements27[0].NodeId;
WriteLn(NodeId27.ToString);
end;
except
on E: EOleException do
begin
WriteLn(Format('*** Failure: %s', [E.BaseException.Message]));
end;
end;
end;
// This example shows different ways of constructing OPC UA node IDs.
//
// A node ID specifies a namespace (either by an URI or by an index), and an identifier.
// The identifier can be numeric (an integer), string, GUID, or opaque.
//
// 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.
const UANodeClass_All = 255;
// A node ID can be specified in string form (so-called expanded text).
// The code below specifies a namespace URI (nsu=...), and an integer identifier (i=...).
// Assigning an expanded text to a node ID parses the value being assigned and sets all corresponding
// properties accordingly.
$NodeId1 = new COM("OpcLabs.EasyOpc.UA.AddressSpace.UANodeId");
$NodeId1->ExpandedText = "nsu=http://test.org/UA/Data/ ;i=10853";
printf("%s\n", $NodeId1);
// Similarly, with a string identifier (s=...).
$NodeId2 = new COM("OpcLabs.EasyOpc.UA.AddressSpace.UANodeId");
$NodeId2->ExpandedText = "nsu=http://test.org/UA/Data/ ;s=someIdentifier";
printf("%s\n", $NodeId2);
// Actually, "s=" can be omitted (not recommended, though)
$NodeId3 = new COM("OpcLabs.EasyOpc.UA.AddressSpace.UANodeId");
$NodeId3->ExpandedText = "nsu=http://test.org/UA/Data/ ;someIdentifier";
printf("%s\n", $NodeId3);
// Notice that the output is normalized - the "s=" is added again.
// Similarly, with a GUID identifier (g=...)
$NodeId4 = new COM("OpcLabs.EasyOpc.UA.AddressSpace.UANodeId");
$NodeId4->ExpandedText = "nsu=http://test.org/UA/Data/ ;g=BAEAF004-1E43-4A06-9EF0-E52010D5CD10";
printf("%s\n", $NodeId4);
// Notice that the output is normalized - uppercase letters in the GUI are converted to lowercase, etc.
// Similarly, with an opaque identifier (b=..., in Base64 encoding).
$NodeId5 = new COM("OpcLabs.EasyOpc.UA.AddressSpace.UANodeId");
$NodeId5->ExpandedText = "nsu=http://test.org/UA/Data/ ;b=AP8=";
printf("%s\n", $NodeId5);
// Namespace index can be used instead of namespace URI. The server is allowed to change the namespace
// indices between sessions (except for namespace 0), and for this reason, you should avoid the use of
// namespace indices, and rather use the namespace URIs whenever possible.
$NodeId6 = new COM("OpcLabs.EasyOpc.UA.AddressSpace.UANodeId");
$NodeId6->ExpandedText = "ns=2;i=10853";
printf("%s\n", $NodeId6);
// Namespace index can be also specified together with namespace URI. This is still safe, but may be
// a bit quicker to perform, because the client can just verify the namespace URI instead of looking
// it up.
$NodeId7 = new COM("OpcLabs.EasyOpc.UA.AddressSpace.UANodeId");
$NodeId7->ExpandedText = "nsu=http://test.org/UA/Data/ ;ns=2;i=10853";
printf("%s\n", $NodeId7);
// When neither namespace URI nor namespace index are given, the node ID is assumed to be in namespace
// with index 0 and URI "http://opcfoundation.org/UA/", which is reserved by OPC UA standard. There are
// many standard nodes that live in this reserved namespace, but no nodes specific to your servers will
// be in the reserved namespace, and hence the need to specify the namespace with server-specific nodes.
$NodeId8 = new COM("OpcLabs.EasyOpc.UA.AddressSpace.UANodeId");
$NodeId8->ExpandedText = "i=2254";
printf("%s\n", $NodeId8);
// If you attempt to pass in a string that does not conform to the syntax rules,
// a UANodeIdFormatException is thrown.
$NodeId9 = new COM("OpcLabs.EasyOpc.UA.AddressSpace.UANodeId");
try
{
$NodeId9->ExpandedText = "nsu=http://test.org/UA/Data/ ;i=notAnInteger";
printf("%s\n", $NodeId9);
}
catch (com_exception $e)
{
printf("*** Failure: %s\n", $e->getMessage());
}
// There is a parser object that can be used to parse the expanded texts of node IDs.
$NodeIdParser10 = new COM("OpcLabs.EasyOpc.UA.AddressSpace.Parsing.UANodeIdParser");
$NodeId10 = $NodeIdParser10->Parse("nsu=http://test.org/UA/Data/ ;i=10853", False);
printf("%s\n", $NodeId10);
// The parser can be used if you want to parse the expanded text of the node ID but do not want
// exceptions be thrown.
$NodeId11 = new COM("OpcLabs.EasyOpc.UA.AddressSpace.UANodeId");
$NodeIdParser11 = new COM("OpcLabs.EasyOpc.UA.AddressSpace.Parsing.UANodeIdParser");
$StringParsingError = $NodeIdParser11->TryParse("nsu=http://test.org/UA/Data/ ;i=notAnInteger", False, $NodeId11);
if (is_null($StringParsingError))
printf("%s\n", $NodeId11);
else
printf("*** Failure: %s\n", $StringParsingError->Message);
// You can also use the parser if you have node IDs where you want the default namespace be different
// from the standard "http://opcfoundation.org/UA/".
$NodeIdParser12 = new COM("OpcLabs.EasyOpc.UA.AddressSpace.Parsing.UANodeIdParser");
$NodeIdParser12->DefaultNamespaceUriString = "http://test.org/UA/Data/";
$NodeId12 = $NodeIdParser12->Parse("i=10853", False);
printf("%s\n", $NodeId12);
// You can create a "null" node ID. Such node ID does not actually identify any valid node in OPC UA, but
// is useful as a placeholder or as a starting point for further modifications of its properties.
$NodeId14 = new COM("OpcLabs.EasyOpc.UA.AddressSpace.UANodeId");
printf("%s\n", $NodeId14);
// Properties of a node ID can be modified individually. The advantage of this approach is that you do
// not have to care about syntax of the node ID expanded text.
$NodeId15 = new COM("OpcLabs.EasyOpc.UA.AddressSpace.UANodeId");
$NodeId15->NamespaceUriString = "http://test.org/UA/Data/";
$NodeId15->Identifier = 10853;
printf("%s\n", $NodeId15);
// If you know the type of the identifier upfront, it is safer to use typed properties that correspond
// to specific types of identifier. Here, with an integer identifier.
$NodeId17 = new COM("OpcLabs.EasyOpc.UA.AddressSpace.UANodeId");
$NodeId17->NamespaceUriString = "http://test.org/UA/Data/";
$NodeId17->NumericIdentifier = 10853;
printf("%s\n", $NodeId17);
// Similarly, with a string identifier.
$NodeId18 = new COM("OpcLabs.EasyOpc.UA.AddressSpace.UANodeId");
$NodeId18->NamespaceUriString = "http://test.org/UA/Data/";
$NodeId18->StringIdentifier = "someIdentifier";
printf("%s\n", $NodeId18);
// If you have GUID in its string form, the node ID object can parse it for you.
$NodeId20 = new COM("OpcLabs.EasyOpc.UA.AddressSpace.UANodeId");
$NodeId20->NamespaceUriString = "http://test.org/UA/Data/";
$NodeId20->GuidIdentifierString = "BAEAF004-1E43-4A06-9EF0-E52010D5CD10";
printf("%s\n", $NodeId20);
// And, with an opaque identifier.
$NodeId21 = new COM("OpcLabs.EasyOpc.UA.AddressSpace.UANodeId");
$NodeId21->NamespaceUriString = "http://test.org/UA/Data/";
$OpaqueIdentifier21[0] = 0x00;
$OpaqueIdentifier21[1] = 0xFF;
$NodeId21->OpaqueIdentifier = $OpaqueIdentifier21;
printf("%s\n", $NodeId21);
// We have built-in a list of all standard nodes specified by OPC UA. You can simply refer to these node IDs in your code.
// You can refer to any standard node using its name (in a string form).
// Note that assigning a non-existing standard name is not allowed, and throws ArgumentException.
$NodeId26 = new COM("OpcLabs.EasyOpc.UA.AddressSpace.UANodeId");
$NodeId26->StandardName = "TypesFolder";
printf("%s\n", $NodeId26);
// When the UANodeId equals to one of the standard nodes, it is output in the shortened form - as the standard name only.
// When you browse for nodes in the OPC UA server, every returned node element contains a node ID that
// you can use further.
$Client27 = new COM("OpcLabs.EasyOpc.UA.EasyUAClient");
$EndpointDescriptor = new COM("OpcLabs.EasyOpc.UA.UAEndpointDescriptor");
$EndpointDescriptor->UrlString = "http://opcua.demo-this.com:51211/UA/SampleServer";
// Browse from the Server node.
$ServerNodeId = new COM("OpcLabs.EasyOpc.UA.AddressSpace.UANodeId");
$ServerNodeId->StandardName = "Server";
$ServerNodeDescriptor = new COM("OpcLabs.EasyOpc.UA.UANodeDescriptor");
$ServerNodeDescriptor->NodeId = $ServerNodeId;
// Browse all References.
$ReferencesNodeId = new COM("OpcLabs.EasyOpc.UA.AddressSpace.UANodeId");
$ReferencesNodeId->StandardName = "References";
$BrowseParameters = new COM("OpcLabs.EasyOpc.UA.UABrowseParameters");
$BrowseParameters->NodeClasses = UANodeClass_All; // this is the default, anyway
$BrowseParameters->ReferenceTypeIds->Add($ReferencesNodeId);
try
{
$NodeElements27 = $Client27->Browse($EndpointDescriptor, $ServerNodeDescriptor, $BrowseParameters);
if ($NodeElements27->Count != 0) {
$NodeId27 = $NodeElements27[0]->NodeId;
printf("%s\n", $NodeId27);
}
}
catch (com_exception $e)
{
printf("*** Failure: %s\n", $e->getMessage());
exit();
}
REM This example shows different ways of constructing OPC UA node IDs.
REM
REM Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
REM OPC client and subscriber examples in Visual Basic on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-VB .
REM Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
REM a commercial license in order to use Online Forums, and we reply to every post.
Private Sub Construction_Main_Command_Click()
OutputText = ""
' A node ID specifies a namespace (either by an URI or by an index), and an identifier.
' The identifier can be numeric (an integer), string, GUID, or opaque.
' A node ID can be specified in string form (so-called expanded text).
' The code below specifies a namespace URI (nsu=...), and an integer identifier (i=...).
' Assigning an expanded text to a node ID parses the value being assigned and sets all corresponding
' properties accordingly.
Dim nodeId1 As New UANodeId
nodeId1.expandedText = "nsu=http://test.org/UA/Data/ ;i=10853"
OutputText = OutputText & nodeId1 & vbCrLf
' Similarly, with a string identifier (s=...).
Dim nodeId2 As New UANodeId
nodeId2.expandedText = "nsu=http://test.org/UA/Data/ ;s=someIdentifier"
OutputText = OutputText & nodeId2 & vbCrLf
' Actually, "s=" can be omitted (not recommended, though)
Dim nodeId3 As New UANodeId
nodeId3.expandedText = "nsu=http://test.org/UA/Data/ ;someIdentifier"
OutputText = OutputText & nodeId3 & vbCrLf
' Notice that the output is normalized - the "s=" is added again.
' Similarly, with a GUID identifier (g=...)
Dim nodeId4 As New UANodeId
nodeId4.expandedText = "nsu=http://test.org/UA/Data/ ;g=BAEAF004-1E43-4A06-9EF0-E52010D5CD10"
OutputText = OutputText & nodeId4 & vbCrLf
' Notice that the output is normalized - uppercase letters in the GUI are converted to lowercase, etc.
' Similarly, with an opaque identifier (b=..., in Base64 encoding).
Dim nodeId5 As New UANodeId
nodeId5.expandedText = "nsu=http://test.org/UA/Data/ ;b=AP8="
OutputText = OutputText & nodeId5 & vbCrLf
' Namespace index can be used instead of namespace URI. The server is allowed to change the namespace
' indices between sessions (except for namespace 0), and for this reason, you should avoid the use of
' namespace indices, and rather use the namespace URIs whenever possible.
Dim nodeId6 As New UANodeId
nodeId6.expandedText = "ns=2;i=10853"
OutputText = OutputText & nodeId6 & vbCrLf
' Namespace index can be also specified together with namespace URI. This is still safe, but may be
' a bit quicker to perform, because the client can just verify the namespace URI instead of looking
' it up.
Dim nodeId7 As New UANodeId
nodeId7.expandedText = "nsu=http://test.org/UA/Data/ ;ns=2;i=10853"
OutputText = OutputText & nodeId7 & vbCrLf
' When neither namespace URI nor namespace index are given, the node ID is assumed to be in namespace
' with index 0 and URI "http://opcfoundation.org/UA/", which is reserved by OPC UA standard. There are
' many standard nodes that live in this reserved namespace, but no nodes specific to your servers will
' be in the reserved namespace, and hence the need to specify the namespace with server-specific nodes.
Dim nodeId8 As New UANodeId
nodeId8.expandedText = "i=2254"
OutputText = OutputText & nodeId8 & vbCrLf
' If you attempt to pass in a string that does not conform to the syntax rules,
' a UANodeIdFormatException is thrown.
Dim nodeId9 As New UANodeId
On Error Resume Next
nodeId9.expandedText = "nsu=http://test.org/UA/Data/ ;i=notAnInteger"
OutputText = OutputText & nodeId9 & vbCrLf
If Err.Number <> 0 Then
OutputText = OutputText & "*** Failure: " & Err.Source & ": " & Err.Description & vbCrLf
End If
On Error GoTo 0
' There is a parser object that can be used to parse the expanded texts of node IDs.
Dim nodeIdParser10 As New UANodeIdParser
Dim nodeId10 As UANodeId
Set nodeId10 = nodeIdParser10.Parse("nsu=http://test.org/UA/Data/ ;i=10853", False)
OutputText = OutputText & nodeId10 & vbCrLf
' The parser can be used if you want to parse the expanded text of the node ID but do not want
' exceptions be thrown.
Dim nodeIdParser11 As New UANodeIdParser
Dim stringParsingError As stringParsingError
Dim nodeId11 As UANodeId
Set stringParsingError = nodeIdParser11.TryParse("nsu=http://test.org/UA/Data/ ;i=notAnInteger", False, nodeId11)
If stringParsingError Is Nothing Then
OutputText = OutputText & nodeId11 & vbCrLf
Else
OutputText = OutputText & "*** Failure: " & stringParsingError.Message & vbCrLf
End If
' You can also use the parser if you have node IDs where you want the default namespace be different
' from the standard "http://opcfoundation.org/UA/".
Dim nodeIdParser12 As New UANodeIdParser
nodeIdParser12.DefaultNamespaceUriString = "http://test.org/UA/Data/"
Dim nodeId12 As UANodeId
Set nodeId12 = nodeIdParser12.Parse("i=10853", False)
OutputText = OutputText & nodeId12 & vbCrLf
' You can create a "null" node ID. Such node ID does not actually identify any valid node in OPC UA, but
' is useful as a placeholder or as a starting point for further modifications of its properties.
Dim nodeId14 As New UANodeId
OutputText = OutputText & nodeId14 & vbCrLf
' If you know the type of the identifier upfront, it is safer to use typed properties that correspond
' to specific types of identifier. Here, with an integer identifier.
Dim nodeId17 As New UANodeId
nodeId17.NamespaceUriString = "http://test.org/UA/Data/"
nodeId17.NumericIdentifier = 10853
OutputText = OutputText & nodeId17 & vbCrLf
' Similarly, with a string identifier.
Dim nodeId18 As New UANodeId
nodeId18.NamespaceUriString = "http://test.org/UA/Data/"
nodeId18.StringIdentifier = "someIdentifier"
OutputText = OutputText & nodeId18 & vbCrLf
' If you have GUID in its string form, the node ID object can parse it for you.
Dim nodeId20 As New UANodeId
nodeId20.NamespaceUriString = "http://test.org/UA/Data/"
nodeId20.GuidIdentifierString = "BAEAF004-1E43-4A06-9EF0-E52010D5CD10"
OutputText = OutputText & nodeId20 & vbCrLf
' And, with an opaque identifier.
Dim nodeId21 As New UANodeId
nodeId21.NamespaceUriString = "http://test.org/UA/Data/"
Dim opaqueIdentifier21(1) As Byte
opaqueIdentifier21(0) = &H0&
opaqueIdentifier21(1) = &HFF&
nodeId21.SetOpaqueIdentifier opaqueIdentifier21
OutputText = OutputText & nodeId21 & vbCrLf
' We have built-in a list of all standard nodes specified by OPC UA. You can simply refer to these node IDs in your code.
' You can refer to any standard node using its name (in a string form).
' Note that assigning a non-existing standard name is not allowed, and throws ArgumentException.
Dim nodeId26 As New UANodeId
nodeId26.StandardName = "TypesFolder"
OutputText = OutputText & nodeId26 & vbCrLf
' When the UANodeId equals to one of the standard nodes, it is output in the shortened form - as the standard name only.
' When you browse for nodes in the OPC UA server, every returned node element contains a node ID that
' you can use further.
Dim client27 As New EasyUAClient
Dim endpointDescriptor As New UAEndpointDescriptor
endpointDescriptor.UrlString = "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer"
' Browse from the Server node.
Dim serverNodeId As New UANodeId
serverNodeId.StandardName = "Server"
Dim serverNodedescriptor As New UANodeDescriptor
Set serverNodedescriptor.NodeId = serverNodeId
' Browse all References.
Dim referencesNodeId As New UANodeId
referencesNodeId.StandardName = "References"
Dim browseParameters As New UABrowseParameters
browseParameters.NodeClasses = UANodeClass_All ' this is the default, anyway
browseParameters.ReferenceTypeIds.Add referencesNodeId
On Error Resume Next
Dim nodeElements27 As UANodeElementCollection
Set nodeElements27 = client27.Browse(endpointDescriptor, serverNodedescriptor, browseParameters)
If Err.Number <> 0 Then
OutputText = OutputText & "*** Failure: " & Err.Source & ": " & Err.Description & vbCrLf
Exit Sub
End If
On Error GoTo 0
If nodeElements27.Count <> 0 Then
Dim nodeId27 As UANodeId
Set nodeId27 = nodeElements27(0).NodeId
OutputText = OutputText & nodeId27 & vbCrLf
End If
End Sub
Rem This example shows different ways of constructing OPC UA node IDs.
Rem
Rem Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
Rem OPC client and subscriber examples in VBScript on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-VBScript .
Rem Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
Rem a commercial license in order to use Online Forums, and we reply to every post.
Option Explicit
' A node ID specifies a namespace (either by an URI or by an index), and an identifier.
' The identifier can be numeric (an integer), string, GUID, or opaque.
Const UANodeClass_All = 255
' A node ID can be specified in string form (so-called expanded text).
' The code below specifies a namespace URI (nsu=...), and an integer identifier (i=...).
' Assigning an expanded text to a node ID parses the value being assigned and sets all corresponding
' properties accordingly.
Dim NodeId1: Set NodeId1 = CreateObject("OpcLabs.EasyOpc.UA.AddressSpace.UANodeId")
NodeId1.ExpandedText = "nsu=http://test.org/UA/Data/ ;i=10853"
WScript.Echo NodeId1
' Similarly, with a string identifier (s=...).
Dim NodeId2: Set NodeId2 = CreateObject("OpcLabs.EasyOpc.UA.AddressSpace.UANodeId")
NodeId2.ExpandedText = "nsu=http://test.org/UA/Data/ ;s=someIdentifier"
WScript.Echo NodeId2
' Actually, "s=" can be omitted (not recommended, though)
Dim NodeId3: Set NodeId3 = CreateObject("OpcLabs.EasyOpc.UA.AddressSpace.UANodeId")
NodeId3.ExpandedText = "nsu=http://test.org/UA/Data/ ;someIdentifier"
WScript.Echo NodeId3
' Notice that the output is normalized - the "s=" is added again.
' Similarly, with a GUID identifier (g=...)
Dim NodeId4: Set NodeId4 = CreateObject("OpcLabs.EasyOpc.UA.AddressSpace.UANodeId")
NodeId4.ExpandedText = "nsu=http://test.org/UA/Data/ ;g=BAEAF004-1E43-4A06-9EF0-E52010D5CD10"
WScript.Echo NodeId4
' Notice that the output is normalized - uppercase letters in the GUI are converted to lowercase, etc.
' Similarly, with an opaque identifier (b=..., in Base64 encoding).
Dim NodeId5: Set NodeId5 = CreateObject("OpcLabs.EasyOpc.UA.AddressSpace.UANodeId")
NodeId5.ExpandedText = "nsu=http://test.org/UA/Data/ ;b=AP8="
WScript.Echo NodeId5
' Namespace index can be used instead of namespace URI. The server is allowed to change the namespace
' indices between sessions (except for namespace 0), and for this reason, you should avoid the use of
' namespace indices, and rather use the namespace URIs whenever possible.
Dim NodeId6: Set NodeId6 = CreateObject("OpcLabs.EasyOpc.UA.AddressSpace.UANodeId")
NodeId6.ExpandedText = "ns=2;i=10853"
WScript.Echo NodeId6
' Namespace index can be also specified together with namespace URI. This is still safe, but may be
' a bit quicker to perform, because the client can just verify the namespace URI instead of looking
' it up.
Dim NodeId7: Set NodeId7 = CreateObject("OpcLabs.EasyOpc.UA.AddressSpace.UANodeId")
NodeId7.ExpandedText = "nsu=http://test.org/UA/Data/ ;ns=2;i=10853"
WScript.Echo NodeId7
' When neither namespace URI nor namespace index are given, the node ID is assumed to be in namespace
' with index 0 and URI "http://opcfoundation.org/UA/", which is reserved by OPC UA standard. There are
' many standard nodes that live in this reserved namespace, but no nodes specific to your servers will
' be in the reserved namespace, and hence the need to specify the namespace with server-specific nodes.
Dim NodeId8: Set NodeId8 = CreateObject("OpcLabs.EasyOpc.UA.AddressSpace.UANodeId")
NodeId8.ExpandedText = "i=2254"
WScript.Echo NodeId8
' If you attempt to pass in a string that does not conform to the syntax rules,
' a UANodeIdFormatException is thrown.
Dim NodeId9: Set NodeId9 = CreateObject("OpcLabs.EasyOpc.UA.AddressSpace.UANodeId")
On Error Resume Next
NodeId9.ExpandedText = "nsu=http://test.org/UA/Data/ ;i=notAnInteger"
If Err.Number = 0 Then
WScript.Echo NodeId9
Else
WScript.Echo "*** Failure: " & Err.Source & ": " & Err.Description
End If
On Error Goto 0
' There is a parser object that can be used to parse the expanded texts of node IDs.
Dim NodeIdParser10: Set NodeIdParser10 = CreateObject("OpcLabs.EasyOpc.UA.AddressSpace.Parsing.UANodeIdParser")
Dim NodeId10: Set NodeId10 = NodeIdParser10.Parse("nsu=http://test.org/UA/Data/ ;i=10853", False)
WScript.Echo NodeId10
' The parser can be used if you want to parse the expanded text of the node ID but do not want
' exceptions be thrown.
Dim NodeIdParser11: Set NodeIdParser11 = CreateObject("OpcLabs.EasyOpc.UA.AddressSpace.Parsing.UANodeIdParser")
Dim NodeId11
Dim StringParsingError: Set StringParsingError = NodeIdParser11.TryParse("nsu=http://test.org/UA/Data/ ;i=notAnInteger", False, NodeId11)
If StringParsingError Is Nothing Then
WScript.Echo NodeId11
Else
WScript.Echo "*** Failure: " & StringParsingError.Message
End If
' You can also use the parser if you have node IDs where you want the default namespace be different
' from the standard "http://opcfoundation.org/UA/".
Dim NodeIdParser12: Set NodeIdParser12 = CreateObject("OpcLabs.EasyOpc.UA.AddressSpace.Parsing.UANodeIdParser")
NodeIdParser12.DefaultNamespaceUriString = "http://test.org/UA/Data/"
Dim NodeId12: Set NodeId12 = NodeIdParser12.Parse("i=10853", False)
WScript.Echo NodeId12
' You can create a "null" node ID. Such node ID does not actually identify any valid node in OPC UA, but
' is useful as a placeholder or as a starting point for further modifications of its properties.
Dim NodeId14: Set NodeId14 = CreateObject("OpcLabs.EasyOpc.UA.AddressSpace.UANodeId")
WScript.Echo NodeId14
' Properties of a node ID can be modified individually. The advantage of this approach is that you do
' not have to care about syntax of the node ID expanded text.
Dim NodeId15: Set NodeId15 = CreateObject("OpcLabs.EasyOpc.UA.AddressSpace.UANodeId")
NodeId15.NamespaceUriString = "http://test.org/UA/Data/"
NodeId15.Identifier = 10853
WScript.Echo NodeId15
' If you know the type of the identifier upfront, it is safer to use typed properties that correspond
' to specific types of identifier. Here, with an integer identifier.
Dim NodeId17: Set NodeId17 = CreateObject("OpcLabs.EasyOpc.UA.AddressSpace.UANodeId")
NodeId17.NamespaceUriString = "http://test.org/UA/Data/"
NodeId17.NumericIdentifier = 10853
WScript.Echo NodeId17
' Similarly, with a string identifier.
Dim NodeId18: Set NodeId18 = CreateObject("OpcLabs.EasyOpc.UA.AddressSpace.UANodeId")
NodeId18.NamespaceUriString = "http://test.org/UA/Data/"
NodeId18.StringIdentifier = "someIdentifier"
WScript.Echo NodeId18
' If you have GUID in its string form, the node ID object can parse it for you.
Dim NodeId20: Set NodeId20 = CreateObject("OpcLabs.EasyOpc.UA.AddressSpace.UANodeId")
NodeId20.NamespaceUriString = "http://test.org/UA/Data/"
NodeId20.GuidIdentifierString = "BAEAF004-1E43-4A06-9EF0-E52010D5CD10"
WScript.Echo NodeId20
' And, with an opaque identifier.
Dim NodeId21: Set NodeId21 = CreateObject("OpcLabs.EasyOpc.UA.AddressSpace.UANodeId")
NodeId21.NamespaceUriString = "http://test.org/UA/Data/"
NodeId21.OpaqueIdentifier = Array(&H00, &HFF)
WScript.Echo NodeId21
' We have built-in a list of all standard nodes specified by OPC UA. You can simply refer to these node IDs in your code.
' You can refer to any standard node using its name (in a string form).
' Note that assigning a non-existing standard name is not allowed, and throws ArgumentException.
Dim NodeId26: Set NodeId26 = CreateObject("OpcLabs.EasyOpc.UA.AddressSpace.UANodeId")
NodeId26.StandardName = "TypesFolder"
WScript.Echo NodeId26
' When the UANodeId equals to one of the standard nodes, it is output in the shortened form - as the standard name only.
' When you browse for nodes in the OPC UA server, every returned node element contains a node ID that
' you can use further.
Dim Client27: Set Client27 = CreateObject("OpcLabs.EasyOpc.UA.EasyUAClient")
Dim EndpointDescriptor: Set EndpointDescriptor = CreateObject("OpcLabs.EasyOpc.UA.UAEndpointDescriptor")
EndpointDescriptor.UrlString = "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer"
' Browse from the Server node.
Dim ServerNodeId: Set ServerNodeId = CreateObject("OpcLabs.EasyOpc.UA.AddressSpace.UANodeId")
ServerNodeId.StandardName = "Server"
Dim ServerNodeDescriptor: Set ServerNodeDescriptor = CreateObject("OpcLabs.EasyOpc.UA.UANodeDescriptor")
ServerNodeDescriptor.NodeId = ServerNodeId
' Browse all References.
Dim ReferencesNodeId: Set ReferencesNodeId = CreateObject("OpcLabs.EasyOpc.UA.AddressSpace.UANodeId")
ReferencesNodeId.StandardName = "References"
'
Dim BrowseParameters: Set BrowseParameters = CreateObject("OpcLabs.EasyOpc.UA.UABrowseParameters")
BrowseParameters.NodeClasses = UANodeClass_All ' this is the default, anyway
BrowseParameters.ReferenceTypeIds.Add ReferencesNodeId
'
On Error Resume Next
Dim NodeElementCollection27: Set NodeElementCollection27 = Client27.Browse( _
EndpointDescriptor, ServerNodeDescriptor, BrowseParameters)
If Err.Number = 0 Then
If NodeElementCollection27.Count <> 0 Then
Dim NodeId27: Set NodeId27 = NodeElementCollection27(0).NodeId
WScript.Echo NodeId27
End If
Else
WScript.Echo "*** Failure: " & Err.Source & ": " & Err.Description
End If
On Error Goto 0
# This example shows different ways of constructing OPC UA node IDs.
#
# 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.EasyOpc.UA import *
from OpcLabs.EasyOpc.UA.AddressSpace import *
from OpcLabs.EasyOpc.UA.AddressSpace.Parsing import *
from OpcLabs.EasyOpc.UA.AddressSpace.Parsing.Extensions import *
from OpcLabs.EasyOpc.UA.AddressSpace.Standard import *
# A node ID specifies a namespace (either by an URI or by an index), and an identifier.
# The identifier can be numeric (an integer), string, GUID, or opaque.
#
# A node ID can be specified in string form (so-called expanded text).
# The code below specifies a namespace URI (nsu=...), and an integer identifier (i=...).
nodeId1 = UANodeId('nsu=http://test.org/UA/Data/ ;i=10853')
print(nodeId1)
# Similarly, with a string identifier (s=...).
nodeId2 = UANodeId('nsu=http://test.org/UA/Data/ ;s=someIdentifier')
print(nodeId2)
# Actually, "s=" can be omitted (not recommended, though).
nodeId3 = UANodeId('nsu=http://test.org/UA/Data/ ;someIdentifier')
print(nodeId3)
# Similarly, with a GUID identifier (g=...).
nodeId4 = UANodeId('nsu=http://test.org/UA/Data/ ;g=BAEAF004-1E43-4A06-9EF0-E52010D5CD10')
print(nodeId4)
# Similarly, with an opaque identifier (b=..., in Base64 encoding).
nodeId5 = UANodeId('nsu=http://test.org/UA/Data/ ;b=AP8=')
print(nodeId5)
# Namespace index can be used instead of namespace URI. The server is allowed to change the namespace
# indices between sessions (except for namespace 0), and for this reason, you should avoid the use of
# namespace indices, and rather use the namespace URIs whenever possible.
nodeId6 = UANodeId('ns=2;i=10853')
print(nodeId6)
# Namespace index can be also specified together with namespace URI. This is still safe, but may be
# a bit quicker to perform, because the client can just verify the namespace URI instead of looking
# it up.
nodeId7 = UANodeId('nsu=http://test.org/UA/Data/ ;ns=2;i=10853')
print(nodeId7)
# When neither namespace URI nor namespace index are given, the node ID is assumed to be in namespace
# with index 0 and URI "http://opcfoundation.org/UA/", which is reserved by OPC UA standard. There are
# many standard nodes that live in this reserved namespace, but no nodes specific to your servers will
# be in the reserved namespace, and hence the need to specify the namespace with server-specific nodes.
nodeId8 = UANodeId('i=2254')
print(nodeId8)
# If you attempt to pass in a string that does not conform to the syntax rules,
# a UANodeIdFormatException is thrown.
try:
nodeId9 = UANodeId('nsu=http://test.org/UA/Data/ ;i=notAnInteger')
except UANodeIdFormatException as nodeIdFormatException:
print('*** Failure: ', nodeIdFormatException.Message, sep='')
# There is a parser object that can be used to parse the expanded texts of node IDs.
nodeIdParser10 = UANodeIdParser()
nodeId10 = IUANodeIdParserExtension.Parse(nodeIdParser10, 'nsu=http://test.org/UA/Data/ ;i=10853')
print(nodeId10)
# The parser can be used if you want to parse the expanded text of the node ID but do not want
# exceptions be thrown.
nodeIdParser11 = UANodeIdParser()
stringParsingError, nodeId11 = IUANodeIdParserExtension.TryParse(nodeIdParser11,
'nsu=http://test.org/UA/Data/ ;i=notAnInteger',
UANodeId()) # placeholder for 'out'
if stringParsingError is None:
print(nodeId11)
else:
print('*** Failure: ', stringParsingError.Message, sep='')
# You can also use the parser if you have node IDs where you want the default namespace be different
# from the standard "http://opcfoundation.org/UA/".
nodeIdParser12 = UANodeIdParser('http://test.org/UA/Data/')
nodeId12 = IUANodeIdParserExtension.Parse(nodeIdParser12, 'i=10853')
print(nodeId12)
# The namespace URI string (or the namespace index, or both) and the identifier can be passed to the
# constructor separately.
nodeId13 = UANodeId('http://test.org/UA/Data/', 10853)
print(nodeId13)
# You can create a "null" node ID. Such node ID does not actually identify any valid node in OPC UA, but
# is useful as a placeholder or as a starting point for further modifications of its properties.
nodeId14 = UANodeId()
print(nodeId14)
# Properties of a node ID can be modified individually. The advantage of this approach is that you do
# not have to care about syntax of the node ID expanded text.
nodeId15 = UANodeId()
nodeId15.NamespaceUriString = 'http://test.org/UA/Data/'
nodeId15.Identifier = 10853
print(nodeId15)
# If you know the type of the identifier upfront, it is safer to use typed properties that correspond
# to specific types of identifier. Here, with an integer identifier.
nodeId17 = UANodeId()
nodeId17.NamespaceUriString = 'http://test.org/UA/Data/'
nodeId17.NumericIdentifier = 10853
print(nodeId17)
# Similarly, with a string identifier.
nodeId18 = UANodeId()
nodeId18.NamespaceUriString = 'http://test.org/UA/Data/'
nodeId18.StringIdentifier = 'someIdentifier'
print(nodeId18)
# Similarly, with a GUID identifier.
nodeId19 = UANodeId()
nodeId19.NamespaceUriString = 'http://test.org/UA/Data/'
nodeId19.GuidIdentifier = Guid.Parse('BAEAF004-1E43-4A06-9EF0-E52010D5CD10')
print(nodeId19)
# If you have GUID in its string form, the node ID object can parse it for you.
nodeId20 = UANodeId()
nodeId20.NamespaceUriString = 'http://test.org/UA/Data/'
nodeId20.GuidIdentifierString = 'BAEAF004-1E43-4A06-9EF0-E52010D5CD10'
print(nodeId20)
# And, with an opaque identifier.
nodeId21 = UANodeId()
nodeId21.NamespaceUriString = 'http://test.org/UA/Data/'
nodeId21.OpaqueIdentifier = [0x00, 0xFF]
print(nodeId21)
# Assigning an expanded text to a node ID parses the value being assigned and sets all corresponding
# properties accordingly.
nodeId22 = UANodeId()
nodeId22.ExpandedText = 'nsu=http://test.org/UA/Data/ ;i=10853'
print(nodeId22)
# There is a copy constructor as well, creating a clone of an existing node ID.
nodeId24a = UANodeId('nsu=http://test.org/UA/Data/ ;i=10853')
print(nodeId24a)
nodeId24b = UANodeId(nodeId24a)
print(nodeId24b)
# We have provided static classes with properties that correspond to all standard nodes specified by
# OPC UA. You can simply refer to these node IDs in your code.
# The class names are UADataTypeIds, UAMethodIds, UAObjectIds, UAObjectTypeIds, UAReferenceTypeIds,
# UAVariableIds and UAVariableTypeIds.
nodeId25 = UAObjectIds.TypesFolder
print(nodeId25)
# When the UANodeId equals to one of the standard nodes, it is output in the shortened form - as the standard
# name only.
# You can also refer to any standard node using its name (in a string form).
# Note that assigning a non-existing standard name is not allowed, and throws ArgumentException.
nodeId26 = UANodeId()
nodeId26.StandardName = "TypesFolder"
print(nodeId26)
# When you browse for nodes in the OPC UA server, every returned node element contains a node ID that
# you can use further.
client27 = EasyUAClient()
try:
nodeElementCollection27 = IEasyUAClientExtension.Browse(client27,
UAEndpointDescriptor('opc.tcp://opcua.demo-this.com:51210/UA/SampleServer'),
UANodeDescriptor(UAObjectIds.Server),
UABrowseParameters(UANodeClass.All, UAReferenceTypeIds.References))
if nodeElementCollection27.Count != 0:
nodeId27 = nodeElementCollection27.get_Item(0).NodeId
print(nodeId27)
except UAException as uaException:
print('*** Failure: ', uaException.GetBaseException().Message, sep='')
# As above, but using a constructor that takes a node element as an input.
client28 = EasyUAClient()
try:
nodeElementCollection28 = IEasyUAClientExtension.Browse(client28,
UAEndpointDescriptor('opc.tcp://opcua.demo-this.com:51210/UA/SampleServer'),
UANodeDescriptor(UAObjectIds.Server),
UABrowseParameters(UANodeClass.All, UAReferenceTypeIds.References))
if nodeElementCollection28.Count != 0:
nodeId28 = UANodeId(nodeElementCollection28.get_Item(0))
print(nodeId28)
except UAException as uaException:
print('*** Failure: ', uaException.GetBaseException().Message, sep='')
# Or, there is an explicit conversion from a node descriptor as well.
client29 = EasyUAClient()
try:
nodeElementCollection29 = IEasyUAClientExtension.Browse(client29,
UAEndpointDescriptor('opc.tcp://opcua.demo-this.com:51210/UA/SampleServer'),
UANodeDescriptor(UAObjectIds.Server),
UABrowseParameters(UANodeClass.All, UAReferenceTypeIds.References))
if nodeElementCollection29.Count != 0:
# FromUANodeDescriptor can be used instead of op_Explicit, too.
nodeId29 = UANodeId.op_Explicit(UANodeDescriptor(nodeElementCollection29.get_Item(0)))
print(nodeId29)
except UAException as uaException:
print('*** Failure: ', uaException.GetBaseException().Message, sep='')
print()
print('Finished.')