Add aggregate API

This commit is contained in:
2020-07-23 20:36:20 -04:00
parent f8a6c71dd0
commit e810c4a240
4 changed files with 88 additions and 0 deletions

View File

@@ -32,6 +32,14 @@ namespace ChrisKaczor.HomeMonitor.Weather.Service.Controllers
return (await _database.GetReadingHistory(start, end)).ToList();
}
[HttpGet("aggregate")]
public async Task<ActionResult<WeatherAggregate>> GetHistoryAggregate(DateTimeOffset start, DateTimeOffset end)
{
var readings = await _database.GetReadingHistory(start, end);
return new WeatherAggregate(readings);
}
[HttpGet("value-history")]
public async Task<ActionResult<List<WeatherValue>>> GetValueHistory(WeatherValueType weatherValueType, DateTimeOffset start, DateTimeOffset end)
{

View File

@@ -1,4 +1,5 @@
using System;
using DecimalMath;
namespace ChrisKaczor.HomeMonitor.Weather.Service
{
@@ -8,5 +9,10 @@ namespace ChrisKaczor.HomeMonitor.Weather.Service
{
return item.CompareTo(start) >= 0 && item.CompareTo(end) <= 0;
}
public static decimal Truncate(this decimal value, int decimalPlaces)
{
return decimal.Truncate(value * DecimalEx.Pow(10, decimalPlaces)) / DecimalEx.Pow(10, decimalPlaces);
}
}
}

View File

@@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Linq;
using ChrisKaczor.HomeMonitor.Weather.Models;
using JetBrains.Annotations;
namespace ChrisKaczor.HomeMonitor.Weather.Service.Models
{
[PublicAPI]
public class ReadingAggregate
{
public decimal Min { get; set; }
public decimal Max { get; set; }
public decimal Average { get; set; }
public ReadingAggregate(IEnumerable<WeatherReading> readings, Func<WeatherReading, decimal> selector, int decimalPlaces)
{
Min = readings.Min(selector);
Max = readings.Max(selector);
Average = readings.Average(selector).Truncate(decimalPlaces);
}
}
}

View File

@@ -0,0 +1,49 @@
using System;
using System.Collections.Generic;
using System.Linq;
using ChrisKaczor.HomeMonitor.Weather.Models;
using JetBrains.Annotations;
namespace ChrisKaczor.HomeMonitor.Weather.Service.Models
{
[PublicAPI]
public class WeatherAggregate
{
public ReadingAggregate Humidity { get; set; }
public ReadingAggregate Temperature { get; set; }
public ReadingAggregate Pressure { get; set; }
public ReadingAggregate Light { get; set; }
public ReadingAggregate WindSpeed { get; set; }
public WindDirection WindDirectionAverage { get; set; }
public decimal RainTotal { get; set; }
private readonly static List<int> _windDirectionValues = ((WindDirection[])Enum.GetValues(typeof(WindDirection))).Select(e => (int)e).ToList();
public WeatherAggregate(IEnumerable<WeatherReading> readings)
{
if (!readings.Any())
return;
Humidity = new ReadingAggregate(readings, r => r.Humidity, 1);
Temperature = new ReadingAggregate(readings, r => r.PressureTemperature, 1);
Pressure = new ReadingAggregate(readings, r => r.Pressure, 2);
Light = new ReadingAggregate(readings, r => (r.LightLevel / 3.3m * 100).Truncate(1), 1);
WindSpeed = new ReadingAggregate(readings, r => r.WindSpeed, 1);
var windDirectionAverage = readings.Average(r => (decimal)r.WindDirection);
WindDirectionAverage = (WindDirection)_windDirectionValues.Aggregate((x, y) => Math.Abs(x - windDirectionAverage) < Math.Abs(y - windDirectionAverage) ? x : y);
RainTotal = readings.Sum(r => r.Rain);
}
}
}