A object which maps a COM DA item to a UA variable.
상속: BaseDataVariableState
예제 #1
0
        /// <summary>
        /// Queues the value to the monitored item.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="request">The request.</param>
        /// <param name="monitoredItem">The monitored item.</param>
        private void QueueValue(ServerSystemContext context, HdaReadRequest request, MonitoredItem monitoredItem)
        {
            NodeHandle handle = monitoredItem.ManagerHandle as NodeHandle;

            if (handle == null)
            {
                return;
            }

            ReadValueId   nodeToRead = monitoredItem.GetReadValueId();
            DataValue     value      = new DataValue();
            ServiceResult error      = null;

            HdaItemState      item      = handle.Node as HdaItemState;
            HdaAttributeState attribute = handle.Node as HdaAttributeState;

            if (item != null)
            {
                error = request.GetResult(context, item, nodeToRead, value, monitoredItem.DiagnosticsMasks);
            }
            else if (attribute != null)
            {
                error = request.GetResult(context, attribute, nodeToRead, value, monitoredItem.DiagnosticsMasks);
            }

            value.ServerTimestamp = DateTime.UtcNow;

            if (value.StatusCode != StatusCodes.BadNotFound)
            {
                monitoredItem.QueueValue(value, error);
            }
        }
예제 #2
0
        /// <summary>
        /// Adds a read request for the specified item.
        /// </summary>
        /// <param name="item">The item.</param>
        /// <param name="nodeToRead">The node to read.</param>
        /// <param name="queued">if set to <c>true</c> if a request was created.</param>
        /// <returns>Any error.</returns>
        private StatusCode Add(HdaItemState item, ReadValueId nodeToRead, out bool queued)
        {
            queued = true;

            switch (nodeToRead.AttributeId)
            {
            case Attributes.Description:
            {
                nodeToRead.Handle = Add(item.ItemId, Constants.OPCHDA_DESCRIPTION);
                break;
            }

            case Attributes.DataType:
            case Attributes.ValueRank:
            {
                nodeToRead.Handle = Add(item.ItemId, Constants.OPCHDA_DATA_TYPE);
                break;
            }

            case Attributes.Historizing:
            {
                nodeToRead.Handle = Add(item.ItemId, Constants.OPCHDA_ARCHIVING);
                break;
            }

            default:
            {
                queued = false;
                break;
            }
            }

            return(StatusCodes.Good);
        }
예제 #3
0
        /// <summary>
        /// Gets the result.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="source">The source.</param>
        /// <param name="nodeToRead">The node to read.</param>
        /// <param name="value">The value.</param>
        /// <param name="diagnosticsMasks">The diagnostics masks.</param>
        /// <returns></returns>
        public ServiceResult GetResult(
            ISystemContext context,
            NodeState source,
            ReadValueId nodeToRead,
            DataValue value,
            DiagnosticsMasks diagnosticsMasks)
        {
            HdaReadRequest request = nodeToRead.Handle as HdaReadRequest;

            if (request == null)
            {
                return(StatusCodes.Good);
            }

            // read item value.
            HdaItemState item = source as HdaItemState;

            if (item != null)
            {
                return(request.GetResult(context, item, nodeToRead, value, diagnosticsMasks));
            }

            // read vendor defined attribute value.
            HdaAttributeState attribute = source as HdaAttributeState;

            if (attribute != null)
            {
                return(request.GetResult(context, attribute, nodeToRead, value, diagnosticsMasks));
            }

            return(StatusCodes.Good);
        }
예제 #4
0
        /// <summary>
        /// Gets the HDA item id associated with the source.
        /// </summary>
        /// <param name="source">The source.</param>
        private string GetItemId(NodeState source)
        {
            HdaItemState item = source as HdaItemState;

            if (item != null)
            {
                return(item.ItemId);
            }

            HdaAttributeState attribute = source as HdaAttributeState;

            if (attribute != null)
            {
                return(attribute.ItemId);
            }

            return(null);
        }
