Пример #1
0
        /// <summary>
        /// Adds a single hop path for all references for the node.
        /// </summary>
        private void AddSingleHopPaths(Node node, BrowsePathCollection pathsToTranslate)
        {
            ReferenceDescriptionCollection references = node.Handle as ReferenceDescriptionCollection;

            if (references == null)
            {
                return;
            }

            for (int ii = 0; ii < references.Count; ii++)
            {
                BrowsePath browsePath = new BrowsePath();
                browsePath.StartingNode = node.NodeId;
                browsePath.Handle       = node;

                RelativePathElement element = new RelativePathElement();

                element.ReferenceTypeId = references[ii].ReferenceTypeId;
                element.IsInverse       = !references[ii].IsForward;
                element.IncludeSubtypes = false;
                element.TargetName      = references[ii].BrowseName;

                browsePath.RelativePath.Elements.Add(element);
                pathsToTranslate.Add(browsePath);
            }
        }
Пример #2
0
        /// <summary>
        /// Parses a relative path formatted as a string.
        /// </summary>
        public static RelativePath Parse(string browsePath, ITypeTable typeTree)
        {
            if (typeTree == null)
            {
                throw new ArgumentNullException("typeTree");
            }

            // parse the string.
            RelativePathFormatter formatter = RelativePathFormatter.Parse(browsePath);

            // convert the browse names to node ids.
            RelativePath relativePath = new RelativePath();

            foreach (RelativePathFormatter.Element element in formatter.Elements)
            {
                RelativePathElement parsedElement = new RelativePathElement();

                parsedElement.ReferenceTypeId = null;
                parsedElement.IsInverse       = false;
                parsedElement.IncludeSubtypes = element.IncludeSubtypes;
                parsedElement.TargetName      = element.TargetName;

                switch (element.ElementType)
                {
                case RelativePathFormatter.ElementType.AnyHierarchical: {
                    parsedElement.ReferenceTypeId = ReferenceTypeIds.HierarchicalReferences;
                    break;
                }

                case RelativePathFormatter.ElementType.AnyComponent: {
                    parsedElement.ReferenceTypeId = ReferenceTypeIds.Aggregates;
                    break;
                }

                case RelativePathFormatter.ElementType.ForwardReference: {
                    parsedElement.ReferenceTypeId = typeTree.FindReferenceType(element.ReferenceTypeName);
                    break;
                }

                case RelativePathFormatter.ElementType.InverseReference: {
                    parsedElement.ReferenceTypeId = typeTree.FindReferenceType(element.ReferenceTypeName);
                    parsedElement.IsInverse       = true;
                    break;
                }
                }

                if (NodeId.IsNull(parsedElement.ReferenceTypeId))
                {
                    throw ServiceResultException.Create(
                              StatusCodes.BadSyntaxError,
                              "Could not convert BrowseName to a ReferenceTypeId: {0}",
                              element.ReferenceTypeName);
                }

                relativePath.Elements.Add(parsedElement);
            }

            return(relativePath);
        }
        /// <summary>
        /// Creates a relative path to follow the forward reference type to find the specified browse name.
        /// </summary>
        public RelativePath(NodeId referenceTypeId, bool isInverse, bool includeSubtypes, QualifiedName browseName)
        {
            Initialize();

            RelativePathElement element = new RelativePathElement();

            element.ReferenceTypeId = referenceTypeId;
            element.IsInverse       = isInverse;
            element.IncludeSubtypes = includeSubtypes;
            element.TargetName      = browseName;

            m_elements.Add(element);
        }                 
Пример #4
0
        /// <summary>
        /// Creates a relative path to follow the forward reference type to find the specified browse name.
        /// </summary>
        public RelativePath(NodeId referenceTypeId, bool isInverse, bool includeSubtypes, QualifiedName browseName)
        {
            Initialize();

            RelativePathElement element = new RelativePathElement();

            element.ReferenceTypeId = referenceTypeId;
            element.IsInverse       = isInverse;
            element.IncludeSubtypes = includeSubtypes;
            element.TargetName      = browseName;

            m_elements.Add(element);
        }
        /// <summary>
        /// Format relative path element information
        /// </summary>
        /// <param name="element"></param>
        /// <param name="context"></param>
        /// <returns></returns>
        private static string FormatRelativePathElement(RelativePathElement element,
                                                        ServiceMessageContext context)
        {
            var value          = "";
            var writeReference = false;

            if (element.ReferenceTypeId == ReferenceTypeIds.HierarchicalReferences)
            {
                value += "/";
            }
            else if (element.ReferenceTypeId == ReferenceTypeIds.Aggregates)
            {
                value += ".";
            }
            else if (element.ReferenceTypeId != ReferenceTypeIds.References)
            {
                value         += "<";
                writeReference = true;
            }
            if (element.IsInverse)
            {
                value += "!";
            }
            if (!element.IncludeSubtypes)
            {
                value += "#";
            }
            if (writeReference)
            {
                string reference = null;
                if (element.ReferenceTypeId.NamespaceIndex == 0 &&
                    element.ReferenceTypeId.Identifier is uint id)
                {
                    TypeMaps.ReferenceTypes.Value.TryGetBrowseName(id, out reference);
                }
                if (string.IsNullOrEmpty(reference))
                {
                    reference = element.ReferenceTypeId.AsString(context);
                }
                // TODO: Escape <,>,/,:,&,.
                value += reference + ">";
            }
            var target = element.TargetName.AsString(context);

            // TODO: Escape <,>,/,:,&,.
            value += target;
            return(value);
        }
Пример #6
0
        /// <summary>
        /// Constructs an operand from a value.
        /// </summary>
        /// <param name="nodeId">The node identifier.</param>
        /// <param name="browsePath">The browse path.</param>
        public AttributeOperand(
            NodeId nodeId,
            QualifiedName browsePath)
        {
            m_nodeId      = nodeId;
            m_attributeId = Attributes.Value;

            m_browsePath = new RelativePath();

            RelativePathElement element = new RelativePathElement();

            element.ReferenceTypeId = ReferenceTypeIds.Aggregates;
            element.IsInverse       = false;
            element.IncludeSubtypes = true;
            element.TargetName      = browsePath;

            m_browsePath.Elements.Add(element);
        }
Пример #7
0
        /// <summary>
        /// Constructs an operand from a value.
        /// </summary>
        /// <param name="nodeId">The node identifier.</param>
        /// <param name="browsePaths">The browse paths.</param>
        public AttributeOperand(
            NodeId nodeId,
            IList <QualifiedName> browsePaths)
        {
            m_nodeId      = nodeId;
            m_attributeId = Attributes.Value;
            m_browsePath  = new RelativePath();

            for (int ii = 0; ii < browsePaths.Count; ii++)
            {
                RelativePathElement element = new RelativePathElement();

                element.ReferenceTypeId = ReferenceTypeIds.Aggregates;
                element.IsInverse       = false;
                element.IncludeSubtypes = true;
                element.TargetName      = browsePaths[ii];

                m_browsePath.Elements.Add(element);
            }
        }
Пример #8
0
        public virtual StatusCode HandleTranslateBrowsePathRequest(
            object session,
            BrowsePath path,
            List <BrowsePathTarget> res)
        {
            if (!this.AddressSpaceTable.TryGetValue(path.StartingNode, out Node node1) || !this.SessionHasPermissionToRead(session, path.StartingNode))
            {
                return(StatusCode.BadNodeIdUnknown);
            }

            for (int index1 = 0; index1 < path.RelativePath.Length; ++index1)
            {
                RelativePathElement relativePathElement = path.RelativePath[index1];
                ReferenceNode       referenceNode       = null;
                for (int index2 = 0; index2 < node1.References.Count; ++index2)
                {
                    ReferenceNode reference = node1.References[index2];
                    if (relativePathElement.IsInverse == reference.IsInverse && (relativePathElement.IncludeSubtypes || reference.ReferenceType.Equals(relativePathElement.ReferenceTypeId)) && ((!relativePathElement.IncludeSubtypes || this.IsSubtypeOrEqual(reference.ReferenceType, relativePathElement.ReferenceTypeId)) && (this.AddressSpaceTable.TryGetValue(reference.Target, out Node node2) && this.SessionHasPermissionToRead(session, reference.Target) && node2.BrowseName.Equals(relativePathElement.TargetName))))
                    {
                        referenceNode = node1.References[index2];
                        node1         = node2;
                        break;
                    }
                }
                if (referenceNode == null || node1 == null)
                {
                    res.Add(new BrowsePathTarget()
                    {
                        Target             = node1.Id,
                        RemainingPathIndex = (uint)index1
                    });
                    return(StatusCode.BadNoMatch);
                }
            }
            res.Add(new BrowsePathTarget()
            {
                Target             = node1.Id,
                RemainingPathIndex = (uint)path.RelativePath.Length
            });
            return(StatusCode.Good);
        }
