diff --git a/SenseApi/SenseApi.csproj b/SenseApi/SenseApi.csproj
index 4832799..8b67d04 100644
--- a/SenseApi/SenseApi.csproj
+++ b/SenseApi/SenseApi.csproj
@@ -14,7 +14,7 @@
Wrapper for the Sense (Energy Monitor) API
0.1.0.0
0.1.0.0
- 0.1.0.1-dev0139
+ 0.1.0.1-dev0331
@@ -24,7 +24,6 @@
runtime; build; native; contentfiles; analyzers
-
diff --git a/SenseApi/SenseApiWrapper.cs b/SenseApi/SenseApiWrapper.cs
index 237afcb..c4a6b46 100644
--- a/SenseApi/SenseApiWrapper.cs
+++ b/SenseApi/SenseApiWrapper.cs
@@ -21,9 +21,11 @@ public class SenseApiWrapper
public MonitorStatus MonitorStatus { get; set; }
public List DeviceList { get; set; }
public static IConfigurationRoot Config { get; private set; }
+
private readonly string apiAddress;
+ private readonly JsonSerializerSettings serializerSettings;
- public SenseApiWrapper()
+ public SenseApiWrapper(JsonSerializerSettings serializerSettings = null)
{
Config = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
@@ -31,8 +33,19 @@ public SenseApiWrapper()
.Build();
apiAddress = Config["api-url"];
+
+ if (serializerSettings == null)
+ {
+ serializerSettings = new JsonSerializerSettings
+ {
+ NullValueHandling = NullValueHandling.Ignore,
+ MissingMemberHandling = MissingMemberHandling.Ignore
+ };
+ }
+
+ this.serializerSettings = serializerSettings;
}
-
+
///
/// Authenticate with the Sense API using your email and password
///
@@ -69,15 +82,14 @@ public async Task Authenticate(string email, string passw
var json = await response.Content.ReadAsStringAsync();
- AuthorizationResponse = JsonConvert.DeserializeObject(json);
+ AuthorizationResponse = JsonConvert.DeserializeObject(json, serializerSettings);
// Update AccessToken and Monitor ID in appsettings.json file
var appSettingsJson = File.ReadAllText("appsettings.json");
- dynamic jsonObj = JsonConvert.DeserializeObject(appSettingsJson);
+ dynamic jsonObj = JsonConvert.DeserializeObject(appSettingsJson, serializerSettings);
jsonObj["accesstoken"] = AuthorizationResponse.AccessToken;
jsonObj["monitor-ids"] = string.Join(",", AuthorizationResponse.Monitors.Select(x => x.Id));
- string output =
- JsonConvert.SerializeObject(jsonObj, Formatting.Indented);
+ string output = JsonConvert.SerializeObject(jsonObj, Formatting.Indented);
File.WriteAllText("appsettings.json", output);
Config.Reload();
@@ -94,22 +106,11 @@ public async Task Authenticate(string email, string passw
/// Monitor Status Object
public async Task GetMonitorStatus(int monitorId)
{
- using (var httpClient = new HttpClient())
- {
- httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", Config["accesstoken"]);
-
- var callData = $"{apiAddress}/app/monitors/{monitorId}/status";
-
- var response = await httpClient.GetAsync(callData);
-
- await CheckResponseStatus(response, httpClient, callData);
-
- var json = await response.Content.ReadAsStringAsync();
+ var callData = $"{apiAddress}/app/monitors/{monitorId}/status";
- MonitorStatus = JsonConvert.DeserializeObject(json);
+ MonitorStatus = await ApiCallAsync(callData);
- return MonitorStatus;
- }
+ return MonitorStatus;
}
///
@@ -119,22 +120,11 @@ public async Task GetMonitorStatus(int monitorId)
/// List of Devices with some details
public async Task> GetDeviceList(int monitorId)
{
- using (var httpClient = new HttpClient())
- {
- httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", Config["accesstoken"]);
-
- var callData = $"{apiAddress}/app/monitors/{monitorId}/devices";
-
- var response = await httpClient.GetAsync(callData);
-
- await CheckResponseStatus(response, httpClient, callData);
-
- var json = await response.Content.ReadAsStringAsync();
+ var callData = $"{apiAddress}/app/monitors/{monitorId}/devices";
- DeviceList = JsonConvert.DeserializeObject>(json);
+ DeviceList = await ApiCallAsync>(callData);
- return DeviceList;
- }
+ return DeviceList;
}
///
@@ -146,32 +136,13 @@ public async Task> GetDeviceList(int monitorId)
/// Device Details for the specified device.
public async Task GetDeviceDetails(int monitorId, string deviceId)
{
- using (var httpClient = new HttpClient())
- {
- httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", Config["accesstoken"]);
-
- var callData = $"{apiAddress}/app/monitors/{monitorId}/devices/{deviceId}";
+ var callData = $"{apiAddress}/app/monitors/{monitorId}/devices/{deviceId}";
- var response = await httpClient.GetAsync(callData);
-
- await CheckResponseStatus(response, httpClient, callData);
-
- var json = await response.Content.ReadAsStringAsync();
-
- var deviceDetails = JsonConvert.DeserializeObject(json);
-
- if (DeviceList == null || DeviceList.Count <= 0) return deviceDetails;
-
- var device = DeviceList.FirstOrDefault(x => x.Id == deviceId);
- if (device == null) return deviceDetails;
+ var deviceDetails = await ApiCallAsync(callData);
- var pos = DeviceList.FindIndex(x => x.Id == deviceId);
- DeviceList.RemoveAt(pos);
- device = deviceDetails.Device;
- DeviceList.Insert(pos, device);
+ UpdateDeviceList(deviceId, deviceDetails);
- return deviceDetails;
- }
+ return deviceDetails;
}
///
@@ -183,33 +154,13 @@ public async Task GetDeviceDetails(int monitorId, string deviceId
public async Task GetAlwaysOnDetails(int monitorId)
{
const string deviceId = "always_on";
+ var callData = $"{apiAddress}/app/monitors/{monitorId}/devices/{deviceId}";
- using (var httpClient = new HttpClient())
- {
- httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", Config["accesstoken"]);
-
- var callData = $"{apiAddress}/app/monitors/{monitorId}/devices/{deviceId}";
-
- var response = await httpClient.GetAsync(callData);
-
- await CheckResponseStatus(response, httpClient, callData);
-
- var json = await response.Content.ReadAsStringAsync();
-
- var deviceDetails = JsonConvert.DeserializeObject(json);
-
- if (DeviceList == null || DeviceList.Count <= 0) return deviceDetails;
-
- var device = DeviceList.FirstOrDefault(x => x.Id == deviceId);
- if (device == null) return deviceDetails;
+ var deviceDetails = await ApiCallAsync(callData);
- var pos = DeviceList.FindIndex(x => x.Id == deviceId);
- DeviceList.RemoveAt(pos);
- device = deviceDetails.Device;
- DeviceList.Insert(pos, device);
+ UpdateDeviceList(deviceId, deviceDetails);
- return deviceDetails;
- }
+ return deviceDetails;
}
///
@@ -221,33 +172,13 @@ public async Task GetAlwaysOnDetails(int monitorId)
public async Task GetOtherDetails(int monitorId)
{
const string deviceId = "unknown";
+ var callData = $"{apiAddress}/app/monitors/{monitorId}/devices/{deviceId}";
- using (var httpClient = new HttpClient())
- {
- httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", Config["accesstoken"]);
-
- var callData = $"{apiAddress}/app/monitors/{monitorId}/devices/{deviceId}";
-
- var response = await httpClient.GetAsync(callData);
-
- await CheckResponseStatus(response, httpClient, callData);
-
- var json = await response.Content.ReadAsStringAsync();
-
- var deviceDetails = JsonConvert.DeserializeObject(json);
+ var deviceDetails = await ApiCallAsync(callData);
- if (DeviceList == null || DeviceList.Count <= 0) return deviceDetails;
+ UpdateDeviceList(deviceId, deviceDetails);
- var device = DeviceList.FirstOrDefault(x => x.Id == deviceId);
- if (device == null) return deviceDetails;
-
- var pos = DeviceList.FindIndex(x => x.Id == deviceId);
- DeviceList.RemoveAt(pos);
- device = deviceDetails.Device;
- DeviceList.Insert(pos, device);
-
- return deviceDetails;
- }
+ return deviceDetails;
}
///
@@ -260,22 +191,11 @@ public async Task GetOtherDetails(int monitorId)
/// HistoryRecord object with a list sampling values for the monitor in the chosen granularity interval
public async Task GetMonitorHistory(int monitorId, Granularity granularity, DateTime startDateTime, int sampleCount)
{
- using (var httpClient = new HttpClient())
- {
- httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", Config["accesstoken"]);
-
- var callData = $"{apiAddress}/app/history/usage?monitor_id={monitorId}&granularity={granularity.ToString().ToLowerInvariant()}&start={startDateTime.ToUniversalTime().ToString("yyyy-MM-ddThh:mm:ssZ",CultureInfo.InvariantCulture)}&frames={sampleCount}";
-
- var response = await httpClient.GetAsync(callData);
-
- await CheckResponseStatus(response, httpClient, callData);
+ var callData = $"{apiAddress}/app/history/usage?monitor_id={monitorId}&granularity={granularity.ToString().ToLowerInvariant()}&start={startDateTime.ToUniversalTime().ToString("yyyy-MM-ddThh:mm:ssZ", CultureInfo.InvariantCulture)}&frames={sampleCount}";
- var json = await response.Content.ReadAsStringAsync();
-
- var history = JsonConvert.DeserializeObject(json);
+ var history = await ApiCallAsync(callData);
- return history;
- }
+ return history;
}
///
@@ -289,29 +209,17 @@ public async Task GetMonitorHistory(int monitorId, Granularity gr
/// HistoryRecord object with a list sampling values for the monitor in the chosen granularity interval
public async Task GetDeviceHistory(int monitorId, string deviceId, Granularity granularity, DateTime startDateTime, int sampleCount)
{
- if (granularity != Granularity.Second && granularity != Granularity.Minute && granularity != Granularity.Hour &&
- granularity != Granularity.Day)
+ if (granularity != Granularity.Second && granularity != Granularity.Minute &&
+ granularity != Granularity.Hour && granularity != Granularity.Day)
{
throw new InvalidEnumArgumentException($"{granularity.ToString()} is not a valid granularity for this call.");
}
- using (var httpClient = new HttpClient())
- {
- httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", Config["accesstoken"]);
-
- var callData =
- $"{apiAddress}/app/history/usage?monitor_id={monitorId}&device_id={deviceId}&granularity={granularity.ToString().ToLowerInvariant()}&start={startDateTime.ToUniversalTime().ToString("yyyy-MM-ddThh:mm:ssZ", CultureInfo.InvariantCulture)}&frames={sampleCount}";
-
- var response = await httpClient.GetAsync(callData);
-
- await CheckResponseStatus(response, httpClient, callData);
-
- var json = await response.Content.ReadAsStringAsync();
+ var callData = $"{apiAddress}/app/history/usage?monitor_id={monitorId}&device_id={deviceId}&granularity={granularity.ToString().ToLowerInvariant()}&start={startDateTime.ToUniversalTime().ToString("yyyy-MM-ddThh:mm:ssZ", CultureInfo.InvariantCulture)}&frames={sampleCount}";
- var history = JsonConvert.DeserializeObject(json);
+ var history = await ApiCallAsync(callData);
- return history;
- }
+ return history;
}
///
@@ -323,28 +231,17 @@ public async Task GetDeviceHistory(int monitorId, string deviceId
/// TrendData object
public async Task GetUsageTrendData(int monitorId, Granularity granularity, DateTime startDateTime)
{
- if (granularity != Granularity.Hour && granularity != Granularity.Day && granularity != Granularity.Month &&
- granularity != Granularity.Year)
+ if (granularity != Granularity.Hour && granularity != Granularity.Day &&
+ granularity != Granularity.Month && granularity != Granularity.Year)
{
throw new InvalidEnumArgumentException($"{granularity.ToString()} is not a valid granularity for this call.");
}
-
- using (var httpClient = new HttpClient())
- {
- httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", Config["accesstoken"]);
-
- var callData = $"{apiAddress}/app/history/trends?monitor_id={monitorId}&device_id=usage&scale={granularity.ToString().ToLowerInvariant()}&start={startDateTime.ToUniversalTime().ToString("yyyy-MM-ddThh:mm:ssZ", CultureInfo.InvariantCulture)}";
-
- var response = await httpClient.GetAsync(callData);
- await CheckResponseStatus(response, httpClient, callData);
-
- var json = await response.Content.ReadAsStringAsync();
+ var callData = $"{apiAddress}/app/history/trends?monitor_id={monitorId}&device_id=usage&scale={granularity.ToString().ToLowerInvariant()}&start={startDateTime.ToUniversalTime().ToString("yyyy-MM-ddThh:mm:ssZ", CultureInfo.InvariantCulture)}";
- var trendData = JsonConvert.DeserializeObject(json);
+ var trendData = await ApiCallAsync(callData);
- return trendData;
- }
+ return trendData;
}
///
@@ -353,26 +250,60 @@ public async Task GetUsageTrendData(int monitorId, Granularity granul
/// User ID to get the timeline data for
/// TimelineData object with the serialized json data
public async Task GetTimelineData(int userId)
+ {
+ var callData = $"{apiAddress}/users/{userId}/timeline";
+
+ var timelineData = await ApiCallAsync(callData);
+
+ return timelineData;
+ }
+
+ #region Private methods
+
+ ///
+ /// If a DeviceList is present this list is also updated with the additional details.
+ ///
+ /// Device ID of the device
+ /// Device Details for the specified device.
+ private void UpdateDeviceList(string deviceId, DeviceDetails deviceDetails)
+ {
+ if (DeviceList != null && DeviceList.Count > 0)
+ {
+ var device = DeviceList.FirstOrDefault(x => x.Id == deviceId);
+ if (device != null)
+ {
+ var pos = DeviceList.FindIndex(x => x.Id == deviceId);
+ DeviceList.RemoveAt(pos);
+ device = deviceDetails.Device;
+ DeviceList.Insert(pos, device);
+ }
+ }
+ }
+
+ ///
+ /// Perform a call to the Sense API
+ ///
+ /// The type of object that is returned
+ /// The detailed call data of the API
+ /// An instance of TR from the API call.
+ private async Task ApiCallAsync
(string callData)
{
using (var httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", Config["accesstoken"]);
- var callData = $"{apiAddress}/users/{userId}/timeline";
-
var response = await httpClient.GetAsync(callData);
await CheckResponseStatus(response, httpClient, callData);
var json = await response.Content.ReadAsStringAsync();
- var trendData = JsonConvert.DeserializeObject(json);
+ var result = JsonConvert.DeserializeObject(json, serializerSettings);
- return trendData;
+ return result;
}
- }
- #region Private methods
+ }
///
/// Check the response status of the Http Call and if we get an Unauthorized response try