예제 #5
0
        /// <summary>
        /// Determines whether the attribute has an external source.
        /// </summary>
        private bool HasExternalSource(NodeState node, uint attributeId)
        {
            HdaItemState item = node as HdaItemState;

            if (item != null)
            {
                switch (attributeId)
                {
                case Attributes.DataType:
                case Attributes.ValueRank:
                case Attributes.Description:
                case Attributes.Historizing:
                {
                    return(true);
                }
                }

                return(false);
            }

            HdaAttributeState attribute = node as HdaAttributeState;

            if (attribute != null)
            {
                switch (attributeId)
                {
                case Attributes.Value:
                case Attributes.AccessLevel:
                case Attributes.UserAccessLevel:
                {
                    return(true);
                }
                }

                return(false);
            }

            return(false);
        }
예제 #6
0
        /// <summary>
        /// Adds a request for the specified source.
        /// </summary>
        /// <param name="source">The source.</param>
        /// <param name="nodeToRead">The node to read.</param>
        /// <param name="queued">if set to <c>true</c> [queued].</param>
        /// <returns></returns>
        public StatusCode Add(NodeState source, ReadValueId nodeToRead, out bool queued)
        {
            queued = true;

            // read item attributes.
            HdaItemState item = source as HdaItemState;

            if (item != null)
            {
                return(Add(item, nodeToRead, out queued));
            }

            // read HDA attribute value.
            HdaAttributeState attribute = source as HdaAttributeState;

            if (attribute != null)
            {
                return(Add(attribute, nodeToRead, out queued));
            }

            queued = false;
            return(StatusCodes.Good);
        }
예제 #7
0
        /// <summary>
        /// Verifies that the specified node exists.
        /// </summary>
        protected override NodeState ValidateNode(
            ServerSystemContext context,
            NodeHandle handle,
            IDictionary<NodeId, NodeState> cache)
        {
            // not valid if no root.
            if (handle == null)
            {
                return null;
            }

            // check if previously validated.
            if (handle.Validated)
            {
                return handle.Node;
            }

            NodeState target = null;

            // check if already in the cache.
            if (cache != null)
            {
                if (cache.TryGetValue(handle.NodeId, out target))
                {
                    // nulls mean a NodeId which was previously found to be invalid has been referenced again.
                    if (target == null)
                    {
                        return null;
                    }

                    handle.Node = target;
                    handle.Validated = true;
                    return handle.Node;
                }

                target = null;
            }

            try
            {
                // check if the node id has been parsed.
                HdaParsedNodeId parsedNodeId = handle.ParsedNodeId as HdaParsedNodeId;

                if (parsedNodeId == null)
                {
                    return null;
                }

                ComHdaClient client = (ComHdaClient)m_system.SelectClient(context, false);

                switch (parsedNodeId.RootType)
                {
                    case HdaModelUtils.HdaBranch:
                    {
                        ComHdaBrowserClient browser = new ComHdaBrowserClient(client, null);
                        target = browser.FindBranch(context, parsedNodeId.RootId, NamespaceIndex);
                        browser.Dispose();
                        break;
                    }

                    case HdaModelUtils.HdaItem:
                    {
                        HdaItem[] items = client.GetItems(parsedNodeId.RootId);

                        if (items[0].Error < 0)
                        {
                            return null;
                        }

                        try
                        {
                            string browseName = null;

                            if (!m_configuration.ItemIdParser.Parse(client, m_configuration, parsedNodeId.RootId, out browseName))
                            {
                                HdaAttributeValue[] attributes = client.ReadAttributeValues(items[0].ServerHandle, OpcRcw.Hda.Constants.OPCHDA_ITEMID);
                                browseName = attributes[0].Value as string;
                            }

                            target = new HdaItemState(items[0].ItemId, browseName, NamespaceIndex);
                        }
                        finally
                        {
                            client.ReleaseItemHandles(items);
                        }

                        break;
                    }

                    case HdaModelUtils.HdaItemAttribute:
                    {
                        bool[] results = client.ValidateItemIds(parsedNodeId.RootId);

                        if (!results[0])
                        {
                            return null;
                        }

                        target = client.FindItemAttribute(parsedNodeId.RootId, parsedNodeId.AttributeId, NamespaceIndex);
                        break;
                    }

                    case HdaModelUtils.HdaItemAnnotations:
                    {
                        bool[] results = client.ValidateItemIds(parsedNodeId.RootId);

                        if (!results[0])
                        {
                            return null;
                        }

                        target = client.FindItemAnnotations(parsedNodeId.RootId, NamespaceIndex);
                        break;
                    }

                    case HdaModelUtils.HdaItemConfiguration:
                    {
                        bool[] results = client.ValidateItemIds(parsedNodeId.RootId);

                        if (results == null || !results[0])
                        {
                            return null;
                        }

                        target = HdaModelUtils.GetItemConfigurationNode(parsedNodeId.RootId, NamespaceIndex);
                        target.OnCreateBrowser = OnCreateItemConfigurationBrowser;
                        break;
                    }

                    case HdaModelUtils.HdaAggregate:
                    {
                        target = client.FindAggregate(parsedNodeId.AggregateId, NamespaceIndex);
                        break;
                    }
                }

                // check if found.
                if (target == null)
                {
                    return null;
                }

                // found a valid component.
                handle.Validated = true;
                handle.Node = target;

                return handle.Node;
            }
            finally
            {
                // store the node in the cache to optimize subsequent lookups.
                if (cache != null)
                {
                    cache.Add(handle.NodeId, target);
                }
            }
        }