Пример #9
0
            /// <summary>
            /// Initializes the object from a RelativePathElement
            /// </summary>
            public Element(RelativePathElement element, ITypeTable typeTree)
            {
                if (element == null)
                {
                    throw new ArgumentNullException("element");
                }
                if (typeTree == null)
                {
                    throw new ArgumentNullException("typeTree");
                }

                m_referenceTypeName = null;
                m_targetName        = element.TargetName;
                m_elementType       = RelativePathFormatter.ElementType.ForwardReference;
                m_includeSubtypes   = element.IncludeSubtypes;

                if (!element.IsInverse && element.IncludeSubtypes)
                {
                    if (element.ReferenceTypeId == ReferenceTypeIds.HierarchicalReferences)
                    {
                        m_elementType = RelativePathFormatter.ElementType.AnyHierarchical;
                    }
                    else if (element.ReferenceTypeId == ReferenceTypeIds.Aggregates)
                    {
                        m_elementType = RelativePathFormatter.ElementType.AnyComponent;
                    }
                    else
                    {
                        m_referenceTypeName = typeTree.FindReferenceTypeName(element.ReferenceTypeId);
                    }
                }
                else
                {
                    if (element.IsInverse)
                    {
                        m_elementType = RelativePathFormatter.ElementType.InverseReference;
                    }

                    m_referenceTypeName = typeTree.FindReferenceTypeName(element.ReferenceTypeId);
                }
            }
Пример #10
0
        /// <summary>
        /// Constructs the browse path.
        /// </summary>
        /// <param name="nodeId">The node id.</param>
        /// <param name="hdaAttributeId">The hda attribute id.</param>
        /// <param name="browsePaths">The browse paths.</param>
        /// <returns></returns>
        private BrowsePath Construct(NodeId nodeId, uint hdaAttributeId, params string[] browsePaths)
        {
            BrowsePath browsePath = new BrowsePath();

            browsePath.StartingNode = nodeId;
            browsePath.Handle       = hdaAttributeId;

            for (int ii = 0; ii < browsePaths.Length; ii++)
            {
                RelativePathElement element = new RelativePathElement();

                element.ReferenceTypeId = ReferenceTypeIds.HasChild;
                element.IsInverse       = false;
                element.IncludeSubtypes = true;
                element.TargetName      = browsePaths[ii];

                browsePath.RelativePath.Elements.Add(element);
            }

            return(browsePath);
        }
Пример #11
0
        /// <summary>
        /// Recursively collects the variables in a NodeState and returns a collection of BrowsePaths.
        /// </summary>
        public void GetBrowsePathFromNodeState(
            ISystemContext context,
            NodeId rootId,
            NodeState parent,
            RelativePath parentPath,
            BrowsePathCollection browsePaths)
        {
            List <BaseInstanceState> children = new List <BaseInstanceState>();

            parent.GetChildren(context, children);

            for (int ii = 0; ii < children.Count; ii++)
            {
                BaseInstanceState child = children[ii];

                BrowsePath browsePath = new BrowsePath();
                browsePath.StartingNode = rootId;
                browsePath.Handle       = child;

                if (parentPath != null)
                {
                    browsePath.RelativePath.Elements.AddRange(parentPath.Elements);
                }

                RelativePathElement element = new RelativePathElement();
                element.ReferenceTypeId = child.ReferenceTypeId;
                element.IsInverse       = false;
                element.IncludeSubtypes = false;
                element.TargetName      = child.BrowseName;

                browsePath.RelativePath.Elements.Add(element);

                if (child.NodeClass == NodeClass.Variable)
                {
                    browsePaths.Add(browsePath);
                }

                GetBrowsePathFromNodeState(context, rootId, child, browsePath.RelativePath, browsePaths);
            }
        }
        /// <summary>
        /// Returns the target of the specified browse path fragment(s).
        /// </summary>
        /// <remarks>
        /// If reference exists but the node manager does not know the browse name it must 
        /// return the NodeId as an unresolvedTargetIds. The caller will try to check the
        /// browse name. 
        /// </remarks>
        public virtual void TranslateBrowsePath(
            OperationContext      context, 
            object                sourceHandle, 
            RelativePathElement   relativePath, 
            IList<ExpandedNodeId> targetIds, 
            IList<NodeId>         unresolvedTargetIds)
        {
            ServerSystemContext systemContext = m_systemContext.Copy(context);
            IDictionary<NodeId,NodeState> operationCache = new NodeIdDictionary<NodeState>();

            lock (Lock)
            {
                // verify that the node exists.
                NodeState source = IsHandleInNamespace(sourceHandle);

                if (source == null)
                {
                    return;
                }

                // validate node.
                if (!ValidateNode(systemContext, source))
                {
                    return;
                }

                // get list of references that relative path.
                INodeBrowser browser = source.CreateBrowser(
                    systemContext,
                    null,
                    relativePath.ReferenceTypeId,
                    relativePath.IncludeSubtypes,
                    (relativePath.IsInverse) ? BrowseDirection.Inverse : BrowseDirection.Forward,
                    relativePath.TargetName,
                    null,
                    false);

                // check the browse names.
                try
                {
                    for (IReference reference = browser.Next(); reference != null; reference = browser.Next())
                    {
                        // ignore unknown external references.
                        if (reference.TargetId.IsAbsolute)
                        {
                            continue;
                        }

                        NodeState target = null;

                        // check for local reference.
                        NodeStateReference referenceInfo = reference as NodeStateReference;

                        if (referenceInfo != null)
                        {
                            target = referenceInfo.Target;
                        }

                        if (target == null)
                        {
                            NodeId targetId = (NodeId)reference.TargetId;

                            // the target may be a reference to a node in another node manager.
                            if (!IsNodeIdInNamespace(targetId))
                            {
                                unresolvedTargetIds.Add((NodeId)reference.TargetId);
                                continue;
                            }

                            // look up the target manually.
                            target = GetManagerHandle(systemContext, targetId, operationCache) as NodeState;

                            if (target == null)
                            {
                                continue;
                            }
                        }

                        // check browse name.
                        if (target.BrowseName == relativePath.TargetName)
                        {
                            targetIds.Add(reference.TargetId);
                        }
                    }
                }
                finally
                {
                    browser.Dispose();
                }
            }
        }
