public APIResponse Get() { var response = Enumerable.Empty <EnergyResponse>(); string status; var message = string.Empty; try { var data = _dataLoader.Load(); response = _dataAggregator.Aggregate(data); status = "Success"; } catch (Exception ex) { _logger.LogError($"Something went wrong : {ex.Message}"); status = "Error"; message = ex.Message; } return(new APIResponse { Status = status, Message = message, EnergyResponse = response }); }
public async Task <AggregatedDataRange> GetAggregatedDataRange(string sourceName, int aggregationSeconds, [FromQuery] DateTime minTimeUtc, [FromQuery] DateTime maxTimeUtc) { var timeRange = new TimeRange(minTimeUtc, maxTimeUtc).Quantise(aggregationSeconds); var raw = await GetRawRange(sourceName, timeRange); if (raw.Data.Count == 0) { return(new AggregatedDataRange(timeRange, new List <double>(), aggregationSeconds)); } var range = new AggregatedDataRange(timeRange, raw.Data, 5, true); return(_aggregator.Aggregate(new[] { range }, timeRange, new[] { aggregationSeconds })[300].FirstOrDefault()); }
private async Task <Dictionary <int, IEnumerable <AggregatedDataRange> > > SaveHistoricalData(Guid entity, Guid attribute, AggregatedDataRange dataRange) { _aggregatedDataRangeValidator.ValidateAndThrow(dataRange); var minAggregationSeconds = _configuration.AggregationsSeconds.Min(); if (dataRange.AggregationSeconds != minAggregationSeconds) { throw new Exception($"Must be lowest aggregation {minAggregationSeconds}"); } var series = await _model.ResolveSeries(entity, attribute, minAggregationSeconds); var maxAggregationSeconds = _configuration.AggregationsSeconds.Max(); var quantised = dataRange.TimeRange.Quantise(maxAggregationSeconds); var semaphore = _seriesSemaphores.GetOrAdd(series, s => new SemaphoreSlim(1)); await semaphore.WaitAsync().ConfigureAwait(false); try { //Console.WriteLine($"Writing data between {dataRange.TimeRange.Min} and {dataRange.TimeRange.Max}"); var persisted = await _persistence.GetAggregatedData(entity, attribute, dataRange.AggregationSeconds, quantised); var existingTimeRanges = await _persistence.GetAllTimeRanges(entity, attribute); if (existingTimeRanges.Any(x => x.Intersects(dataRange.TimeRange))) { Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine("Overwriting data"); Console.ResetColor(); } var merged = _aggregatedMerger.MergeRangeWithRanges(persisted, dataRange); var aggregations = _aggregator.Aggregate(merged, quantised, _configuration.AggregationsSeconds); //Console.WriteLine("Aggregations: " + JsonConvert.SerializeObject(aggregations)); var affectedAggregatedPoints = aggregations.Select(x => FilterAggregationToAffectedRanges(x.Value, dataRange.TimeRange, x.Key)).Where(x => x != null && x.Any()).ToList(); var rangesToPersist = affectedAggregatedPoints.Select(ranges => new ValueTuple <Guid, Guid, int, IEnumerable <AggregatedDataRange> >(entity, attribute, ranges.First().AggregationSeconds, ranges)); await _persistence.SaveData(rangesToPersist); var afterTimeRanges = _timeMerger.MergeRangeWithRanges(existingTimeRanges, dataRange.TimeRange); await _persistence.SaveTimeRanges(entity, attribute, afterTimeRanges); var saved = await _persistence.GetTimeRanges(entity, attribute, new TimeRange(100, 4102444100)); if (JsonConvert.SerializeObject(existingTimeRanges) == JsonConvert.SerializeObject(saved)) { Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine("No new time ranges saved"); Console.ResetColor(); } /*Directory.CreateDirectory("timeRanges"); * File.WriteAllText($@"timeRanges\{entity}_{attribute}.json", JsonConvert.SerializeObject(afterTimeRanges)); * Console.WriteLine("Before time ranges: " + JsonConvert.SerializeObject(existingTimeRanges)); * Console.WriteLine("New time range: " + JsonConvert.SerializeObject(dataRange.TimeRange)); * Console.WriteLine("After time ranges: " + JsonConvert.SerializeObject(afterTimeRanges));*/ _telemetry.TrackTrace($"Saved historical data from {dataRange.TimeRange.Min.ToDateTime():s} to {dataRange.TimeRange.Max.ToDateTime():s} after receiving {dataRange.Data.Count / 2} points from source"); return(affectedAggregatedPoints.ToDictionary(x => x.First().AggregationSeconds, x => x)); } finally { semaphore.Release(); } }