예제 #8
0
        /// <summary>
        /// Gets the result for the read operayoin.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="item">The item.</param>
        /// <param name="nodeToRead">The node to read.</param>
        /// <param name="value">The value.</param>
        /// <param name="diagnosticsMasks">The diagnostics masks.</param>
        /// <returns></returns>
        public ServiceResult GetResult(
            ISystemContext context,
            HdaItemState item,
            ReadValueId nodeToRead,
            DataValue value,
            DiagnosticsMasks diagnosticsMasks)
        {
            switch (nodeToRead.AttributeId)
            {
            case Attributes.Description:
            {
                string description = this.GetAttributeValue <string>(Constants.OPCHDA_DESCRIPTION, value, false);

                if (StatusCode.IsGood(value.StatusCode))
                {
                    value.Value = new LocalizedText(description);
                }

                break;
            }

            case Attributes.DataType:
            {
                short datatype = this.GetAttributeValue <short>(Constants.OPCHDA_DATA_TYPE, value, false);

                if (StatusCode.IsGood(value.StatusCode))
                {
                    value.Value = ComUtils.GetDataTypeId(datatype);
                }
                else
                {
                    value.Value      = DataTypeIds.BaseDataType;
                    value.StatusCode = StatusCodes.GoodLocalOverride;
                }

                break;
            }

            case Attributes.ValueRank:
            {
                short datatype = this.GetAttributeValue <short>(Constants.OPCHDA_DATA_TYPE, value, false);

                if (StatusCode.IsGood(value.StatusCode))
                {
                    value.Value = ComUtils.GetValueRank(datatype);
                }
                else
                {
                    value.Value      = ValueRanks.Any;
                    value.StatusCode = StatusCodes.GoodLocalOverride;
                }

                break;
            }

            case Attributes.Historizing:
            {
                bool archiving = this.GetAttributeValue <bool>(Constants.OPCHDA_ARCHIVING, value, false);

                if (StatusCode.IsGood(value.StatusCode))
                {
                    value.Value = archiving;
                }
                else
                {
                    value.Value      = false;
                    value.StatusCode = StatusCodes.GoodLocalOverride;
                }

                break;
            }

            default:
            {
                return(StatusCodes.BadAttributeIdInvalid);
            }
            }

            // check if the attribute value is missing.
            if (value.StatusCode == StatusCodes.BadNotFound)
            {
                return(StatusCodes.BadAttributeIdInvalid);
            }

            return(ApplyIndexRangeAndDataEncoding(context, nodeToRead, value));
        }
