public static object GetHistoricData(HistoricRate rate, string deviceId, string connString) { var temperatures = new List <PlotDataPoint>(); var thermocoupleStatuses = new List <PlotDataPoint>(); MySqlConnection conn = null; int minsFrom = 5; switch (rate) { case HistoricRate.Back5Minutes: minsFrom = 5; break; case HistoricRate.Back30Minutes: minsFrom = 30; break; case HistoricRate.Back2Hours: minsFrom = 120; break; case HistoricRate.Back1Day: minsFrom = 1440; break; case HistoricRate.Back1Week: minsFrom = 10080; break; } conn = OpenConnection(connString); var query = $"CALL GetDataSamples({minsFrom}, '{deviceId}');"; MySqlCommand cmd = new MySqlCommand(query, conn); var reader = cmd.ExecuteReader(); while (reader.Read()) { var item = new ThermostatRequest { DeviceStatus = (string)reader[2], Measurement = Convert.ToSingle(reader[3]), Timestamp = (DateTime)reader[5] }; temperatures.Add(new PlotDataPoint(item.Measurement, item.Timestamp.ToUniversalTime())); thermocoupleStatuses.Add(new PlotDataPoint(item.DeviceStatus == "ON" ? 1 : 0, item.Timestamp.ToUniversalTime())); } reader.Close(); if (conn != null && conn.State == ConnectionState.Open) { conn.Close(); } return(new { Temperatures = temperatures, Statuses = thermocoupleStatuses }); }
public static ThermostatRequest[] GetLatestEntries(string connString) { var items = new List <ThermostatRequest>(); MySqlConnection conn = null; conn = OpenConnection(connString); var query = "SELECT * FROM Temperature ORDER BY id DESC LIMIT 10"; MySqlCommand cmd = new MySqlCommand(query, conn); var reader = cmd.ExecuteReader(); while (reader.Read()) { var item = new ThermostatRequest { Id = (int)reader[0], DeviceId = (string)reader[1], DeviceStatus = (string)reader[2], Measurement = Convert.ToSingle(reader[3]), Unit = (string)reader[4], Timestamp = (DateTime)reader[5] }; items.Add(item); } reader.Close(); if (conn != null && conn.State == ConnectionState.Open) { conn.Close(); } return(items.ToArray()); }
public static void InsertDataRequest(ThermostatRequest item, string connString) { MySqlConnection conn = null; conn = OpenConnection(connString); var query = "INSERT INTO Temperature (device_id, device_status, measurement, unit, timestamp) VALUES " + "(@DeviceId, @DeviceStatus, @Measurement, @Unit, @Timestamp)"; MySqlCommand cmd = new MySqlCommand(query, conn); cmd.Parameters.AddWithValue("@DeviceId", item.DeviceId); cmd.Parameters.AddWithValue("@DeviceStatus", item.DeviceStatus); cmd.Parameters.AddWithValue("@Measurement", item.Measurement); cmd.Parameters.AddWithValue("@Unit", item.Unit); cmd.Parameters.AddWithValue("@Timestamp", item.Timestamp); cmd.ExecuteNonQuery(); if (conn != null && conn.State == ConnectionState.Open) { conn.Close(); } }
public int Post([FromBody] ThermostatRequestViewModel request) { var item = new ThermostatRequest { DeviceId = request.DeviceId, DeviceStatus = request.DeviceStatus, Measurement = request.Measurement, Unit = request.Unit, Timestamp = DateTime.Now }; try { DbService.InsertDataRequest(item, _connString); var activateIt = Rules.DecideActivation(_connString, item, float.Parse(_defaultTempLevel)); return(activateIt ? 1 : 0); } catch (Exception e) { _logger.LogError("InsertLoginRequest(item) THROWS AN ERROR", e); throw; } }
/// <summary> /// Handles updating status for a thermostat and publishing changes. /// </summary> /// <param name="revisionStatus">Revision status that triggered the update.</param> /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns> private async Task RefreshThermostatAsync(RevisionStatus revisionStatus) { // Build single thermostat request var thermostatRequest = new ThermostatRequest { Selection = new Selection { SelectionType = "thermostats", SelectionMatch = revisionStatus.ThermostatIdentifier, IncludeEquipmentStatus = true, IncludeEvents = true, IncludeRuntime = true, IncludeSensors = true, IncludeSettings = true, IncludeWeather = true } }; var thermostatUpdate = await _client.GetAsync <ThermostatRequest, ThermostatResponse>(thermostatRequest) .ConfigureAwait(false); // Publish updates and cache new values await UpdateState(thermostatUpdate?.ThermostatList?.FirstOrDefault()); }
public static bool DecideActivation(string connString, ThermostatRequest request, float defaultLevel) { var config = DbService.GetDeviceConfig(connString, request.DeviceId); float tempTarget = defaultLevel; // 1. If no levels, then use default if (config.SpecialDayPoints.Count > 0 || config.WeekendPoints.Count > 0 || config.DailyPoints.Count > 0) { DateTime now = DateTime.Now; bool hasSelectedPoint = false; var hasSaturdays = config.WeekendPoints.Any(x => x.IsSaturday); var hasSundays = config.WeekendPoints.Any(x => x.IsSunday); if (config.SpecialDayPoints.Count > 0) { hasSelectedPoint = ScanSpecialDayPoints(config, ref tempTarget); if (!hasSelectedPoint) { if (config.WeekendPoints.Count > 0) { if (now.DayOfWeek == DayOfWeek.Saturday && hasSaturdays) { hasSelectedPoint = ScanWeekendPoints(config, ref tempTarget); } else if (now.DayOfWeek == DayOfWeek.Sunday && hasSundays) { hasSelectedPoint = ScanWeekendPoints(config, ref tempTarget); } } } if (!hasSelectedPoint) { hasSelectedPoint = ScanDailyPoints(config, ref tempTarget); } } else if (config.WeekendPoints.Count > 0) { if (now.DayOfWeek == DayOfWeek.Saturday && hasSaturdays) { hasSelectedPoint = ScanWeekendPoints(config, ref tempTarget); } else if (now.DayOfWeek == DayOfWeek.Sunday && hasSundays) { hasSelectedPoint = ScanWeekendPoints(config, ref tempTarget); } if (!hasSelectedPoint) { hasSelectedPoint = ScanDailyPoints(config, ref tempTarget); } } else { hasSelectedPoint = ScanDailyPoints(config, ref tempTarget); } if (!hasSelectedPoint) { tempTarget = defaultLevel; } } return(tempTarget > request.Measurement); }
/// <summary> /// Handles updating status for a thermostat and publishing changes. /// </summary> /// <param name="revisionStatus">Revision status that triggered the update.</param> private async void RefreshThermostatAsync(RevisionStatus revisionStatus) { // Build single thermostat request var thermostatRequest = new ThermostatRequest { Selection = new Selection { SelectionType = "thermostats", SelectionMatch = revisionStatus.ThermostatIdentifier, IncludeEquipmentStatus = true, IncludeDevice = true, IncludeLocation = true, IncludeSettings = true, IncludeRuntime = true, IncludeSensors = true, IncludeWeather = true } }; var thermostatUpdate = await _client.GetAsync <ThermostatRequest, ThermostatResponse>(thermostatRequest) .ConfigureAwait(false); // Publish updates and cache new values var thermostat = thermostatUpdate.ThermostatList.FirstOrDefault(); if (thermostat != null) { var thermostatStatus = new ThermostatStatus(); // Equipment status foreach (var device in thermostat.EquipmentStatus.Split(',').Where(x => !string.IsNullOrEmpty(x))) { thermostatStatus.EquipmentStatus[device] = "on"; } // ID thermostatStatus.Status["name"] = thermostat.Name; thermostatStatus.Status["city"] = thermostat.Location.City; // Status thermostatStatus.Status["hvacMode"] = thermostat.Settings.HvacMode; thermostatStatus.Status["humidifierMode"] = thermostat.Settings.HumidifierMode; thermostatStatus.Status["dehumidifierMode"] = thermostat.Settings.DehumidifierMode; thermostatStatus.Status["autoAway"] = thermostat.Settings.AutoAway ? "true" : "false"; thermostatStatus.Status["vent"] = thermostat.Settings.Vent; thermostatStatus.Status["actualTemperature"] = (thermostat.Runtime.ActualTemperature / 10m).ToString(); thermostatStatus.Status["actualHumidity"] = thermostat.Runtime.ActualHumidity.ToString(); thermostatStatus.Status["desiredHeat"] = (thermostat.Runtime.DesiredHeat / 10m).ToString(); thermostatStatus.Status["desiredCool"] = (thermostat.Runtime.DesiredCool / 10m).ToString(); thermostatStatus.Status["desiredHumidity"] = thermostat.Runtime.DesiredHumidity.ToString(); thermostatStatus.Status["desiredDehumidity"] = thermostat.Runtime.DesiredDehumidity.ToString(); thermostatStatus.Status["desiredFanMode"] = thermostat.Runtime.DesiredFanMode; // Weather forcasts var forecast = thermostat.Weather.Forecasts?.FirstOrDefault(); if (forecast != null) { thermostatStatus.Status["weatherDewPoint"] = (forecast.Dewpoint / 10m).ToString(); thermostatStatus.Status["weatherPrecipitationChance"] = forecast.Pop.ToString(); thermostatStatus.Status["weatherPressure"] = (forecast.Pressure / 100m).ToString(); thermostatStatus.Status["weatherRelativeHumidity"] = forecast.RelativeHumidity.ToString(); thermostatStatus.Status["weatherTemperature"] = (forecast.Temperature / 10m).ToString(); thermostatStatus.Status["weatherTempLow"] = (forecast.TempLow / 10m).ToString(); thermostatStatus.Status["weatherTempHigh"] = (forecast.TempHigh / 10m).ToString(); thermostatStatus.Status["weatherVisibility"] = forecast.Visibility.ToString(); thermostatStatus.Status["weatherWindBearing"] = forecast.WindBearing.ToString(); thermostatStatus.Status["weatherWindDirection"] = forecast.WindDirection.ToString(); thermostatStatus.Status["weatherWindGust"] = forecast.WindGust.ToString(); thermostatStatus.Status["weatherWindSpeed"] = forecast.WindSpeed.ToString(); } // Sensors if (thermostat.RemoteSensors != null && thermostat.RemoteSensors.Count > 0) { foreach (var sensor in thermostat.RemoteSensors) { thermostatStatus.Sensors[sensor.Name] = sensor.Capability.ToDictionary( s => s.Type, s => { // Convert temperature values to human readable if (string.Equals(s.Type, "temperature", System.StringComparison.OrdinalIgnoreCase)) { if (decimal.TryParse(s.Value, out var decimalValue)) { return((decimalValue / 10m).ToString()); } } return(s.Value); }); } } if (_thermostatStatus.ContainsKey(revisionStatus.ThermostatIdentifier)) { // Publish updates foreach (var device in thermostatStatus.EquipmentStatus) { if (device.Value != _thermostatStatus[revisionStatus.ThermostatIdentifier].EquipmentStatus[device.Key]) { await MqttClient.PublishAsync(new MqttApplicationMessageBuilder() .WithTopic($"{TopicRoot}/{revisionStatus.ThermostatIdentifier}/{device.Key}") .WithPayload(device.Value.ToString()) .WithAtLeastOnceQoS() .WithRetainFlag() .Build()) .ConfigureAwait(false); } } foreach (var status in thermostatStatus.Status) { if (status.Value != _thermostatStatus[revisionStatus.ThermostatIdentifier].Status[status.Key]) { await MqttClient.PublishAsync(new MqttApplicationMessageBuilder() .WithTopic($"{TopicRoot}/{revisionStatus.ThermostatIdentifier}/{status.Key}") .WithPayload(status.Value) .WithAtLeastOnceQoS() .WithRetainFlag() .Build()) .ConfigureAwait(false); } } // Publish everything for new sensors, new capabilities, and changes in existing ability values foreach (var sensor in thermostatStatus.Sensors) { foreach (var sensorCapability in sensor.Value) { if (!_thermostatStatus[revisionStatus.ThermostatIdentifier].Sensors.ContainsKey(sensor.Key)) { await MqttClient.PublishAsync(new MqttApplicationMessageBuilder() .WithTopic($"{TopicRoot}/{revisionStatus.ThermostatIdentifier}/sensor/{sensor.Key.Sluggify()}/{sensorCapability.Key}") .WithPayload(sensorCapability.Value) .WithAtLeastOnceQoS() .WithRetainFlag() .Build()) .ConfigureAwait(false); } else if (!_thermostatStatus[revisionStatus.ThermostatIdentifier].Sensors[sensor.Key].ContainsKey(sensorCapability.Key)) { await MqttClient.PublishAsync(new MqttApplicationMessageBuilder() .WithTopic($"{TopicRoot}/{revisionStatus.ThermostatIdentifier}/sensor/{sensor.Key.Sluggify()}/{sensorCapability.Key}") .WithPayload(sensorCapability.Value) .WithAtLeastOnceQoS() .WithRetainFlag() .Build()) .ConfigureAwait(false); } else if (sensorCapability.Value != _thermostatStatus[revisionStatus.ThermostatIdentifier].Sensors[sensor.Key][sensorCapability.Key]) { await MqttClient.PublishAsync(new MqttApplicationMessageBuilder() .WithTopic($"{TopicRoot}/{revisionStatus.ThermostatIdentifier}/sensor/{sensor.Key.Sluggify()}/{sensorCapability.Key}") .WithPayload(sensorCapability.Value) .WithAtLeastOnceQoS() .WithRetainFlag() .Build()) .ConfigureAwait(false); } } } } else { // Publish initial state foreach (var device in thermostatStatus.EquipmentStatus) { await MqttClient.PublishAsync(new MqttApplicationMessageBuilder() .WithTopic($"{TopicRoot}/{revisionStatus.ThermostatIdentifier}/{device.Key}") .WithPayload(device.Value.ToString()) .WithAtLeastOnceQoS() .WithRetainFlag() .Build()) .ConfigureAwait(false); } foreach (var status in thermostatStatus.Status) { await MqttClient.PublishAsync(new MqttApplicationMessageBuilder() .WithTopic($"{TopicRoot}/{revisionStatus.ThermostatIdentifier}/{status.Key}") .WithPayload(status.Value) .WithAtLeastOnceQoS() .WithRetainFlag() .Build()) .ConfigureAwait(false); } foreach (var sensor in thermostatStatus.Sensors) { foreach (var sensorCapability in sensor.Value) { await MqttClient.PublishAsync(new MqttApplicationMessageBuilder() .WithTopic($"{TopicRoot}/{revisionStatus.ThermostatIdentifier}/sensor/{sensor.Key.Sluggify()}/{sensorCapability.Key}") .WithPayload(sensorCapability.Value) .WithAtLeastOnceQoS() .WithRetainFlag() .Build()) .ConfigureAwait(false); } } } _thermostatStatus[revisionStatus.ThermostatIdentifier] = thermostatStatus; } }