mirror of
https://github.com/ckaczor/WeatherService.git
synced 2026-01-13 17:23:11 -05:00
- Stop storing history in memory
- Add start/end dates to history requests - Cleanup
This commit is contained in:
109
Format.cs
109
Format.cs
@@ -1,109 +0,0 @@
|
|||||||
using WeatherService.Devices;
|
|
||||||
using WeatherService.Values;
|
|
||||||
|
|
||||||
namespace WeatherService.Common.Formatting
|
|
||||||
{
|
|
||||||
public static class Format
|
|
||||||
{
|
|
||||||
#region Value unit conversion
|
|
||||||
|
|
||||||
public static double ConvertValue(ReadingBase reading)
|
|
||||||
{
|
|
||||||
switch (reading.ValueType)
|
|
||||||
{
|
|
||||||
case WeatherValueType.Humidity:
|
|
||||||
return reading.Value;
|
|
||||||
|
|
||||||
case WeatherValueType.Pressure:
|
|
||||||
return reading.Value;
|
|
||||||
|
|
||||||
case WeatherValueType.Rain:
|
|
||||||
return Conversion.ConvertLength(reading.Value, LengthUnit.Millimeters, LengthUnit.Inches);
|
|
||||||
|
|
||||||
case WeatherValueType.Temperature:
|
|
||||||
return Conversion.ConvertTemperature(reading.Value, TemperatureUnit.Celsius, TemperatureUnit.Fahrenheit);
|
|
||||||
|
|
||||||
case WeatherValueType.WindDirection:
|
|
||||||
return reading.Value;
|
|
||||||
|
|
||||||
case WeatherValueType.WindSpeed:
|
|
||||||
return reading.Value;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return reading.Value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Value string formatting
|
|
||||||
|
|
||||||
public static string FormatValue(Value actualValue)
|
|
||||||
{
|
|
||||||
switch (actualValue.ValueType)
|
|
||||||
{
|
|
||||||
case WeatherValueType.Humidity:
|
|
||||||
return string.Format("{0:f2}", actualValue.Current.Value);
|
|
||||||
case WeatherValueType.Pressure:
|
|
||||||
return string.Format("{0:f2}", actualValue.Current.Value);
|
|
||||||
case WeatherValueType.Rain:
|
|
||||||
return string.Format("{0:f2}", Conversion.ConvertLength(actualValue.Total.Value, LengthUnit.Millimeters, LengthUnit.Inches));
|
|
||||||
case WeatherValueType.Temperature:
|
|
||||||
return string.Format("{0:f2}", actualValue.Current.Value * 9 / 5 + 32);
|
|
||||||
case WeatherValueType.WindDirection:
|
|
||||||
return string.Format("{0}", GetShortDirectionString((WindDirection)actualValue.Current.Value));
|
|
||||||
case WeatherValueType.WindSpeed:
|
|
||||||
return string.Format("{0:f2}", actualValue.Current.Value);
|
|
||||||
default:
|
|
||||||
return actualValue.Current.Value.ToString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Wind direction
|
|
||||||
|
|
||||||
public static string GetShortDirectionString(WindDirection actualValue)
|
|
||||||
{
|
|
||||||
switch (actualValue)
|
|
||||||
{
|
|
||||||
case WindDirection.North:
|
|
||||||
return "N";
|
|
||||||
case WindDirection.NorthNorthEast:
|
|
||||||
return "NNE";
|
|
||||||
case WindDirection.NorthEast:
|
|
||||||
return "NE";
|
|
||||||
case WindDirection.EastNorthEast:
|
|
||||||
return "ENE";
|
|
||||||
case WindDirection.East:
|
|
||||||
return "E";
|
|
||||||
case WindDirection.EastSouthEast:
|
|
||||||
return "ESE";
|
|
||||||
case WindDirection.SouthEast:
|
|
||||||
return "SE";
|
|
||||||
case WindDirection.SouthSouthEast:
|
|
||||||
return "SSE";
|
|
||||||
case WindDirection.South:
|
|
||||||
return "S";
|
|
||||||
case WindDirection.SouthSouthWest:
|
|
||||||
return "SSW";
|
|
||||||
case WindDirection.SouthWest:
|
|
||||||
return "SW";
|
|
||||||
case WindDirection.WestSouthWest:
|
|
||||||
return "WSW";
|
|
||||||
case WindDirection.West:
|
|
||||||
return "W";
|
|
||||||
case WindDirection.WestNorthWest:
|
|
||||||
return "WNW";
|
|
||||||
case WindDirection.NorthWest:
|
|
||||||
return "NW";
|
|
||||||
case WindDirection.NorthNorthWest:
|
|
||||||
return "NNW";
|
|
||||||
default:
|
|
||||||
return string.Empty;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.Collections.Generic;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.ServiceModel;
|
using System.ServiceModel;
|
||||||
using WeatherService.Devices;
|
using WeatherService.Devices;
|
||||||
using WeatherService.Values;
|
using WeatherService.Values;
|
||||||
@@ -11,9 +12,6 @@ namespace WeatherService.Remote
|
|||||||
[OperationContract]
|
[OperationContract]
|
||||||
List<DeviceBase> GetDevices();
|
List<DeviceBase> GetDevices();
|
||||||
|
|
||||||
[OperationContract]
|
|
||||||
ReadingBase GetLatestReading(string deviceAddress, WeatherValueType valueType);
|
|
||||||
|
|
||||||
[OperationContract]
|
[OperationContract]
|
||||||
bool Subscribe();
|
bool Subscribe();
|
||||||
|
|
||||||
@@ -21,15 +19,12 @@ namespace WeatherService.Remote
|
|||||||
bool Unsubscribe();
|
bool Unsubscribe();
|
||||||
|
|
||||||
[OperationContract]
|
[OperationContract]
|
||||||
DeviceHistory GetDeviceHistory(string deviceAddress);
|
Dictionary<DeviceBase, List<ReadingBase>> GetGenericHistory(WeatherValueType valueType, DateTimeOffset start, DateTimeOffset end);
|
||||||
|
|
||||||
[OperationContract]
|
[OperationContract]
|
||||||
Dictionary<DeviceBase, List<ReadingBase>> GetDeviceHistoryByValueType(WeatherValueType valueType);
|
Dictionary<string, List<WindSpeedReading>> GetWindSpeedHistory(int groupIntervalMinutes, DateTimeOffset start, DateTimeOffset end);
|
||||||
|
|
||||||
[OperationContract]
|
[OperationContract]
|
||||||
Dictionary<string, List<WindSpeedReading>> GetWindSpeedHistory(int groupIntervalMinutes);
|
Dictionary<string, int> GetWindDirectionHistory(DateTimeOffset start, DateTimeOffset end);
|
||||||
|
|
||||||
[OperationContract]
|
|
||||||
Dictionary<string, int> GetWindDirectionHistory();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,12 +5,30 @@ using System.Linq;
|
|||||||
using WeatherService.Data;
|
using WeatherService.Data;
|
||||||
using WeatherService.Values;
|
using WeatherService.Values;
|
||||||
using WeatherService.Devices;
|
using WeatherService.Devices;
|
||||||
using WeatherService.Reporting;
|
|
||||||
|
|
||||||
namespace WeatherService.Remote
|
namespace WeatherService.Remote
|
||||||
{
|
{
|
||||||
internal static class WeatherServiceCommon
|
internal static class WeatherServiceCommon
|
||||||
{
|
{
|
||||||
|
private static List<ReadingBase> LoadHistory(WeatherValueType valueType, int deviceId, DateTimeOffset start, DateTimeOffset end)
|
||||||
|
{
|
||||||
|
var history = new List<ReadingBase>();
|
||||||
|
|
||||||
|
for (var year = start.Year; year <= end.Year; year++)
|
||||||
|
{
|
||||||
|
using (var archiveData = new WeatherArchiveData(year))
|
||||||
|
{
|
||||||
|
var readings = archiveData.Readings;
|
||||||
|
|
||||||
|
var yearlyHistory = readings.Where(r => r.DeviceId == deviceId && r.Type == (int) valueType && r.ReadTime >= start && r.ReadTime <= end).ToList();
|
||||||
|
|
||||||
|
history.AddRange(yearlyHistory.Select(r => ReadingBase.CreateReading(valueType, r.ReadTime.DateTime, r.Value)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return history;
|
||||||
|
}
|
||||||
|
|
||||||
public static List<DeviceBase> GetDevices()
|
public static List<DeviceBase> GetDevices()
|
||||||
{
|
{
|
||||||
var deviceList = Program.Session.Devices.ToList();
|
var deviceList = Program.Session.Devices.ToList();
|
||||||
@@ -18,48 +36,21 @@ namespace WeatherService.Remote
|
|||||||
return deviceList;
|
return deviceList;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ReadingBase GetLatestReading(string deviceAddress, WeatherValueType valueType)
|
public static Dictionary<DeviceBase, List<ReadingBase>> GetGenericHistory(WeatherValueType valueType, DateTimeOffset start, DateTimeOffset end)
|
||||||
{
|
|
||||||
var deviceBase = Program.Session.Devices.FirstOrDefault(d => d.Address == deviceAddress);
|
|
||||||
|
|
||||||
if (deviceBase == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
return deviceBase.GetValue(valueType).Current;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static DeviceHistory GetDeviceHistory(string deviceAddress)
|
|
||||||
{
|
|
||||||
var deviceBase = Program.Session.Devices.FirstOrDefault(d => d.Address == deviceAddress);
|
|
||||||
|
|
||||||
if (deviceBase == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
var deviceHistory = new DeviceHistory();
|
|
||||||
|
|
||||||
foreach (var valueEntry in deviceBase.Values)
|
|
||||||
{
|
|
||||||
deviceHistory[valueEntry.Key] = valueEntry.Value.History;
|
|
||||||
}
|
|
||||||
|
|
||||||
return deviceHistory;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Dictionary<DeviceBase, List<ReadingBase>> GetDeviceHistoryByValueType(WeatherValueType valueType)
|
|
||||||
{
|
{
|
||||||
var devices = Program.Session.Devices.Where(d => d.SupportedValues.Contains(valueType));
|
var devices = Program.Session.Devices.Where(d => d.SupportedValues.Contains(valueType));
|
||||||
|
|
||||||
var deviceHistoryList = new Dictionary<DeviceBase, List<ReadingBase>>();
|
var deviceHistoryList = new Dictionary<DeviceBase, List<ReadingBase>>();
|
||||||
|
|
||||||
foreach (var device in devices)
|
foreach (var device in devices)
|
||||||
{
|
{
|
||||||
deviceHistoryList[device] = device.GetValue(valueType).History;
|
deviceHistoryList[device] = LoadHistory(valueType, device.Id, start, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
return deviceHistoryList;
|
return deviceHistoryList;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Dictionary<string, List<WindSpeedReading>> GetWindSpeedHistory(int groupIntervalMinutes)
|
public static Dictionary<string, List<WindSpeedReading>> GetWindSpeedHistory(int groupIntervalMinutes, DateTimeOffset start, DateTimeOffset end)
|
||||||
{
|
{
|
||||||
var windSpeedHistory = new Dictionary<string, List<WindSpeedReading>>();
|
var windSpeedHistory = new Dictionary<string, List<WindSpeedReading>>();
|
||||||
|
|
||||||
@@ -68,7 +59,7 @@ namespace WeatherService.Remote
|
|||||||
if (device == null)
|
if (device == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
var values = device.GetValue(WeatherValueType.WindSpeed).History;
|
var values = LoadHistory(WeatherValueType.WindSpeed, device.Id, start, end);
|
||||||
|
|
||||||
var interval = new TimeSpan(0, groupIntervalMinutes, 0);
|
var interval = new TimeSpan(0, groupIntervalMinutes, 0);
|
||||||
|
|
||||||
@@ -78,21 +69,23 @@ namespace WeatherService.Remote
|
|||||||
Readings = d.Select(r => r.Value)
|
Readings = d.Select(r => r.Value)
|
||||||
}).ToList();
|
}).ToList();
|
||||||
|
|
||||||
windSpeedHistory["Average"] = groupList.Select(d => new WindSpeedReading(WeatherValueType.WindSpeed) { ReadTime = d.ReadTime, Value = d.Readings.Average() }).ToList();
|
windSpeedHistory["Average"] = groupList.Select(d => new WindSpeedReading() { ReadTime = d.ReadTime, Value = d.Readings.Average() }).ToList();
|
||||||
windSpeedHistory["Minimum"] = groupList.Select(d => new WindSpeedReading(WeatherValueType.WindSpeed) { ReadTime = d.ReadTime, Value = d.Readings.Min() }).ToList();
|
windSpeedHistory["Minimum"] = groupList.Select(d => new WindSpeedReading() { ReadTime = d.ReadTime, Value = d.Readings.Min() }).ToList();
|
||||||
windSpeedHistory["Maximum"] = groupList.Select(d => new WindSpeedReading(WeatherValueType.WindSpeed) { ReadTime = d.ReadTime, Value = d.Readings.Max() }).ToList();
|
windSpeedHistory["Maximum"] = groupList.Select(d => new WindSpeedReading() { ReadTime = d.ReadTime, Value = d.Readings.Max() }).ToList();
|
||||||
|
|
||||||
return windSpeedHistory;
|
return windSpeedHistory;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Dictionary<string, int> GetWindDirectionHistory()
|
public static Dictionary<string, int> GetWindDirectionHistory(DateTimeOffset start, DateTimeOffset end)
|
||||||
{
|
{
|
||||||
var device = Program.Session.Devices.FirstOrDefault(d => d.SupportedValues.Contains(WeatherValueType.WindDirection));
|
var device = Program.Session.Devices.FirstOrDefault(d => d.SupportedValues.Contains(WeatherValueType.WindDirection));
|
||||||
|
|
||||||
if (device == null)
|
if (device == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
var history = device.GetValue(WeatherValueType.WindDirection).History
|
var values = LoadHistory(WeatherValueType.WindDirection, device.Id, start, end);
|
||||||
|
|
||||||
|
var history = values
|
||||||
.Cast<WindDirectionReading>()
|
.Cast<WindDirectionReading>()
|
||||||
.Where(r => r.WindDirectionValue != WindDirection.Unknown)
|
.Where(r => r.WindDirectionValue != WindDirection.Unknown)
|
||||||
.OrderBy(r => r.Value);
|
.OrderBy(r => r.Value);
|
||||||
@@ -104,31 +97,33 @@ namespace WeatherService.Remote
|
|||||||
return grouped;
|
return grouped;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<DailySummary> GetDailySummary(int deviceId, int valueType, DateTime startDate, DateTime endDate)
|
public static Dictionary<string, List<ReadingBase>> GetDailySummary(WeatherValueType valueType, int deviceId, DateTime startDate, DateTime endDate)
|
||||||
{
|
{
|
||||||
var summaryList = new List<DailySummary>();
|
var summaryList = new Dictionary<string, List<ReadingBase>>();
|
||||||
|
|
||||||
|
summaryList["Average"] = new List<ReadingBase>();
|
||||||
|
summaryList["Minimum"] = new List<ReadingBase>();
|
||||||
|
summaryList["Maximum"] = new List<ReadingBase>();
|
||||||
|
|
||||||
for (var year = startDate.Year; year <= endDate.Year; year++)
|
for (var year = startDate.Year; year <= endDate.Year; year++)
|
||||||
{
|
{
|
||||||
using (var archiveData = new WeatherArchiveData(year))
|
using (var archiveData = new WeatherArchiveData(year))
|
||||||
{
|
{
|
||||||
var groupedReadings = archiveData.Readings
|
var groupList = archiveData.Readings
|
||||||
.Where(r => r.ReadTime >= startDate &&
|
.Where(r => r.ReadTime >= startDate &&
|
||||||
r.ReadTime <= endDate &&
|
r.ReadTime <= endDate &&
|
||||||
r.DeviceId == deviceId &&
|
r.DeviceId == deviceId &&
|
||||||
r.Type == valueType)
|
r.Type == (int) valueType)
|
||||||
.GroupBy(r => DbFunctions.TruncateTime(r.ReadTime))
|
.GroupBy(r => DbFunctions.TruncateTime(r.ReadTime))
|
||||||
.Select(r => new DailySummary
|
.Select(g => new
|
||||||
{
|
{
|
||||||
Date = r.Key,
|
ReadTime = g.Key,
|
||||||
Count = r.Count(),
|
Readings = g.Select(r => r.Value)
|
||||||
Minimum = r.Min(v => v.Value),
|
}).ToList();
|
||||||
Maximum = r.Max(v => v.Value),
|
|
||||||
Average = r.Average(v => v.Value)
|
|
||||||
})
|
|
||||||
.OrderBy(d => d.Date);
|
|
||||||
|
|
||||||
summaryList.AddRange(groupedReadings);
|
summaryList["Average"].AddRange(groupList.Select(d => ReadingBase.CreateReading(valueType, d.ReadTime.Value.DateTime, d.Readings.Average())));
|
||||||
|
summaryList["Minimum"].AddRange(groupList.Select(d => ReadingBase.CreateReading(valueType, d.ReadTime.Value.DateTime, d.Readings.Min())));
|
||||||
|
summaryList["Maximum"].AddRange(groupList.Select(d => ReadingBase.CreateReading(valueType, d.ReadTime.Value.DateTime, d.Readings.Max())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.Collections.Generic;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.ServiceModel;
|
using System.ServiceModel;
|
||||||
using WeatherService.Devices;
|
using WeatherService.Devices;
|
||||||
using WeatherService.Values;
|
using WeatherService.Values;
|
||||||
@@ -15,29 +16,19 @@ namespace WeatherService.Remote
|
|||||||
return WeatherServiceCommon.GetDevices();
|
return WeatherServiceCommon.GetDevices();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ReadingBase GetLatestReading(string deviceAddress, WeatherValueType valueType)
|
public Dictionary<DeviceBase, List<ReadingBase>> GetGenericHistory(WeatherValueType valueType, DateTimeOffset start, DateTimeOffset end)
|
||||||
{
|
{
|
||||||
return WeatherServiceCommon.GetLatestReading(deviceAddress, valueType);
|
return WeatherServiceCommon.GetGenericHistory(valueType, start, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
public DeviceHistory GetDeviceHistory(string deviceAddress)
|
public Dictionary<string, List<WindSpeedReading>> GetWindSpeedHistory(int groupIntervalMinutes, DateTimeOffset start, DateTimeOffset end)
|
||||||
{
|
{
|
||||||
return WeatherServiceCommon.GetDeviceHistory(deviceAddress);
|
return WeatherServiceCommon.GetWindSpeedHistory(groupIntervalMinutes, start, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Dictionary<DeviceBase, List<ReadingBase>> GetDeviceHistoryByValueType(WeatherValueType valueType)
|
public Dictionary<string, int> GetWindDirectionHistory(DateTimeOffset start, DateTimeOffset end)
|
||||||
{
|
{
|
||||||
return WeatherServiceCommon.GetDeviceHistoryByValueType(valueType);
|
return WeatherServiceCommon.GetWindDirectionHistory(start, end);
|
||||||
}
|
|
||||||
|
|
||||||
public Dictionary<string, List<WindSpeedReading>> GetWindSpeedHistory(int groupIntervalMinutes)
|
|
||||||
{
|
|
||||||
return WeatherServiceCommon.GetWindSpeedHistory(groupIntervalMinutes);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Dictionary<string, int> GetWindDirectionHistory()
|
|
||||||
{
|
|
||||||
return WeatherServiceCommon.GetWindDirectionHistory();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Subscribe()
|
public bool Subscribe()
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ using Microsoft.AspNet.SignalR;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using WeatherService.Devices;
|
using WeatherService.Devices;
|
||||||
using WeatherService.Remote;
|
using WeatherService.Remote;
|
||||||
using WeatherService.Reporting;
|
|
||||||
using WeatherService.Values;
|
using WeatherService.Values;
|
||||||
|
|
||||||
namespace WeatherService.SignalR
|
namespace WeatherService.SignalR
|
||||||
@@ -16,34 +15,24 @@ namespace WeatherService.SignalR
|
|||||||
return WeatherServiceCommon.GetDevices();
|
return WeatherServiceCommon.GetDevices();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ReadingBase GetLatestReading(string deviceAddress, WeatherValueType valueType)
|
public List<KeyValuePair<DeviceBase, List<ReadingBase>>> GetGenericHistory(WeatherValueType valueType, DateTimeOffset start, DateTimeOffset end)
|
||||||
{
|
{
|
||||||
return WeatherServiceCommon.GetLatestReading(deviceAddress, valueType);
|
return WeatherServiceCommon.GetGenericHistory(valueType, start, end).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public DeviceHistory GetDeviceHistory(string deviceAddress)
|
public List<KeyValuePair<string, List<WindSpeedReading>>> GetWindSpeedHistory(int groupIntervalMinutes, DateTimeOffset start, DateTimeOffset end)
|
||||||
{
|
{
|
||||||
return WeatherServiceCommon.GetDeviceHistory(deviceAddress);
|
return WeatherServiceCommon.GetWindSpeedHistory(groupIntervalMinutes, start, end).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<KeyValuePair<DeviceBase, List<ReadingBase>>> GetDeviceHistoryByValueType(WeatherValueType valueType)
|
public List<KeyValuePair<string, int>> GetWindDirectionHistory(DateTimeOffset start, DateTimeOffset end)
|
||||||
{
|
{
|
||||||
return WeatherServiceCommon.GetDeviceHistoryByValueType(valueType).ToList();
|
return WeatherServiceCommon.GetWindDirectionHistory(start, end).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<KeyValuePair<string, List<WindSpeedReading>>> GetWindSpeedHistory(int groupIntervalMinutes)
|
public List<KeyValuePair<string, List<ReadingBase>>> GetDailySummary(WeatherValueType valueType, int deviceId, DateTime startDate, DateTime endDate)
|
||||||
{
|
{
|
||||||
return WeatherServiceCommon.GetWindSpeedHistory(groupIntervalMinutes).ToList();
|
return WeatherServiceCommon.GetDailySummary(valueType, deviceId, startDate, endDate).ToList();
|
||||||
}
|
|
||||||
|
|
||||||
public List<KeyValuePair<string, int>> GetWindDirectionHistory()
|
|
||||||
{
|
|
||||||
return WeatherServiceCommon.GetWindDirectionHistory().ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<DailySummary> GetDailySummary(int deviceId, int valueType, DateTime startDate, DateTime endDate)
|
|
||||||
{
|
|
||||||
return WeatherServiceCommon.GetDailySummary(deviceId, valueType, startDate, endDate);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ namespace WeatherService.Values
|
|||||||
[DataContract]
|
[DataContract]
|
||||||
public class HumidityReading : ReadingBase
|
public class HumidityReading : ReadingBase
|
||||||
{
|
{
|
||||||
public HumidityReading(WeatherValueType valueType) : base(valueType)
|
public HumidityReading() : base(WeatherValueType.Humidity)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ namespace WeatherService.Values
|
|||||||
[DataContract]
|
[DataContract]
|
||||||
public class PressureReading : ReadingBase
|
public class PressureReading : ReadingBase
|
||||||
{
|
{
|
||||||
public PressureReading(WeatherValueType valueType) : base(valueType)
|
public PressureReading() : base(WeatherValueType.Pressure)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ namespace WeatherService.Values
|
|||||||
[DataContract]
|
[DataContract]
|
||||||
public class RainReading : ReadingBase
|
public class RainReading : ReadingBase
|
||||||
{
|
{
|
||||||
public RainReading(WeatherValueType valueType) : base(valueType)
|
public RainReading() : base(WeatherValueType.Rain)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -78,22 +78,32 @@ namespace WeatherService.Values
|
|||||||
switch (valueType)
|
switch (valueType)
|
||||||
{
|
{
|
||||||
case WeatherValueType.Temperature:
|
case WeatherValueType.Temperature:
|
||||||
return new TemperatureReading(valueType);
|
return new TemperatureReading();
|
||||||
case WeatherValueType.Pressure:
|
case WeatherValueType.Pressure:
|
||||||
return new PressureReading(valueType);
|
return new PressureReading();
|
||||||
case WeatherValueType.Humidity:
|
case WeatherValueType.Humidity:
|
||||||
return new HumidityReading(valueType);
|
return new HumidityReading();
|
||||||
case WeatherValueType.WindSpeed:
|
case WeatherValueType.WindSpeed:
|
||||||
return new WindSpeedReading(valueType);
|
return new WindSpeedReading();
|
||||||
case WeatherValueType.WindDirection:
|
case WeatherValueType.WindDirection:
|
||||||
return new WindDirectionReading(valueType);
|
return new WindDirectionReading();
|
||||||
case WeatherValueType.Rain:
|
case WeatherValueType.Rain:
|
||||||
return new RainReading(valueType);
|
return new RainReading();
|
||||||
default:
|
default:
|
||||||
throw new ArgumentOutOfRangeException("valueType");
|
throw new ArgumentOutOfRangeException("valueType");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ReadingBase CreateReading(WeatherValueType valueType, DateTime readTime, double value)
|
||||||
|
{
|
||||||
|
var reading = CreateReading(valueType);
|
||||||
|
|
||||||
|
reading.ReadTime = readTime;
|
||||||
|
reading.Value = value;
|
||||||
|
|
||||||
|
return reading;
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ namespace WeatherService.Values
|
|||||||
[DataContract]
|
[DataContract]
|
||||||
public class TemperatureReading : ReadingBase
|
public class TemperatureReading : ReadingBase
|
||||||
{
|
{
|
||||||
public TemperatureReading(WeatherValueType valueType) : base(valueType)
|
public TemperatureReading() : base(WeatherValueType.Temperature)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
197
Values/Value.cs
197
Values/Value.cs
@@ -1,6 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Runtime.Serialization;
|
using System.Runtime.Serialization;
|
||||||
using WeatherService.Data;
|
using WeatherService.Data;
|
||||||
using WeatherService.Devices;
|
using WeatherService.Devices;
|
||||||
@@ -35,12 +33,6 @@ namespace WeatherService.Values
|
|||||||
[DataContract]
|
[DataContract]
|
||||||
public class Value
|
public class Value
|
||||||
{
|
{
|
||||||
#region Constants
|
|
||||||
|
|
||||||
private const int MaximumHours = 24;
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Member variables
|
#region Member variables
|
||||||
|
|
||||||
private readonly DeviceBase _ownerDevice; // Owner device
|
private readonly DeviceBase _ownerDevice; // Owner device
|
||||||
@@ -51,161 +43,12 @@ namespace WeatherService.Values
|
|||||||
|
|
||||||
public Value(WeatherValueType valueType, DeviceBase ownerDevice)
|
public Value(WeatherValueType valueType, DeviceBase ownerDevice)
|
||||||
{
|
{
|
||||||
MaximumHistoryHours = MaximumHours;
|
|
||||||
|
|
||||||
// Remember information we were given
|
// Remember information we were given
|
||||||
ValueType = valueType;
|
ValueType = valueType;
|
||||||
_ownerDevice = ownerDevice;
|
_ownerDevice = ownerDevice;
|
||||||
|
|
||||||
// Create the readings
|
// Create the readings
|
||||||
Current = ReadingBase.CreateReading(ValueType);
|
Current = ReadingBase.CreateReading(ValueType);
|
||||||
Maximum = ReadingBase.CreateReading(ValueType);
|
|
||||||
Minimum = ReadingBase.CreateReading(ValueType);
|
|
||||||
Average = ReadingBase.CreateReading(ValueType);
|
|
||||||
|
|
||||||
Total = valueType == WeatherValueType.Rain ? ReadingBase.CreateReading(ValueType) : new ReadingBase(valueType);
|
|
||||||
|
|
||||||
History = new List<ReadingBase>();
|
|
||||||
|
|
||||||
// Figure out the minimum time we want to load into history
|
|
||||||
DateTime minimumTime = DateTime.Now.AddHours(-MaximumHours);
|
|
||||||
|
|
||||||
using (var weatherArchiveData = new WeatherArchiveData(minimumTime.Year))
|
|
||||||
{
|
|
||||||
var readingList =
|
|
||||||
weatherArchiveData.Readings.Where(
|
|
||||||
reading =>
|
|
||||||
reading.DeviceId == ownerDevice.Id && reading.Type == (int) valueType &&
|
|
||||||
reading.ReadTime >= minimumTime);
|
|
||||||
|
|
||||||
// Loop over all readings and reload them into the history
|
|
||||||
foreach (var readingData in readingList)
|
|
||||||
{
|
|
||||||
// Get the value from the reading
|
|
||||||
double dValue = readingData.Value;
|
|
||||||
|
|
||||||
// Get the timestamp from the reading
|
|
||||||
DateTime dtTimestamp = readingData.ReadTime.LocalDateTime;
|
|
||||||
|
|
||||||
// Set the value into the history
|
|
||||||
SetValue(dValue, dtTimestamp, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
// Build a list for this device using the right value type and limit to the maximum number of hours
|
|
||||||
var readingList = from reading in Database.ReadingTable
|
|
||||||
where reading.DeviceId == ownerDevice.Id && reading.Type == valueType && reading.ReadTime >= minimumTime
|
|
||||||
select reading;
|
|
||||||
|
|
||||||
// Loop over all readings and reload them into the history
|
|
||||||
foreach (ReadingData readingData in readingList)
|
|
||||||
{
|
|
||||||
// Get the value from the reading
|
|
||||||
double dValue = readingData.Value;
|
|
||||||
|
|
||||||
// Get the timestamp from the reading
|
|
||||||
DateTime dtTimestamp = readingData.ReadTime;
|
|
||||||
|
|
||||||
// Set the value into the history
|
|
||||||
SetValue(dValue, dtTimestamp, false);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Private methods
|
|
||||||
|
|
||||||
private void AddHistory(double value, DateTime timeStamp)
|
|
||||||
{
|
|
||||||
// Create the reading
|
|
||||||
ReadingBase readingBase = ReadingBase.CreateReading(ValueType);
|
|
||||||
readingBase.Value = value;
|
|
||||||
readingBase.ReadTime = timeStamp;
|
|
||||||
|
|
||||||
// Add the current value to the history
|
|
||||||
History.Add(readingBase);
|
|
||||||
|
|
||||||
// Get the current head of the history list
|
|
||||||
ReadingBase oHead = History[0];
|
|
||||||
|
|
||||||
// Get the difference in time between the now and the reading time
|
|
||||||
TimeSpan oTimeSpan = DateTime.Now - oHead.ReadTime;
|
|
||||||
|
|
||||||
// If the span is over the maximum time then remove it
|
|
||||||
if (oTimeSpan.TotalHours > MaximumHours)
|
|
||||||
{
|
|
||||||
// Remove this sample
|
|
||||||
Readings--;
|
|
||||||
|
|
||||||
// Remove this value from the total
|
|
||||||
Total.Value -= oHead.Value;
|
|
||||||
|
|
||||||
// Remove the reading
|
|
||||||
History.RemoveAt(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void CheckMinimumValue(double value, DateTime timeStamp)
|
|
||||||
{
|
|
||||||
// Figure out if we want a zero value
|
|
||||||
bool bNoZero = (ValueType == WeatherValueType.WindSpeed || ValueType == WeatherValueType.Rain);
|
|
||||||
|
|
||||||
// Figure out how old the current minimum is
|
|
||||||
TimeSpan oTimeSpan = DateTime.Now - Minimum.ReadTime;
|
|
||||||
|
|
||||||
// If the minimum is too old then we need a new minimum
|
|
||||||
if (oTimeSpan.TotalHours > MaximumHours)
|
|
||||||
{
|
|
||||||
List<ReadingBase> readings = bNoZero ? History.Where(r => r.Value > 0).ToList() : History;
|
|
||||||
|
|
||||||
ReadingBase newMin = readings.Min();
|
|
||||||
|
|
||||||
// If we got a minimum value then set it
|
|
||||||
if (newMin != null)
|
|
||||||
{
|
|
||||||
// Set the data into the value
|
|
||||||
Minimum.SetValue(newMin.Value, newMin.ReadTime);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we have no minimum or the value is over the current minimum then reset the minimum
|
|
||||||
if ((Minimum.ReadTime == DateTime.MinValue) || (value < Minimum.Value) || (Minimum.Value.Equals(0) && bNoZero))
|
|
||||||
{
|
|
||||||
bool bSetMinimum; // Is this value the new minimum?
|
|
||||||
|
|
||||||
if (bNoZero)
|
|
||||||
bSetMinimum = (value > 0) || (Minimum.ReadTime == DateTime.MinValue);
|
|
||||||
else
|
|
||||||
bSetMinimum = true;
|
|
||||||
|
|
||||||
if (bSetMinimum)
|
|
||||||
Minimum.SetValue(value, timeStamp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void CheckMaximumValue(double value, DateTime timeStamp)
|
|
||||||
{
|
|
||||||
// Figure out how old the current maximum is
|
|
||||||
TimeSpan oTimeSpan = DateTime.Now - Maximum.ReadTime;
|
|
||||||
|
|
||||||
// If the maximum is too old then we need a new maximum
|
|
||||||
if (oTimeSpan.TotalHours > MaximumHours)
|
|
||||||
{
|
|
||||||
// Get the new maximum
|
|
||||||
var newMax = History.Max();
|
|
||||||
|
|
||||||
// Set the maximum
|
|
||||||
Maximum.SetValue(newMax.Value, newMax.ReadTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we have no maximum or the value is over the current maximum then reset the maximum
|
|
||||||
if ((Maximum.ReadTime == DateTime.MinValue) || (value >= Maximum.Value))
|
|
||||||
{
|
|
||||||
Maximum.SetValue(value, timeStamp);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@@ -229,21 +72,12 @@ namespace WeatherService.Values
|
|||||||
// Set the current value
|
// Set the current value
|
||||||
Current.SetValue(value, timeStamp);
|
Current.SetValue(value, timeStamp);
|
||||||
|
|
||||||
// Add another sample
|
|
||||||
Readings++;
|
|
||||||
|
|
||||||
// Add the current value to the total
|
|
||||||
Total.Value += value;
|
|
||||||
|
|
||||||
// Add the value to the history
|
|
||||||
AddHistory(value, timeStamp);
|
|
||||||
|
|
||||||
if (save)
|
if (save)
|
||||||
{
|
{
|
||||||
// Save the reading
|
// Save the reading
|
||||||
using (var weatherArchiveData = new WeatherArchiveData(timeStamp.Year))
|
using (var weatherArchiveData = new WeatherArchiveData(timeStamp.Year))
|
||||||
{
|
{
|
||||||
var reading = new Data.ReadingData
|
var reading = new ReadingData
|
||||||
{
|
{
|
||||||
DeviceId = _ownerDevice.Id,
|
DeviceId = _ownerDevice.Id,
|
||||||
Type = (int) ValueType,
|
Type = (int) ValueType,
|
||||||
@@ -254,16 +88,7 @@ namespace WeatherService.Values
|
|||||||
weatherArchiveData.Readings.Add(reading);
|
weatherArchiveData.Readings.Add(reading);
|
||||||
weatherArchiveData.SaveChanges();
|
weatherArchiveData.SaveChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the minimum value
|
|
||||||
CheckMinimumValue(value, timeStamp);
|
|
||||||
|
|
||||||
// Update the maximum value
|
|
||||||
CheckMaximumValue(value, timeStamp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate the new average value
|
|
||||||
Average.SetValue(Total.Value / Readings);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@@ -273,29 +98,9 @@ namespace WeatherService.Values
|
|||||||
[DataMember]
|
[DataMember]
|
||||||
public ReadingBase Current { get; set; }
|
public ReadingBase Current { get; set; }
|
||||||
|
|
||||||
[DataMember]
|
|
||||||
public ReadingBase Maximum { get; set; }
|
|
||||||
|
|
||||||
[DataMember]
|
|
||||||
public ReadingBase Minimum { get; set; }
|
|
||||||
|
|
||||||
[DataMember]
|
|
||||||
public ReadingBase Average { get; set; }
|
|
||||||
|
|
||||||
[DataMember]
|
|
||||||
public ReadingBase Total { get; set; }
|
|
||||||
|
|
||||||
[DataMember]
|
|
||||||
public long Readings { get; set; }
|
|
||||||
|
|
||||||
[DataMember]
|
[DataMember]
|
||||||
public WeatherValueType ValueType { get; set; }
|
public WeatherValueType ValueType { get; set; }
|
||||||
|
|
||||||
[DataMember]
|
|
||||||
public int MaximumHistoryHours { get; set; }
|
|
||||||
|
|
||||||
public List<ReadingBase> History { get; set; }
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
using System.Runtime.Serialization;
|
using System;
|
||||||
using WeatherService.Common.Formatting;
|
using System.Runtime.Serialization;
|
||||||
using WeatherService.Devices;
|
using WeatherService.Devices;
|
||||||
|
|
||||||
namespace WeatherService.Values
|
namespace WeatherService.Values
|
||||||
@@ -7,21 +7,63 @@ namespace WeatherService.Values
|
|||||||
[DataContract]
|
[DataContract]
|
||||||
public class WindDirectionReading : ReadingBase
|
public class WindDirectionReading : ReadingBase
|
||||||
{
|
{
|
||||||
public WindDirectionReading(WeatherValueType valueType) : base(valueType)
|
public static string GetShortDirectionString(WindDirection actualValue)
|
||||||
|
{
|
||||||
|
switch (actualValue)
|
||||||
|
{
|
||||||
|
case WindDirection.North:
|
||||||
|
return "N";
|
||||||
|
case WindDirection.NorthNorthEast:
|
||||||
|
return "NNE";
|
||||||
|
case WindDirection.NorthEast:
|
||||||
|
return "NE";
|
||||||
|
case WindDirection.EastNorthEast:
|
||||||
|
return "ENE";
|
||||||
|
case WindDirection.East:
|
||||||
|
return "E";
|
||||||
|
case WindDirection.EastSouthEast:
|
||||||
|
return "ESE";
|
||||||
|
case WindDirection.SouthEast:
|
||||||
|
return "SE";
|
||||||
|
case WindDirection.SouthSouthEast:
|
||||||
|
return "SSE";
|
||||||
|
case WindDirection.South:
|
||||||
|
return "S";
|
||||||
|
case WindDirection.SouthSouthWest:
|
||||||
|
return "SSW";
|
||||||
|
case WindDirection.SouthWest:
|
||||||
|
return "SW";
|
||||||
|
case WindDirection.WestSouthWest:
|
||||||
|
return "WSW";
|
||||||
|
case WindDirection.West:
|
||||||
|
return "W";
|
||||||
|
case WindDirection.WestNorthWest:
|
||||||
|
return "WNW";
|
||||||
|
case WindDirection.NorthWest:
|
||||||
|
return "NW";
|
||||||
|
case WindDirection.NorthNorthWest:
|
||||||
|
return "NNW";
|
||||||
|
default:
|
||||||
|
return String.Empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public WindDirectionReading()
|
||||||
|
: base(WeatherValueType.WindDirection)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
[DataMember]
|
[DataMember]
|
||||||
public WindDirection WindDirectionValue
|
public WindDirection WindDirectionValue
|
||||||
{
|
{
|
||||||
get { return (WindDirection) Value; }
|
get { return (WindDirection)Value; }
|
||||||
set { Value = (double) value; }
|
set { Value = (double)value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
[DataMember]
|
[DataMember]
|
||||||
public string WindDirectionString
|
public string WindDirectionString
|
||||||
{
|
{
|
||||||
get { return Format.GetShortDirectionString(WindDirectionValue); }
|
get { return GetShortDirectionString(WindDirectionValue); }
|
||||||
set { }
|
set { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ namespace WeatherService.Values
|
|||||||
[DataContract]
|
[DataContract]
|
||||||
public class WindSpeedReading : ReadingBase
|
public class WindSpeedReading : ReadingBase
|
||||||
{
|
{
|
||||||
public WindSpeedReading(WeatherValueType valueType) : base(valueType)
|
public WindSpeedReading() : base(WeatherValueType.WindSpeed)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -133,7 +133,6 @@
|
|||||||
<Compile Include="Devices\TemperatureDevice.cs" />
|
<Compile Include="Devices\TemperatureDevice.cs" />
|
||||||
<Compile Include="Devices\WindDirectionDevice.cs" />
|
<Compile Include="Devices\WindDirectionDevice.cs" />
|
||||||
<Compile Include="Devices\WindSpeedDevice.cs" />
|
<Compile Include="Devices\WindSpeedDevice.cs" />
|
||||||
<Compile Include="Format.cs" />
|
|
||||||
<Compile Include="Framework\ConsoleHarness.cs" />
|
<Compile Include="Framework\ConsoleHarness.cs" />
|
||||||
<Compile Include="Framework\IWindowsService.cs" />
|
<Compile Include="Framework\IWindowsService.cs" />
|
||||||
<Compile Include="Framework\TypeExtensions.cs" />
|
<Compile Include="Framework\TypeExtensions.cs" />
|
||||||
|
|||||||
Reference in New Issue
Block a user