Пример #13
0
        /// <summary>
        /// Finds an element identified by the path from the root.
        /// </summary>
        private AeBrowseElement Find(Session session, string itemId, AeBrowseElement root, Stack <string> names, bool isArea)
        {
            string browseText = null;

            BrowsePath browsePath = new BrowsePath();

            browsePath.StartingNode = root.NodeId;

            while (names.Count > 0)
            {
                RelativePathElement path = new RelativePathElement();

                path.ReferenceTypeId = Opc.Ua.ReferenceTypeIds.HasNotifier;
                path.IsInverse       = false;
                path.IncludeSubtypes = true;

                // final hop can be HasEventSource for sources.
                if (!isArea && names.Count == 1)
                {
                    path.ReferenceTypeId = Opc.Ua.ReferenceTypeIds.HasEventSource;
                }

                browseText      = names.Pop();
                path.TargetName = m_mapper.GetRemoteBrowseName(browseText);
                browsePath.RelativePath.Elements.Add(path);
            }

            BrowsePathCollection browsePaths = new BrowsePathCollection();

            browsePaths.Add(browsePath);

            // make the call to the server.
            BrowsePathResultCollection results;
            DiagnosticInfoCollection   diagnosticInfos;

            ResponseHeader responseHeader = session.TranslateBrowsePathsToNodeIds(
                null,
                browsePaths,
                out results,
                out diagnosticInfos);

            // ensure that the server returned valid results.
            Session.ValidateResponse(results, browsePaths);
            Session.ValidateDiagnosticInfos(diagnosticInfos, browsePaths);

            // check if the start node actually exists.
            if (StatusCode.IsBad(results[0].StatusCode))
            {
                return(null);
            }

            // must be exact one target.
            if (results[0].Targets.Count != 1)
            {
                return(null);
            }

            // can't be an external reference.
            BrowsePathTarget target = results[0].Targets[0];

            if (target.RemainingPathIndex != UInt32.MaxValue)
            {
                return(null);
            }

            // need to check if at the end of the tree.
            BrowseDescription nodeToBrowse = new BrowseDescription();

            nodeToBrowse.NodeId          = (NodeId)target.TargetId;
            nodeToBrowse.ReferenceTypeId = Opc.Ua.ReferenceTypeIds.HasEventSource;
            nodeToBrowse.BrowseDirection = BrowseDirection.Forward;
            nodeToBrowse.IncludeSubtypes = true;

            ReferenceDescriptionCollection children = ComAeUtils.Browse(session, nodeToBrowse, false);

            if (!isArea)
            {
                if (children != null && children.Count > 0)
                {
                    return(null);
                }
            }
            else
            {
                if (children == null || children.Count == 0)
                {
                    return(null);
                }
            }

            // construct the element.
            AeBrowseElement element = new AeBrowseElement();

            element.NodeId     = (NodeId)target.TargetId;
            element.ItemId     = itemId;
            element.BrowseText = browseText;
            element.IsArea     = isArea;

            return(element);
        }
Пример #14
0
        /// <summary>
        /// Adds a single hop path for all references for the node.
        /// </summary>
        private void AddMultiHopPaths(
            Node node,
            Node baseNode,
            IList <RelativePathElement> basePath,
            BrowsePathCollection pathsToTranslate,
            int hops)
        {
            ReferenceDescriptionCollection references = node.Handle as ReferenceDescriptionCollection;

            if (references == null)
            {
                return;
            }

            for (int ii = 0; ii < references.Count; ii++)
            {
                ReferenceDescription reference = references[ii];

                BrowsePath browsePath = new BrowsePath();

                browsePath.StartingNode = baseNode.NodeId;
                browsePath.Handle       = baseNode;

                if (basePath != null)
                {
                    browsePath.RelativePath.Elements.AddRange(basePath);
                }

                RelativePathElement element = new RelativePathElement();

                element.ReferenceTypeId = ReferenceTypeIds.NonHierarchicalReferences;
                element.IsInverse       = !reference.IsForward;
                element.IncludeSubtypes = true;
                element.TargetName      = reference.BrowseName;

                browsePath.RelativePath.Elements.Add(element);
                pathsToTranslate.Add(browsePath);

                // only follow forward heiarchical
                if (!Session.TypeTree.IsTypeOf(reference.ReferenceTypeId, ReferenceTypeIds.HierarchicalReferences))
                {
                    continue;
                }

                element.ReferenceTypeId = ReferenceTypeIds.HierarchicalReferences;

                // can't do anything with absolute or inverse references.
                if (!reference.IsForward || reference.NodeId.IsAbsolute)
                {
                    continue;
                }

                // look up target
                if (browsePath.RelativePath.Elements.Count < hops)
                {
                    Node target = null;

                    if (!AvailableNodes.TryGetValue((NodeId)reference.NodeId, out target))
                    {
                        continue;
                    }

                    AddMultiHopPaths(target, baseNode, browsePath.RelativePath.Elements, pathsToTranslate, hops);
                }
            }
        }
Пример #15
0
        /// <summary>
        /// Recursively finds the targets of the specified path.
        /// </summary>
        private void GetTargets(Node start, IList <RelativePathElement> path, int index, BrowsePathResult result)
        {
            // check for invalid parameters.
            if (index >= path.Count)
            {
                return;
            }

            // look for list of references for node.
            ReferenceDescriptionCollection references = start.Handle as ReferenceDescriptionCollection;

            if (references == null || references.Count == 0)
            {
                return;
            }

            RelativePathElement element = path[index];

            // each list of references.
            for (int ii = 0; ii < references.Count; ii++)
            {
                ReferenceDescription reference = references[ii];

                // check for a reference match.
                if (element.IsInverse == reference.IsForward)
                {
                    continue;
                }

                if (element.ReferenceTypeId != reference.ReferenceTypeId)
                {
                    if (!element.IncludeSubtypes)
                    {
                        continue;
                    }

                    if (!Session.TypeTree.IsTypeOf(reference.ReferenceTypeId, element.ReferenceTypeId))
                    {
                        continue;
                    }
                }

                // check for a browse name match.
                if (element.TargetName != reference.BrowseName)
                {
                    continue;
                }

                // check for end of list.
                if (index == path.Count - 1)
                {
                    BrowsePathTarget item = new BrowsePathTarget();
                    item.TargetId           = reference.NodeId;
                    item.RemainingPathIndex = UInt32.MaxValue;
                    result.Targets.Add(item);
                    continue;
                }

                // check for external reference.
                if (reference.NodeId.IsAbsolute)
                {
                    BrowsePathTarget item = new BrowsePathTarget();
                    item.TargetId           = reference.NodeId;
                    item.RemainingPathIndex = (uint)index + 1;
                    result.Targets.Add(item);
                    continue;
                }

                // check for targets.
                Node target = null;

                if (!AvailableNodes.TryGetValue((NodeId)reference.NodeId, out target))
                {
                    BrowsePathTarget item = new BrowsePathTarget();
                    item.TargetId           = reference.NodeId;
                    item.RemainingPathIndex = (uint)index + 1;
                    result.Targets.Add(item);
                    continue;
                }

                // recursively follow targets.
                GetTargets(target, path, index + 1, result);
            }
        }
        /// <see cref="INodeManager.TranslateBrowsePath(OperationContext,object,RelativePathElement,IList{ExpandedNodeId},IList{NodeId})" />
        public void TranslateBrowsePath(
            OperationContext      context,
            object                sourceHandle, 
            RelativePathElement   relativePath, 
            IList<ExpandedNodeId> targetIds,
            IList<NodeId>         unresolvedTargetIds)
        {
            if (sourceHandle == null) throw new ArgumentNullException("sourceHandle");
            if (relativePath == null) throw new ArgumentNullException("relativePath");
            if (targetIds == null) throw new ArgumentNullException("targetIds");
            if (unresolvedTargetIds == null) throw new ArgumentNullException("unresolvedTargetIds");

            // check for valid handle.
            ILocalNode source = sourceHandle as ILocalNode;

            if (source == null)
            {
                return;
            }
            
            lock(m_lock)
            {
                // find the references that meet the filter criteria.
                IList<IReference> references = source.References.Find(
                    relativePath.ReferenceTypeId, 
                    relativePath.IsInverse, 
                    relativePath.IncludeSubtypes, 
                    m_server.TypeTree);

                // nothing more to do.
                if (references == null || references.Count == 0)
                {
                    return;
                }

                // find targets with matching browse names.
                foreach (IReference reference in references)
                {
                    INode target = GetLocalNode(reference.TargetId);

                    // target is not known to the node manager.
                    if (target == null)
                    {
                        // ignore unknown external references.
                        if (reference.TargetId.IsAbsolute)
                        {
                            continue;
                        }

                        // caller must check the browse name.
                        unresolvedTargetIds.Add((NodeId)reference.TargetId);
                        continue;
                    }

                    // check browse name.
                    if (target.BrowseName == relativePath.TargetName)
                    {
                        targetIds.Add(reference.TargetId);
                    }
                }
            }
        }
