opcua-asyncio
opcua-asyncio copied to clipboard
get_children may return duplicated nodes
Hi all, Thank you for developing this library, I hope I can contribute to it in the future. I have been building a scraper, OPC UA client, since the last two weeks. I noticed that, by connecting to a machine, I get some of the children more than one time. These nodes have the same namespace and node type of their clones. I wonder if obtaining multiple clone children is a normal behavior, or if there is something wrong with the client, or it is something wrong with the server (I lack experience and I cannot figure out alone ^_^").
My solution
node_list = set(await base_node.get_children())
Describe the bug
Calling get_children may return the same object multiple times.
To Reproduce
node_list = await base_node.get_children()
assert len(node_list) == len(set(node_list))
It triggers the assertion error on my machine
Expected behavior
I expect to scrape only different nodes.
Screenshots
Output of: print(node_list)
I put in bold the duplicated nodes. The duplicated nodes are fixed.
[Node(NodeId(Identifier='BaseObject.A', NamespaceIndex=5, NodeIdType=<NodeIdType.String: 3>)),
Node(NodeId(Identifier='BaseObject.B', NamespaceIndex=5, NodeIdType=<NodeIdType.String: 3>)),
Node(NodeId(Identifier='BaseObject.C', NamespaceIndex=5, NodeIdType=<NodeIdType.String: 3>)),
Node(NodeId(Identifier='BaseObject.D', NamespaceIndex=5, NodeIdType=<NodeIdType.String: 3>)),
Node(NodeId(Identifier='BaseObject.E', NamespaceIndex=5, NodeIdType=<NodeIdType.String: 3>)),
Node(NodeId(Identifier='BaseObject.F', NamespaceIndex=5, NodeIdType=<NodeIdType.String: 3>)),
Node(NodeId(Identifier='BaseObject.G', NamespaceIndex=5, NodeIdType=<NodeIdType.String: 3>)),
Node(NodeId(Identifier='BaseObject.H', NamespaceIndex=5, NodeIdType=<NodeIdType.String: 3>)),
Node(NodeId(Identifier='BaseObject.I', NamespaceIndex=5, NodeIdType=<NodeIdType.String: 3>)),
Node(NodeId(Identifier='BaseObject.L', NamespaceIndex=5, NodeIdType=<NodeIdType.String: 3>)),
Node(NodeId(Identifier='BaseObject.F', NamespaceIndex=5, NodeIdType=<NodeIdType.String: 3>)),
Node(NodeId(Identifier='BaseObject.B', NamespaceIndex=5, NodeIdType=<NodeIdType.String: 3>)),
Node(NodeId(Identifier='BaseObject.L', NamespaceIndex=5, NodeIdType=<NodeIdType.String: 3>)),
Node(NodeId(Identifier='BaseObject.G', NamespaceIndex=5, NodeIdType=<NodeIdType.String: 3>)),
Node(NodeId(Identifier='Extension', NamespaceIndex=6, NodeIdType=<NodeIdType.String: 3>)),
Node(NodeId(Identifier='HistoricalEventFilter', NamespaceIndex=5, NodeIdType=<NodeIdType.String: 3>))]
The problem also affects the children of not duplicated nodes (e.g. BaseObject.A).
[Node(NodeId(Identifier='BaseObject.A.N', NamespaceIndex=5, NodeIdType=<NodeIdType.String: 3>)), Node(NodeId(Identifier='BaseObject.A.M', NamespaceIndex=5, NodeIdType=<NodeIdType.String: 3>)), Node(NodeId(Identifier='BaseObject.A.M', NamespaceIndex=5, NodeIdType=<NodeIdType.String: 3>))]
Version
Python-Version: 3.7.11
opcua-asyncio Version: master, 0.9.90 (installed by pip)
Thank you
The Idea with set() would be a workaround.
Could you tell us how your base_node
looks like?
What references does base_node
got?
Thank you for the prompt reply.
Yes, I know that it would be a workaround.
base_node is an instance of a subtype of BaseObjectType, which has 10 ObjectType components (plus other things).
Every ObjectType is different, and I expect only 1 from each. In UA Expert I see only one of each.
I do not know if I answered fully your question.
Anything is possible. In UA you can create links in all directions. Uaexpert probably does a filtering to remove duplicates. Get_children returns what the server returns so in that case the server returned duplicates
Thank you for your answer. Probably I should filter out some kind of cross-reference between the components, I'll do some experiment on the next week and eventually share some insights.