public HistoryExtract Build(string componentUid, string statusUid, DateTime rangeStart, DateTime rangeEnd, TimeSpan interval, HistoryExtractDataType dataType) { if (componentUid == null) { throw new ArgumentNullException(nameof(componentUid)); } if (statusUid == null) { throw new ArgumentNullException(nameof(statusUid)); } var entities = _repository.GetComponentStatusValues(componentUid, statusUid, rangeStart, rangeEnd); var historyExtract = new HistoryExtract { ComponentUid = componentUid, StatusUid = statusUid, EntityCount = entities.Count }; while (rangeStart <= rangeEnd) { var dataPoint = new HistoryExtractDataPoint { Timestamp = rangeStart }; var entity = entities.FirstOrDefault(e => e.RangeStart <= dataPoint.Timestamp && e.RangeEnd >= dataPoint.Timestamp); if (entity != null) { if (dataType == HistoryExtractDataType.Number) { dataPoint.Value = Convert.ToDouble(entity.Value, CultureInfo.InvariantCulture); } else { dataPoint.Value = entity.Value; } } historyExtract.DataPoints.Add(dataPoint); rangeStart += interval; } return(historyExtract); }
private static List <HistoryExtractDataPoint> GenerateTextBasedDataPoints(List <ComponentStatusEntity> entities, DateTime rangeStart, DateTime rangeEnd) { var dataPoints = new List <HistoryExtractDataPoint>(); foreach (var entity in entities) { var @break = false; var timestamp = entity.RangeStart; if (timestamp <= rangeStart) { // This value is outside of the range (too old). But the value is still the same when our range begins. // So we adopt the value from that range and treat it as our initial value. timestamp = rangeStart; } if (entity.RangeEnd >= rangeEnd) { // The value is still valid after the requested range. So we treat it as our last value. // Also there is no further data point needed because we already reached the end. timestamp = rangeEnd; @break = true; } var dataPoint = new HistoryExtractDataPoint { Timestamp = timestamp, Value = entity.Value }; dataPoints.Add(dataPoint); if (@break) { break; } } return(dataPoints); }
private static IEnumerable <HistoryExtractDataPoint> GenerateNumberBasedDataPoints( List <ComponentStatusEntity> entities, DateTime rangeStart, DateTime rangeEnd, TimeSpan?interval) { if (!interval.HasValue) { var dataPoints = GenerateTextBasedDataPoints(entities, rangeStart, rangeEnd); foreach (var dataPoint in dataPoints) { if (double.TryParse(dataPoint.Value as string, NumberStyles.Float, CultureInfo.InvariantCulture, out var numberValue)) { dataPoint.Value = numberValue; } } return(dataPoints); } var intervalDataPoints = new List <HistoryExtractDataPoint>(); while (rangeStart <= rangeEnd) { // Start (real) value var dataPointStart = new HistoryExtractDataPoint { Timestamp = rangeStart }; dataPointStart.Value = GetValue(entities, dataPointStart.Timestamp); // End (real) value var dataPointEnd = new HistoryExtractDataPoint { Timestamp = rangeStart.Add(interval.Value * 2) }; dataPointEnd.Value = GetValue(entities, dataPointEnd.Timestamp); // Middle (average) value var dataPointMiddle = new HistoryExtractDataPoint { Timestamp = rangeStart.Add(interval.Value), Value = GetAverageValue(entities, dataPointStart.Timestamp, dataPointEnd.Timestamp) }; if (!intervalDataPoints.Any()) { intervalDataPoints.Add(dataPointStart); } intervalDataPoints.Add(dataPointMiddle); intervalDataPoints.Add(dataPointEnd); rangeStart += interval.Value * 3; } return(intervalDataPoints); }