/// <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); } }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); } } }
/// <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)); }
/// <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); }
/// <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; }