Пример #17
0
        /// <summary>
        /// Updates the list of references.
        /// </summary>
        private void UpdateArguments(Session session, NodeId nodeId)
        {
            ArgumentsLV.Items.Clear();

            // need to fetch the node ids for the argument properties.
            BrowsePathCollection browsePaths = new BrowsePathCollection();

            foreach (string browseName in new string[] { BrowseNames.InputArguments, BrowseNames.OutputArguments })
            {
                BrowsePath browsePath = new BrowsePath();
                browsePath.StartingNode = nodeId;
                browsePath.Handle       = browseName;

                RelativePathElement element = new RelativePathElement();
                element.ReferenceTypeId = ReferenceTypeIds.HasProperty;
                element.IsInverse       = false;
                element.IncludeSubtypes = true;
                element.TargetName      = browseName;

                browsePath.RelativePath.Elements.Add(element);
                browsePaths.Add(browsePath);
            }

            // translate property names.
            BrowsePathResultCollection results         = null;
            DiagnosticInfoCollection   diagnosticInfos = null;

            session.TranslateBrowsePathsToNodeIds(
                null,
                browsePaths,
                out results,
                out diagnosticInfos);

            ClientBase.ValidateResponse(results, browsePaths);
            ClientBase.ValidateDiagnosticInfos(diagnosticInfos, browsePaths);

            // create a list of values to read.
            ReadValueIdCollection valuesToRead = new ReadValueIdCollection();

            for (int ii = 0; ii < results.Count; ii++)
            {
                if (StatusCode.IsBad(results[ii].StatusCode) || results[ii].Targets.Count <= 0)
                {
                    continue;
                }

                ReadValueId valueToRead = new ReadValueId();
                valueToRead.NodeId      = (NodeId)results[ii].Targets[0].TargetId;
                valueToRead.AttributeId = Attributes.Value;
                valueToRead.Handle      = browsePaths[ii].Handle;
                valuesToRead.Add(valueToRead);
            }

            // read the values.
            if (valuesToRead.Count > 0)
            {
                DataValueCollection values = null;

                session.Read(
                    null,
                    0,
                    TimestampsToReturn.Neither,
                    valuesToRead,
                    out values,
                    out diagnosticInfos);

                ClientBase.ValidateResponse(results, valuesToRead);
                ClientBase.ValidateDiagnosticInfos(diagnosticInfos, valuesToRead);

                // update the list control.
                for (int ii = 0; ii < values.Count; ii++)
                {
                    // all structures are wrapped in extension objects.
                    ExtensionObject[] extensions = values[ii].GetValue <ExtensionObject[]>(null);

                    if (extensions != null)
                    {
                        // convert to an argument structure.
                        Argument[] arguments = (Argument[])ExtensionObject.ToArray(extensions, typeof(Argument));
                        UpdateList(session, arguments, (string)valuesToRead[ii].Handle);
                    }
                }
            }

            // auto size the columns.
            for (int ii = 0; ii < ArgumentsLV.Columns.Count; ii++)
            {
                ArgumentsLV.Columns[ii].Width = -2;
            }
        }
Пример #18
0
        /// <summary>
        /// Constructs the browse path.
        /// </summary>
        /// <param name="nodeId">The node id.</param>
        /// <param name="hdaAttributeId">The hda attribute id.</param>
        /// <param name="browsePaths">The browse paths.</param>
        /// <returns></returns>
        private BrowsePath Construct(NodeId nodeId, uint hdaAttributeId, params string[] browsePaths)
        {
            BrowsePath browsePath = new BrowsePath();
            browsePath.StartingNode = nodeId;
            browsePath.Handle = hdaAttributeId;

            for (int ii = 0; ii < browsePaths.Length; ii++)
            {
                RelativePathElement element = new RelativePathElement();

                element.ReferenceTypeId = ReferenceTypeIds.HasChild;
                element.IsInverse = false;
                element.IncludeSubtypes = true;
                element.TargetName = browsePaths[ii];

                browsePath.RelativePath.Elements.Add(element);
            }

            return browsePath;
        }
            /// <summary>
            /// Initializes the object from a RelativePathElement
            /// </summary>
            public Element(RelativePathElement element, ITypeTable typeTree)
            {                
                if (element == null) throw new ArgumentNullException("element");
                if (typeTree == null) throw new ArgumentNullException("typeTree");

                m_referenceTypeName = null;
                m_targetName = element.TargetName;
                m_elementType = RelativePathFormatter.ElementType.ForwardReference;
                m_includeSubtypes = element.IncludeSubtypes;

                if (!element.IsInverse && element.IncludeSubtypes)
                {
                    if (element.ReferenceTypeId == ReferenceTypeIds.HierarchicalReferences)
                    {
                        m_elementType = RelativePathFormatter.ElementType.AnyHierarchical;
                    }
                    else if (element.ReferenceTypeId == ReferenceTypeIds.Aggregates)
                    {
                        m_elementType = RelativePathFormatter.ElementType.AnyComponent;
                    }
                    else
                    {
                        m_referenceTypeName = typeTree.FindReferenceTypeName(element.ReferenceTypeId);
                    }
                }
                else
                {
                    if (element.IsInverse)
                    {
                        m_elementType = RelativePathFormatter.ElementType.InverseReference;
                    }

                    m_referenceTypeName = typeTree.FindReferenceTypeName(element.ReferenceTypeId);
                }
            }
Пример #20
0
        /// <summary>
        /// Finds an element identified by the path from the root.
        /// </summary>
        private AeBrowseElement Find(Session session, string itemId, AeBrowseElement root, Stack<string> names, bool isArea)
        {
            string browseText = null;

            BrowsePath browsePath = new BrowsePath();
            browsePath.StartingNode = root.NodeId;

            while (names.Count > 0)
            {
                RelativePathElement path = new RelativePathElement();

                path.ReferenceTypeId = Opc.Ua.ReferenceTypeIds.HasNotifier;
                path.IsInverse = false;
                path.IncludeSubtypes = true;

                // final hop can be HasEventSource for sources.
                if (!isArea && names.Count == 1)
                {
                    path.ReferenceTypeId = Opc.Ua.ReferenceTypeIds.HasEventSource;
                }

                browseText = names.Pop();
                path.TargetName = m_mapper.GetRemoteBrowseName(browseText);
                browsePath.RelativePath.Elements.Add(path);
            }

            BrowsePathCollection browsePaths = new BrowsePathCollection();
            browsePaths.Add(browsePath);

            // make the call to the server.
            BrowsePathResultCollection results;
            DiagnosticInfoCollection diagnosticInfos;

            ResponseHeader responseHeader = session.TranslateBrowsePathsToNodeIds(
                null,
                browsePaths,
                out results,
                out diagnosticInfos);

            // ensure that the server returned valid results.
            Session.ValidateResponse(results, browsePaths);
            Session.ValidateDiagnosticInfos(diagnosticInfos, browsePaths);

            // check if the start node actually exists.
            if (StatusCode.IsBad(results[0].StatusCode))
            {
                return null;
            }

            // must be exact one target.
            if (results[0].Targets.Count != 1)
            {
                return null;
            }

            // can't be an external reference.
            BrowsePathTarget target = results[0].Targets[0];

            if (target.RemainingPathIndex != UInt32.MaxValue)
            {
                return null;
            }

            // need to check if at the end of the tree.
            BrowseDescription nodeToBrowse = new BrowseDescription();
            nodeToBrowse.NodeId = (NodeId)target.TargetId;
            nodeToBrowse.ReferenceTypeId = Opc.Ua.ReferenceTypeIds.HasEventSource;
            nodeToBrowse.BrowseDirection = BrowseDirection.Forward;
            nodeToBrowse.IncludeSubtypes = true;

            ReferenceDescriptionCollection children = ComAeUtils.Browse(session, nodeToBrowse, false);

            if (!isArea)
            {
                if (children != null && children.Count > 0)
                {
                    return null;
                }
            }
            else
            {
                if (children == null || children.Count == 0)
                {
                    return null;
                }
            }

            // construct the element.
            AeBrowseElement element = new AeBrowseElement();
            element.NodeId = (NodeId)target.TargetId;
            element.ItemId = itemId;
            element.BrowseText = browseText;
            element.IsArea = isArea;

            return element;
        }
