From 011d1cd1efaf5e67beaedc74229d7ba3bdd5603e Mon Sep 17 00:00:00 2001 From: admin Date: Fri, 14 Dec 2018 16:18:17 -0800 Subject: [PATCH] Consolidate plumbing code into a single method to reduce code duplication. Remove unnecessary dependency. --- SenseApi/SenseApi.csproj | 3 +- SenseApi/SenseApiWrapper.cs | 247 +++++++++++++----------------------- 2 files changed, 90 insertions(+), 160 deletions(-) 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