Avatar

Please consider registering
guest

sp_LogInOut Log In sp_Registration Register

Register | Lost password?
Advanced Search

— Forum Scope —




— Match —





— Forum Options —





Minimum search word length is 3 characters - maximum search word length is 84 characters

sp_Feed Topic RSS sp_TopicIcon
addressspace.getNodeId(nodeId) vs readAttributes(nodeId, ...)
September 15, 2016
15:50, EEST
Avatar
gjevremovic
Member
Members
Forum Posts: 49
Member Since:
January 30, 2014
sp_UserOfflineSmall Offline

Hi,
we found that call of getNodeId(nodeId) which returns UaNode is very slow. It is significant especially if server is not in local network.
We reduced the browsing time of server when this method was replaced with readAttributes.
Do you know what is the reason for this behavior?

BR,
Goran

September 15, 2016
17:12, EEST
Avatar
Heikki Tahvanainen
Member
Members
Forum Posts: 402
Member Since:
April 17, 2013
sp_UserOfflineSmall Offline

Hello,

The AddressSpace.getNode method initializes all kinds of information about the UaNode in question: it reads common attributes of the node and in addition to that, attributes that are specific to the NodeClass in question. The method also browses the properties of the node and initializes the Properties into the node object.

UaClient.readAttributes method instead makes a single read service call to the OPC UA server.

So, if you just need to read some attributes as fast as possible, you should indeed use the UaClient.readAttributes method or actually the UaClient.read which allows for the most customizations. In general case the assumption is that the NodeCache concept and initializations of AddressSpace.getNode pay off and this is the recommended way to use the SDK.

September 16, 2016
12:48, EEST
Avatar
gjevremovic
Member
Members
Forum Posts: 49
Member Since:
January 30, 2014
sp_UserOfflineSmall Offline

Thanks, yes in this case fastest as possible as we reduced traversing server address space more then 10 times. Server is on different subnet, via vpn,…
Now traversing with client.readAttributes last less then 5min instead more then 1h. Are there some settings in AddressSpace that can influence getNode to be quicker?
BR,
Goran

September 16, 2016
14:49, EEST
Avatar
Heikki Tahvanainen
Member
Members
Forum Posts: 402
Member Since:
April 17, 2013
sp_UserOfflineSmall Offline

Oh, that is indeed a long time.

Can you provide some information about your application scenario so that we can understand why you are traversing so many nodes and if there’s something in the SDK that just doesn’t work in this situation? How much time does it take to just ping the server from the client machine? If there’s some details that you do not wish to share here on forum, you can contact us by email at uajava-support mailing list.

You can tune the NodeCache size and set the maximum time to keep nodes in the cache which may help with getNode performance in some situations. Please see the methods

AddressSpace.getCache().setMaxQueueLength

AddressSpace.getCache().setNodeMaxAgeInMillis
September 23, 2016
16:47, EEST
Avatar
gjevremovic
Member
Members
Forum Posts: 49
Member Since:
January 30, 2014
sp_UserOfflineSmall Offline

Hi,
sorry for late answer. Scenario is simple I think. It is just collecting of server address space info (mostly about variables) which can be used
later in the form of xml. Program starts from starting node, get all references and go further to next node, …
Ping to server at different network is 60ms.
At one line as I wrote we just replaced getNodeId(nodeId) with readAttributes(…) and program significantly speed up.
As you wrote because of additional readings of getNodeId it is slower than readAttributes but that wasn’t visible in local environment where speed of traversing was ok.
I tried tweak methods for cache but I didn’t see any difference.
Anyway, solution with readAttributes in this scenario is suitable too.

BR,
jev

September 23, 2016
17:59, EEST
Avatar
Heikki Tahvanainen
Member
Members
Forum Posts: 402
Member Since:
April 17, 2013
sp_UserOfflineSmall Offline

Hello,

Thanks for the information. You have a special application scenario and this also leads to special requirements. Just for curiosity, I must ask why are you storing the address space to xml?

For the best performance of browsing and reading available in the Prosys OPC UA Java SDK, I suggest that you only use AddressSpace.browse and UaClient.read methods. These offer only the simplest interface but also no time consuming side effects.

The ping to the server is 60 ms which is not especially slow but still influences the sequential browsing and reading. There’s also asynchronous versions of the above mentioned methods which you should take a look at. These are AddressSpace.browseAsync and UaClient.readAsync.

After talking about the read and browsing performance, in the end I would like to mention that the biggest performance gain would be achieved if the server would generate the file for you without multiple browse and read calls. The specification part 5 defines AddressSpaceFileType with method named ExportNamespace which may be intended for similar kind of purpose what you have in this case. Unfortunately this is not implemented in the Java SDK at the moment but depending on what server application you use, this may be one option for you. And if you control the server application yourself, you could implement similar kind of method yourself.

September 30, 2016
10:58, EEST
Avatar
gjevremovic
Member
Members
Forum Posts: 49
Member Since:
January 30, 2014
sp_UserOfflineSmall Offline

Hi,
Thank you for a new tips especially related to AddressSpaceFileType. I will take a look that part. We dill with couple of opcua servers (some of them implements very limited set of opcua spec) and only one is controlled by us. Unfortunately I can conclude that in the world of opcua server providers situation is not very good. Most of them do not follow 100% spec and some of them provides very logic explanation for something which is not by spec but also it is not forbidden by spec:) Maybe because opcua spec grows too much.
>> ust for curiosity, I must ask why are you storing the address space to xml?
For client application design time which is off-line. Besides it is exported in special format suitable for existing tools set.

