Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding free OPC/UA code in python

Tags:

python

opc

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.

like image 411
S Andrew Avatar asked Jul 26 '17 12:07

S Andrew


People also ask

Is OPC UA free?

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.

What is OPC Python?

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.

How does OPC UA communication work?

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.

What is open62541?

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.


1 Answers

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)

like image 187
davy gillebert Avatar answered Sep 24 '22 07:09

davy gillebert