了解python中的免费OPC/UA代码

Posted

技术标签:

【中文标题】了解python中的免费OPC/UA代码【英文标题】:Understanding free OPC/UA code in python 【发布时间】:2018-01-01 18:22:10 【问题描述】:

我正在使用 python 处理OPCUA。我正在使用freeopc。我已经使用了他们的 server_minimal 和 client_minimal 示例,并且运行良好。我在理解代码时遇到了一些问题。据我所知 OPCUA 堆栈,它的地址空间就像所有节点的集合。然后这些节点进一步包含对象,并且这些对象具有我们可以从中读取写入数据的变量。如果我错了,请纠正我。

---------------------------------
         Address space
---------------------------------
   |                    |
   |                    |
   V                    V
  Node1               Node2
   |
   Object1
    |
    Var1, Var2

所以在服务器端我想知道什么是命名空间

# setup our own namespace, not really necessary but should as spec
uri = "http://examples.freeopcua.github.io"
idx = server.register_namespace(uri)

命名空间的用途是什么?在 uri 里面放什么?

在客户端,我想知道:

连接服务器后,我们正在做:

    # 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)

get_root_node() 是什么意思。是不是就像我们正在连接到定义了所有节点的服务器的地址空间一样?

    # 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()-- 意思是获取节点的对象吗?

    # 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是什么意思?

客户端输出:

 ('Objects node is: ', Node(TwoByteNodeId(i=84)))
 ('Children of root are: ', [Node(NumericNodeId(i=85)), Node(NumericNodeId(i=86)), Node(NumericNodeId(i=87))])

以上代码取自server_minimal.pyclient_minimal.py

谁能解释一下这些。我尝试阅读他们的文档,但那里没有提到。

谢谢。

【问题讨论】:

【参考方案1】:

为了更好地理解这一点,您可以使用 Unified Automation UA Expert 作为客户端。 https://www.unified-automation.com/downloads/opc-ua-clients.html 启动 server_minimal.py,使用“opc.tcp://localhost:4840/freeopcua/server/”使用“自定义发现”打开 UA Expert 添加服务器。您可以轻松查看整个地址空间。

【讨论】:

【参考方案2】:

我也在使用 freeopcua,对于一些问题我想我有答案

root = client.get_root_node()

将为您提供服务器根节点的节点,因此基本上是图表中的“地址空间”。

root.get_children()

将返回所有节点的列表,这些节点是根的直接子节点,因此在树的示例中。 [节点1,节点2]。但是添加根节点,这是 0:Objects, 0:Types, 0:Views

要查看服务器的树,最好使用 opcua-client,这是一个 GUI,可让您查看树。

为此启动您的服务器,然后在您的终端输入;

 $ opcua-client

(在 Linux 上时)

您可以添加限制来获取孩子,例如:

        objects = root.get_children(refs=ua.ObjectIds.HasChild, nodeclassmask=ua.NodeClass.Object)

这只会返回其他对象,而不是节点的方法或属性。

您得到的输出是因为 Node 没有真正的“ToString()”,i 是节点的 id(也可以通过 GUI 客户端看到)。

Node.getChild(NodeId)

如果您确定添加了一个值,则将返回一个节点对象,您可以通过调用 .get_value() 来获取它的值。 NodeId 是您想要的孩子的规范。所以说你想要 var1 这将是

# 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()

这里重要的是,要获得孩子,您需要知道自己在哪里(您可以从任何 Node 对象获得孩子,而不仅仅是根),然后使用“idx:Name”的组合进行下去,这是您在添加时添加的内容您首先将值添加到服务器。

希望这会有所帮助(未测试代码,因此可能需要进行一些调整才能实际运行)

【讨论】:

太棒了。不错的资料。谢谢。我只需要知道,However add the root node this is 0:Objects, 0:Types, 0:Views 是什么意思。对象类型视图在节点中意味着什么。同样,当我们执行root.get_child() 时,我们会得到i=84i=85 的输出。我是什么意思。?这是NodeId吗?我们可以使用这个 id 访问那个特定的节点吗?再次感谢! 这是他们在整个结构中的id。当它们存储在 0: 中时,这将始终是单个 i=NodeId。当存储在不同的 idx 中时,格式为 ns=;i=id。如果您有 nodeId,则始终可以使用它而不是名称来获取节点。 *编辑: 基本服务器已经有一些标准节点,无论您是否添加了节点,您都从 3 个节点开始,它们是对象、类型和视图节点。也可以使用 server.nodes.objects 访问,因为 opcua 服务器知道这将是哪些 @davygillebert 你能回复我吗?我需要讨论一些与 OPC ua 堆栈相关的事情。 @Akash,我可以,我现在正在学校考试,但无论如何我都会提供帮助。

以上是关于了解python中的免费OPC/UA代码的主要内容,如果未能解决你的问题,请参考以下文章

OPC UA 发现中的多播 DNS 名称冲突

基于open62541的opc ua 服务器开发实现

你猜,回复的是什么笑脸 | 大话OPC UA中的对称加密

SharpNodeSettings项目,可配置的数据采集,统一的工业数据网关,OPC UA服务器开发,PLC数据发布到自身内存,redis,opc ua,以及数据可视化开发

是否为 OPC UA 地址空间中的应用程序级节点 ID 保留了 951 到 1999 的范围?

探索 OPC UA