public static async Task TemperatureCopAsync( [TimerTrigger("0 */10 * * * 1-5")] TimerInfo myTimer, [Table("ThermostatData", Connection = "StorageConnectionAppSetting")] CloudTable temperatureTable, [Table("ReportsTable", Connection = "StorageConnectionAppSetting")] CloudTable reportsTable, [Blob(ContainerName + "/" + TokenFileName, FileAccess.Read, Connection = "StorageConnectionAppSetting")] Stream inputBlob, TraceWriter log, ExecutionContext context) { log.Info($"Temperature Cop Timer trigger function executed at: {DateTime.Now}"); IConfigurationRoot configurationRoot = ReadConfiguration(context); int temperatureCheckRangeMinutes = int.Parse(configurationRoot["RunCheckRangeMinutes"]); int temperatureReportingRangeMinutes = int.Parse(configurationRoot["RunReportingRangeMinutes"]); double targetTemp = double.Parse(configurationRoot["TargetValue"]); double comfortRange = double.Parse(configurationRoot["ComfortRange"]); double comfortMaxTemp = targetTemp + comfortRange; double comfortMinTemp = targetTemp - comfortRange; var dateFrom = DateTime.UtcNow.AddMinutes(-temperatureCheckRangeMinutes).ToString(DateTimeFormat); foreach (var device in configurationRoot["Nest.Devices"].Split(',')) { // Get the latests lectures var query = new TableQuery <ThermostatData>() .Where( TableQuery.CombineFilters( TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, device), TableOperators.And, TableQuery.GenerateFilterCondition("RowKey", QueryComparisons.GreaterThan, dateFrom))); var result = await temperatureTable.ExecuteQueryAsync <ThermostatData>(query); if (result != null && result.Any()) { // If all readings are below/above comfort temperature var tooHot = result.All(x => x.AmbientTemperatureC > comfortMaxTemp); var tooCold = result.All(x => x.AmbientTemperatureC < comfortMinTemp); if (tooHot || tooCold) { var currentTemp = result.OrderBy(x => x.RowKey).Last().AmbientTemperatureC; var message = new TemperatureNotification() { DeviceId = device, NotificationType = tooHot ? TemperatureNotificationType.Hot : TemperatureNotificationType.Cold, ComfortTemperatureMax = comfortMaxTemp, ComfortTemperatureMin = comfortMinTemp, CurrentTemperature = currentTemp, EvaluationPeriodMinutes = temperatureReportingRangeMinutes, RowKey = DateTime.UtcNow.ToString(DateTimeFormat), PartitionKey = device }; // Check if a report has recently sent in the last minutes var notificationType = Enum.GetName(typeof(TemperatureNotificationType), message.NotificationType); log.Info($"Temperature out of range detected for device {message.DeviceId}, Notification Type {notificationType}."); var reportDateFrom = DateTime.UtcNow.AddMinutes(-temperatureReportingRangeMinutes).ToString(DateTimeFormat); var latestReportsQuery = new TableQuery <TemperatureNotification>() .Where( TableQuery.CombineFilters( TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, device), TableOperators.And, TableQuery.GenerateFilterCondition("RowKey", QueryComparisons.GreaterThan, dateFrom))); var latestReports = await reportsTable.ExecuteQueryAsync <TemperatureNotification>(latestReportsQuery); if (!latestReports.Any(x => x.NotificationType == message.NotificationType)) { await ReportTemperatureIssue(configurationRoot, message, log); await reportsTable.ExecuteAsync(TableOperation.Insert(message)); } else { log.Info($"Temperature {notificationType} has been already reported in the last {temperatureReportingRangeMinutes} minutes."); } } } } }
private static async Task ReportTemperatureIssue(IConfigurationRoot configurationRoot, TemperatureNotification notification, TraceWriter log) { var notificationType = Enum.GetName(typeof(TemperatureNotificationType), notification.NotificationType); log.Info($"Generating Temperature Notification for device {notification.DeviceId}, Notification Type {notificationType}."); var messageTemplate = configurationRoot[$"ReportTemperatureMessage.{notificationType}"]; var message = string.Format(messageTemplate, notification.DeviceId, notification.CurrentTemperature, notification.EvaluationPeriodMinutes, notification.ComfortTemperatureMin, notification.ComfortTemperatureMax); var notificationUrl = configurationRoot["SlackNotificationUrl"]; var client = new HttpClient(); var request = new HttpRequestMessage(HttpMethod.Post, notificationUrl); request.Content = new StringContent(JsonConvert.SerializeObject(new { text = message })); await client.SendAsync(request); }