From a398b39e12ff049375a8e2377558ebb1d24db34e Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Thu, 1 Aug 2019 12:32:48 -0700 Subject: [PATCH] Expose comfort presets as HA presets (#25491) * Expose comfort presets as HA presets * Fix bugs * Handle unavailable * log level debug on update * Lint --- homeassistant/components/ecobee/__init__.py | 2 +- homeassistant/components/ecobee/climate.py | 65 +++++++++------------ tests/components/ecobee/test_climate.py | 14 ----- 3 files changed, 29 insertions(+), 52 deletions(-) diff --git a/homeassistant/components/ecobee/__init__.py b/homeassistant/components/ecobee/__init__.py index e69884af59f..cb8b7436b51 100644 --- a/homeassistant/components/ecobee/__init__.py +++ b/homeassistant/components/ecobee/__init__.py @@ -97,7 +97,7 @@ class EcobeeData: def update(self): """Get the latest data from pyecobee.""" self.ecobee.update() - _LOGGER.info("Ecobee data updated successfully") + _LOGGER.debug("Ecobee data updated successfully") def setup(hass, config): diff --git a/homeassistant/components/ecobee/climate.py b/homeassistant/components/ecobee/climate.py index 6520a3aadba..d9af0f93e11 100644 --- a/homeassistant/components/ecobee/climate.py +++ b/homeassistant/components/ecobee/climate.py @@ -88,16 +88,6 @@ PRESET_TO_ECOBEE_HOLD = { PRESET_HOLD_INDEFINITE: "indefinite", } -PRESET_MODES = [ - PRESET_NONE, - PRESET_AWAY, - PRESET_TEMPERATURE, - PRESET_HOME, - PRESET_SLEEP, - PRESET_HOLD_NEXT_TRANSITION, - PRESET_HOLD_INDEFINITE, -] - SERVICE_SET_FAN_MIN_ON_TIME = "ecobee_set_fan_min_on_time" SERVICE_RESUME_PROGRAM = "ecobee_resume_program" @@ -199,7 +189,6 @@ class Thermostat(ClimateDevice): self._name = self.thermostat["name"] self.hold_temp = hold_temp self.vacation = None - self._climate_list = self.climate_list self._operation_list = [] if self.thermostat["settings"]["heatStages"]: @@ -210,6 +199,10 @@ class Thermostat(ClimateDevice): self._operation_list.insert(0, HVAC_MODE_AUTO) self._operation_list.append(HVAC_MODE_OFF) + self._preset_modes = { + comfort["climateRef"]: comfort["name"] + for comfort in self.thermostat["program"]["climates"] + } self._fan_modes = [FAN_AUTO, FAN_ON] self.update_without_throttle = False @@ -223,6 +216,11 @@ class Thermostat(ClimateDevice): self.thermostat = self.data.ecobee.get_thermostat(self.thermostat_index) + @property + def available(self): + """Return if device is available.""" + return self.thermostat["runtime"]["connected"] + @property def supported_features(self): """Return the list of supported features.""" @@ -294,15 +292,9 @@ class Thermostat(ClimateDevice): continue if event["type"] == "hold": - if event["holdClimateRef"] == "away": - if int(event["endDate"][0:4]) - int(event["startDate"][0:4]) <= 1: - # A temporary hold from away climate is a hold - return PRESET_AWAY - # A permanent hold from away climate - return PRESET_AWAY - if event["holdClimateRef"] != "": - # Any other hold based on climate - return event["holdClimateRef"] + if event["holdClimateRef"] in self._preset_modes: + return self._preset_modes[event["holdClimateRef"]] + # Any hold not based on a climate is a temp hold return PRESET_TEMPERATURE if event["type"].startswith("auto"): @@ -324,14 +316,6 @@ class Thermostat(ClimateDevice): """Return the operation modes list.""" return self._operation_list - @property - def climate_mode(self): - """Return current mode, as the user-visible name.""" - cur = self.thermostat["program"]["currentClimateRef"] - climates = self.thermostat["program"]["climates"] - current = list(filter(lambda x: x["climateRef"] == cur, climates)) - return current[0]["name"] - @property def current_humidity(self) -> Optional[int]: """Return the current humidity.""" @@ -373,9 +357,7 @@ class Thermostat(ClimateDevice): status = self.thermostat["equipmentStatus"] return { "fan": self.fan, - "climate_mode": self.climate_mode, "equipment_running": status, - "climate_list": self.climate_list, "fan_min_on_time": self.thermostat["settings"]["fanMinOnTime"], } @@ -413,6 +395,21 @@ class Thermostat(ClimateDevice): elif preset_mode == PRESET_NONE: self.data.ecobee.resume_program(self.thermostat_index) + elif preset_mode in self.preset_modes: + climate_ref = None + + for comfort in self.thermostat["program"]["climates"]: + if comfort["name"] == preset_mode: + climate_ref = comfort["climateRef"] + break + + if climate_ref is not None: + self.data.ecobee.set_climate_hold( + self.thermostat_index, climate_ref, self.hold_preference() + ) + else: + _LOGGER.warning("Received unknown preset mode: %s", preset_mode) + else: self.data.ecobee.set_climate_hold( self.thermostat_index, preset_mode, self.hold_preference() @@ -421,7 +418,7 @@ class Thermostat(ClimateDevice): @property def preset_modes(self): """Return available preset modes.""" - return PRESET_MODES + return list(self._preset_modes.values()) def set_auto_temp_hold(self, heat_temp, cool_temp): """Set temperature hold in auto mode.""" @@ -543,9 +540,3 @@ class Thermostat(ClimateDevice): # supported; note that this should not include 'indefinite' # as an indefinite away hold is interpreted as away_mode return "nextTransition" - - @property - def climate_list(self): - """Return the list of climates currently available.""" - climates = self.thermostat["program"]["climates"] - return list(map((lambda x: x["name"]), climates)) diff --git a/tests/components/ecobee/test_climate.py b/tests/components/ecobee/test_climate.py index fa3f84b4b12..24938e52621 100644 --- a/tests/components/ecobee/test_climate.py +++ b/tests/components/ecobee/test_climate.py @@ -130,44 +130,34 @@ class TestEcobee(unittest.TestCase): """Test device state attributes property.""" self.ecobee["equipmentStatus"] = "heatPump2" assert { - "climate_list": ["Climate1", "Climate2"], "fan": "off", "fan_min_on_time": 10, - "climate_mode": "Climate1", "equipment_running": "heatPump2", } == self.thermostat.device_state_attributes self.ecobee["equipmentStatus"] = "auxHeat2" assert { - "climate_list": ["Climate1", "Climate2"], "fan": "off", "fan_min_on_time": 10, - "climate_mode": "Climate1", "equipment_running": "auxHeat2", } == self.thermostat.device_state_attributes self.ecobee["equipmentStatus"] = "compCool1" assert { - "climate_list": ["Climate1", "Climate2"], "fan": "off", "fan_min_on_time": 10, - "climate_mode": "Climate1", "equipment_running": "compCool1", } == self.thermostat.device_state_attributes self.ecobee["equipmentStatus"] = "" assert { - "climate_list": ["Climate1", "Climate2"], "fan": "off", "fan_min_on_time": 10, - "climate_mode": "Climate1", "equipment_running": "", } == self.thermostat.device_state_attributes self.ecobee["equipmentStatus"] = "Unknown" assert { - "climate_list": ["Climate1", "Climate2"], "fan": "off", "fan_min_on_time": 10, - "climate_mode": "Climate1", "equipment_running": "Unknown", } == self.thermostat.device_state_attributes @@ -267,10 +257,6 @@ class TestEcobee(unittest.TestCase): self.ecobee["settings"]["holdAction"] = action assert "nextTransition" == self.thermostat.hold_preference() - def test_climate_list(self): - """Test climate list property.""" - assert ["Climate1", "Climate2"] == self.thermostat.climate_list - def test_set_fan_mode_on(self): """Test set fan mode to on.""" self.data.reset_mock()