You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从OPC UA服务器获取未知组与标签?附代码改造需求

解决方案

不需要额外配置,利用OPC UA标准的**地址空间浏览(Browse)**功能即可实现,现有Opc.Ua.Client命名空间完全支持该操作。核心思路是从服务器的根节点(或指定命名空间节点)开始递归遍历,区分文件夹(对应你说的“组”)和变量(对应“标签”),并输出层级结构。

代码示例

在你现有代码的OPCUAClass中添加浏览节点的递归方法,并在会话初始化完成后调用:

1. 添加浏览方法到OPCUAClass

// 递归浏览服务器节点,输出组(文件夹)和标签(变量)
public void BrowseServerNodes(NodeId startingNodeId, int indentLevel = 0)
{
    if (OPCSession == null || !OPCSession.Connected)
    {
        Console.WriteLine("会话未连接,无法浏览节点");
        return;
    }

    // 构建浏览请求配置
    var browseDescription = new BrowseDescription
    {
        NodeId = startingNodeId,
        BrowseDirection = BrowseDirection.Forward,
        ReferenceTypeId = ReferenceTypeIds.HierarchicalReferences,
        IncludeSubtypes = true,
        NodeClassMask = (uint)(NodeClass.Object | NodeClass.Variable),
        ResultMask = (uint)BrowseResultMask.All
    };

    // 执行浏览请求
    BrowseResult browseResult = OPCSession.Browse(null, null, 0, browseDescription);
    foreach (var reference in browseResult.References)
    {
        // 读取节点的显示名称和类型属性
        NodeAttributes attributes = OPCSession.ReadNodeAttributes(reference.NodeId, Attributes.DisplayName | Attributes.NodeClass);
        string displayName = attributes.DisplayName?.Text ?? reference.NodeId.ToString();
        NodeClass nodeClass = (NodeClass)attributes.NodeClass;

        // 层级缩进,优化控制台输出格式
        string indent = new string(' ', indentLevel * 2);

        if (nodeClass == NodeClass.Object)
        {
            // 对象节点(文件夹),视为"组"
            Console.WriteLine($"{indent}[组] {displayName} (NodeId: {reference.NodeId})");
            // 递归浏览子节点
            BrowseServerNodes(reference.NodeId, indentLevel + 1);
        }
        else if (nodeClass == NodeClass.Variable)
        {
            // 变量节点,视为"标签"
            Console.WriteLine($"{indent}[标签] {displayName} (NodeId: {reference.NodeId})");
        }
    }
}

2. 在会话初始化后调用浏览方法

修改InitializeOPCUAClient方法,在会话创建成功后添加浏览逻辑:

// 原会话创建代码之后添加:
Console.WriteLine("\n=== 服务器节点结构 ===");
// 从OPC UA根节点开始全量浏览
BrowseServerNodes(ObjectIds.RootFolder);

// 如果只想浏览指定命名空间的节点(比如你代码中的ns=2),可以先定位到该命名空间的根节点
// 示例:假设命名空间根节点标识符为0,可替换为实际值
// NodeId namespaceRoot = new NodeId(0, OPCNameSpace);
// BrowseServerNodes(namespaceRoot);

3. 测试浏览功能(可选修改Main方法)

可以暂时注释掉已知标签的订阅逻辑,先验证浏览功能:

public static void Main(string[] args)
{
    Console.WriteLine("Start");

    // 注释已知标签,先测试浏览
    // TagList.Add("Value 1", new OPCUAClass.TagClass("Number 1", "FileValue.FileData"));
    // TagList.Add("Value 2", new OPCUAClass.TagClass("Number 2", "FileValue.FileData2"));

    myOPCUAServer = new OPCUAClass("127.0.0.1", "8666", new Dictionary<string, OPCUAClass.TagClass>(), true, 1, "2");
}

配置说明

不需要额外配置,只需满足两个前提:

  1. 客户端已成功与OPC UA服务器建立会话(你的现有代码已实现连接逻辑)。
  2. 服务器允许地址空间浏览操作(绝大多数OPC UA服务器默认开启该权限,无需额外配置)。

内容的提问来源于stack exchange,提问作者FaceHoof

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 07:50:47