/// <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> /// Adds the specified attribute read to the request list. /// </summary> /// <param name="attribute">The attribute.</param> /// <param name="nodeToRead">The node to read.</param> /// <param name="queued">if set to <c>true</c> [queued].</param> /// <returns></returns> private StatusCode Add(HdaAttributeState attribute, ReadValueId nodeToRead, out bool queued) { queued = false; if (nodeToRead.AttributeId != Attributes.Value && nodeToRead.AttributeId != Attributes.AccessLevel && nodeToRead.AttributeId != Attributes.UserAccessLevel) { return(StatusCodes.Good); } queued = true; switch (attribute.Attribute.Id) { case Constants.OPCHDA_NORMAL_MAXIMUM: { nodeToRead.Handle = Add(attribute.ItemId, Constants.OPCHDA_NORMAL_MAXIMUM, Constants.OPCHDA_NORMAL_MINIMUM); break; } case Constants.OPCHDA_HIGH_ENTRY_LIMIT: { nodeToRead.Handle = Add(attribute.ItemId, Constants.OPCHDA_HIGH_ENTRY_LIMIT, Constants.OPCHDA_LOW_ENTRY_LIMIT); break; } default: { nodeToRead.Handle = Add(attribute.ItemId, attribute.Attribute.Id); break; } } return(StatusCodes.Good); }
/// <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> /// 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> /// Finds the UA defined component of the item. /// </summary> /// <param name="itemId">The item id.</param> /// <param name="attributeId">The attribute id.</param> /// <param name="namespaceIndex">Index of the namespace.</param> /// <returns></returns> public PropertyState FindItemAttribute(string itemId, uint attributeId, ushort namespaceIndex) { if (itemId == null) { return null; } // get the supported attributes. if (m_supportedAttributes == null) { UpdateServerMetadata(); } HdaAttribute[] supportedAttributes = m_supportedAttributes; if (supportedAttributes == null || supportedAttributes.Length == 0) { return null; } // validate the attribute. HdaAttribute attribute = null; for (int ii = 0; ii < supportedAttributes.Length; ii++) { if (attributeId == supportedAttributes[ii].Id) { attribute = supportedAttributes[ii]; break; } } if (attribute == null) { return null; } // check for attributes which are not exposed. switch (attributeId) { case Constants.OPCHDA_ITEMID: case Constants.OPCHDA_DATA_TYPE: case Constants.OPCHDA_DESCRIPTION: case Constants.OPCHDA_ARCHIVING: case Constants.OPCHDA_NORMAL_MINIMUM: case Constants.OPCHDA_LOW_ENTRY_LIMIT: { return null; } } // create the property. HdaAttributeState property = new HdaAttributeState( m_configuration, itemId, attribute, namespaceIndex); return property; }
/// <summary> /// Gets the result for the read operation. /// </summary> /// <param name="context">The context.</param> /// <param name="attribute">The attribute.</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, HdaAttributeState attribute, ReadValueId nodeToRead, DataValue value, DiagnosticsMasks diagnosticsMasks) { if (nodeToRead.AttributeId != Attributes.Value) { // check if reading access level. if (nodeToRead.AttributeId == Attributes.AccessLevel || nodeToRead.AttributeId == Attributes.UserAccessLevel) { HdaAttributeValue result = GetAttributeValue(attribute.Attribute.Id); if (result == null || result.Error < 0 || result.Error == ResultIds.S_NODATA) { value.StatusCode = StatusCodes.BadNotFound; return(value.StatusCode); } value.Value = AccessLevels.CurrentRead; if (result.Error != ResultIds.S_CURRENTVALUE) { value.Value = (byte)(AccessLevels.CurrentRead | AccessLevels.HistoryRead); } return(value.StatusCode); } return(StatusCodes.BadAttributeIdInvalid); } // convert values when required. switch (attribute.Attribute.Id) { case Constants.OPCHDA_NORMAL_MAXIMUM: { double high = this.GetAttributeValue <double>(Constants.OPCHDA_NORMAL_MAXIMUM, value, true); if (StatusCode.IsBad(value.StatusCode)) { return(value.StatusCode); } double low = this.GetAttributeValue <double>(Constants.OPCHDA_NORMAL_MINIMUM, value, true); if (StatusCode.IsBad(value.StatusCode)) { return(value.StatusCode); } value.Value = new Range(high, low); break; } case Constants.OPCHDA_HIGH_ENTRY_LIMIT: { double high = this.GetAttributeValue <double>(Constants.OPCHDA_HIGH_ENTRY_LIMIT, value, true); if (StatusCode.IsBad(value.StatusCode)) { return(value.StatusCode); } double low = this.GetAttributeValue <double>(Constants.OPCHDA_LOW_ENTRY_LIMIT, value, true); if (StatusCode.IsBad(value.StatusCode)) { return(value.StatusCode); } value.Value = new Range(high, low); break; } case Constants.OPCHDA_ENG_UNITS: { string units = this.GetAttributeValue <string>(Constants.OPCHDA_ENG_UNITS, value, true); if (StatusCode.IsBad(value.StatusCode)) { return(value.StatusCode); } value.Value = new EUInformation(units, Namespaces.ComInterop); break; } case Constants.OPCHDA_MAX_TIME_INT: case Constants.OPCHDA_MIN_TIME_INT: { string number = this.GetAttributeValue <string>(attribute.Attribute.Id, value, true); if (StatusCode.IsBad(value.StatusCode)) { return(value.StatusCode); } try { value.Value = Convert.ToDouble(number); } catch (Exception) { value.StatusCode = StatusCodes.BadTypeMismatch; return(value.StatusCode); } break; } case Constants.OPCHDA_EXCEPTION_DEV_TYPE: { short number = this.GetAttributeValue <short>(attribute.Attribute.Id, value, true); if (StatusCode.IsBad(value.StatusCode)) { return(value.StatusCode); } value.Value = (int)number; break; } default: { object result = this.GetAttributeValue <object>(attribute.Attribute.Id, value, true); if (StatusCode.IsBad(value.StatusCode)) { return(value.StatusCode); } value.Value = result; break; } } // check if the attribute value is missing. if (value.StatusCode == StatusCodes.BadNotFound) { return(StatusCodes.BadNodeIdUnknown); } return(ApplyIndexRangeAndDataEncoding(context, nodeToRead, value)); }