/// <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> /// Called when the scan attributes timer expires. /// </summary> private void DoScan(Dictionary <string, HdaSubscribeAttributeRequest> requests, bool initialUpdate) { try { ComHdaClientManager system = (ComHdaClientManager)m_context.SystemHandle; ComHdaClient client = (ComHdaClient)system.SelectClient(m_context, false); // ensure all requests have valid handles. AssignHandles(client, requests); // collect the list of attributes that need reading. HdaReadRequestCollection itemsToRead = new HdaReadRequestCollection(); List <HdaSubscribeAttributeRequest> subscribeRequests = new List <HdaSubscribeAttributeRequest>(); List <HdaReadRequest> readRequestsForSubscribeRequests = new List <HdaReadRequest>(); lock (m_lock) { DateTime now = DateTime.UtcNow; foreach (KeyValuePair <string, HdaSubscribeAttributeRequest> entry in requests) { // check if it is time for an update. if (!initialUpdate && entry.Value.NextUpdateTime > now) { continue; } // create a read request for each monitored item. bool somethingToDo = false; for (int ii = 0; ii < entry.Value.MonitoredItems.Count; ii++) { MonitoredItem monitoredItem = entry.Value.MonitoredItems[ii]; NodeHandle handle = monitoredItem.ManagerHandle as NodeHandle; if (handle == null) { continue; } // check if item is not valid. if (entry.Value.ServerHandle == null) { monitoredItem.QueueValue(null, StatusCodes.BadNodeIdUnknown); continue; } ReadValueId valueToRead = monitoredItem.GetReadValueId(); bool queued = false; StatusCode error = itemsToRead.Add(handle.Node, valueToRead, out queued); if (StatusCode.IsBad(error)) { monitoredItem.QueueValue(null, error); continue; } if (!somethingToDo && queued) { // add server handle to read request. HdaReadRequest request = (HdaReadRequest)valueToRead.Handle; request.ServerHandle = entry.Value.ServerHandle.Value; // save mapping between subscribe request and read requests. subscribeRequests.Add(entry.Value); readRequestsForSubscribeRequests.Add(request); somethingToDo = true; } } } // check if nothing to do. if (requests.Count == 0) { return; } } // read the attributes from the server. client.Read(itemsToRead, true); // update the monitored items. lock (m_lock) { for (int ii = 0; ii < subscribeRequests.Count; ii++) { subscribeRequests[ii].QueueValues(m_context, readRequestsForSubscribeRequests[ii], initialUpdate); } } } catch (Exception e) { Utils.Trace(e, "Unexpected error scanning attributes in HDA COM server."); } }