Пример #21
0
        /// <summary>
        /// Reads the historical configuration for the node.
        /// </summary>
        private HistoricalDataConfigurationState ReadConfiguration()
        {
            // load the defaults for the historical configuration object. 
            HistoricalDataConfigurationState configuration = new HistoricalDataConfigurationState(null);

            configuration.Definition = new PropertyState<string>(configuration);
            configuration.MaxTimeInterval = new PropertyState<double>(configuration);
            configuration.MinTimeInterval = new PropertyState<double>(configuration);
            configuration.ExceptionDeviation = new PropertyState<double>(configuration);
            configuration.ExceptionDeviationFormat = new PropertyState<ExceptionDeviationFormat>(configuration);
            configuration.StartOfArchive = new PropertyState<DateTime>(configuration);
            configuration.StartOfOnlineArchive = new PropertyState<DateTime>(configuration);

            configuration.Create(
                m_session.SystemContext,
                null,
                Opc.Ua.BrowseNames.HAConfiguration,
                null,
                false);
            
            // get the browse paths to query.
            RelativePathElement element = new RelativePathElement();
            element.ReferenceTypeId = Opc.Ua.ReferenceTypeIds.HasHistoricalConfiguration;
            element.IsInverse = false;
            element.IncludeSubtypes = false;
            element.TargetName = Opc.Ua.BrowseNames.HAConfiguration;

            RelativePath relativePath = new RelativePath();
            relativePath.Elements.Add(element);

            BrowsePathCollection pathsToTranslate = new BrowsePathCollection();

            GetBrowsePathFromNodeState(
                m_session.SystemContext,
                m_nodeId,
                configuration,
                relativePath,
                pathsToTranslate);

            // translate browse paths.
            BrowsePathResultCollection results = null;
            DiagnosticInfoCollection diagnosticInfos = null;

            m_session.TranslateBrowsePathsToNodeIds(
                null,
                pathsToTranslate,
                out results,
                out diagnosticInfos);

            ClientBase.ValidateResponse(results, pathsToTranslate);
            ClientBase.ValidateDiagnosticInfos(diagnosticInfos, pathsToTranslate);

            // build list of values to read.
            ReadValueIdCollection valuesToRead = new ReadValueIdCollection();

            for (int ii = 0; ii < pathsToTranslate.Count; ii++)
            {
                BaseVariableState variable = (BaseVariableState)pathsToTranslate[ii].Handle;
                variable.Value = null;
                variable.StatusCode = StatusCodes.BadNotSupported;

                if (StatusCode.IsBad(results[ii].StatusCode) || results[ii].Targets.Count == 0)
                {
                    continue;
                }

                if (results[ii].Targets[0].RemainingPathIndex == UInt32.MaxValue && !results[ii].Targets[0].TargetId.IsAbsolute)
                {
                    variable.NodeId = (NodeId)results[ii].Targets[0].TargetId;

                    ReadValueId valueToRead = new ReadValueId();
                    valueToRead.NodeId = variable.NodeId;
                    valueToRead.AttributeId = Attributes.Value;
                    valueToRead.Handle = variable;
                    valuesToRead.Add(valueToRead);
                }
            }
            
            // read the values.
            if (valuesToRead.Count > 0)
            {
                DataValueCollection values = null;

                m_session.Read(
                    null,
                    0,
                    TimestampsToReturn.Neither,
                    valuesToRead,
                    out values,
                    out diagnosticInfos);

                ClientBase.ValidateResponse(values, valuesToRead);
                ClientBase.ValidateDiagnosticInfos(diagnosticInfos, valuesToRead);

                for (int ii = 0; ii < valuesToRead.Count; ii++)
                {
                    BaseVariableState variable = (BaseVariableState)valuesToRead[ii].Handle;
                    variable.WrappedValue = values[ii].WrappedValue;
                    variable.StatusCode = values[ii].StatusCode;
                }
            }

            return configuration;
        }
Пример #22
0
        /// <summary>
        /// Constructs an operand from a value.
        /// </summary>
        /// <param name="nodeId">The node identifier.</param>
        /// <param name="browsePath">The browse path.</param>
        public AttributeOperand(
            NodeId nodeId,
            QualifiedName browsePath)
        {
            m_nodeId = nodeId;
            m_attributeId = Attributes.Value;

            m_browsePath = new RelativePath();

            RelativePathElement element = new RelativePathElement();

            element.ReferenceTypeId = ReferenceTypeIds.Aggregates;
            element.IsInverse = false;
            element.IncludeSubtypes = true;
            element.TargetName = browsePath;

            m_browsePath.Elements.Add(element);
        }
Пример #23
0
        /// <summary>
        /// Recursively collects the variables in a NodeState and returns a collection of BrowsePaths.
        /// </summary>
        public void GetBrowsePathFromNodeState(
            ISystemContext context,
            NodeId rootId,
            NodeState parent,
            RelativePath parentPath,
            BrowsePathCollection browsePaths)
        {
            List<BaseInstanceState> children = new List<BaseInstanceState>();
            parent.GetChildren(context, children);

            for (int ii = 0; ii < children.Count; ii++)
            {
                BaseInstanceState child = children[ii];

                BrowsePath browsePath = new BrowsePath();
                browsePath.StartingNode = rootId;
                browsePath.Handle = child;

                if (parentPath != null)
                {
                    browsePath.RelativePath.Elements.AddRange(parentPath.Elements);
                }

                RelativePathElement element = new RelativePathElement();
                element.ReferenceTypeId = child.ReferenceTypeId;
                element.IsInverse = false;
                element.IncludeSubtypes = false;
                element.TargetName = child.BrowseName;

                browsePath.RelativePath.Elements.Add(element);

                if (child.NodeClass == NodeClass.Variable)
                {
                    browsePaths.Add(browsePath);
                }

                GetBrowsePathFromNodeState(context, rootId, child, browsePath.RelativePath, browsePaths); 
            }
        }
