示例#1
0
        /// <summary>
        /// 修改节点树(添加节点,删除节点,修改节点名称)
        /// </summary>
        /// <param name="nodes"></param>
        public void UpdateNodesAttribute(List <OpcuaNode> nodes)
        {
            //修改或创建根节点
            var scadas = nodes.Where(d => d.NodeType == NodeType.Scada);

            foreach (var item in scadas)
            {
                FolderState scadaNode = null;
                if (!_folderDic.TryGetValue(item.NodePath, out scadaNode))
                {
                    //如果根节点都不存在  那么整个树都需要创建
                    FolderState root = CreateFolder(null, item.NodePath, item.NodeName);
                    root.AddReference(ReferenceTypes.Organizes, true, ObjectIds.ObjectsFolder);
                    _references.Add(new NodeStateReference(ReferenceTypes.Organizes, false, root.NodeId));
                    root.EventNotifier = EventNotifiers.SubscribeToEvents;
                    AddRootNotifier(root);
                    CreateNodes(nodes, root, item.NodePath);
                    _folderDic.Add(item.NodePath, root);
                    AddPredefinedNode(SystemContext, root);
                    continue;
                }
                else
                {
                    scadaNode.DisplayName = item.NodeName;
                    scadaNode.ClearChangeMasks(SystemContext, false);
                }
            }
            //修改或创建目录(此处设计为可以有多级目录,上面是演示数据,所以我只写了三级,事实上更多级也是可以的)
            var folders = nodes.Where(d => d.NodeType != NodeType.Scada && !d.IsTerminal);

            foreach (var item in folders)
            {
                FolderState folder = null;
                if (!_folderDic.TryGetValue(item.NodePath, out folder))
                {
                    var par = GetParentFolderState(nodes, item);
                    folder = CreateFolder(par, item.NodePath, item.NodeName);
                    AddPredefinedNode(SystemContext, folder);
                    par.ClearChangeMasks(SystemContext, false);
                    _folderDic.Add(item.NodePath, folder);
                }
                else
                {
                    folder.DisplayName = item.NodeName;
                    folder.ClearChangeMasks(SystemContext, false);
                }
            }
            //修改或创建测点
            //这里我的数据结构采用IsTerminal来代表是否是测点  实际业务中可能需要根据自身需要调整
            var paras = nodes.Where(d => d.IsTerminal);

            foreach (var item in paras)
            {
                BaseDataVariableState node = null;
                if (_nodeDic.TryGetValue(item.NodeId.ToString(), out node))
                {
                    node.DisplayName = item.NodeName;
                    node.Timestamp   = DateTime.Now;
                    node.ClearChangeMasks(SystemContext, false);
                }
                else
                {
                    FolderState folder = null;
                    if (_folderDic.TryGetValue(item.ParentPath, out folder))
                    {
                        node = CreateVariable(folder, item.NodePath, item.NodeName, DataTypeIds.Double, ValueRanks.Scalar);
                        AddPredefinedNode(SystemContext, node);
                        folder.ClearChangeMasks(SystemContext, false);
                        _nodeDic.Add(item.NodeId.ToString(), node);
                    }
                }
            }

            /*
             * 将新获取到的菜单列表与原列表对比
             * 如果新菜单列表中不包含原有的菜单
             * 则说明这个菜单被删除了  这里也需要删除
             */
            List <string> folderPath = _folderDic.Keys.ToList();
            List <string> nodePath   = _nodeDic.Keys.ToList();
            var           remNode    = nodePath.Except(nodes.Where(d => d.IsTerminal).Select(d => d.NodeId.ToString()));

            foreach (var str in remNode)
            {
                BaseDataVariableState node = null;
                if (_nodeDic.TryGetValue(str, out node))
                {
                    var parent = node.Parent;
                    parent.RemoveChild(node);
                    _nodeDic.Remove(str);
                }
            }
            var remFolder = folderPath.Except(nodes.Where(d => !d.IsTerminal).Select(d => d.NodePath));

            foreach (string str in remFolder)
            {
                FolderState folder = null;
                if (_folderDic.TryGetValue(str, out folder))
                {
                    var parent = folder.Parent;
                    if (parent != null)
                    {
                        parent.RemoveChild(folder);
                        _folderDic.Remove(str);
                    }
                    else
                    {
                        RemoveRootNotifier(folder);
                        RemovePredefinedNode(SystemContext, folder, new List <LocalReference>());
                    }
                }
            }
        }