diff --git a/homeassistant/components/ecobee/climate.py b/homeassistant/components/ecobee/climate.py index b8c73e61447..e8c19f5cd69 100644 --- a/homeassistant/components/ecobee/climate.py +++ b/homeassistant/components/ecobee/climate.py @@ -11,8 +11,9 @@ from homeassistant.components.climate.const import ( DOMAIN, HVAC_MODE_COOL, HVAC_MODE_HEAT, HVAC_MODE_AUTO, HVAC_MODE_OFF, ATTR_TARGET_TEMP_LOW, ATTR_TARGET_TEMP_HIGH, SUPPORT_TARGET_TEMPERATURE, SUPPORT_AUX_HEAT, SUPPORT_TARGET_TEMPERATURE_RANGE, SUPPORT_FAN_MODE, - PRESET_AWAY, FAN_AUTO, FAN_ON, CURRENT_HVAC_OFF, CURRENT_HVAC_HEAT, - CURRENT_HVAC_COOL, SUPPORT_PRESET_MODE, PRESET_NONE + PRESET_AWAY, FAN_AUTO, FAN_ON, CURRENT_HVAC_IDLE, CURRENT_HVAC_HEAT, + CURRENT_HVAC_COOL, SUPPORT_PRESET_MODE, PRESET_NONE, CURRENT_HVAC_FAN, + CURRENT_HVAC_DRY, ) from homeassistant.const import ( ATTR_ENTITY_ID, STATE_ON, ATTR_TEMPERATURE, TEMP_FAHRENHEIT) @@ -27,7 +28,6 @@ ATTR_RESUME_ALL = 'resume_all' DEFAULT_RESUME_ALL = False PRESET_TEMPERATURE = 'temp' PRESET_VACATION = 'vacation' -PRESET_AUX_HEAT_ONLY = 'aux_heat_only' PRESET_HOLD_NEXT_TRANSITION = 'next_transition' PRESET_HOLD_INDEFINITE = 'indefinite' AWAY_MODE = 'awayMode' @@ -43,6 +43,25 @@ ECOBEE_HVAC_TO_HASS = collections.OrderedDict([ ('auxHeatOnly', HVAC_MODE_HEAT), ]) +ECOBEE_HVAC_ACTION_TO_HASS = { + # Map to None if we do not know how to represent. + "heatPump": CURRENT_HVAC_HEAT, + "heatPump2": CURRENT_HVAC_HEAT, + "heatPump3": CURRENT_HVAC_HEAT, + "compCool1": CURRENT_HVAC_COOL, + "compCool2": CURRENT_HVAC_COOL, + "auxHeat1": CURRENT_HVAC_HEAT, + "auxHeat2": CURRENT_HVAC_HEAT, + "auxHeat3": CURRENT_HVAC_HEAT, + "fan": CURRENT_HVAC_FAN, + "humidifier": None, + "dehumidifier": CURRENT_HVAC_DRY, + "ventilator": CURRENT_HVAC_FAN, + "economizer": CURRENT_HVAC_FAN, + "compHotWater": None, + "auxHotWater": None, +} + PRESET_TO_ECOBEE_HOLD = { PRESET_HOLD_NEXT_TRANSITION: 'nextTransition', PRESET_HOLD_INDEFINITE: 'indefinite', @@ -51,8 +70,11 @@ PRESET_TO_ECOBEE_HOLD = { PRESET_MODES = [ PRESET_NONE, PRESET_AWAY, + PRESET_TEMPERATURE, PRESET_HOME, - PRESET_SLEEP + PRESET_SLEEP, + PRESET_HOLD_NEXT_TRANSITION, + PRESET_HOLD_INDEFINITE ] SERVICE_SET_FAN_MIN_ON_TIME = 'ecobee_set_fan_min_on_time' @@ -140,9 +162,16 @@ class Thermostat(ClimateDevice): self.hold_temp = hold_temp self.vacation = None self._climate_list = self.climate_list - self._operation_list = [ - HVAC_MODE_AUTO, HVAC_MODE_HEAT, HVAC_MODE_COOL, HVAC_MODE_OFF - ] + + self._operation_list = [] + if self.thermostat['settings']['heatStages']: + self._operation_list.append(HVAC_MODE_HEAT) + if self.thermostat['settings']['coolStages']: + self._operation_list.append(HVAC_MODE_COOL) + if len(self._operation_list) == 2: + self._operation_list.insert(0, HVAC_MODE_AUTO) + self._operation_list.append(HVAC_MODE_OFF) + self._fan_modes = [FAN_AUTO, FAN_ON] self.update_without_throttle = False @@ -247,9 +276,6 @@ class Thermostat(ClimateDevice): self.vacation = event['name'] return PRESET_VACATION - if self.is_aux_heat: - return PRESET_AUX_HEAT_ONLY - return None @property @@ -277,18 +303,29 @@ class Thermostat(ClimateDevice): @property def hvac_action(self): - """Return current HVAC action.""" - status = self.thermostat['equipmentStatus'] - operation = None + """Return current HVAC action. - if status == '': - operation = CURRENT_HVAC_OFF - elif 'Cool' in status: - operation = CURRENT_HVAC_COOL - elif 'auxHeat' in status or 'heatPump' in status: - operation = CURRENT_HVAC_HEAT + Ecobee returns a CSV string with different equipment that is active. + We are prioritizing any heating/cooling equipment, otherwase look at + drying/fanning. Idle if nothing going on. - return operation + We are unable to map all actions to HA equivalents. + """ + if self.thermostat['equipmentStatus'] == "": + return CURRENT_HVAC_IDLE + + actions = [ + ECOBEE_HVAC_ACTION_TO_HASS[status] for status in + self.thermostat['equipmentStatus'].split(",") + if ECOBEE_HVAC_ACTION_TO_HASS[status] is not None + ] + + for action in (CURRENT_HVAC_HEAT, CURRENT_HVAC_COOL, + CURRENT_HVAC_DRY, CURRENT_HVAC_FAN): + if action in actions: + return action + + return CURRENT_HVAC_IDLE @property def device_state_attributes(self): @@ -332,13 +369,12 @@ class Thermostat(ClimateDevice): self.thermostat_index, PRESET_TO_ECOBEE_HOLD[preset_mode], self.hold_preference()) - elif preset_mode is PRESET_NONE: + elif preset_mode == PRESET_NONE: self.data.ecobee.resume_program(self.thermostat_index) else: self.data.ecobee.set_climate_hold( self.thermostat_index, preset_mode, self.hold_preference()) - self.update_without_throttle = True @property def preset_modes(self): diff --git a/homeassistant/components/ecobee/manifest.json b/homeassistant/components/ecobee/manifest.json index d2aa7f0b515..31cca1e676f 100644 --- a/homeassistant/components/ecobee/manifest.json +++ b/homeassistant/components/ecobee/manifest.json @@ -3,7 +3,7 @@ "name": "Ecobee", "documentation": "https://www.home-assistant.io/components/ecobee", "requirements": [ - "python-ecobee-api==0.0.18" + "python-ecobee-api==0.0.21" ], "dependencies": ["configurator"], "codeowners": [] diff --git a/requirements_all.txt b/requirements_all.txt index ca41c7fdff2..569af7b9609 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1438,7 +1438,7 @@ python-clementine-remote==1.0.1 python-digitalocean==1.13.2 # homeassistant.components.ecobee -python-ecobee-api==0.0.18 +python-ecobee-api==0.0.21 # homeassistant.components.eq3btsmart # python-eq3bt==0.1.9 diff --git a/tests/components/ecobee/test_climate.py b/tests/components/ecobee/test_climate.py index 6a0e9e08435..f996040ed73 100644 --- a/tests/components/ecobee/test_climate.py +++ b/tests/components/ecobee/test_climate.py @@ -23,6 +23,8 @@ class TestEcobee(unittest.TestCase): 'desiredCool': 200, 'desiredFanMode': 'on'}, 'settings': {'hvacMode': 'auto', + 'heatStages': 1, + 'coolStages': 1, 'fanMinOnTime': 10, 'heatCoolMinDelta': 50, 'holdAction': 'nextTransition'},