From 3a3d448f17df26f9772c6438a8a2153365f0ab17 Mon Sep 17 00:00:00 2001 From: William Sutton Date: Thu, 9 Jan 2020 09:25:19 -0500 Subject: [PATCH] Add preset scheduling to radiothermostat (#29847) * Added preset scheduling to radiothermostat. Added alternate scheduling & religious scheduling to climate/const.py * Fix Flake8 Errors in climate.py * Fixing more flake8 errors in climate.py Removed duplicate set_preset_mode def * Fixed more flake8 errors. Please be the end of these errors. * Fixed black formatting * Fixed black, broke flake8, fixed flake8 * Fixed CODE_TO_FAN_STATE black error * Fixed isort issues * Local isort broke black formatting Docs should run isort before black. Default isort will undo certain black formatting. * Removed last commas from imports * Added removed line * Fixed formatting Hopefully this is what the CI pipeline is looking for. * Ran isort from git repo root, utilizing setup.cfg. * One more try * fixed added definition and fixed logger string * fixed formatting * lost a close-paren * Update const.py Removed radiotherm specific presets * Update climate.py Moved preset definitions into radiotherm climate.py --- homeassistant/components/climate/const.py | 1 - .../components/radiotherm/climate.py | 48 ++++++++++++++++++- 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/climate/const.py b/homeassistant/components/climate/const.py index 26cec7efbeb6..b489071db573 100644 --- a/homeassistant/components/climate/const.py +++ b/homeassistant/components/climate/const.py @@ -56,7 +56,6 @@ PRESET_SLEEP = "sleep" # Device is reacting to activity (e.g. movement sensors) PRESET_ACTIVITY = "activity" - # Possible fan state FAN_ON = "on" FAN_OFF = "off" diff --git a/homeassistant/components/radiotherm/climate.py b/homeassistant/components/radiotherm/climate.py index d6bc3d6d5794..a6beeaa187b4 100644 --- a/homeassistant/components/radiotherm/climate.py +++ b/homeassistant/components/radiotherm/climate.py @@ -15,7 +15,10 @@ from homeassistant.components.climate.const import ( HVAC_MODE_COOL, HVAC_MODE_HEAT, HVAC_MODE_OFF, + PRESET_AWAY, + PRESET_HOME, SUPPORT_FAN_MODE, + SUPPORT_PRESET_MODE, SUPPORT_TARGET_TEMPERATURE, ) from homeassistant.const import ( @@ -34,8 +37,14 @@ ATTR_FAN_ACTION = "fan_action" CONF_HOLD_TEMP = "hold_temp" +PRESET_HOLIDAY = "holiday" + +PRESET_ALTERNATE = "alternate" + STATE_CIRCULATE = "circulate" +PRESET_MODES = [PRESET_HOME, PRESET_ALTERNATE, PRESET_AWAY, PRESET_HOLIDAY] + OPERATION_LIST = [HVAC_MODE_AUTO, HVAC_MODE_COOL, HVAC_MODE_HEAT, HVAC_MODE_OFF] CT30_FAN_OPERATION_LIST = [STATE_ON, HVAC_MODE_AUTO] CT80_FAN_OPERATION_LIST = [STATE_ON, STATE_CIRCULATE, HVAC_MODE_AUTO] @@ -55,6 +64,7 @@ TEMP_MODE_TO_CODE = {v: k for k, v in CODE_TO_TEMP_MODE.items()} # Programmed fan mode (circulate is supported by CT80 models) CODE_TO_FAN_MODE = {0: HVAC_MODE_AUTO, 1: STATE_CIRCULATE, 2: STATE_ON} + FAN_MODE_TO_CODE = {v: k for k, v in CODE_TO_FAN_MODE.items()} # Active thermostat state (is it heating or cooling?). In the future @@ -65,6 +75,10 @@ CODE_TO_TEMP_STATE = {0: CURRENT_HVAC_IDLE, 1: CURRENT_HVAC_HEAT, 2: CURRENT_HVA # future this should probably made into a binary sensor for the fan. CODE_TO_FAN_STATE = {0: FAN_OFF, 1: FAN_ON} +PRESET_MODE_TO_CODE = {"home": 0, "alternate": 1, "away": 2, "holiday": 3} + +CODE_TO_PRESET_MODE = {0: "home", 1: "alternate", 2: "away", 3: "holiday"} + def round_temp(temperature): """Round a temperature to the resolution of the thermostat. @@ -82,7 +96,8 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( } ) -SUPPORT_FLAGS = SUPPORT_TARGET_TEMPERATURE | SUPPORT_FAN_MODE + +SUPPORT_FLAGS = SUPPORT_TARGET_TEMPERATURE | SUPPORT_FAN_MODE | SUPPORT_PRESET_MODE def setup_platform(hass, config, add_entities, discovery_info=None): @@ -128,6 +143,9 @@ class RadioThermostat(ClimateDevice): self._hold_temp = hold_temp self._hold_set = False self._prev_temp = None + self._preset_mode = None + self._program_mode = None + self._is_away = False # Fan circulate mode is only supported by the CT80 models. self._is_model_ct80 = isinstance(self.device, radiotherm.thermostat.CT80) @@ -216,6 +234,23 @@ class RadioThermostat(ClimateDevice): """Return the temperature we try to reach.""" return self._target_temperature + @property + def preset_mode(self): + """Return the current preset mode, e.g., home, away, temp.""" + if self._program_mode == 0: + return PRESET_HOME + if self._program_mode == 1: + return PRESET_ALTERNATE + if self._program_mode == 2: + return PRESET_AWAY + if self._program_mode == 3: + return PRESET_HOLIDAY + + @property + def preset_modes(self): + """Return a list of available preset modes.""" + return PRESET_MODES + def update(self): """Update and validate the data from the thermostat.""" # Radio thermostats are very slow, and sometimes don't respond @@ -262,6 +297,8 @@ class RadioThermostat(ClimateDevice): self._fstate = CODE_TO_FAN_STATE[data["fstate"]] self._tmode = CODE_TO_TEMP_MODE[data["tmode"]] self._tstate = CODE_TO_TEMP_STATE[data["tstate"]] + self._program_mode = data["program_mode"] + self._preset_mode = CODE_TO_PRESET_MODE[data["program_mode"]] self._current_operation = self._tmode if self._tmode == HVAC_MODE_COOL: @@ -327,3 +364,12 @@ class RadioThermostat(ClimateDevice): self.device.t_cool = self._target_temperature elif hvac_mode == HVAC_MODE_HEAT: self.device.t_heat = self._target_temperature + + def set_preset_mode(self, preset_mode): + """Set Preset mode (Home, Alternate, Away, Holiday).""" + if preset_mode in (PRESET_MODES): + self.device.program_mode = PRESET_MODE_TO_CODE[preset_mode] + else: + _LOGGER.error( + "preset_mode %s not in PRESET_MODES", preset_mode, + )