/// <summary> /// Browse all variables in the objects folder. /// </summary> private IList <INode> BrowseAllVariables() { var result = new List <INode>(); var nodesToBrowse = new ExpandedNodeIdCollection(); nodesToBrowse.Add(ObjectIds.ObjectsFolder); while (nodesToBrowse.Count > 0) { var nextNodesToBrowse = new ExpandedNodeIdCollection(); foreach (var node in nodesToBrowse) { try { var organizers = _session.NodeCache.FindReferences( node, ReferenceTypeIds.Organizes, false, false); var components = _session.NodeCache.FindReferences( node, ReferenceTypeIds.HasComponent, false, false); var properties = _session.NodeCache.FindReferences( node, ReferenceTypeIds.HasProperty, false, false); nextNodesToBrowse.AddRange(organizers .Where(n => n is ObjectNode) .Select(n => n.NodeId).ToList()); nextNodesToBrowse.AddRange(components .Where(n => n is ObjectNode) .Select(n => n.NodeId).ToList()); result.AddRange(organizers.Where(n => n is VariableNode)); result.AddRange(components.Where(n => n is VariableNode)); result.AddRange(properties.Where(n => n is VariableNode)); } catch (ServiceResultException sre) { if (sre.StatusCode == StatusCodes.BadUserAccessDenied) { Console.WriteLine($"Access denied: Skip node {node}."); } } } nodesToBrowse = nextNodesToBrowse; } return(result); }
/// <summary> /// Load all subTypes and optionally nested subtypes of a type definition. /// Filter for all subtypes or only subtypesoutside the default namespace. /// </summary> private IList <INode> LoadDataTypes( ExpandedNodeId dataType, bool nestedSubTypes = false, bool addRootNode = false, bool filterUATypes = true) { var result = new List <INode>(); var nodesToBrowse = new ExpandedNodeIdCollection(); nodesToBrowse.Add(dataType); if (addRootNode) { var rootNode = m_session.NodeCache.Find(dataType); if (!(rootNode is DataTypeNode)) { throw new ServiceResultException("Root Node is not a DataType node."); } result.Add(rootNode); } while (nodesToBrowse.Count > 0) { var nextNodesToBrowse = new ExpandedNodeIdCollection(); foreach (var node in nodesToBrowse) { var response = m_session.NodeCache.FindReferences( node, ReferenceTypeIds.HasSubtype, false, false); if (nestedSubTypes) { nextNodesToBrowse.AddRange(response.Select(r => r.NodeId).ToList()); } if (filterUATypes) { // filter out default namespace result.AddRange(response.Where(rd => rd.NodeId.NamespaceIndex != 0)); } else { result.AddRange(response); } } nodesToBrowse = nextNodesToBrowse; } return(result); }
/// <summary> /// Reads an ExpandedNodeId array from the stream. /// </summary> public ExpandedNodeIdCollection ReadExpandedNodeIdArray(string fieldName) { bool isNil = false; ExpandedNodeIdCollection values = new ExpandedNodeIdCollection(); if (BeginField(fieldName, true, out isNil)) { PushNamespace(Namespaces.OpcUaXsd); while (MoveToElement("ExpandedNodeId")) { values.Add(ReadExpandedNodeId("ExpandedNodeId")); } // check the length. if (m_context.MaxArrayLength > 0 && m_context.MaxArrayLength < values.Count) { throw new ServiceResultException(StatusCodes.BadEncodingLimitsExceeded); } PopNamespace(); EndField(fieldName); return values; } if (isNil) { return null; } return values; }
/// <summary> /// Reads an ExpandedNodeId array from the stream. /// </summary> public ExpandedNodeIdCollection ReadExpandedNodeIdArray(string fieldName) { int length = ReadArrayLength(); if (length == -1) { return null; } ExpandedNodeIdCollection values = new ExpandedNodeIdCollection(length); for (int ii = 0; ii < length; ii++) { values.Add(ReadExpandedNodeId(null)); } return values; }
/// <summary> /// Reads an ExpandedNodeId array from the stream. /// </summary> public ExpandedNodeIdCollection ReadExpandedNodeIdArray(string fieldName) { var values = new ExpandedNodeIdCollection(); List<object> token = null; if (!ReadArrayField(fieldName, out token)) { return values; } for (int ii = 0; ii < token.Count; ii++) { try { m_stack.Push(token[ii]); var element = ReadExpandedNodeId(null); values.Add(element); } finally { m_stack.Pop(); } } return values; }
/// <summary> /// Finds a set of nodes in the nodeset, /// fetches missing nodes from server. /// </summary> /// <param name="nodeIds">The node identifier collection.</param> public IList <INode> Find(IList <ExpandedNodeId> nodeIds) { // check for null. if (nodeIds == null || nodeIds.Count == 0) { return(new List <INode>()); } int count = nodeIds.Count; IList <INode> nodes = new List <INode>(count); var fetchNodeIds = new ExpandedNodeIdCollection(); int ii; for (ii = 0; ii < count; ii++) { // check if node already exists. INode node = m_nodes.Find(nodeIds[ii]); // do not return temporary nodes created after a Browse(). if (node != null && node?.GetType() != typeof(Node)) { nodes.Add(node); } else { nodes.Add(null); fetchNodeIds.Add(nodeIds[ii]); } } if (fetchNodeIds.Count == 0) { return(nodes); } // fetch missing nodes from server. IList <Node> fetchedNodes; try { fetchedNodes = FetchNodes(fetchNodeIds); } catch (Exception e) { Utils.LogError("Could not fetch nodes from server: Reason='{1}'.", e.Message); // m_nodes[nodeId] = null; return(nodes); } ii = 0; foreach (Node fetchedNode in fetchedNodes) { while (ii < count && nodes[ii] != null) { ii++; } if (ii < count && nodes[ii] == null) { nodes[ii++] = fetchedNode; } else { Utils.LogError("Inconsistency fetching nodes from server. Not all nodes could be assigned."); break; } } return(nodes); }