使用Python opcua-asyncio读取西门子S7-1200 PLC变量遇BadNoMatch错误
西门子S7-1200(固件V14)OPC UA变量读取问题排查建议
先修正节点路径认知:西门子S7-1200的用户程序变量(比如t1-t19)通常不在
Objects→ServerInterfaces→Face路径下。固件V14版本里,用户变量一般存放在Objects→DeviceSet→[你的PLC设备名]→Application→[对应的程序块]层级中(比如OB1或自定义功能块)。建议先用UA Expert这类可视化OPC UA客户端连接PLC,直接浏览节点结构,确认t1-t19的实际位置——这是最快定位问题的方法。解决
BadNoMatch错误:这个错误说明你当前访问的Face节点没有子节点,或者节点定位方式有误。如果要继续用代码遍历,试试这些调整:- 不要仅依赖
get_children_descriptions(),改用get_child()直接指定路径获取节点:face_node = await objects.get_child(["ServerInterfaces", "Face"]) - 若路径方式失效,尝试用节点ID直接获取(可通过UA Expert查看
Face节点的NodeId):face_node = await client.get_node("ns=2;s=ServerInterfaces.Face") - 调用
get_children_descriptions()时,明确指定引用类型参数,避免过滤掉合法子节点:children = await face_node.get_children_descriptions(reference_types=ua.ObjectIds.HierarchicalReferences)
- 不要仅依赖
更高效的变量读取方式:遍历节点效率低且容易出错,直接通过节点ID或BrowseName读取更可靠。在UA Expert中找到t1-t19后,记录它们的NodeId(比如
ns=4;s="t1"),然后用以下代码批量读取:# 构建所有目标变量的节点ID列表(注意替换正确的命名空间索引ns值) node_ids = [f"ns=4;s=\"t{i}\"" for i in range(1, 20)] # 获取节点对象 target_nodes = [await client.get_node(nid) for nid in node_ids] # 批量读取值 values = await client.read_values(target_nodes)注意命名空间索引:西门子S7-1200的OPC UA服务器会给不同类型的节点分配不同命名空间,用户程序变量的命名空间索引(即NodeId中的
ns值)通常不是0,务必在UA客户端中确认准确值。版本兼容性检查:确保你使用的opcua-asyncio版本与Python 3.11兼容,建议升级到最新稳定版,避免因版本适配问题导致节点交互异常。
内容的提问来源于stack exchange,提问作者afkJStck159
相关产品推荐
相关产品推荐

