Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to get list of all published nodes? #863

Closed
HubertLaczak opened this issue Jul 10, 2019 · 14 comments
Closed

How to get list of all published nodes? #863

HubertLaczak opened this issue Jul 10, 2019 · 14 comments

Comments

@HubertLaczak
Copy link

Hi, I'm writing Client app and I don't want to hardcode methods to get specific node with ids. I would like to ask server which nodes (variables) are published, I want to get list of each nodes.

How to make it? I was reading example from
https://github.com/FreeOpcUa/python-opcua/blob/master/examples/client-example.py
but I am not sure which methods are necessary. Can you give me tips?

@oroulet
Copy link
Member

oroulet commented Jul 10, 2019

Every server publishes 1000s of nodes. You do not want to access all of them. The protocol is based on knowing what nodes you want. Ideally using domain specific profiles

@brubbel
Copy link
Contributor

brubbel commented Jul 11, 2019

I would just browse the tree upwards starting from the root node.

@zerox1212
Copy link
Contributor

You would need to browse the tree recursively to achieve this.

@HubertLaczak
Copy link
Author

HubertLaczak commented Jul 12, 2019

When I try with:
client.connect()
print ("\nConnected\n")
root = client.get_root_node()
print("%s" %root)
print("Children of root are: %s" %root.get_children())

The answer is:
Node(TwoByteNodeId(i=84))
Children of root are: [Node(TwoByteNodeId(i=87)), Node(TwoByteNodeId(i=85)), Node(TwoByteNodeId(i=86))]

Am I right, that ids of my nodes are: 87,85,86? At least I use:
var = client.get_node(ua.NodeId(85,2))
val = var.get_value()

but there is an error: "The node id refers to a node that does not exist in the server address.."

Could you give me an advise or some example? I read:

https://github.com/FreeOpcUa/python-opcua/blob/master/examples/client-example.py

@brubbel
Copy link
Contributor

brubbel commented Jul 12, 2019

root = client.get_root_node()
print("Root node is: {:s} ".format(str(root)))

def browse_recursive(node):
    for childId in node.get_children():
        ch = client.get_node(childId)
        print(ch.get_node_class())
        if ch.get_node_class() == ua.NodeClass.Object:
            browse_recursive(ch)
        elif ch.get_node_class() == ua.NodeClass.Variable:
            try:
                print("{bn} has value {val}".format(
                    bn=ch.get_browse_name(),
                    val=str(ch.get_value()))
                )
            except ua.uaerrors._auto.BadWaitingForInitialData:
                pass

browse_recursive(root)

@HubertLaczak
Copy link
Author

I still have problems. I receive:

 Root node is Node(TwoByteNodeId(i=84))
 NodeClass.Object
 3
 NodeClass.Object
 3
 NodeClass.Object
 3

