mirror of
https://github.com/ckaczor/WeatherService.git
synced 2026-01-25 09:35:41 -05:00
Initial commit
This commit is contained in:
9
Remote/DeviceHistory.cs
Normal file
9
Remote/DeviceHistory.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
using System.Collections.Generic;
|
||||
using WeatherService.Values;
|
||||
|
||||
namespace WeatherService.Remote
|
||||
{
|
||||
public class DeviceHistory : Dictionary<WeatherValueType, List<ReadingBase>>
|
||||
{
|
||||
}
|
||||
}
|
||||
31
Remote/IWeatherService.cs
Normal file
31
Remote/IWeatherService.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
using System.Collections.Generic;
|
||||
using System.ServiceModel;
|
||||
using System.ServiceModel.Web;
|
||||
using WeatherService.Devices;
|
||||
using WeatherService.Remote;
|
||||
using WeatherService.Values;
|
||||
|
||||
namespace WeatherService
|
||||
{
|
||||
[ServiceContract]
|
||||
public interface IWeatherService
|
||||
{
|
||||
[WebGet(ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)]
|
||||
List<DeviceBase> GetDevices();
|
||||
|
||||
[WebGet(ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)]
|
||||
ReadingBase GetLatestReading(string deviceAddress, WeatherValueType valueType);
|
||||
|
||||
[WebGet(ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)]
|
||||
DeviceHistory GetDeviceHistory(string deviceAddress);
|
||||
|
||||
[WebGet(ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)]
|
||||
Dictionary<DeviceBase, List<ReadingBase>> GetDeviceHistoryByValueType(WeatherValueType valueType);
|
||||
|
||||
[WebGet(ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)]
|
||||
Dictionary<string, List<WindSpeedReading>> GetWindSpeedHistory(int groupIntervalMinutes);
|
||||
|
||||
[WebGet(ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)]
|
||||
Dictionary<string, int> GetWindDirectionHistory();
|
||||
}
|
||||
}
|
||||
11
Remote/IWeatherServiceCallback.cs
Normal file
11
Remote/IWeatherServiceCallback.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using System.ServiceModel;
|
||||
using WeatherService.Devices;
|
||||
|
||||
namespace WeatherService
|
||||
{
|
||||
public interface IWeatherServiceCallback
|
||||
{
|
||||
[OperationContract(IsOneWay = true)]
|
||||
void OnDeviceUpdate(DeviceBase device);
|
||||
}
|
||||
}
|
||||
36
Remote/IWeatherServiceDuplex.cs
Normal file
36
Remote/IWeatherServiceDuplex.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using System.Collections.Generic;
|
||||
using System.ServiceModel;
|
||||
using WeatherService.Devices;
|
||||
using WeatherService.Remote;
|
||||
using WeatherService.Values;
|
||||
|
||||
namespace WeatherService
|
||||
{
|
||||
[ServiceContract(CallbackContract = typeof(IWeatherServiceCallback))]
|
||||
public interface IWeatherServiceDuplex
|
||||
{
|
||||
[OperationContract]
|
||||
List<DeviceBase> GetDevices();
|
||||
|
||||
[OperationContract]
|
||||
ReadingBase GetLatestReading(string deviceAddress, WeatherValueType valueType);
|
||||
|
||||
[OperationContract]
|
||||
bool Subscribe();
|
||||
|
||||
[OperationContract]
|
||||
bool Unsubscribe();
|
||||
|
||||
[OperationContract]
|
||||
DeviceHistory GetDeviceHistory(string deviceAddress);
|
||||
|
||||
[OperationContract]
|
||||
Dictionary<DeviceBase, List<ReadingBase>> GetDeviceHistoryByValueType(WeatherValueType valueType);
|
||||
|
||||
[OperationContract]
|
||||
Dictionary<string, List<WindSpeedReading>> GetWindSpeedHistory(int groupIntervalMinutes);
|
||||
|
||||
[OperationContract]
|
||||
Dictionary<string, int> GetWindDirectionHistory();
|
||||
}
|
||||
}
|
||||
55
Remote/WeatherService.cs
Normal file
55
Remote/WeatherService.cs
Normal file
@@ -0,0 +1,55 @@
|
||||
using System.Collections.Generic;
|
||||
using System.ServiceModel.Activation;
|
||||
using System.ServiceModel.Web;
|
||||
using WeatherService.Devices;
|
||||
using WeatherService.Remote;
|
||||
using WeatherService.Values;
|
||||
|
||||
namespace WeatherService
|
||||
{
|
||||
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
|
||||
public class WeatherService : IWeatherService
|
||||
{
|
||||
public List<DeviceBase> GetDevices()
|
||||
{
|
||||
WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Origin", "*");
|
||||
|
||||
return WeatherServiceCommon.GetDevices();
|
||||
}
|
||||
|
||||
public ReadingBase GetLatestReading(string deviceAddress, WeatherValueType valueType)
|
||||
{
|
||||
WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Origin", "*");
|
||||
|
||||
return WeatherServiceCommon.GetLatestReading(deviceAddress, valueType);
|
||||
}
|
||||
|
||||
public DeviceHistory GetDeviceHistory(string deviceAddress)
|
||||
{
|
||||
WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Origin", "*");
|
||||
|
||||
return WeatherServiceCommon.GetDeviceHistory(deviceAddress);
|
||||
}
|
||||
|
||||
public Dictionary<DeviceBase, List<ReadingBase>> GetDeviceHistoryByValueType(WeatherValueType valueType)
|
||||
{
|
||||
WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Origin", "*");
|
||||
|
||||
return WeatherServiceCommon.GetDeviceHistoryByValueType(valueType);
|
||||
}
|
||||
|
||||
public Dictionary<string, List<WindSpeedReading>> GetWindSpeedHistory(int groupIntervalMinutes)
|
||||
{
|
||||
WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Origin", "*");
|
||||
|
||||
return WeatherServiceCommon.GetWindSpeedHistory(groupIntervalMinutes);
|
||||
}
|
||||
|
||||
public Dictionary<string, int> GetWindDirectionHistory()
|
||||
{
|
||||
WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Origin", "*");
|
||||
|
||||
return WeatherServiceCommon.GetWindDirectionHistory();
|
||||
}
|
||||
}
|
||||
}
|
||||
104
Remote/WeatherServiceCommon.cs
Normal file
104
Remote/WeatherServiceCommon.cs
Normal file
@@ -0,0 +1,104 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using WeatherService.Values;
|
||||
using WeatherService.Devices;
|
||||
|
||||
namespace WeatherService.Remote
|
||||
{
|
||||
internal static class WeatherServiceCommon
|
||||
{
|
||||
public static List<DeviceBase> GetDevices()
|
||||
{
|
||||
var deviceList = Program.Session.Devices.ToList();
|
||||
|
||||
return deviceList;
|
||||
}
|
||||
|
||||
public static ReadingBase GetLatestReading(string deviceAddress, WeatherValueType valueType)
|
||||
{
|
||||
DeviceBase deviceBase = Program.Session.Devices.Where(d => d.Address == deviceAddress).FirstOrDefault();
|
||||
|
||||
if (deviceBase == null)
|
||||
return null;
|
||||
|
||||
return deviceBase.GetValue(valueType).Current;
|
||||
}
|
||||
|
||||
public static DeviceHistory GetDeviceHistory(string deviceAddress)
|
||||
{
|
||||
DeviceBase deviceBase = Program.Session.Devices.Where(d => d.Address == deviceAddress).FirstOrDefault();
|
||||
|
||||
if (deviceBase == null)
|
||||
return null;
|
||||
|
||||
DeviceHistory 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));
|
||||
|
||||
Dictionary<DeviceBase, List<ReadingBase>> deviceHistoryList = new Dictionary<DeviceBase, List<ReadingBase>>();
|
||||
|
||||
foreach (var device in devices)
|
||||
{
|
||||
deviceHistoryList[device] = device.GetValue(valueType).History;
|
||||
}
|
||||
|
||||
return deviceHistoryList;
|
||||
}
|
||||
|
||||
public static Dictionary<string, List<WindSpeedReading>> GetWindSpeedHistory(int groupIntervalMinutes)
|
||||
{
|
||||
var windSpeedHistory = new Dictionary<string, List<WindSpeedReading>>();
|
||||
|
||||
var device = Program.Session.Devices.Where(d => d.SupportedValues.Contains(WeatherValueType.WindSpeed)).FirstOrDefault();
|
||||
|
||||
if (device == null)
|
||||
return null;
|
||||
|
||||
var values = device.GetValue(WeatherValueType.WindSpeed).History;
|
||||
|
||||
TimeSpan interval = new TimeSpan(0, groupIntervalMinutes, 0);
|
||||
|
||||
var groupList = values.GroupBy(reading => reading.ReadTime.Ticks / interval.Ticks).Select(d => new
|
||||
{
|
||||
ReadTime = new DateTime(d.Key * interval.Ticks),
|
||||
Readings = d.Select(r => r.Value)
|
||||
});
|
||||
|
||||
windSpeedHistory["Average"] = groupList.Select(d => new WindSpeedReading(WeatherValueType.WindSpeed) { 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["Maximum"] = groupList.Select(d => new WindSpeedReading(WeatherValueType.WindSpeed) { ReadTime = d.ReadTime, Value = d.Readings.Max() }).ToList();
|
||||
|
||||
return windSpeedHistory;
|
||||
}
|
||||
|
||||
public static Dictionary<string, int> GetWindDirectionHistory()
|
||||
{
|
||||
var device = Program.Session.Devices.Where(d => d.SupportedValues.Contains(WeatherValueType.WindDirection)).FirstOrDefault();
|
||||
|
||||
if (device == null)
|
||||
return null;
|
||||
|
||||
var history = device.GetValue(WeatherValueType.WindDirection).History
|
||||
.Cast<WindDirectionReading>()
|
||||
.Where(r => r.WindDirectionValue != WindDirection.Unknown)
|
||||
.OrderBy(r => r.Value);
|
||||
|
||||
var grouped = history
|
||||
.GroupBy(r => r.WindDirectionString)
|
||||
.ToDictionary(r => r.Key, r => r.Count());
|
||||
|
||||
return grouped;
|
||||
}
|
||||
}
|
||||
}
|
||||
111
Remote/WeatherServiceDuplex.cs
Normal file
111
Remote/WeatherServiceDuplex.cs
Normal file
@@ -0,0 +1,111 @@
|
||||
using System.Collections.Generic;
|
||||
using System.ServiceModel;
|
||||
using WeatherService.Devices;
|
||||
using WeatherService.Remote;
|
||||
using WeatherService.Values;
|
||||
|
||||
namespace WeatherService
|
||||
{
|
||||
[CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant)]
|
||||
public class WeatherServiceDuplex : IWeatherServiceDuplex
|
||||
{
|
||||
private static readonly List<IWeatherServiceCallback> subscribers = new List<IWeatherServiceCallback>();
|
||||
|
||||
public List<DeviceBase> GetDevices()
|
||||
{
|
||||
return WeatherServiceCommon.GetDevices();
|
||||
}
|
||||
|
||||
public ReadingBase GetLatestReading(string deviceAddress, WeatherValueType valueType)
|
||||
{
|
||||
return WeatherServiceCommon.GetLatestReading(deviceAddress, valueType);
|
||||
}
|
||||
|
||||
public DeviceHistory GetDeviceHistory(string deviceAddress)
|
||||
{
|
||||
return WeatherServiceCommon.GetDeviceHistory(deviceAddress);
|
||||
}
|
||||
|
||||
public Dictionary<DeviceBase, List<ReadingBase>> GetDeviceHistoryByValueType(WeatherValueType valueType)
|
||||
{
|
||||
return WeatherServiceCommon.GetDeviceHistoryByValueType(valueType);
|
||||
}
|
||||
|
||||
public Dictionary<string, List<WindSpeedReading>> GetWindSpeedHistory(int groupIntervalMinutes)
|
||||
{
|
||||
return WeatherServiceCommon.GetWindSpeedHistory(groupIntervalMinutes);
|
||||
}
|
||||
|
||||
public Dictionary<string, int> GetWindDirectionHistory()
|
||||
{
|
||||
return WeatherServiceCommon.GetWindDirectionHistory();
|
||||
}
|
||||
|
||||
public bool Subscribe()
|
||||
{
|
||||
try
|
||||
{
|
||||
IWeatherServiceCallback callback = OperationContext.Current.GetCallbackChannel<IWeatherServiceCallback>();
|
||||
|
||||
if (!subscribers.Contains(callback))
|
||||
subscribers.Add(callback);
|
||||
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool Unsubscribe()
|
||||
{
|
||||
try
|
||||
{
|
||||
IWeatherServiceCallback callback = OperationContext.Current.GetCallbackChannel<IWeatherServiceCallback>();
|
||||
|
||||
if (subscribers.Contains(callback))
|
||||
subscribers.Remove(callback);
|
||||
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
internal static void FireNotification(DeviceBase device)
|
||||
{
|
||||
// Create a list of callbacks that need to be removed
|
||||
var removeList = new List<IWeatherServiceCallback>();
|
||||
|
||||
// Loop over each subscriber
|
||||
foreach (var callback in subscribers)
|
||||
{
|
||||
// If the callback connection isn't open...
|
||||
if ((callback as ICommunicationObject).State != CommunicationState.Opened)
|
||||
{
|
||||
// ...add it to the remove list and continue
|
||||
removeList.Add(callback);
|
||||
continue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// Make the callback
|
||||
callback.OnDeviceUpdate(device);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// The callback failed - add it to the remove list
|
||||
removeList.Add(callback);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Remove all callbacks in the remove list
|
||||
removeList.ForEach(o => subscribers.Remove(o));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user