예제 #9
0
        /// <summary>
        /// Returns the next AE area or source.
        /// </summary>
        /// <returns>A DA element. Null if nothing left to browse.</returns>
        public BaseInstanceState Next(ISystemContext context, ushort namespaceIndex)
        {
            // check if already completed.
            if (m_completed)
            {
                return(null);
            }

            // create the browser.
            if (base.Unknown == null)
            {
                base.Unknown = m_client.CreateBrowser();

                if (base.Unknown == null)
                {
                    return(null);
                }

                if (!String.IsNullOrEmpty(m_itemId))
                {
                    if (!ChangeBrowsePosition(OPCHDA_BROWSEDIRECTION.OPCHDA_BROWSE_DIRECT, m_itemId))
                    {
                        return(null);
                    }
                }
            }

            // create the enumerator if not already created.
            if (m_enumerator == null)
            {
                m_enumerator = CreateEnumerator(true);
                m_branches   = true;

                // a null indicates an error.
                if (m_enumerator == null)
                {
                    m_completed = true;
                    return(null);
                }
            }

            // need a loop in case errors occur fetching element metadata.
            BaseInstanceState node = null;

            do
            {
                // fetch the next name.
                string name = m_enumerator.Next();

                // a null indicates the end of list.
                if (name == null)
                {
                    if (m_branches)
                    {
                        m_enumerator.Dispose();
                        m_enumerator = CreateEnumerator(false);
                        m_branches   = false;

                        // a null indicates an error.
                        if (m_enumerator != null)
                        {
                            continue;
                        }
                    }

                    m_completed = true;
                    return(null);
                }

                // create the node.
                if (m_branches)
                {
                    string itemId = GetBranchPosition(m_itemId, name);
                    node = new HdaBranchState(itemId, name, namespaceIndex);
                }
                else
                {
                    string itemId = GetItemId(name);
                    node = new HdaItemState(itemId, name, namespaceIndex);
                }

                break;
            }while (node == null);

            // return node.
            return(node);
        }
예제 #10
0
        /// <summary>
        /// Returns the next AE area or source.
        /// </summary>
        /// <returns>A DA element. Null if nothing left to browse.</returns>
        public BaseInstanceState Next(ISystemContext context, ushort namespaceIndex)
        {
            // check if already completed.
            if (m_completed)
            {
                return null;
            }

            // create the browser.
            if (base.Unknown == null)
            {
                base.Unknown = m_client.CreateBrowser();

                if (base.Unknown == null)
                {
                    return null;
                }

                if (!String.IsNullOrEmpty(m_itemId))
                {
                    if (!ChangeBrowsePosition(OPCHDA_BROWSEDIRECTION.OPCHDA_BROWSE_DIRECT, m_itemId))
                    {
                        return null;
                    }
                }
            }

            // create the enumerator if not already created.
            if (m_enumerator == null)
            {
                m_enumerator = CreateEnumerator(true);
                m_branches = true;

                // a null indicates an error.
                if (m_enumerator == null)
                {
                    m_completed = true;
                    return null;
                }
            }

            // need a loop in case errors occur fetching element metadata.
            BaseInstanceState node = null;

            do
            {
                // fetch the next name.
                string name = m_enumerator.Next();

                // a null indicates the end of list.
                if (name == null)
                {
                    if (m_branches)
                    {
                        m_enumerator.Dispose();
                        m_enumerator = CreateEnumerator(false);
                        m_branches = false;

                        // a null indicates an error.
                        if (m_enumerator != null)
                        {
                            continue;
                        }
                    }

                    m_completed = true;
                    return null;
                }

                // create the node.
                if (m_branches)
                {
                    string itemId = GetBranchPosition(m_itemId, name);
                    node = new HdaBranchState(itemId, name, namespaceIndex);

                }
                else
                {
                    string itemId = GetItemId(name);
                    node = new HdaItemState(itemId, name, namespaceIndex);
                }

                break;
            }
            while (node == null);

            // return node.
            return node;
        }