I am working on OPCUA
in python. I am using freeopc. I have used their server_minimal & client_minimal example and it is running fine. I am having some issues understanding the code. As far as I know the OPCUA stack, it has address space which is like a collection of all the nodes. These nodes then further contains objects and these objects have variable from where we can read write data. Please correct me if I am wrong.
---------------------------------
Address space
---------------------------------
| |
| |
V V
Node1 Node2
|
Object1
|
Var1, Var2
So on the server side I want to know what is namespace
# setup our own namespace, not really necessary but should as spec
uri = "http://examples.freeopcua.github.io"
idx = server.register_namespace(uri)
What is the namespace used for.? What to put inside uri.?
On client side, I want to know:
After connecting to server, we are doing:
# Client has a few methods to get proxy to UA nodes that should always be in address space such as Root or Objects
root = client.get_root_node()
print("Objects node is: ", root)
What does get_root_node()
means. Is it like we are connecting to address space of server where all the nodes are defined.?
# Node objects have methods to read and write node attributes as well as browse or populate address space
print("Children of root are: ", root.get_children())
root.get_children()
-- Does this means getting the objects of the nodes.?
# Now getting a variable node using its browse path
myvar = root.get_child(["0:Objects", "2:MyObject", "2:MyVariable"])
obj = root.get_child(["0:Objects", "2:MyObject"])
root.get_child
what does it means.?
Client output:
('Objects node is: ', Node(TwoByteNodeId(i=84)))
('Children of root are: ', [Node(NumericNodeId(i=85)), Node(NumericNodeId(i=86)), Node(NumericNodeId(i=87))])
Above code is taken from server_minimal.py client_minimal.py
Can anyone please explain these. I tried reading their docs but this is not mentioned there.
Thanks.
OPC UA Client is a free client tool that supports the main OPC Unified Architecture information models. These models are Data Access, Alarms & Conditions, and Historical Data Access.
About OpenOPC OpenOPC for Python is a free, open source OPC (OLE for Process Control) toolkit designed for use with the popular Python programming language.
OPC UA is used as a transport route and IT standard featuring integrated security. As an OPC UA client, the controller pushes the data as "historical access" data directly into the "big data management solution" stored in the cloud.
open62541 is an open source implementation of OPC UA licensed under the Mozilla Public License v2. 0. open62541 is based on the IEC standard IEC 62541 and is available royalty-free on GitHub under the open-source license (Mozilla Public License v2.
I'm working with freeopcua too and on some questions I think I have an answer
root = client.get_root_node()
will get you the node of the root of your server so basically 'adress space' in your diagram.
root.get_children()
will return a list of all nodes that are direct children of the root so in the example of your tree. [node1, node2]. However add the root node this is 0:Objects, 0:Types, 0:Views
To see the tree of the server you can best use the opcua-client this is a GUI that will allow you to see the tree.
to do this start your server and then in your terminal typ;
$ opcua-client
(when on linux)
You can add limitation to get children e.g.:
objects = root.get_children(refs=ua.ObjectIds.HasChild, nodeclassmask=ua.NodeClass.Object)
This will only return other objects not methods or properties of your node.
The output you get is because Node doesn't have a real 'ToString()' the i is the id of the node (can also be seen with the GUI client).
the
Node.getChild(NodeId)
will return a node object if you're certain you added a value you can get it,s value by calling .get_value() on the return of this. NodeId is the specification of what child you want. So say you want var1 this would be
# First the code needed to add the node
node1 = root.add_object(2, "Node1") # root is the root node which can be obtained by either client.get_root_node or server.get_root_node
object1 = node1.add_object(3, "Object1")
object1.add_variable(4, "Var1", 42)
object1.add_variable(4, "Var2", 13)
# Now the code to ask the server for the node
var1_node = root.getChild(["2:Node1", "3:Object1", "4:Var1"])
# And to get its value
var1_node.get_value()
Important here is that to get a child you need to know where you are (you can get children from any Node object not only root) and then go down with a combination of "idx:Name" which is what you add when you added the value to the server in the first place.
Hoped this helped a bit (did not test the code so it might need some adjustments to actually run)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With