- Stop storing history in memory

- Add start/end dates to history requests
- Cleanup
This commit is contained in:
2015-03-29 17:57:05 -04:00
parent 340a486f95
commit 297a2914ad
14 changed files with 137 additions and 420 deletions

109
Format.cs
View File

@@ -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
}
}

View File

@@ -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();
} }
} }

View File

@@ -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())));
} }
} }

View File

@@ -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()

View File

@@ -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);
} }
} }
} }

View File

@@ -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)
{ {
} }
} }

View File

@@ -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)
{ {
} }
} }

View File

@@ -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)
{ {
} }

View File

@@ -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
} }
} }

View File

@@ -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)
{ {
} }

View File

@@ -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
} }
} }

View File

@@ -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 { }
} }
} }

View File

@@ -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)
{ {
} }
} }

View File

@@ -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" />