/// <summary> /// Return the time series for a relevance /// </summary> public AggregatedTimeSeriesResult AggregatedOeeKpiTimeSeries(AggregationView aggregationView, ContosoPerformanceRelevance relevance, TimeSpan scaledTimeSpan) { int aggregateIndex = (int)aggregationView; int count = Aggregations[aggregateIndex].Intervals.Count; AggregatedTimeSeriesResult result = new AggregatedTimeSeriesResult(count, Aggregations[aggregateIndex].EndTime, Aggregations[aggregateIndex].IntervalTimeSpan); double scaleFactor = 100.0 * OeeKpiScaleFactor(relevance, Aggregations[aggregateIndex].IntervalTimeSpan, scaledTimeSpan); for (int i = 0; i < count; i++) { result.YValues[count - i - 1] = Math.Round(scaleFactor * GetData(Aggregations[aggregateIndex].Intervals[i], relevance).Value) / 100.0; } return(result); }
/// <summary> /// Return the time series for a given OPC UA server and a given node /// </summary> /// <param name="station">The OPC UA server</param> /// <param name="node">The OPC UA node Id</param> /// <param name="aggregationView">The hourly, daily or weekly view</param> /// <param name="getCount">Get event Count aggregate</param> public static async Task <AggregatedTimeSeriesResult> AggregatedNodeId( Station station, ContosoOpcUaNode node, ContosoTopologyNode.AggregationView aggregationView, bool getCount = false) { int aggregateIndex = (int)aggregationView; RDXOpcUaQueries opcUaQuery = new RDXOpcUaQueries(CancellationToken.None); ContosoAggregatedOeeKpiHistogram aggregatedTimeSpan = station[aggregateIndex]; DateTimeRange searchSpan = RDXUtils.TotalSearchRangeFromNow(aggregatedTimeSpan); DateTimeRange aggregateSpan = new DateTimeRange( searchSpan.To.Subtract(aggregatedTimeSpan.TotalTimeSpan), searchSpan.To ); double roundFactor = 100.0; int index = (int)RDXOpcUaQueries.AggregateIndex.Count; if (!getCount) { if (!IsAggregatedOperator(node.OpCode)) { throw new Exception("Unsupported Operator for aggregation"); } // handle special case for SubMaxMin, result is derived by substraction if (node.OpCode == ContosoOpcNodeOpCode.SubMaxMin) { index = (int)RDXOpcUaQueries.AggregateIndex.Max; } else { index = AggregatedOperatorIndex(node.OpCode); } } int resultDimension = aggregatedTimeSpan.Intervals.Count; DateTime [] dateTimeResult = CreateAggregateDateTimeArray(aggregateSpan.From, aggregatedTimeSpan.IntervalTimeSpan, resultDimension); AggregateResult queryResult = await opcUaQuery.GetAllAggregatedNodesWithInterval( aggregateSpan, station.Key, node.NodeId, aggregatedTimeSpan.IntervalTimeSpan ); int count = queryResult.Aggregate.Dimension.Count; AggregatedTimeSeriesResult result = new AggregatedTimeSeriesResult(resultDimension, aggregateSpan.To, aggregatedTimeSpan.IntervalTimeSpan, node.Units); if (queryResult != null) { for (int i = 0; i < count; i++) { double?value = queryResult.Aggregate.Aggregate.Measures.TryGetPropertyMeasure <double?>(new int[] { 0, i, index }); if (value != null) { // find matching date/time slot for value var dateTime = queryResult.Aggregate.Dimension[i]; int resultIndex = Array.IndexOf(dateTimeResult, dateTime); if (resultIndex >= 0) { result.YValues[resultIndex] = roundFactor * (double)value; if (node.OpCode == ContosoOpcNodeOpCode.SubMaxMin) { value = queryResult.Aggregate.Aggregate.Measures.TryGetPropertyMeasure <double?>(new int[] { 0, i, (int)RDXOpcUaQueries.AggregateIndex.Min }); if (value != null) { result.YValues[resultIndex] -= roundFactor * (double)value; } } result.YValues[resultIndex] = Math.Round(result.YValues[resultIndex]) / roundFactor; } else { throw new Exception("DateTime not found in aggregated query array"); } } } } return(result); }