I copied your code:

 try:
    root = client.get_root_node()
    print("Root node is {:s} " .format(str(root)))

    def browse_recursive(node):
    for childId in node.get_children():
           ch = client.get_node(childId)
           print(ch.get_node_class())
           if ch.get_node_class == ua.NodeClass.Object:
                   print("1")
                   browse_recursive(ch)
           elif ch.get_node_class() == ua.NodeClass.Variable:
                     print("2")
                     try:
                               print("{bn} has value {val}".format(bn=$
                     except ua.uaerror._auto.BadWaitingForInitialDat$
                               pass
            else:
                      print("3")
    browse_recursive(root)

It looks like NodeClass.Object != ua.NodeClass.Object?
Normally, I use:

    var = client.get_node("ns=2;s=Register1")

to get node and later to get the value. But when I add in the code above:

 for childId in node.get_children():
           ch = client.get_node(childId)
           print(ch.get_node_class())
           print(ch.get_browse_name()) #I added this line

I receive:

 NodeClass.Object
 QualifiedName(0:Views)
 3
 NodeClass.Object
 QualifiedName(0:Objects)
 3
 NodeClass.Object
 QualifiedName(0:Types)
 3

@brubbel
Copy link
Contributor

brubbel commented Jul 12, 2019

ch.get_node_class**()** == ua.NodeClass.Object
There is a typo in your code.

@HubertLaczak
Copy link
Author

Great work, thank you :)

@twodonkeys
Copy link

mark

@mukaraT
Copy link

mukaraT commented Jun 8, 2022

@brubbel I tried your code and received the below error. Its because of the variable level/structure I guess. Any idea how to fix it?

(.python_venv) PS C:\Users\Mukara> & d:/Thangz/Projekte/VC/python_venv/.python_venv/Scripts/python.exe d:/Thangz/Projekte/VC/OPC/read_write_OPCUA_thangz.py
Requested session timeout to be 3600000ms, got 30000ms instead
Objects root node is:  i=84
Root node is: i=84
NodeClass.Object
NodeClass.Object
NodeClass.Variable
QualifiedName(0:Auditing) has value True
NodeClass.Method
NodeClass.Variable
QualifiedName(0:NamespaceArray) has value ['http://opcfoundation.org/UA/', 'urn:SIMATIC.S7-1500.OPC-UA.Application:PLC_1', 'http://opcfoundation.org/UA/DI/', 'http://www.siemens.com/simatic-s7-opcua']
NodeClass.Object
NodeClass.Object
NodeClass.Variable
.
.
.
NodeClass.Object
NodeClass.Variable
QualifiedName(3:PT) has value 0
NodeClass.Variable
QualifiedName(3:ET) has value 0
NodeClass.Variable
QualifiedName(3:IN) has value False
NodeClass.Variable
QualifiedName(3:Q) has value False
NodeClass.Object
NodeClass.Variable
QualifiedName(3:4125_6S1) has value ExtensionObject(TypeId:StringNodeId(ns=3;s=TE_"U_StB1"), Encoding:1, 2 bytes)
NodeClass.Variable
QualifiedName(3:4125Man) has value ExtensionObject(TypeId:StringNodeId(ns=3;s=TE_"U_StB1"), Encoding:1, 2 bytes)
NodeClass.Variable
Traceback (most recent call last):
  File "d:\Thangz\Projekte\VC\OPC\read_write_OPCUA_thangz.py", line 58, in <module>
    browse_recursive(root)
  File "d:\Thangz\Projekte\VC\OPC\read_write_OPCUA_thangz.py", line 30, in browse_recursive
    browse_recursive(ch)
  File "d:\Thangz\Projekte\VC\OPC\read_write_OPCUA_thangz.py", line 30, in browse_recursive
    browse_recursive(ch)
  File "d:\Thangz\Projekte\VC\OPC\read_write_OPCUA_thangz.py", line 30, in browse_recursive
    browse_recursive(ch)
  [Previous line repeated 2 more times]
  File "d:\Thangz\Projekte\VC\OPC\read_write_OPCUA_thangz.py", line 35, in browse_recursive
    val=str(ch.get_value()))
  File "D:\Thangz\Projekte\VC\python_venv\.python_venv\lib\site-packages\opcua\common\node.py", line 155, in get_value
    result = self.get_data_value()
  File "D:\Thangz\Projekte\VC\python_venv\.python_venv\lib\site-packages\opcua\common\node.py", line 164, in get_data_value
    return self.get_attribute(ua.AttributeIds.Value)
  File "D:\Thangz\Projekte\VC\python_venv\.python_venv\lib\site-packages\opcua\common\node.py", line 276, in get_attribute
    result[0].StatusCode.check()
  File "D:\Thangz\Projekte\VC\python_venv\.python_venv\lib\site-packages\opcua\ua\uatypes.py", line 218, in check
    raise UaStatusCodeError(self.value)
opcua.ua.uaerrors._auto.BadNotReadable: "The access level does not allow reading or subscribing to the Node."(BadNotReadable)
(.python_venv) PS C:\Users\Mukara> 

Regards,
Mukara

@schroeder-
Copy link
Contributor

schroeder- commented Jun 8, 2022

You have to check the access level of the node before browsing via:
if ch.get_access_level() & (1<< ua.AccessLevel.CurrentRead.mask):
....
Or just catch the exception and continue

@mukaraT
Copy link

mukaraT commented Jul 4, 2022

I tried with this below function, it is still not able to read the rest of the node ids :(

def browse_recursive(node):
    for childId in node.get_children():
        ch = client.get_node(childId)
        print(ch.get_node_class())
        if ch.get_access_level() & (1<< ua.AccessLevel.CurrentRead.mask):
            if ch.get_node_class() == ua.NodeClass.Object:
                browse_recursive(ch)
            elif ch.get_node_class() == ua.NodeClass.Variable:
                try:
                    print("{bn} has value {val}".format(
                        bn=ch.get_browse_name(),
                        val=str(ch.get_value()))
                    )
                except ua.uaerrors._auto.BadWaitingForInitialData:
                    pass
            

Any Ideas/Suggestions, where I could read all the node IDs or pass the exceptions and read further variables?

Regards,
Mukara

@brubbel
Copy link
Contributor

brubbel commented Jul 4, 2022

...
                try:
                    print("{bn} has value {val}".format(
                        bn=ch.get_browse_name(),
                        val=str(ch.get_value()))
                    )
                except ua.uaerrors.UaStatusCodeError as e:
                    print(e)
                    pass
....

@SHAFIT
Copy link

SHAFIT commented Feb 4, 2023

I was trying to get the complete list of variables. But it is showing some data which are not really required.
is it possible to browse only the variables which are assinged to a particular "ns". for example "ns=1; "

node = client.get_objects_node()
print("Starting Node: ", node)

def browse_recursive(node):
    for childId in node.get_children():
        ch = client.get_node(childId)
        if ch.get_node_class() == ua.NodeClass.Object:
            browse_recursive(ch)
            #print ("Recusrising ", ch)
        elif ch.get_node_class() == ua.NodeClass.Variable:
            try:
                print ("Node is variable ", ch)
            except ua.uaerrors._auto.BadWaitingForInitialData:
                pass

browse_recursive(node)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants