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

UAExpert中动态创建节点无法自动显示的问题求助

问题原因及解决方法

核心原因

你创建节点时仅完成了节点的地址空间注册,但未将节点挂载到UAExpert“数据访问视图”对应的父节点(通常是Objects文件夹)下,也没有触发地址空间变更通知,导致客户端无法自动发现新节点。

具体修复步骤

1. 为新节点添加父节点引用

OPC UA地址空间基于引用关系构建,“数据访问视图”默认展示ObjectsFolder(节点ID:Objects)下的节点。你需要手动建立从ObjectsFolder到新节点的Organizes引用:

if (opcUaServer != null)
{
    AddPredefinedNode(SystemContext, variable);

    // 获取ObjectsFolder节点
    var objectsFolder = opcUaServer.CoreServerManager.AddressSpace.FindNode(ObjectIds.ObjectsFolder) as FolderState;
    if (objectsFolder != null)
    {
        // 添加从ObjectsFolder到新节点的正向Organizes引用
        objectsFolder.AddReference(
            ReferenceTypes.Organizes,
            false,
            variable.NodeId.ExpandedNodeId
        );
        // 添加新节点到ObjectsFolder的反向Organizes引用
        variable.AddReference(
            ReferenceTypes.Organizes,
            true,
            ObjectIds.ObjectsFolder.ExpandedNodeId
        );
    }
}

2. 触发地址空间变更通知

服务器需要主动通知客户端地址空间发生变化,UAExpert才能自动刷新视图。添加完节点和引用后,发送变更通知:

// 通知所有客户端节点已添加
opcUaServer.CoreServerManager.AddressSpace.NotifyNodeAdded(variable);

3. 验证节点挂载逻辑

修改后可在UAExpert中手动浏览Objects文件夹,确认新节点是否存在其中,以此验证引用关系是否正确建立。

完整修改后的代码片段

public ServiceResult AddNodeMethod(ISystemContext context, MethodState method, IList<object> inputArgs, IList<object> outputArgs0)
{
    BaseDataVariableState variable = new BaseDataVariableState(opcUaServer);

    variable.SymbolicName = "THISISATEST";
    variable.ReferenceTypeId = ReferenceTypes.Organizes;
    variable.TypeDefinitionId = VariableTypeIds.BaseDataVariableType;
    variable.NodeId = new NodeId((uint)2099, NamespaceIndex);
    variable.BrowseName = new QualifiedName("TEST2");
    variable.DisplayName = new LocalizedText("en", "Thisisatest");
    variable.WriteMask = AttributeWriteMask.DisplayName | AttributeWriteMask.Description;
    variable.UserWriteMask = AttributeWriteMask.DisplayName | AttributeWriteMask.Description;
    variable.DataType = DataTypeIds.Int32;
    variable.ValueRank = ValueRanks.Scalar;
    variable.AccessLevel = AccessLevels.CurrentReadOrWrite;
    variable.UserAccessLevel = AccessLevels.CurrentReadOrWrite;
    variable.Historizing = false;
    variable.Value = 0;
    variable.StatusCode = StatusCodes.Good;
    variable.Timestamp = DateTime.UtcNow;

    if (opcUaServer != null)
    {
        AddPredefinedNode(SystemContext, variable);

        // 挂载到ObjectsFolder
        var objectsFolder = opcUaServer.CoreServerManager.AddressSpace.FindNode(ObjectIds.ObjectsFolder) as FolderState;
        if (objectsFolder != null)
        {
            objectsFolder.AddReference(ReferenceTypes.Organizes, false, variable.NodeId.ExpandedNodeId);
            variable.AddReference(ReferenceTypes.Organizes, true, ObjectIds.ObjectsFolder.ExpandedNodeId);
        }

        // 通知客户端地址空间变更
        opcUaServer.CoreServerManager.AddressSpace.NotifyNodeAdded(variable);
    }

    if(FindNodeInAddressSpace(variable.NodeId) != null){
        Console.WriteLine("Node succesfully created");
        return ServiceResult.Good;
    }
    return new ServiceResult(2);
}

额外说明

  • CreateCustomNode能正常显示节点,是因为它内部默认完成了父节点挂载、引用建立和变更通知的逻辑。
  • 如果需要将节点挂载到自定义父节点下,只需将代码中的ObjectIds.ObjectsFolder替换为目标父节点的NodeId即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 12:47:08