Пример #24
0
        /// <summary>
        /// Updates the EUInfo for the items.
        /// </summary>
        /// <param name="group">The group.</param>
        /// <param name="items">The items. Null entries are ignored.</param>
        public void UpdateItemEuInfo(
            ComDaGroup group,
            IList<ComDaGroupItem> items)
        {
            // get the session to use for the operation.
            Session session = m_session;

            if (session == null)
            {
                throw ComUtils.CreateComException(ResultIds.E_FAIL);
            }

            // build list of properties that need to be read.
            BrowsePathCollection browsePaths = new BrowsePathCollection();

            for (int ii = 0; ii < items.Count; ii++)
            {
                ComDaGroupItem item = (ComDaGroupItem)items[ii];

                // ignore invalid items or items which have already checked their EU type.
                if (item == null || item.EuType >= 0)
                {
                    continue;
                }

                BrowsePath browsePath = new BrowsePath();
                browsePath.StartingNode = item.NodeId;
                RelativePathElement element = new RelativePathElement();
                element.ReferenceTypeId = ReferenceTypeIds.HasProperty;
                element.IsInverse = false;
                element.IncludeSubtypes = false;
                element.TargetName = Opc.Ua.BrowseNames.EURange;
                browsePath.RelativePath.Elements.Add(element);
                browsePath.Handle = item;
                browsePaths.Add(browsePath);

                browsePath = new BrowsePath();
                browsePath.StartingNode = item.NodeId;
                element = new RelativePathElement();
                element.ReferenceTypeId = ReferenceTypeIds.HasProperty;
                element.IsInverse = false;
                element.IncludeSubtypes = false;
                element.TargetName = Opc.Ua.BrowseNames.EnumStrings;
                browsePath.RelativePath.Elements.Add(element);
                browsePath.Handle = item;
                browsePaths.Add(browsePath);
            }

            // check if nothing to do.
            if (browsePaths.Count == 0)
            {
                return;
            }

            // translate browse paths.
            BrowsePathResultCollection results = null;
            DiagnosticInfoCollection diagnosticInfos = null;

            try
            {
                session.TranslateBrowsePathsToNodeIds(
                    null,
                    browsePaths,
                    out results,
                    out diagnosticInfos);

                ClientBase.ValidateResponse(results, browsePaths);
                ClientBase.ValidateDiagnosticInfos(diagnosticInfos, browsePaths);
            }
            catch (Exception)
            {
                for (int ii = 0; ii < browsePaths.Count; ii++)
                {
                    ComDaGroupItem item = (ComDaGroupItem)browsePaths[ii].Handle;
                    item.EuType = 0;
                }

                return;
            }

            // build list of properties that need to be read.
            ReadValueIdCollection propertiesToRead = new ReadValueIdCollection();

            for (int ii = 0; ii < results.Count; ii++)
            {
                ComDaGroupItem item = (ComDaGroupItem)browsePaths[ii].Handle;
                BrowsePathResult result = results[ii];

                if (StatusCode.IsBad(result.StatusCode))
                {
                    if (item.EuType < 0 && result.StatusCode == StatusCodes.BadNoMatch)
                    {
                        item.EuType = (int)OpcRcw.Da.OPCEUTYPE.OPC_NOENUM;
                    }

                    continue;
                }

                if (result.Targets.Count == 0 || result.Targets[0].TargetId.IsAbsolute)
                {
                    if (item.EuType < 0)
                    {
                        item.EuType = (int)OpcRcw.Da.OPCEUTYPE.OPC_NOENUM;
                    }

                    continue;
                }

                ReadValueId propertyToRead = new ReadValueId();
                propertyToRead.NodeId = (NodeId)result.Targets[0].TargetId;
                propertyToRead.AttributeId = Attributes.Value;
                propertyToRead.Handle = item;
                propertiesToRead.Add(propertyToRead);

                if (browsePaths[ii].RelativePath.Elements[0].TargetName.Name == Opc.Ua.BrowseNames.EURange)
                {
                    item.EuType = (int)OpcRcw.Da.OPCEUTYPE.OPC_ANALOG;
                }
                else
                {
                    item.EuType = (int)OpcRcw.Da.OPCEUTYPE.OPC_ENUMERATED;
                }
            }

            // check if nothing to do.
            if (propertiesToRead.Count == 0)
            {
                return;
            }

            // read attribute values from the server.
            DataValueCollection values = null;

            try
            {
                session.Read(
                    null,
                    0,
                    TimestampsToReturn.Neither,
                    propertiesToRead,
                    out values,
                    out diagnosticInfos);

                ClientBase.ValidateResponse(values, propertiesToRead);
                ClientBase.ValidateDiagnosticInfos(diagnosticInfos, propertiesToRead);
            }
            catch (Exception)
            {
                for (int ii = 0; ii < propertiesToRead.Count; ii++)
                {
                    ComDaGroupItem item = (ComDaGroupItem)propertiesToRead[ii].Handle;
                    item.EuType = 0;
                }

                return;
            }

            // process results.
            for (int ii = 0; ii < values.Count; ii++)
            {
                ComDaGroupItem item = (ComDaGroupItem)propertiesToRead[ii].Handle;

                if (StatusCode.IsBad(values[ii].StatusCode))
                {
                    item.EuType = 0;
                    continue;
                }

                if (item.EuType == (int)OpcRcw.Da.OPCEUTYPE.OPC_ANALOG)
                {
                    Range range = (Range)values[ii].GetValue<Range>(null);

                    if (range == null)
                    {
                        item.EuType = 0;
                        continue;
                    }

                    item.EuInfo = new double[] { range.Low, range.High };
                    continue;
                }

                if (item.EuType == (int)OpcRcw.Da.OPCEUTYPE.OPC_ENUMERATED)
                {
                    LocalizedText[] texts = (LocalizedText[])values[ii].GetValue<LocalizedText[]>(null);

                    if (texts == null)
                    {
                        item.EuType = 0;
                        continue;
                    }

                    string[] strings = new string[texts.Length];

                    for (int jj = 0; jj < strings.Length; jj++)
                    {
                        if (!LocalizedText.IsNullOrEmpty(texts[jj]))
                        {
                            strings[jj] = texts[jj].Text;
                        }
                    }

                    item.EuInfo = strings;
                    continue;
                }
            }
        }