BR,
jev

September 14, 2020
22:30, EEST
Avatar
michaeldegli
New Member
Members
Forum Posts: 2
Member Since:
September 14, 2020
sp_UserOfflineSmall Offline

Hi,

We have a similar performance issue when querying the nodes and setting it’s data type but I’m not sure we can get around calling `getNode(nodeId)`. If we do not worry about getting/setting the data type, the tree build takes about 2-3 minutes, but with the data types it will take 25 minutes.

“`
import scala.util.{ Try, Success, Failure }
private def getNode(browser: AddressSpace, nodeId: ExpandedNodeId): UaNode = {
Try(browser.getNode(nodeId)) match {
case Success(node) => node
case Failure(e) => null
}
}

childRefs.addAll(browser.browse(nodeId))
import scala.collection.JavaConversions._

var dataType: String = null
for (ref <- childRefs) {
var uaNode = getNode(browser, ref.getNodeId())

if (uaNode != null && uaNode.supportsAttribute(Attributes.DataType)) {
// First, read the DataType attribute of the specified Node
val nodeType = session.readAttribute(uaNode.getNodeId(), Attributes.DataType)
// DataType attributes reference the Node that specifies the actual DataType. So, the value we need is of type NodeId
val dataTypeId = nodeType.getValue().getValue().asInstanceOf[NodeId];

if (uaNode.supportsAttribute(Attributes.DisplayName)) {
// Now that we have the NodeId of the DataType, we can read the DisplayName which gives us, for example, the value "Int32"
val nodeDataType = session.readAttribute(dataTypeId, Attributes.DisplayName);
dataType = nodeDataType.getValue().toString
}
}

val target = browser.getNamespaceTable.toNodeId(ref.getNodeId)
val childNode = new OpcTreeNode(parent, ref.getNodeId.toString, ref.getDisplayName.getText, ref.getTypeDefinition.getIdType.toString, dataType, parent.getServerUri)
parent.getChildren.add(childNode)
createHierarchy(browser, target, childNode) // recursive call
“`

Is there a way we can achieve better performance?

September 15, 2020
18:20, EEST
Avatar
Jouni Aro
Moderator
Moderators
Forum Posts: 1026
Member Since:
December 21, 2011
sp_UserOfflineSmall Offline

Yes, getNode() can end up in quite a number of service calls to the server and therefore it may take quite a while. On the other hand, you are doing some extra stuff here – and also we have a method called getNodes(), which you can use instead to read several nodes at once.

And if you use the UaNode objects, they should have the DataType initialised automatically for you in a more efficient way.

So, in practice, you can do something like this, which reads all variables from the Simulation folder of the Prosys OPC UA Simulation Server and prints their DataTypes. (I added this to the SimpleClient sample of the SDK):

    // Find the Simulation Folder
    ExpandedNodeId id = new ExpandedNodeId("http://www.prosysopc.com/OPCUA/SimulationNodes/", "85/0:Simulation");
    FolderType simFolder = client.getAddressSpace().getNode(id, FolderType.class);
    // Find all targets of Organizes references under the Simulation Folder
    UaReference[] refs = simFolder.getForwardReferences(Identifiers.Organizes);
    NodeId[] refTargets = new NodeId[refs.length];
    for (int i = 0; i < refs.length; i++) {
      refTargets[i] = client.getNamespaceTable().toNodeId(refs[i].getTargetId());
    }
    // Find all corresponding nodes
    UaNode[] nodes = client.getAddressSpace().getNodes(refTargets);
    for (UaNode n : nodes) {
      // Print data of all variables that we found
      if (n instanceof UaVariable) {
        UaVariable v = (UaVariable) n;
        System.out.println(String.format("%s: %s DataType=%s", v.getDisplayName().getText(),
            v.getTypeDefinition().getDisplayName().getText(), v.getDataType().getDisplayName()));
      }
    }

This results in just 6 service calls to the server (which you can verify in the ReqRes Log of the Simulation Server).

September 16, 2020
17:22, EEST
Avatar
michaeldegli
New Member
Members
Forum Posts: 2
Member Since:
September 14, 2020
sp_UserOfflineSmall Offline

Thank you for your reply, Jouni.

Is this line correct?

UaNode[] nodes = client.getAddressSpace().getNodes(refTargets);

getNodes will accept NodeId*, not an Array of NodeId’s

September 16, 2020
18:09, EEST
Avatar
Jouni Aro
Moderator
Moderators
Forum Posts: 1026
Member Since:
December 21, 2011
sp_UserOfflineSmall Offline

Yes, it is. It’s declared as

  public UaNode[] getNodes(final NodeId... nodeIds)

which means that you can give it a list of individual NodeIds or an array of NodeId.

https://docs.oracle.com/javase/8/docs/technotes/guides/language/varargs.html

Forum Timezone: Europe/Helsinki

Most Users Ever Online: 1919

Currently Online:
17 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: 735

Moderators: 7

Admins: 1

Forum Stats:

Groups: 3

Forums: 15

Topics: 1523

Posts: 6449

Newest Members:

rust, christamcdowall, redaahern07571, nigelbdhmp, travistimmons, AnnelCib, dalenegettinger, howardkennerley, Thomassnism, biancacraft16

Moderators: Jouni Aro: 1026, Pyry: 1, Petri: 0, Bjarne Boström: 1026, Jimmy Ni: 26, Matti Siponen: 346, Lusetti: 0

Administrators: admin: 1