/// <summary> /// Query all relevant nodes of the station, add tasks to list or await tasks sequentially. /// </summary> /// <param name="tasks">The task list</param> /// <param name="nodelist">The node list to query</param> /// <param name="awaitTasks">serialize or schedule all</param> /// <param name="aggregatedQuery">precachedQuery</param> public async Task QueryAllNodes(List <Task> tasks, List <OpcUaNode> nodelist, bool awaitTasks, RDXCachedAggregatedQuery aggregatedQuery = null) { foreach (ContosoOpcUaNode node in nodelist) { if (node.Relevance != null && node.OpCode != ContosoOpcNodeOpCode.Undefined) { Task newTask; // query opcode and update relevance if (aggregatedQuery != null) { newTask = aggregatedQuery.CallOperator(node.OpCode, this, node); } else { newTask = RDXContosoOpCodes.CallOperator(node.OpCode, this, node); } if (newTask != null && newTask != Task.CompletedTask && newTask.Status != TaskStatus.RanToCompletion) { if (awaitTasks) { await newTask; } else { tasks.Add(newTask); } } } } }
/// <summary> /// Call the operator on a query and node. /// Gets value from cache if operation is supported, /// if not forwards the call to single query engine. /// </summary> /// <param name="opCode">Operation to get the value</param> /// <param name="rdxQuery">The query</param> /// <param name="opcUaNode">The Topology node </param> public async Task CallOperator(ContosoOpcNodeOpCode opCode, RDXOeeKpiQuery rdxQuery, ContosoOpcUaNode opcUaNode) { if (RDXUtils.IsAggregatedOperator(opCode) && _task != null) { _result = await _task; if (_result != null) { double?value = GetValue(opCode, rdxQuery.AppUri, opcUaNode.NodeId); if (value != null) { opcUaNode.Last.Value = (double)value; opcUaNode.Last.Time = rdxQuery.SearchSpan.To; opcUaNode.UpdateRelevance(rdxQuery.TopologyNode); } } return; } // issue a single query if the operator can not be handled from aggregated values await RDXContosoOpCodes.CallOperator(opCode, rdxQuery, opcUaNode); }