diff --git a/homeassistant/components/climate/__init__.py b/homeassistant/components/climate/__init__.py index 347cb275e42..cd297548273 100644 --- a/homeassistant/components/climate/__init__.py +++ b/homeassistant/components/climate/__init__.py @@ -74,7 +74,7 @@ SET_FAN_MODE_SCHEMA = vol.Schema({ }) SET_PRESET_MODE_SCHEMA = vol.Schema({ vol.Optional(ATTR_ENTITY_ID): cv.comp_entity_ids, - vol.Required(ATTR_PRESET_MODE): vol.Maybe(cv.string), + vol.Required(ATTR_PRESET_MODE): cv.string, }) SET_HVAC_MODE_SCHEMA = vol.Schema({ vol.Optional(ATTR_ENTITY_ID): cv.comp_entity_ids, diff --git a/homeassistant/components/climate/const.py b/homeassistant/components/climate/const.py index 13f8e3b616a..7b99442c2d7 100644 --- a/homeassistant/components/climate/const.py +++ b/homeassistant/components/climate/const.py @@ -32,6 +32,8 @@ HVAC_MODES = [ HVAC_MODE_FAN_ONLY, ] +# No preset is active +PRESET_NONE = 'none' # Device is running an energy-saving mode PRESET_ECO = 'eco' diff --git a/homeassistant/components/ecobee/climate.py b/homeassistant/components/ecobee/climate.py index 3b034d4a838..b8c73e61447 100644 --- a/homeassistant/components/ecobee/climate.py +++ b/homeassistant/components/ecobee/climate.py @@ -12,7 +12,7 @@ from homeassistant.components.climate.const import ( 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 + CURRENT_HVAC_COOL, SUPPORT_PRESET_MODE, PRESET_NONE ) from homeassistant.const import ( ATTR_ENTITY_ID, STATE_ON, ATTR_TEMPERATURE, TEMP_FAHRENHEIT) @@ -49,6 +49,7 @@ PRESET_TO_ECOBEE_HOLD = { } PRESET_MODES = [ + PRESET_NONE, PRESET_AWAY, PRESET_HOME, PRESET_SLEEP @@ -331,7 +332,7 @@ class Thermostat(ClimateDevice): self.thermostat_index, PRESET_TO_ECOBEE_HOLD[preset_mode], self.hold_preference()) - elif preset_mode is None: + elif preset_mode is PRESET_NONE: self.data.ecobee.resume_program(self.thermostat_index) else: diff --git a/homeassistant/components/eq3btsmart/climate.py b/homeassistant/components/eq3btsmart/climate.py index 6a9d65b3883..90b6b7e134e 100644 --- a/homeassistant/components/eq3btsmart/climate.py +++ b/homeassistant/components/eq3btsmart/climate.py @@ -7,7 +7,7 @@ import voluptuous as vol from homeassistant.components.climate import PLATFORM_SCHEMA, ClimateDevice from homeassistant.components.climate.const import ( HVAC_MODE_AUTO, HVAC_MODE_HEAT, HVAC_MODE_OFF, PRESET_AWAY, PRESET_BOOST, - SUPPORT_PRESET_MODE, SUPPORT_TARGET_TEMPERATURE) + SUPPORT_PRESET_MODE, SUPPORT_TARGET_TEMPERATURE, PRESET_NONE) from homeassistant.const import ( ATTR_TEMPERATURE, CONF_DEVICES, CONF_MAC, PRECISION_HALVES, TEMP_CELSIUS) import homeassistant.helpers.config_validation as cv @@ -181,7 +181,7 @@ class EQ3BTSmartThermostat(ClimateDevice): def set_preset_mode(self, preset_mode): """Set new preset mode.""" - if not preset_mode: + if preset_mode == PRESET_NONE: self.set_hvac_mode(HVAC_MODE_HEAT) self._thermostat.mode = HA_TO_EQ_PRESET[preset_mode] diff --git a/homeassistant/components/evohome/climate.py b/homeassistant/components/evohome/climate.py index 540675d7ef4..a953c2e3244 100644 --- a/homeassistant/components/evohome/climate.py +++ b/homeassistant/components/evohome/climate.py @@ -10,7 +10,7 @@ from homeassistant.components.climate import ClimateDevice from homeassistant.components.climate.const import ( HVAC_MODE_HEAT, HVAC_MODE_AUTO, HVAC_MODE_OFF, CURRENT_HVAC_HEAT, CURRENT_HVAC_IDLE, CURRENT_HVAC_OFF, - PRESET_AWAY, PRESET_ECO, PRESET_HOME, + PRESET_AWAY, PRESET_ECO, PRESET_HOME, PRESET_NONE, SUPPORT_TARGET_TEMPERATURE, SUPPORT_PRESET_MODE) from homeassistant.const import PRECISION_TENTHS from homeassistant.util.dt import parse_datetime @@ -40,12 +40,11 @@ HA_PRESET_TO_TCS = { TCS_PRESET_TO_HA = {v: k for k, v in HA_PRESET_TO_TCS.items()} EVO_PRESET_TO_HA = { - EVO_FOLLOW: None, + EVO_FOLLOW: PRESET_NONE, EVO_TEMPOVER: 'temporary', EVO_PERMOVER: 'permanent', } -HA_PRESET_TO_EVO = {v: k for k, v in EVO_PRESET_TO_HA.items() - if v is not None} +HA_PRESET_TO_EVO = {v: k for k, v in EVO_PRESET_TO_HA.items()} def setup_platform(hass, hass_config, add_entities, diff --git a/homeassistant/components/generic_thermostat/climate.py b/homeassistant/components/generic_thermostat/climate.py index ba18d9de936..409c44d1bca 100644 --- a/homeassistant/components/generic_thermostat/climate.py +++ b/homeassistant/components/generic_thermostat/climate.py @@ -8,7 +8,7 @@ from homeassistant.components.climate import PLATFORM_SCHEMA, ClimateDevice from homeassistant.components.climate.const import ( ATTR_PRESET_MODE, CURRENT_HVAC_COOL, CURRENT_HVAC_HEAT, CURRENT_HVAC_IDLE, CURRENT_HVAC_OFF, HVAC_MODE_COOL, HVAC_MODE_HEAT, HVAC_MODE_OFF, - PRESET_AWAY, SUPPORT_PRESET_MODE, SUPPORT_TARGET_TEMPERATURE) + PRESET_AWAY, SUPPORT_PRESET_MODE, SUPPORT_TARGET_TEMPERATURE, PRESET_NONE) from homeassistant.const import ( ATTR_ENTITY_ID, ATTR_TEMPERATURE, CONF_NAME, EVENT_HOMEASSISTANT_START, PRECISION_HALVES, PRECISION_TENTHS, PRECISION_WHOLE, SERVICE_TURN_OFF, @@ -251,7 +251,7 @@ class GenericThermostat(ClimateDevice, RestoreEntity): def preset_modes(self): """Return a list of available preset modes.""" if self._away_temp: - return [PRESET_AWAY] + return [PRESET_NONE, PRESET_AWAY] return None async def async_set_hvac_mode(self, hvac_mode): @@ -404,7 +404,7 @@ class GenericThermostat(ClimateDevice, RestoreEntity): self._saved_target_temp = self._target_temp self._target_temp = self._away_temp await self._async_control_heating(force=True) - elif not preset_mode and self._is_away: + elif preset_mode == PRESET_NONE and self._is_away: self._is_away = False self._target_temp = self._saved_target_temp await self._async_control_heating(force=True) diff --git a/homeassistant/components/hive/climate.py b/homeassistant/components/hive/climate.py index bfc43e3357f..dd7e0164367 100644 --- a/homeassistant/components/hive/climate.py +++ b/homeassistant/components/hive/climate.py @@ -2,7 +2,7 @@ from homeassistant.components.climate import ClimateDevice from homeassistant.components.climate.const import ( HVAC_MODE_AUTO, HVAC_MODE_HEAT, HVAC_MODE_OFF, PRESET_BOOST, - SUPPORT_PRESET_MODE, SUPPORT_TARGET_TEMPERATURE) + SUPPORT_PRESET_MODE, SUPPORT_TARGET_TEMPERATURE, PRESET_NONE) from homeassistant.const import ATTR_TEMPERATURE, TEMP_CELSIUS from . import DATA_HIVE, DOMAIN @@ -21,7 +21,7 @@ HASS_TO_HIVE_STATE = { SUPPORT_FLAGS = SUPPORT_TARGET_TEMPERATURE | SUPPORT_PRESET_MODE SUPPORT_HVAC = [HVAC_MODE_AUTO, HVAC_MODE_HEAT, HVAC_MODE_OFF] -SUPPORT_PRESET = [PRESET_BOOST] +SUPPORT_PRESET = [PRESET_NONE, PRESET_BOOST] def setup_platform(hass, config, add_entities, discovery_info=None): @@ -168,7 +168,7 @@ class HiveClimateEntity(ClimateDevice): def set_preset_mode(self, preset_mode) -> None: """Set new preset mode.""" - if preset_mode is None and self.preset_mode == PRESET_BOOST: + if preset_mode == PRESET_NONE and self.preset_mode == PRESET_BOOST: self.session.heating.turn_boost_off(self.node_id) elif preset_mode == PRESET_BOOST: diff --git a/homeassistant/components/homematicip_cloud/climate.py b/homeassistant/components/homematicip_cloud/climate.py index 56cab03396e..44f0c148a41 100644 --- a/homeassistant/components/homematicip_cloud/climate.py +++ b/homeassistant/components/homematicip_cloud/climate.py @@ -10,7 +10,7 @@ from homematicip.aio.home import AsyncHome from homeassistant.components.climate import ClimateDevice from homeassistant.components.climate.const import ( HVAC_MODE_AUTO, HVAC_MODE_HEAT, PRESET_BOOST, PRESET_ECO, - SUPPORT_PRESET_MODE, SUPPORT_TARGET_TEMPERATURE) + SUPPORT_PRESET_MODE, SUPPORT_TARGET_TEMPERATURE, PRESET_NONE) from homeassistant.config_entries import ConfigEntry from homeassistant.const import ATTR_TEMPERATURE, TEMP_CELSIUS from homeassistant.core import HomeAssistant @@ -121,7 +121,7 @@ class HomematicipHeatingGroup(HomematicipGenericDevice, ClimateDevice): Requires SUPPORT_PRESET_MODE. """ - return [PRESET_BOOST] + return [PRESET_NONE, PRESET_BOOST] @property def min_temp(self) -> float: diff --git a/homeassistant/components/honeywell/climate.py b/homeassistant/components/honeywell/climate.py index 8d0a3602d02..4f3adaf4b2e 100644 --- a/homeassistant/components/honeywell/climate.py +++ b/homeassistant/components/honeywell/climate.py @@ -15,7 +15,7 @@ from homeassistant.components.climate.const import ( SUPPORT_TARGET_HUMIDITY, SUPPORT_TARGET_TEMPERATURE_RANGE, CURRENT_HVAC_COOL, CURRENT_HVAC_HEAT, CURRENT_HVAC_IDLE, CURRENT_HVAC_OFF, HVAC_MODE_OFF, HVAC_MODE_HEAT, HVAC_MODE_COOL, HVAC_MODE_HEAT_COOL, - PRESET_AWAY, + PRESET_AWAY, PRESET_NONE, ) from homeassistant.const import ( CONF_PASSWORD, CONF_USERNAME, TEMP_CELSIUS, TEMP_FAHRENHEIT, @@ -229,7 +229,7 @@ class HoneywellUSThermostat(ClimateDevice): @property def preset_modes(self) -> Optional[List[str]]: """Return a list of available preset modes.""" - return [PRESET_AWAY] + return [PRESET_NONE, PRESET_AWAY] @property def is_aux_heat(self) -> Optional[str]: diff --git a/homeassistant/components/mqtt/climate.py b/homeassistant/components/mqtt/climate.py index b70ffa80145..4106ce6fa3b 100644 --- a/homeassistant/components/mqtt/climate.py +++ b/homeassistant/components/mqtt/climate.py @@ -12,7 +12,7 @@ from homeassistant.components.climate.const import ( HVAC_MODE_DRY, HVAC_MODE_FAN_ONLY, HVAC_MODE_HEAT, HVAC_MODE_OFF, SUPPORT_AUX_HEAT, SUPPORT_FAN_MODE, SUPPORT_PRESET_MODE, SUPPORT_SWING_MODE, SUPPORT_TARGET_TEMPERATURE, PRESET_AWAY, - SUPPORT_TARGET_TEMPERATURE_RANGE) + SUPPORT_TARGET_TEMPERATURE_RANGE, PRESET_NONE) from homeassistant.components.fan import SPEED_HIGH, SPEED_LOW, SPEED_MEDIUM from homeassistant.const import ( ATTR_TEMPERATURE, CONF_DEVICE, CONF_NAME, CONF_VALUE_TEMPLATE, STATE_ON) @@ -538,6 +538,9 @@ class MqttClimate(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate, presets.extend(self._config[CONF_HOLD_LIST]) + if presets: + presets.insert(0, PRESET_NONE) + return presets @property diff --git a/homeassistant/components/nest/climate.py b/homeassistant/components/nest/climate.py index 5dd1db52650..63d91cbc829 100644 --- a/homeassistant/components/nest/climate.py +++ b/homeassistant/components/nest/climate.py @@ -8,7 +8,7 @@ from homeassistant.components.climate.const import ( ATTR_TARGET_TEMP_HIGH, ATTR_TARGET_TEMP_LOW, FAN_AUTO, FAN_ON, HVAC_MODE_AUTO, HVAC_MODE_COOL, HVAC_MODE_HEAT, HVAC_MODE_OFF, SUPPORT_PRESET_MODE, SUPPORT_FAN_MODE, SUPPORT_TARGET_TEMPERATURE, - SUPPORT_TARGET_TEMPERATURE_RANGE, PRESET_AWAY, PRESET_ECO) + SUPPORT_TARGET_TEMPERATURE_RANGE, PRESET_AWAY, PRESET_ECO, PRESET_NONE) from homeassistant.const import ( ATTR_TEMPERATURE, CONF_SCAN_INTERVAL, TEMP_CELSIUS, TEMP_FAHRENHEIT) from homeassistant.helpers.dispatcher import async_dispatcher_connect @@ -28,7 +28,7 @@ NEST_MODE_HEAT = 'heat' NEST_MODE_COOL = 'cool' NEST_MODE_OFF = 'off' -PRESET_MODES = [PRESET_AWAY, PRESET_ECO] +PRESET_MODES = [PRESET_NONE, PRESET_AWAY, PRESET_ECO] def setup_platform(hass, config, add_entities, discovery_info=None): diff --git a/homeassistant/components/nuheat/climate.py b/homeassistant/components/nuheat/climate.py index dcc85b1a814..e53b60d1ca1 100644 --- a/homeassistant/components/nuheat/climate.py +++ b/homeassistant/components/nuheat/climate.py @@ -7,7 +7,7 @@ import voluptuous as vol from homeassistant.components.climate import ClimateDevice from homeassistant.components.climate.const import ( HVAC_MODE_AUTO, HVAC_MODE_HEAT, HVAC_MODE_OFF, SUPPORT_PRESET_MODE, - SUPPORT_TARGET_TEMPERATURE) + SUPPORT_TARGET_TEMPERATURE, PRESET_NONE) from homeassistant.const import ( ATTR_ENTITY_ID, ATTR_TEMPERATURE, TEMP_CELSIUS, TEMP_FAHRENHEIT) import homeassistant.helpers.config_validation as cv @@ -157,6 +157,7 @@ class NuHeatThermostat(ClimateDevice): def preset_modes(self): """Return available preset modes.""" return [ + PRESET_NONE, MODE_HOLD_TEMPERATURE, MODE_TEMPORARY_HOLD ] @@ -173,7 +174,7 @@ class NuHeatThermostat(ClimateDevice): def set_preset_mode(self, preset_mode): """Update the hold mode of the thermostat.""" - if preset_mode is None: + if preset_mode == PRESET_NONE: schedule_mode = SCHEDULE_RUN elif preset_mode == MODE_HOLD_TEMPERATURE: diff --git a/homeassistant/components/opentherm_gw/climate.py b/homeassistant/components/opentherm_gw/climate.py index d0b706cdad8..db6dfd33c91 100644 --- a/homeassistant/components/opentherm_gw/climate.py +++ b/homeassistant/components/opentherm_gw/climate.py @@ -170,7 +170,7 @@ class OpenThermClimate(ClimateDevice): @property def preset_modes(self): """Available preset modes to set.""" - return [PRESET_AWAY] + return [] def set_preset_mode(self, preset_mode): """Set the preset mode.""" diff --git a/homeassistant/components/toon/climate.py b/homeassistant/components/toon/climate.py index d8c2f0ad5ee..2ce0ed954b8 100644 --- a/homeassistant/components/toon/climate.py +++ b/homeassistant/components/toon/climate.py @@ -130,9 +130,8 @@ class ToonThermostatDevice(ToonDisplayDeviceEntity, ClimateDevice): def set_preset_mode(self, preset_mode: str) -> None: """Set new preset mode.""" - if preset_mode is not None: - self._client.thermostat_state = self._preset = preset_mode - self.schedule_update_ha_state() + self._client.thermostat_state = self._preset = preset_mode + self.schedule_update_ha_state() def set_hvac_mode(self, hvac_mode: str) -> None: """Set new target hvac mode.""" diff --git a/homeassistant/components/venstar/climate.py b/homeassistant/components/venstar/climate.py index de7894059d4..7d3fc9e59a1 100644 --- a/homeassistant/components/venstar/climate.py +++ b/homeassistant/components/venstar/climate.py @@ -8,7 +8,7 @@ from homeassistant.components.climate.const import ( ATTR_HVAC_MODE, ATTR_TARGET_TEMP_HIGH, ATTR_TARGET_TEMP_LOW, HVAC_MODE_AUTO, HVAC_MODE_COOL, HVAC_MODE_HEAT, SUPPORT_FAN_MODE, SUPPORT_TARGET_HUMIDITY, SUPPORT_PRESET_MODE, - SUPPORT_TARGET_TEMPERATURE, PRESET_AWAY, + SUPPORT_TARGET_TEMPERATURE, PRESET_AWAY, PRESET_NONE, SUPPORT_TARGET_TEMPERATURE_RANGE, HVAC_MODE_OFF) from homeassistant.const import ( @@ -213,6 +213,7 @@ class VenstarThermostat(ClimateDevice): def preset_modes(self): """Return valid preset modes.""" return [ + PRESET_NONE, PRESET_AWAY, HOLD_MODE_TEMPERATURE, ] @@ -286,7 +287,7 @@ class VenstarThermostat(ClimateDevice): success = self._client.set_away(self._client.AWAY_AWAY) elif preset_mode == HOLD_MODE_TEMPERATURE: success = self._client.set_schedule(0) - elif preset_mode is None: + elif preset_mode == PRESET_NONE: success = False if self._client.away: success = self._client.set_away(self._client.AWAY_HOME) diff --git a/homeassistant/components/wink/climate.py b/homeassistant/components/wink/climate.py index 0a27db396b5..9d7893eefc7 100644 --- a/homeassistant/components/wink/climate.py +++ b/homeassistant/components/wink/climate.py @@ -10,7 +10,7 @@ from homeassistant.components.climate.const import ( FAN_LOW, FAN_MEDIUM, FAN_ON, HVAC_MODE_AUTO, HVAC_MODE_COOL, HVAC_MODE_FAN_ONLY, HVAC_MODE_HEAT, HVAC_MODE_OFF, PRESET_AWAY, PRESET_ECO, SUPPORT_AUX_HEAT, SUPPORT_FAN_MODE, SUPPORT_TARGET_TEMPERATURE, - SUPPORT_TARGET_TEMPERATURE_RANGE) + SUPPORT_TARGET_TEMPERATURE_RANGE, PRESET_NONE) from homeassistant.const import ( ATTR_TEMPERATURE, PRECISION_TENTHS, TEMP_CELSIUS) from homeassistant.helpers.temperature import display_temp as show_temp @@ -44,7 +44,7 @@ SUPPORT_PRESET_THERMOSTAT = [PRESET_AWAY, PRESET_ECO] SUPPORT_FLAGS_AC = SUPPORT_TARGET_TEMPERATURE | SUPPORT_FAN_MODE SUPPORT_FAN_AC = [FAN_HIGH, FAN_LOW, FAN_MEDIUM] -SUPPORT_PRESET_AC = [PRESET_ECO] +SUPPORT_PRESET_AC = [PRESET_NONE, PRESET_ECO] def setup_platform(hass, config, add_entities, discovery_info=None): diff --git a/tests/components/generic_thermostat/test_climate.py b/tests/components/generic_thermostat/test_climate.py index 46bd021b877..c7d73b02cbf 100644 --- a/tests/components/generic_thermostat/test_climate.py +++ b/tests/components/generic_thermostat/test_climate.py @@ -9,7 +9,7 @@ import voluptuous as vol from homeassistant.components import input_boolean, switch from homeassistant.components.climate.const import ( ATTR_PRESET_MODE, DOMAIN, HVAC_MODE_COOL, HVAC_MODE_HEAT, HVAC_MODE_OFF, - PRESET_AWAY) + PRESET_AWAY, PRESET_NONE) from homeassistant.const import ( ATTR_TEMPERATURE, SERVICE_TURN_OFF, SERVICE_TURN_ON, STATE_OFF, STATE_ON, TEMP_CELSIUS, TEMP_FAHRENHEIT) @@ -202,7 +202,7 @@ async def test_set_away_mode_and_restore_prev_temp(hass, setup_comp_2): await common.async_set_preset_mode(hass, PRESET_AWAY) state = hass.states.get(ENTITY) assert 16 == state.attributes.get('temperature') - await common.async_set_preset_mode(hass, None) + await common.async_set_preset_mode(hass, PRESET_NONE) state = hass.states.get(ENTITY) assert 23 == state.attributes.get('temperature') @@ -217,7 +217,7 @@ async def test_set_away_mode_twice_and_restore_prev_temp(hass, setup_comp_2): await common.async_set_preset_mode(hass, PRESET_AWAY) state = hass.states.get(ENTITY) assert 16 == state.attributes.get('temperature') - await common.async_set_preset_mode(hass, None) + await common.async_set_preset_mode(hass, PRESET_NONE) state = hass.states.get(ENTITY) assert 23 == state.attributes.get('temperature') diff --git a/tests/components/mqtt/test_climate.py b/tests/components/mqtt/test_climate.py index 6792675f594..407285b116f 100644 --- a/tests/components/mqtt/test_climate.py +++ b/tests/components/mqtt/test_climate.py @@ -16,7 +16,7 @@ from homeassistant.components.climate.const import ( SUPPORT_FAN_MODE, SUPPORT_SWING_MODE, SUPPORT_TARGET_TEMPERATURE, HVAC_MODE_AUTO, HVAC_MODE_COOL, HVAC_MODE_HEAT, HVAC_MODE_DRY, HVAC_MODE_FAN_ONLY, - SUPPORT_TARGET_TEMPERATURE_RANGE) + SUPPORT_TARGET_TEMPERATURE_RANGE, PRESET_NONE) from homeassistant.components.mqtt.discovery import async_start from homeassistant.const import STATE_OFF, STATE_UNAVAILABLE @@ -425,7 +425,7 @@ async def test_set_away_mode(hass, mqtt_mock): state = hass.states.get(ENTITY_CLIMATE) assert state.attributes.get('preset_mode') == 'away' - await common.async_set_preset_mode(hass, None, ENTITY_CLIMATE) + await common.async_set_preset_mode(hass, PRESET_NONE, ENTITY_CLIMATE) mqtt_mock.async_publish.assert_called_once_with( 'away-mode-topic', 'AUS', 0, False) state = hass.states.get(ENTITY_CLIMATE) @@ -467,7 +467,7 @@ async def test_set_hold(hass, mqtt_mock): state = hass.states.get(ENTITY_CLIMATE) assert state.attributes.get('preset_mode') == 'hold-on' - await common.async_set_preset_mode(hass, None, ENTITY_CLIMATE) + await common.async_set_preset_mode(hass, PRESET_NONE, ENTITY_CLIMATE) mqtt_mock.async_publish.assert_called_once_with( 'hold-topic', 'off', 0, False) state = hass.states.get(ENTITY_CLIMATE)