13:00, EEST
May 24, 2013
I am writing a client that will connect to an OPC UA server. After connecting, it needs to subscribe to all devices on that server.
Currently, I have a hierarchical search through the entire address space and subscribe to a node if I consider it a device. What is the best way to see if the type of the node is a device that I can read values from? I was testing on an Ignition server and checking if the UaType#DisplayName was “VariableNode” worked, but this doesn’t work for another Prosys OPC UA Server that I just set up.
I have 2 main questions:
1) Is there a better way to query the address space for just devices?
2) If I need to do a hierarchical search, how do I determine if a node is a readable device?
Thanks,
Troy
14:10, EEST
December 21, 2011
You should look at the TypeDefinition of the node, i.e. the target of the HasTypeDefinition reference.
You can use UaClient.getAddressSpace().getNode() to get the respective node object from the address space. If this is UaInstance, you can get the type from getTypeDefinition(). You can use UaType.inheritsFrom() to verify if it is a subtype of a known ObjectType or VariableType.
1) OPC UA defines a Query service, but I have not yet seen a server that would implement it – our SDK does not do that either.
2) All variable nodes have the Value property – and you can check AccessLevel/UserAccessLevel whether it contains CurrentRead. It is not available in the “device” level, which is an object, instead of a variable.
15:49, EEST
May 24, 2013
Thanks Jouni, that’s really helpful.
Using UaExpert, I can see the AccessLevel and UserAccessLevel attributes of each node but I can’t seem to find those within the Client SDK.
Here’s what I have to iterate through the address space:
// Grab our address space and grab all references at the root
AddressSpace addressSpace = client.getAddressSpace();
addressSpace.setReferenceTypeId(Identifiers.HierarchicalReferences);
List references = addressSpace.browse(Identifiers.RootFolder);
// While we still have a reference to do work with
while(!references.isEmpty())
{
// Grab the last reference in our list
ReferenceDescription reference = references.remove(references.size() – 1);
// Grab all children of that reference
List iReferences = addressSpace.browse(addressSpace.getNamespaceTable().toNodeId(reference.getNodeId()));
// For each child, add it to our list to check for any sub nodes
for (int i = 0; i < iReferences.size(); i++)
{
ReferenceDescription iReference = iReferences.get(i);
references.add(iReference);
}
// Grab the node of the current reference
UaNode uaNode = addressSpace.getNode(reference.getNodeId());
if (uaNode instanceof UaInstance)
{
// Grab the type for this node
UaNode uaType = ((UaInstance) uaNode).getTypeDefinition();
}
How am I supposed to go from the current reference/UaNode/ UaType to a UserAccessLevel attribute?
Thanks,
Troy
17:52, EEST
May 24, 2013
Okay, I figured out my last post.
I’m currently doing:
if (uaNode instanceof UaVariable)
{
UaVariable uaVariable = ((UaVariable) uaNode);
for (AccessLevel level : uaVariable.getUserAccessLevel())
{
if (level.compareTo(AccessLevel.CurrentRead) == 0)
{
subscribeToNode(node);
break;
}
}
}
This however subscribes to any node that is readable which is not what I want. How can I do the inerhitsFrom check as well? I tried uaType.inheritsFrom(NodeType.VariableNode) but it’s a type mismatch.
Thanks,
Troy
18:19, EEST
December 21, 2011
Great, looks like you are progressing.
This however subscribes to any node that is readable which is not what I want. How can I do the inerhitsFrom check as well? I tried uaType.inheritsFrom(NodeType.VariableNode) but it’s a type mismatch.
You need to find a Type Node from the address space that you check against. If you know the NodeId of the type, just get it with
and check against that.
NodeType is an unused enumeration (I was not even aware there is such 🙂 It seems that it is a left-over from a very early design, which was forgotten in UaNode. The node classes are available from UaNode.getNodeClass() – and they just provide the major classification between UA node classes. The types on the other hand are defined by type nodes (of NodeClass=ObjectType or NodeClass=VariableType).
You can actually browse the address space also from each Node object, by getting the References of it. No need to call browse manually then. But it’s more a matter of taste, which is more convenient for you.
Most Users Ever Online: 1919
Currently Online:
26 Guest(s)
Currently Browsing this Page:
1 Guest(s)
Top Posters:
Heikki Tahvanainen: 402
hbrackel: 144
rocket science: 88
pramanj: 86
Francesco Zambon: 83
Ibrahim: 78
Sabari: 62
kapsl: 57
gjevremovic: 49
Xavier: 43
Member Stats:
Guest Posters: 0
Members: 727
Moderators: 7
Admins: 1
Forum Stats:
Groups: 3
Forums: 15
Topics: 1525
Posts: 6456
Newest Members:
ernestoportus31, martin123, rickie5305, shaylamaggard4, rickyjuarez140, jonathonmcintyre, fannielima, kristiewinkle8, rust, christamcdowallModerators: Jouni Aro: 1026, Pyry: 1, Petri: 0, Bjarne Boström: 1028, Jimmy Ni: 26, Matti Siponen: 346, Lusetti: 0
Administrators: admin: 1