Пример #25
0
        /// <summary>
        /// Follows the browse path and returns any targets found.
        /// </summary>
        public void TranslateBrowsePath(
            BrowsePath request,
            BrowsePathResult result,
            DiagnosticInfo diagnosticInfo)
        {
            lock (m_lock)
            {
                // find the starting node.
                Node source = m_nodes.Find(request.StartingNode);

                if (source == null)
                {
                    result.StatusCode = new StatusCode(StatusCodes.BadNodeIdUnknown);
                    return;
                }

                // check if there is nothing to do.
                if (request.RelativePath.Elements == null || request.RelativePath.Elements.Count == 0)
                {
                    result.StatusCode = new StatusCode(StatusCodes.BadNothingToDo);
                    return;
                }

                result.Targets = new ListOfBrowsePathTarget();

                Node current = source;

                // follow each element in the browse path.
                for (int ii = 0; ii < request.RelativePath.Elements.Count; ii++)
                {
                    RelativePathElement element = request.RelativePath.Elements[ii];

                    bool found = false;

                    // need to find any matching reference.
                    foreach (ReferenceNode reference in current.References)
                    {
                        // inverse is a quick check - do that first.
                        if (reference.IsInverse != element.IsInverse)
                        {
                            continue;
                        }

                        // check for reference type matches.
                        if (reference.ReferenceTypeId != element.ReferenceTypeId)
                        {
                            if (!element.IncludeSubtypes)
                            {
                                continue;
                            }

                            if (!IsTypeOf(reference.ReferenceTypeId, element.ReferenceTypeId))
                            {
                                continue;
                            }
                        }

                        // The UA type model requires that the browse names of all targets of hierarchial references
                        // be unique within a parent. This means most browse paths will point to no more than one node.
                        // However, instances are allowed to add additional nodes with duplicate browse names. If the server
                        // allows this it must keep track of the child that matches the type model and return it as the
                        // first target.

                        // need to find the target to check the browse name.
                        Node target = m_nodes.Find(reference.TargetId);

                        if (target != null)
                        {
                            if (element.TargetName == target.BrowseName)
                            {
                                found   = true;
                                current = target;
                                break;
                            }
                        }
                    }

                    if (found)
                    {
                        // check if the complete path has been followed.
                        if (ii == request.RelativePath.Elements.Count - 1)
                        {
                            BrowsePathTarget item = new BrowsePathTarget();
                            item.TargetId           = new ExpandedNodeId(current.NodeId);
                            item.RemainingPathIndex = UInt32.MaxValue;
                            result.Targets.Add(item);
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Parses a relative path formatted as a string. 
        /// </summary>
        public static RelativePath Parse(string browsePath, ITypeTable typeTree)
        {
            if (typeTree == null) throw new ArgumentNullException("typeTree");

            // parse the string.
            RelativePathFormatter formatter = RelativePathFormatter.Parse(browsePath);

            // convert the browse names to node ids.
            RelativePath relativePath = new RelativePath();

            foreach (RelativePathFormatter.Element element in formatter.Elements)
            {
                RelativePathElement parsedElement = new RelativePathElement();

                parsedElement.ReferenceTypeId = null;
                parsedElement.IsInverse = false;
                parsedElement.IncludeSubtypes = element.IncludeSubtypes;
                parsedElement.TargetName = element.TargetName;

                switch (element.ElementType)
                {
                    case RelativePathFormatter.ElementType.AnyHierarchical:
                    {
                        parsedElement.ReferenceTypeId = ReferenceTypeIds.HierarchicalReferences;
                        break;
                    }

                    case RelativePathFormatter.ElementType.AnyComponent:
                    {
                        parsedElement.ReferenceTypeId = ReferenceTypeIds.Aggregates;
                        break;
                    }

                    case RelativePathFormatter.ElementType.ForwardReference:
                    {
                        parsedElement.ReferenceTypeId = typeTree.FindReferenceType(element.ReferenceTypeName);
                        break;
                    }

                    case RelativePathFormatter.ElementType.InverseReference:
                    {
                        parsedElement.ReferenceTypeId = typeTree.FindReferenceType(element.ReferenceTypeName);
                        parsedElement.IsInverse = true;
                        break;
                    }
                }

                if (NodeId.IsNull(parsedElement.ReferenceTypeId))
                {
                    throw ServiceResultException.Create(
                        StatusCodes.BadSyntaxError,
                        "Could not convert BrowseName to a ReferenceTypeId: {0}",
                        element.ReferenceTypeName);
                }

                relativePath.Elements.Add(parsedElement);
            }

            return relativePath;
        }
Пример #27
0
        /// <summary>
        /// Adds a single hop path for all references for the node.
        /// </summary>
        private void AddSingleHopPaths(Node node, BrowsePathCollection pathsToTranslate)
        {
            ReferenceDescriptionCollection references = node.Handle as ReferenceDescriptionCollection;

            if (references == null)
            {
                return;
            }

            for (int ii = 0; ii < references.Count; ii++)
            {
                BrowsePath browsePath = new BrowsePath();
                browsePath.StartingNode = node.NodeId;
                browsePath.Handle = node;

                RelativePathElement element = new RelativePathElement();

                element.ReferenceTypeId = references[ii].ReferenceTypeId;
                element.IsInverse = !references[ii].IsForward;
                element.IncludeSubtypes = false;
                element.TargetName = references[ii].BrowseName;

                browsePath.RelativePath.Elements.Add(element);
                pathsToTranslate.Add(browsePath);
            }
        }
        /// <summary>
        /// Convert to path element object
        /// </summary>
        /// <param name="element"></param>
        /// <param name="context"></param>
        /// <returns></returns>
        private static RelativePathElement ParsePathElement(string element,
                                                            ServiceMessageContext context)
        {
            if (string.IsNullOrEmpty(element))
            {
                throw new ArgumentNullException(nameof(element));
            }

            var pathElement = new RelativePathElement {
                IncludeSubtypes = true,
                IsInverse       = false
            };
            //
            // Parse relative path reference information
            // This should allow
            // - "targeturi" == "/targeturi"
            // - ".targeturi"
            // - "!.parenturi"
            // - "!/parenturi"
            // - "<!#uri>parenturi"
            //
            var index          = 0;
            var exit           = false;
            var parseReference = false;

            while (index < element.Length && !exit)
            {
                switch (element[index])
                {
                case '<':
                    if (pathElement.ReferenceTypeId == null)
                    {
                        parseReference = true;
                        break;
                    }
                    throw new FormatException("Reference type set.");

                case '!':
                    pathElement.IsInverse = true;
                    break;

                case '#':
                    pathElement.IncludeSubtypes = false;
                    break;

                case '/':
                    if (pathElement.ReferenceTypeId == null &&
                        !parseReference)
                    {
                        pathElement.ReferenceTypeId =
                            ReferenceTypeIds.HierarchicalReferences;
                        break;
                    }
                    throw new FormatException("Reference type set.");

                case '.':
                    if (pathElement.ReferenceTypeId == null &&
                        !parseReference)
                    {
                        pathElement.ReferenceTypeId =
                            ReferenceTypeIds.Aggregates;
                        break;
                    }
                    throw new FormatException("Reference type set.");

                default:
                    if (element[index] == '&')
                    {
                        index++;
                    }
                    if (pathElement.ReferenceTypeId == null &&
                        !parseReference)
                    {
                        // Set to all references
                        pathElement.ReferenceTypeId =
                            ReferenceTypeIds.References;
                    }
                    exit = true;
                    break;
                }
                index++;
            }
            index--;
            if (parseReference)
            {
                var to = index;
                while (to < element.Length)
                {
                    if (element[to] == '>' && element[to - 1] != '&')
                    {
                        break;
                    }
                    to++;
                    if (to == element.Length)
                    {
                        throw new FormatException(
                                  "Reference path starts in < but does not end in >");
                    }
                }
                var reference = element.Substring(index, to - index);
                // TODO: Deescape &<, &>, &/, &., &:, &&
                index = to + 1;
                pathElement.ReferenceTypeId = reference.ToNodeId(context);
                if (NodeId.IsNull(pathElement.ReferenceTypeId))
                {
                    if (TypeMaps.ReferenceTypes.Value.TryGetIdentifier(reference,
                                                                       out var id))
                    {
                        pathElement.ReferenceTypeId = id;
                    }
                }
            }
            var target = element.Substring(index);

            // TODO: Deescape &<, &>, &/, &., &:, &&
            if (string.IsNullOrEmpty(target))
            {
                throw new FormatException("Bad target name is empty");
            }
            pathElement.TargetName = target.ToQualifiedName(context);
            return(pathElement);
        }
Пример #29
0
        /// <summary>
        /// Constructs an operand from a value.
        /// </summary>
        /// <param name="nodeId">The node identifier.</param>
        /// <param name="browsePaths">The browse paths.</param>
        public AttributeOperand(
            NodeId nodeId,
            IList<QualifiedName> browsePaths)
        {
            m_nodeId = nodeId;
            m_attributeId = Attributes.Value;
            m_browsePath = new RelativePath();

            for (int ii = 0; ii < browsePaths.Count; ii++)
            {
                RelativePathElement element = new RelativePathElement();

                element.ReferenceTypeId = ReferenceTypeIds.Aggregates;
                element.IsInverse = false;
                element.IncludeSubtypes = true;
                element.TargetName = browsePaths[ii];

                m_browsePath.Elements.Add(element);
            }
        }
Пример #30
0
        /// <summary>
        /// Adds a single hop path for all references for the node.
        /// </summary>
        private void AddMultiHopPaths(
            Node node, 
            Node baseNode,
            IList<RelativePathElement> basePath,
            BrowsePathCollection pathsToTranslate,
            int hops)
        {
            ReferenceDescriptionCollection references = node.Handle as ReferenceDescriptionCollection;

            if (references == null)
            {
                return;
            }

            for (int ii = 0; ii < references.Count; ii++)
            {
                ReferenceDescription reference = references[ii];
                
                BrowsePath browsePath = new BrowsePath();

                browsePath.StartingNode = baseNode.NodeId;
                browsePath.Handle = baseNode;

                if (basePath != null)
                {
                    browsePath.RelativePath.Elements.AddRange(basePath);
                }
                
                RelativePathElement element = new RelativePathElement();

                element.ReferenceTypeId = ReferenceTypeIds.NonHierarchicalReferences;
                element.IsInverse = !reference.IsForward;
                element.IncludeSubtypes = true;
                element.TargetName = reference.BrowseName;

                browsePath.RelativePath.Elements.Add(element);
                pathsToTranslate.Add(browsePath);

                // only follow forward heiarchical
                if (!Session.TypeTree.IsTypeOf(reference.ReferenceTypeId, ReferenceTypeIds.HierarchicalReferences))
                {
                    continue;
                }

                element.ReferenceTypeId = ReferenceTypeIds.HierarchicalReferences;

                // can't do anything with absolute or inverse references.
                if (!reference.IsForward || reference.NodeId.IsAbsolute)
                {
                    continue;
                }
                                    
                // look up target
                if (browsePath.RelativePath.Elements.Count < hops)
                {
                    Node target = null;

                    if (!AvailableNodes.TryGetValue((NodeId)reference.NodeId, out target))
                    {
                        continue;
                    }

                    AddMultiHopPaths(target, baseNode, browsePath.RelativePath.Elements, pathsToTranslate, hops);
                }
            }
        }
Пример #31
0
        /// <summary>
        /// Updates the EUInfo for the items.
        /// </summary>
        /// <param name="group">The group.</param>
        /// <param name="items">The items. Null entries are ignored.</param>
        public void UpdateItemEuInfo(
            ComDaGroup group,
            IList <ComDaGroupItem> items)
        {
            // get the session to use for the operation.
            Session session = m_session;

            if (session == null)
            {
                throw ComUtils.CreateComException(ResultIds.E_FAIL);
            }

            // build list of properties that need to be read.
            BrowsePathCollection browsePaths = new BrowsePathCollection();

            for (int ii = 0; ii < items.Count; ii++)
            {
                ComDaGroupItem item = (ComDaGroupItem)items[ii];

                // ignore invalid items or items which have already checked their EU type.
                if (item == null || item.EuType >= 0)
                {
                    continue;
                }

                BrowsePath browsePath = new BrowsePath();
                browsePath.StartingNode = item.NodeId;
                RelativePathElement element = new RelativePathElement();
                element.ReferenceTypeId = ReferenceTypeIds.HasProperty;
                element.IsInverse       = false;
                element.IncludeSubtypes = false;
                element.TargetName      = Opc.Ua.BrowseNames.EURange;
                browsePath.RelativePath.Elements.Add(element);
                browsePath.Handle = item;
                browsePaths.Add(browsePath);

                browsePath = new BrowsePath();
                browsePath.StartingNode = item.NodeId;
                element = new RelativePathElement();
                element.ReferenceTypeId = ReferenceTypeIds.HasProperty;
                element.IsInverse       = false;
                element.IncludeSubtypes = false;
                element.TargetName      = Opc.Ua.BrowseNames.EnumStrings;
                browsePath.RelativePath.Elements.Add(element);
                browsePath.Handle = item;
                browsePaths.Add(browsePath);
            }

            // check if nothing to do.
            if (browsePaths.Count == 0)
            {
                return;
            }

            // translate browse paths.
            BrowsePathResultCollection results         = null;
            DiagnosticInfoCollection   diagnosticInfos = null;

            try
            {
                session.TranslateBrowsePathsToNodeIds(
                    null,
                    browsePaths,
                    out results,
                    out diagnosticInfos);

                ClientBase.ValidateResponse(results, browsePaths);
                ClientBase.ValidateDiagnosticInfos(diagnosticInfos, browsePaths);
            }
            catch (Exception)
            {
                for (int ii = 0; ii < browsePaths.Count; ii++)
                {
                    ComDaGroupItem item = (ComDaGroupItem)browsePaths[ii].Handle;
                    item.EuType = 0;
                }

                return;
            }

            // build list of properties that need to be read.
            ReadValueIdCollection propertiesToRead = new ReadValueIdCollection();

            for (int ii = 0; ii < results.Count; ii++)
            {
                ComDaGroupItem   item   = (ComDaGroupItem)browsePaths[ii].Handle;
                BrowsePathResult result = results[ii];

                if (StatusCode.IsBad(result.StatusCode))
                {
                    if (item.EuType < 0 && result.StatusCode == StatusCodes.BadNoMatch)
                    {
                        item.EuType = (int)OpcRcw.Da.OPCEUTYPE.OPC_NOENUM;
                    }

                    continue;
                }

                if (result.Targets.Count == 0 || result.Targets[0].TargetId.IsAbsolute)
                {
                    if (item.EuType < 0)
                    {
                        item.EuType = (int)OpcRcw.Da.OPCEUTYPE.OPC_NOENUM;
                    }

                    continue;
                }

                ReadValueId propertyToRead = new ReadValueId();
                propertyToRead.NodeId      = (NodeId)result.Targets[0].TargetId;
                propertyToRead.AttributeId = Attributes.Value;
                propertyToRead.Handle      = item;
                propertiesToRead.Add(propertyToRead);

                if (browsePaths[ii].RelativePath.Elements[0].TargetName.Name == Opc.Ua.BrowseNames.EURange)
                {
                    item.EuType = (int)OpcRcw.Da.OPCEUTYPE.OPC_ANALOG;
                }
                else
                {
                    item.EuType = (int)OpcRcw.Da.OPCEUTYPE.OPC_ENUMERATED;
                }
            }

            // check if nothing to do.
            if (propertiesToRead.Count == 0)
            {
                return;
            }

            // read attribute values from the server.
            DataValueCollection values = null;

            try
            {
                session.Read(
                    null,
                    0,
                    TimestampsToReturn.Neither,
                    propertiesToRead,
                    out values,
                    out diagnosticInfos);

                ClientBase.ValidateResponse(values, propertiesToRead);
                ClientBase.ValidateDiagnosticInfos(diagnosticInfos, propertiesToRead);
            }
            catch (Exception)
            {
                for (int ii = 0; ii < propertiesToRead.Count; ii++)
                {
                    ComDaGroupItem item = (ComDaGroupItem)propertiesToRead[ii].Handle;
                    item.EuType = 0;
                }

                return;
            }

            // process results.
            for (int ii = 0; ii < values.Count; ii++)
            {
                ComDaGroupItem item = (ComDaGroupItem)propertiesToRead[ii].Handle;

                if (StatusCode.IsBad(values[ii].StatusCode))
                {
                    item.EuType = 0;
                    continue;
                }

                if (item.EuType == (int)OpcRcw.Da.OPCEUTYPE.OPC_ANALOG)
                {
                    Range range = (Range)values[ii].GetValue <Range>(null);

                    if (range == null)
                    {
                        item.EuType = 0;
                        continue;
                    }

                    item.EuInfo = new double[] { range.Low, range.High };
                    continue;
                }

                if (item.EuType == (int)OpcRcw.Da.OPCEUTYPE.OPC_ENUMERATED)
                {
                    LocalizedText[] texts = (LocalizedText[])values[ii].GetValue <LocalizedText[]>(null);

                    if (texts == null)
                    {
                        item.EuType = 0;
                        continue;
                    }

                    string[] strings = new string[texts.Length];

                    for (int jj = 0; jj < strings.Length; jj++)
                    {
                        if (!LocalizedText.IsNullOrEmpty(texts[jj]))
                        {
                            strings[jj] = texts[jj].Text;
                        }
                    }

                    item.EuInfo = strings;
                    continue;
                }
            }
        }
Пример #32
0
        /// <summary>
        /// Updates the list of references.
        /// </summary>
        private void UpdateArguments(Session session, NodeId nodeId)
        {
            ArgumentsLV.Items.Clear();

            // need to fetch the node ids for the argument properties.
            BrowsePathCollection browsePaths = new BrowsePathCollection();

            foreach (string browseName in new string[] { BrowseNames.InputArguments, BrowseNames.OutputArguments })
            {
                BrowsePath browsePath = new BrowsePath();
                browsePath.StartingNode = nodeId;
                browsePath.Handle = browseName;

                RelativePathElement element = new RelativePathElement();
                element.ReferenceTypeId = ReferenceTypeIds.HasProperty;
                element.IsInverse = false;
                element.IncludeSubtypes = true;
                element.TargetName = browseName;

                browsePath.RelativePath.Elements.Add(element);
                browsePaths.Add(browsePath);
            }

            // translate property names.
            BrowsePathResultCollection results = null;
            DiagnosticInfoCollection diagnosticInfos = null;

            session.TranslateBrowsePathsToNodeIds(
                null,
                browsePaths,
                out results,
                out diagnosticInfos);

            ClientBase.ValidateResponse(results, browsePaths);
            ClientBase.ValidateDiagnosticInfos(diagnosticInfos, browsePaths);

            // create a list of values to read.
            ReadValueIdCollection valuesToRead = new ReadValueIdCollection();

            for (int ii = 0; ii < results.Count; ii++)
            {
                if (StatusCode.IsBad(results[ii].StatusCode) || results[ii].Targets.Count <= 0)
                {
                    continue;
                }

                ReadValueId valueToRead = new ReadValueId();
                valueToRead.NodeId = (NodeId)results[ii].Targets[0].TargetId;
                valueToRead.AttributeId = Attributes.Value;
                valueToRead.Handle = browsePaths[ii].Handle;
                valuesToRead.Add(valueToRead);
            }

            // read the values.
            if (valuesToRead.Count > 0)
            {
                DataValueCollection values = null;

                session.Read(
                    null,
                    0,
                    TimestampsToReturn.Neither,
                    valuesToRead,
                    out values,
                    out diagnosticInfos);

                ClientBase.ValidateResponse(results, valuesToRead);
                ClientBase.ValidateDiagnosticInfos(diagnosticInfos, valuesToRead);

                // update the list control.
                for (int ii = 0; ii < values.Count; ii++)
                {
                    // all structures are wrapped in extension objects.
                    ExtensionObject[] extensions = values[ii].GetValue<ExtensionObject[]>(null);

                    if (extensions != null)
                    {
                        // convert to an argument structure.
                        Argument[] arguments = (Argument[])ExtensionObject.ToArray(extensions, typeof(Argument));
                        UpdateList(session, arguments, (string)valuesToRead[ii].Handle);
                    }
                }
            }

            // auto size the columns.
            for (int ii = 0; ii < ArgumentsLV.Columns.Count; ii++)
            {
                ArgumentsLV.Columns[ii].Width = -2;
            }
        }