导入OPC UA XML文件时出现BadNodeIdExists错误的解决咨询
解决asyncua导入OPC UA节点集时的BadNodeIdExists错误及相关疑问解答
错误原因分析
你遇到的BadNodeIdExists错误核心原因是:asyncua的Server.init()方法会自动导入标准的Opc.Ua.Nodeset2.xml(即OPC UA基础节点集,对应命名空间0),而你手动再次导入该文件,导致命名空间0下的节点ID(比如错误里的3062)重复创建。
解决方案
移除重复的基础节点集导入代码
修改代码,删除await server.import_xml("Opc.Ua.Nodeset2.xml")这一行,因为server.init()已经完成了基础节点集的加载:import asyncio async def main(): server = Server() await server.init() server.set_endpoint("opc.tcp://192.168.1.216:4000") # 移除重复的基础节点集导入 await server.import_xml("Opc.Ua.Di.Nodeset2.xml") await server.import_xml("Opc.Ua.Machinery.Nodeset2.xml") await server.import_xml("Opc.Ua.Pumps.Nodeset2.xml") await server.import_xml("testing_Nodeset.xml") await server.start() if __name__ == "__main__": asyncio.run(main())验证自定义节点集的命名空间正确性
打开testing_Nodeset.xml,检查所有自定义节点的NodeId属性,确保它们的NamespaceIndex不是0(0是标准节点集的专属命名空间),而是你在SiOME中创建的自定义命名空间对应的索引,避免和标准节点ID冲突。确保节点集导入顺序符合依赖关系
当前的导入顺序DI -> Machinery -> Pumps -> 自定义节点集是正确的,因为Machinery依赖DI、Pumps依赖Machinery、自定义节点集依赖上述所有标准节点集,保持这个顺序即可。
针对你的疑问解答
1. 创建自定义命名空间的方式是否正确?
在SiOME中先导入OPC UA Device、Machinery、Pumps等标准节点集,再创建自定义命名空间的方式是正确的。需要额外注意:
- 自定义节点必须分配到自己的命名空间(而非命名空间0),避免和标准节点ID冲突
- 导出的
testing_Nodeset.xml中,自定义节点的命名空间URI和索引要与asyncua自动识别的配置对应,确保无配置错误
2. 是否需要按照OPC UA配套规范导入所有XML文件?
是的,必须导入所有依赖的标准节点集。因为你的自定义节点集基于这些规范创建,会引用其中的类型、对象、变量等定义。但注意:
- 基础UA节点集(
Opc.Ua.Nodeset2.xml)无需手动导入,asyncua的Server.init()已经自动完成 - 其他依赖节点集(DI、Machinery、Pumps)必须按依赖顺序导入,否则会出现找不到类型定义的错误
内容的提问来源于stack exchange,提问作者Ankit Mavani
相关产品推荐
相关产品推荐

