From 373508693aeb71e1fdc4093b4f429ada77b8afbc Mon Sep 17 00:00:00 2001 From: Lukas Barth Date: Wed, 29 Nov 2017 11:01:28 +0100 Subject: [PATCH] Climate component: add supported_features (#10658) * Implement supported_features for the climate component * Test supported features * Convert generic thermostat to supported features * Max / min temperature are not features * Fix lint * Min / max humidity are not features * Linting * Remove current temperature / humidity * Move c-hacker-style constants to boring integers. Booo! * Refactor all the climate platforms to use the new supported_features * Force all climate platforms to implement supported_features * Fix mistakes * Adapt hive platform * Move flags into a constant * Calm the hound --- homeassistant/components/climate/__init__.py | 18 +++++++++ homeassistant/components/climate/demo.py | 17 +++++++- homeassistant/components/climate/ecobee.py | 34 +++++++++++++--- homeassistant/components/climate/ephember.py | 7 +++- .../components/climate/eq3btsmart.py | 11 +++++- homeassistant/components/climate/flexit.py | 11 +++++- .../components/climate/generic_thermostat.py | 8 +++- homeassistant/components/climate/heatmiser.py | 8 +++- homeassistant/components/climate/hive.py | 13 +++++-- homeassistant/components/climate/homematic.py | 11 +++++- homeassistant/components/climate/honeywell.py | 19 ++++++++- homeassistant/components/climate/knx.py | 12 +++++- homeassistant/components/climate/maxcube.py | 11 +++++- homeassistant/components/climate/mqtt.py | 39 ++++++++++++++++++- homeassistant/components/climate/mysensors.py | 13 ++++++- homeassistant/components/climate/nest.py | 13 ++++++- homeassistant/components/climate/netatmo.py | 11 +++++- homeassistant/components/climate/oem.py | 10 ++++- homeassistant/components/climate/proliphix.py | 7 +++- .../components/climate/radiotherm.py | 11 +++++- homeassistant/components/climate/sensibo.py | 14 ++++++- homeassistant/components/climate/tado.py | 10 ++++- homeassistant/components/climate/tesla.py | 11 +++++- homeassistant/components/climate/toon.py | 9 ++++- homeassistant/components/climate/vera.py | 12 +++++- homeassistant/components/climate/wink.py | 31 ++++++++++++++- homeassistant/components/climate/zwave.py | 17 +++++++- tests/components/climate/test_mqtt.py | 16 +++++++- 28 files changed, 370 insertions(+), 34 deletions(-) diff --git a/homeassistant/components/climate/__init__.py b/homeassistant/components/climate/__init__.py index 81a7adca1b7..f9ffe4faec9 100644 --- a/homeassistant/components/climate/__init__.py +++ b/homeassistant/components/climate/__init__.py @@ -51,6 +51,19 @@ STATE_HIGH_DEMAND = 'high_demand' STATE_HEAT_PUMP = 'heat_pump' STATE_GAS = 'gas' +SUPPORT_TARGET_TEMPERATURE = 1 +SUPPORT_TARGET_TEMPERATURE_HIGH = 2 +SUPPORT_TARGET_TEMPERATURE_LOW = 4 +SUPPORT_TARGET_HUMIDITY = 8 +SUPPORT_TARGET_HUMIDITY_HIGH = 16 +SUPPORT_TARGET_HUMIDITY_LOW = 32 +SUPPORT_FAN_MODE = 64 +SUPPORT_OPERATION_MODE = 128 +SUPPORT_HOLD_MODE = 256 +SUPPORT_SWING_MODE = 512 +SUPPORT_AWAY_MODE = 1024 +SUPPORT_AUX_HEAT = 2048 + ATTR_CURRENT_TEMPERATURE = 'current_temperature' ATTR_MAX_TEMP = 'max_temp' ATTR_MIN_TEMP = 'min_temp' @@ -717,6 +730,11 @@ class ClimateDevice(Entity): """ return self.hass.async_add_job(self.turn_aux_heat_off) + @property + def supported_features(self): + """Return the list of supported features.""" + raise NotImplementedError() + @property def min_temp(self): """Return the minimum temperature.""" diff --git a/homeassistant/components/climate/demo.py b/homeassistant/components/climate/demo.py index 377985aaa12..4c4b57d42a3 100644 --- a/homeassistant/components/climate/demo.py +++ b/homeassistant/components/climate/demo.py @@ -5,9 +5,19 @@ For more details about this platform, please refer to the documentation https://home-assistant.io/components/demo/ """ from homeassistant.components.climate import ( - ClimateDevice, ATTR_TARGET_TEMP_HIGH, ATTR_TARGET_TEMP_LOW) + ClimateDevice, ATTR_TARGET_TEMP_HIGH, ATTR_TARGET_TEMP_LOW, + SUPPORT_TARGET_TEMPERATURE, SUPPORT_TARGET_HUMIDITY, + SUPPORT_AWAY_MODE, SUPPORT_HOLD_MODE, SUPPORT_FAN_MODE, + SUPPORT_OPERATION_MODE, SUPPORT_AUX_HEAT, SUPPORT_SWING_MODE, + SUPPORT_TARGET_TEMPERATURE_HIGH, SUPPORT_TARGET_TEMPERATURE_LOW) from homeassistant.const import TEMP_CELSIUS, TEMP_FAHRENHEIT, ATTR_TEMPERATURE +SUPPORT_FLAGS = (SUPPORT_TARGET_TEMPERATURE | SUPPORT_TARGET_HUMIDITY | + SUPPORT_AWAY_MODE | SUPPORT_HOLD_MODE | SUPPORT_FAN_MODE | + SUPPORT_OPERATION_MODE | SUPPORT_AUX_HEAT | + SUPPORT_SWING_MODE | SUPPORT_TARGET_TEMPERATURE_HIGH | + SUPPORT_TARGET_TEMPERATURE_LOW) + def setup_platform(hass, config, add_devices, discovery_info=None): """Set up the Demo climate devices.""" @@ -47,6 +57,11 @@ class DemoClimate(ClimateDevice): self._target_temperature_high = target_temp_high self._target_temperature_low = target_temp_low + @property + def supported_features(self): + """Return the list of supported features.""" + return SUPPORT_FLAGS + @property def should_poll(self): """Return the polling state.""" diff --git a/homeassistant/components/climate/ecobee.py b/homeassistant/components/climate/ecobee.py index 100312f643e..aae70a4f1f7 100644 --- a/homeassistant/components/climate/ecobee.py +++ b/homeassistant/components/climate/ecobee.py @@ -12,7 +12,9 @@ import voluptuous as vol from homeassistant.components import ecobee from homeassistant.components.climate import ( DOMAIN, STATE_COOL, STATE_HEAT, STATE_AUTO, STATE_IDLE, ClimateDevice, - ATTR_TARGET_TEMP_LOW, ATTR_TARGET_TEMP_HIGH) + ATTR_TARGET_TEMP_LOW, ATTR_TARGET_TEMP_HIGH, SUPPORT_TARGET_TEMPERATURE, + SUPPORT_AWAY_MODE, SUPPORT_HOLD_MODE, SUPPORT_OPERATION_MODE, + SUPPORT_TARGET_HUMIDITY_LOW, SUPPORT_TARGET_HUMIDITY_HIGH) from homeassistant.const import ( ATTR_ENTITY_ID, STATE_OFF, STATE_ON, ATTR_TEMPERATURE, TEMP_FAHRENHEIT) from homeassistant.config import load_yaml_config_file @@ -44,6 +46,10 @@ RESUME_PROGRAM_SCHEMA = vol.Schema({ vol.Optional(ATTR_RESUME_ALL, default=DEFAULT_RESUME_ALL): cv.boolean, }) +SUPPORT_FLAGS = (SUPPORT_TARGET_TEMPERATURE | SUPPORT_AWAY_MODE | + SUPPORT_HOLD_MODE | SUPPORT_OPERATION_MODE | + SUPPORT_TARGET_HUMIDITY_LOW | SUPPORT_TARGET_HUMIDITY_HIGH) + def setup_platform(hass, config, add_devices, discovery_info=None): """Set up the Ecobee Thermostat Platform.""" @@ -132,6 +138,11 @@ class Thermostat(ClimateDevice): self.thermostat = self.data.ecobee.get_thermostat( self.thermostat_index) + @property + def supported_features(self): + """Return the list of supported features.""" + return SUPPORT_FLAGS + @property def name(self): """Return the name of the Ecobee Thermostat.""" @@ -318,8 +329,21 @@ class Thermostat(ClimateDevice): def set_auto_temp_hold(self, heat_temp, cool_temp): """Set temperature hold in auto mode.""" - self.data.ecobee.set_hold_temp(self.thermostat_index, cool_temp, - heat_temp, self.hold_preference()) + if cool_temp is not None: + cool_temp_setpoint = cool_temp + else: + cool_temp_setpoint = ( + self.thermostat['runtime']['desiredCool'] / 10.0) + + if heat_temp is not None: + heat_temp_setpoint = heat_temp + else: + heat_temp_setpoint = ( + self.thermostat['runtime']['desiredCool'] / 10.0) + + self.data.ecobee.set_hold_temp(self.thermostat_index, + cool_temp_setpoint, heat_temp_setpoint, + self.hold_preference()) _LOGGER.debug("Setting ecobee hold_temp to: heat=%s, is=%s, " "cool=%s, is=%s", heat_temp, isinstance( heat_temp, (int, float)), cool_temp, @@ -348,8 +372,8 @@ class Thermostat(ClimateDevice): high_temp = kwargs.get(ATTR_TARGET_TEMP_HIGH) temp = kwargs.get(ATTR_TEMPERATURE) - if self.current_operation == STATE_AUTO and low_temp is not None \ - and high_temp is not None: + if self.current_operation == STATE_AUTO and (low_temp is not None or + high_temp is not None): self.set_auto_temp_hold(low_temp, high_temp) elif temp is not None: self.set_temp_hold(temp) diff --git a/homeassistant/components/climate/ephember.py b/homeassistant/components/climate/ephember.py index 79ff767c82b..a1d11bce901 100644 --- a/homeassistant/components/climate/ephember.py +++ b/homeassistant/components/climate/ephember.py @@ -9,7 +9,7 @@ from datetime import timedelta import voluptuous as vol from homeassistant.components.climate import ( - ClimateDevice, PLATFORM_SCHEMA, STATE_HEAT, STATE_IDLE) + ClimateDevice, PLATFORM_SCHEMA, STATE_HEAT, STATE_IDLE, SUPPORT_AUX_HEAT) from homeassistant.const import ( TEMP_CELSIUS, CONF_USERNAME, CONF_PASSWORD) import homeassistant.helpers.config_validation as cv @@ -56,6 +56,11 @@ class EphEmberThermostat(ClimateDevice): self._zone = zone self._hot_water = zone['isHotWater'] + @property + def supported_features(self): + """Return the list of supported features.""" + return SUPPORT_AUX_HEAT + @property def name(self): """Return the name of the thermostat, if any.""" diff --git a/homeassistant/components/climate/eq3btsmart.py b/homeassistant/components/climate/eq3btsmart.py index dba096bb632..eb9b5c5ba6e 100644 --- a/homeassistant/components/climate/eq3btsmart.py +++ b/homeassistant/components/climate/eq3btsmart.py @@ -9,7 +9,8 @@ import logging import voluptuous as vol from homeassistant.components.climate import ( - STATE_ON, STATE_OFF, STATE_AUTO, PLATFORM_SCHEMA, ClimateDevice) + STATE_ON, STATE_OFF, STATE_AUTO, PLATFORM_SCHEMA, ClimateDevice, + SUPPORT_TARGET_TEMPERATURE, SUPPORT_OPERATION_MODE, SUPPORT_AWAY_MODE) from homeassistant.const import ( CONF_MAC, CONF_DEVICES, TEMP_CELSIUS, ATTR_TEMPERATURE, PRECISION_HALVES) import homeassistant.helpers.config_validation as cv @@ -37,6 +38,9 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ vol.Schema({cv.string: DEVICE_SCHEMA}), }) +SUPPORT_FLAGS = (SUPPORT_TARGET_TEMPERATURE | SUPPORT_OPERATION_MODE | + SUPPORT_AWAY_MODE) + def setup_platform(hass, config, add_devices, discovery_info=None): """Set up the eQ-3 BLE thermostats.""" @@ -72,6 +76,11 @@ class EQ3BTSmartThermostat(ClimateDevice): self._name = _name self._thermostat = eq3.Thermostat(_mac) + @property + def supported_features(self): + """Return the list of supported features.""" + return SUPPORT_FLAGS + @property def available(self) -> bool: """Return if thermostat is available.""" diff --git a/homeassistant/components/climate/flexit.py b/homeassistant/components/climate/flexit.py index c3ba2224b06..98c03217509 100644 --- a/homeassistant/components/climate/flexit.py +++ b/homeassistant/components/climate/flexit.py @@ -17,7 +17,9 @@ import voluptuous as vol from homeassistant.const import ( CONF_NAME, CONF_SLAVE, TEMP_CELSIUS, ATTR_TEMPERATURE, DEVICE_DEFAULT_NAME) -from homeassistant.components.climate import (ClimateDevice, PLATFORM_SCHEMA) +from homeassistant.components.climate import ( + ClimateDevice, PLATFORM_SCHEMA, SUPPORT_TARGET_TEMPERATURE, + SUPPORT_FAN_MODE) import homeassistant.components.modbus as modbus import homeassistant.helpers.config_validation as cv @@ -31,6 +33,8 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ _LOGGER = logging.getLogger(__name__) +SUPPORT_FLAGS = SUPPORT_TARGET_TEMPERATURE | SUPPORT_FAN_MODE + def setup_platform(hass, config, add_devices, discovery_info=None): """Set up the Flexit Platform.""" @@ -62,6 +66,11 @@ class Flexit(ClimateDevice): self._alarm = False self.unit = pyflexit.pyflexit(modbus.HUB, modbus_slave) + @property + def supported_features(self): + """Return the list of supported features.""" + return SUPPORT_FLAGS + def update(self): """Update unit attributes.""" if not self.unit.update(): diff --git a/homeassistant/components/climate/generic_thermostat.py b/homeassistant/components/climate/generic_thermostat.py index 3f3470c1c86..987708834cc 100644 --- a/homeassistant/components/climate/generic_thermostat.py +++ b/homeassistant/components/climate/generic_thermostat.py @@ -13,7 +13,7 @@ from homeassistant.core import callback from homeassistant.core import DOMAIN as HA_DOMAIN from homeassistant.components.climate import ( STATE_HEAT, STATE_COOL, STATE_IDLE, ClimateDevice, PLATFORM_SCHEMA, - STATE_AUTO) + STATE_AUTO, SUPPORT_OPERATION_MODE, SUPPORT_TARGET_TEMPERATURE) from homeassistant.const import ( ATTR_UNIT_OF_MEASUREMENT, STATE_ON, STATE_OFF, ATTR_TEMPERATURE, CONF_NAME, ATTR_ENTITY_ID, SERVICE_TURN_ON, SERVICE_TURN_OFF) @@ -41,6 +41,7 @@ CONF_COLD_TOLERANCE = 'cold_tolerance' CONF_HOT_TOLERANCE = 'hot_tolerance' CONF_KEEP_ALIVE = 'keep_alive' +SUPPORT_FLAGS = SUPPORT_TARGET_TEMPERATURE | SUPPORT_OPERATION_MODE PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ vol.Required(CONF_HEATER): cv.entity_id, @@ -313,6 +314,11 @@ class GenericThermostat(ClimateDevice): """If the toggleable device is currently active.""" return self.hass.states.is_state(self.heater_entity_id, STATE_ON) + @property + def supported_features(self): + """Return the list of supported features.""" + return SUPPORT_FLAGS + @callback def _heater_turn_on(self): """Turn heater toggleable device on.""" diff --git a/homeassistant/components/climate/heatmiser.py b/homeassistant/components/climate/heatmiser.py index 56015ebeb5a..b05c880cc37 100644 --- a/homeassistant/components/climate/heatmiser.py +++ b/homeassistant/components/climate/heatmiser.py @@ -8,7 +8,8 @@ import logging import voluptuous as vol -from homeassistant.components.climate import ClimateDevice, PLATFORM_SCHEMA +from homeassistant.components.climate import ( + ClimateDevice, PLATFORM_SCHEMA, SUPPORT_TARGET_TEMPERATURE) from homeassistant.const import ( TEMP_CELSIUS, ATTR_TEMPERATURE, CONF_PORT, CONF_NAME, CONF_ID) import homeassistant.helpers.config_validation as cv @@ -68,6 +69,11 @@ class HeatmiserV3Thermostat(ClimateDevice): self.update() self._target_temperature = int(self.dcb.get('roomset')) + @property + def supported_features(self): + """Return the list of supported features.""" + return SUPPORT_TARGET_TEMPERATURE + @property def name(self): """Return the name of the thermostat, if any.""" diff --git a/homeassistant/components/climate/hive.py b/homeassistant/components/climate/hive.py index 18833558b44..267657d56ce 100644 --- a/homeassistant/components/climate/hive.py +++ b/homeassistant/components/climate/hive.py @@ -4,9 +4,9 @@ Support for the Hive devices. For more details about this platform, please refer to the documentation at https://home-assistant.io/components/climate.hive/ """ -from homeassistant.components.climate import (ClimateDevice, - STATE_AUTO, STATE_HEAT, - STATE_OFF, STATE_ON) +from homeassistant.components.climate import ( + ClimateDevice, STATE_AUTO, STATE_HEAT, STATE_OFF, STATE_ON, + SUPPORT_TARGET_TEMPERATURE, SUPPORT_OPERATION_MODE) from homeassistant.const import ATTR_TEMPERATURE, TEMP_CELSIUS from homeassistant.components.hive import DATA_HIVE @@ -16,6 +16,8 @@ HIVE_TO_HASS_STATE = {'SCHEDULE': STATE_AUTO, 'MANUAL': STATE_HEAT, HASS_TO_HIVE_STATE = {STATE_AUTO: 'SCHEDULE', STATE_HEAT: 'MANUAL', STATE_ON: 'ON', STATE_OFF: 'OFF'} +SUPPORT_FLAGS = SUPPORT_TARGET_TEMPERATURE | SUPPORT_OPERATION_MODE + def setup_platform(hass, config, add_devices, discovery_info=None): """Set up Hive climate devices.""" @@ -45,6 +47,11 @@ class HiveClimateEntity(ClimateDevice): self.session.entities.append(self) + @property + def supported_features(self): + """Return the list of supported features.""" + return SUPPORT_FLAGS + def handle_update(self, updatesource): """Handle the new update request.""" if '{}.{}'.format(self.device_type, self.node_id) not in updatesource: diff --git a/homeassistant/components/climate/homematic.py b/homeassistant/components/climate/homematic.py index 5236c0788fd..33a63b35530 100644 --- a/homeassistant/components/climate/homematic.py +++ b/homeassistant/components/climate/homematic.py @@ -5,7 +5,9 @@ For more details about this platform, please refer to the documentation at https://home-assistant.io/components/climate.homematic/ """ import logging -from homeassistant.components.climate import ClimateDevice, STATE_AUTO +from homeassistant.components.climate import ( + ClimateDevice, STATE_AUTO, SUPPORT_TARGET_TEMPERATURE, + SUPPORT_OPERATION_MODE) from homeassistant.components.homematic import HMDevice, ATTR_DISCOVER_DEVICES from homeassistant.const import TEMP_CELSIUS, STATE_UNKNOWN, ATTR_TEMPERATURE @@ -38,6 +40,8 @@ HM_HUMI_MAP = [ HM_CONTROL_MODE = 'CONTROL_MODE' +SUPPORT_FLAGS = SUPPORT_TARGET_TEMPERATURE | SUPPORT_OPERATION_MODE + def setup_platform(hass, config, add_devices, discovery_info=None): """Set up the Homematic thermostat platform.""" @@ -55,6 +59,11 @@ def setup_platform(hass, config, add_devices, discovery_info=None): class HMThermostat(HMDevice, ClimateDevice): """Representation of a Homematic thermostat.""" + @property + def supported_features(self): + """Return the list of supported features.""" + return SUPPORT_FLAGS + @property def temperature_unit(self): """Return the unit of measurement that is used.""" diff --git a/homeassistant/components/climate/honeywell.py b/homeassistant/components/climate/honeywell.py index a6d27665fa2..20d93e3116a 100644 --- a/homeassistant/components/climate/honeywell.py +++ b/homeassistant/components/climate/honeywell.py @@ -14,7 +14,8 @@ import voluptuous as vol import homeassistant.helpers.config_validation as cv from homeassistant.components.climate import ( ClimateDevice, PLATFORM_SCHEMA, ATTR_FAN_MODE, ATTR_FAN_LIST, - ATTR_OPERATION_MODE, ATTR_OPERATION_LIST) + ATTR_OPERATION_MODE, ATTR_OPERATION_LIST, SUPPORT_TARGET_TEMPERATURE, + SUPPORT_AWAY_MODE, SUPPORT_OPERATION_MODE) from homeassistant.const import ( CONF_PASSWORD, CONF_USERNAME, TEMP_CELSIUS, TEMP_FAHRENHEIT, ATTR_TEMPERATURE, CONF_REGION) @@ -126,6 +127,14 @@ class RoundThermostat(ClimateDevice): self._away_temp = away_temp self._away = False + @property + def supported_features(self): + """Return the list of supported features.""" + supported = (SUPPORT_TARGET_TEMPERATURE | SUPPORT_AWAY_MODE) + if hasattr(self.client, ATTR_SYSTEM_MODE): + supported |= SUPPORT_OPERATION_MODE + return supported + @property def name(self): """Return the name of the honeywell, if any.""" @@ -234,6 +243,14 @@ class HoneywellUSThermostat(ClimateDevice): self._username = username self._password = password + @property + def supported_features(self): + """Return the list of supported features.""" + supported = (SUPPORT_TARGET_TEMPERATURE | SUPPORT_AWAY_MODE) + if hasattr(self._device, ATTR_SYSTEM_MODE): + supported |= SUPPORT_OPERATION_MODE + return supported + @property def is_fan_on(self): """Return true if fan is on.""" diff --git a/homeassistant/components/climate/knx.py b/homeassistant/components/climate/knx.py index 69c144985d6..fb0de1e2de0 100644 --- a/homeassistant/components/climate/knx.py +++ b/homeassistant/components/climate/knx.py @@ -8,7 +8,9 @@ import asyncio import voluptuous as vol from homeassistant.components.knx import DATA_KNX, ATTR_DISCOVER_DEVICES -from homeassistant.components.climate import PLATFORM_SCHEMA, ClimateDevice +from homeassistant.components.climate import ( + PLATFORM_SCHEMA, ClimateDevice, SUPPORT_TARGET_TEMPERATURE, + SUPPORT_OPERATION_MODE) from homeassistant.const import CONF_NAME, TEMP_CELSIUS, ATTR_TEMPERATURE from homeassistant.core import callback import homeassistant.helpers.config_validation as cv @@ -135,6 +137,14 @@ class KNXClimate(ClimateDevice): self._unit_of_measurement = TEMP_CELSIUS + @property + def supported_features(self): + """Return the list of supported features.""" + support = SUPPORT_TARGET_TEMPERATURE + if self.device.supports_operation_mode: + support |= SUPPORT_OPERATION_MODE + return support + def async_register_callbacks(self): """Register callbacks to update hass after device was changed.""" @asyncio.coroutine diff --git a/homeassistant/components/climate/maxcube.py b/homeassistant/components/climate/maxcube.py index 271616daf8b..067d11437b2 100644 --- a/homeassistant/components/climate/maxcube.py +++ b/homeassistant/components/climate/maxcube.py @@ -7,7 +7,9 @@ https://home-assistant.io/components/maxcube/ import socket import logging -from homeassistant.components.climate import ClimateDevice, STATE_AUTO +from homeassistant.components.climate import ( + ClimateDevice, STATE_AUTO, SUPPORT_TARGET_TEMPERATURE, + SUPPORT_OPERATION_MODE) from homeassistant.components.maxcube import MAXCUBE_HANDLE from homeassistant.const import TEMP_CELSIUS, ATTR_TEMPERATURE @@ -17,6 +19,8 @@ STATE_MANUAL = 'manual' STATE_BOOST = 'boost' STATE_VACATION = 'vacation' +SUPPORT_FLAGS = SUPPORT_TARGET_TEMPERATURE | SUPPORT_OPERATION_MODE + def setup_platform(hass, config, add_devices, discovery_info=None): """Iterate through all MAX! Devices and add thermostats.""" @@ -47,6 +51,11 @@ class MaxCubeClimate(ClimateDevice): self._rf_address = rf_address self._cubehandle = hass.data[MAXCUBE_HANDLE] + @property + def supported_features(self): + """Return the list of supported features.""" + return SUPPORT_FLAGS + @property def should_poll(self): """Return the polling state.""" diff --git a/homeassistant/components/climate/mqtt.py b/homeassistant/components/climate/mqtt.py index de6ac7a0227..d571ebd39e4 100644 --- a/homeassistant/components/climate/mqtt.py +++ b/homeassistant/components/climate/mqtt.py @@ -15,7 +15,9 @@ import homeassistant.components.mqtt as mqtt from homeassistant.components.climate import ( STATE_HEAT, STATE_COOL, STATE_DRY, STATE_FAN_ONLY, ClimateDevice, PLATFORM_SCHEMA as CLIMATE_PLATFORM_SCHEMA, STATE_AUTO, - ATTR_OPERATION_MODE) + ATTR_OPERATION_MODE, SUPPORT_TARGET_TEMPERATURE, SUPPORT_OPERATION_MODE, + SUPPORT_SWING_MODE, SUPPORT_FAN_MODE, SUPPORT_AWAY_MODE, SUPPORT_HOLD_MODE, + SUPPORT_AUX_HEAT) from homeassistant.const import ( STATE_ON, STATE_OFF, ATTR_TEMPERATURE, CONF_NAME) from homeassistant.components.mqtt import (CONF_QOS, CONF_RETAIN, @@ -483,3 +485,38 @@ class MqttClimate(ClimateDevice): if self._topic[CONF_AUX_STATE_TOPIC] is None: self._aux = False self.async_schedule_update_ha_state() + + @property + def supported_features(self): + """Return the list of supported features.""" + support = 0 + + if (self._topic[CONF_TEMPERATURE_STATE_TOPIC] is not None) or \ + (self._topic[CONF_TEMPERATURE_COMMAND_TOPIC] is not None): + support |= SUPPORT_TARGET_TEMPERATURE + + if (self._topic[CONF_MODE_COMMAND_TOPIC] is not None) or \ + (self._topic[CONF_MODE_STATE_TOPIC] is not None): + support |= SUPPORT_OPERATION_MODE + + if (self._topic[CONF_FAN_MODE_STATE_TOPIC] is not None) or \ + (self._topic[CONF_FAN_MODE_COMMAND_TOPIC] is not None): + support |= SUPPORT_FAN_MODE + + if (self._topic[CONF_SWING_MODE_STATE_TOPIC] is not None) or \ + (self._topic[CONF_SWING_MODE_COMMAND_TOPIC] is not None): + support |= SUPPORT_SWING_MODE + + if (self._topic[CONF_AWAY_MODE_STATE_TOPIC] is not None) or \ + (self._topic[CONF_AWAY_MODE_COMMAND_TOPIC] is not None): + support |= SUPPORT_AWAY_MODE + + if (self._topic[CONF_HOLD_STATE_TOPIC] is not None) or \ + (self._topic[CONF_HOLD_COMMAND_TOPIC] is not None): + support |= SUPPORT_HOLD_MODE + + if (self._topic[CONF_AUX_STATE_TOPIC] is not None) or \ + (self._topic[CONF_AUX_COMMAND_TOPIC] is not None): + support |= SUPPORT_AUX_HEAT + + return support diff --git a/homeassistant/components/climate/mysensors.py b/homeassistant/components/climate/mysensors.py index d4316c2cfba..db43a6d3be4 100755 --- a/homeassistant/components/climate/mysensors.py +++ b/homeassistant/components/climate/mysensors.py @@ -7,7 +7,9 @@ https://home-assistant.io/components/climate.mysensors/ from homeassistant.components import mysensors from homeassistant.components.climate import ( ATTR_TARGET_TEMP_HIGH, ATTR_TARGET_TEMP_LOW, DOMAIN, STATE_AUTO, - STATE_COOL, STATE_HEAT, STATE_OFF, ClimateDevice) + STATE_COOL, STATE_HEAT, STATE_OFF, ClimateDevice, + SUPPORT_TARGET_TEMPERATURE, SUPPORT_TARGET_TEMPERATURE_HIGH, + SUPPORT_TARGET_TEMPERATURE_LOW, SUPPORT_FAN_MODE, SUPPORT_OPERATION_MODE) from homeassistant.const import ATTR_TEMPERATURE, TEMP_CELSIUS, TEMP_FAHRENHEIT DICT_HA_TO_MYS = { @@ -23,6 +25,10 @@ DICT_MYS_TO_HA = { 'Off': STATE_OFF, } +SUPPORT_FLAGS = (SUPPORT_TARGET_TEMPERATURE | SUPPORT_TARGET_TEMPERATURE_HIGH | + SUPPORT_TARGET_TEMPERATURE_LOW | SUPPORT_FAN_MODE | + SUPPORT_OPERATION_MODE) + def setup_platform(hass, config, add_devices, discovery_info=None): """Setup the mysensors climate.""" @@ -33,6 +39,11 @@ def setup_platform(hass, config, add_devices, discovery_info=None): class MySensorsHVAC(mysensors.MySensorsEntity, ClimateDevice): """Representation of a MySensors HVAC.""" + @property + def supported_features(self): + """Return the list of supported features.""" + return SUPPORT_FLAGS + @property def assumed_state(self): """Return True if unable to access real state of entity.""" diff --git a/homeassistant/components/climate/nest.py b/homeassistant/components/climate/nest.py index ac4f64f4ec8..3b550c43368 100644 --- a/homeassistant/components/climate/nest.py +++ b/homeassistant/components/climate/nest.py @@ -12,7 +12,9 @@ from homeassistant.components.nest import DATA_NEST from homeassistant.components.climate import ( STATE_AUTO, STATE_COOL, STATE_HEAT, ClimateDevice, PLATFORM_SCHEMA, ATTR_TARGET_TEMP_HIGH, ATTR_TARGET_TEMP_LOW, - ATTR_TEMPERATURE) + ATTR_TEMPERATURE, SUPPORT_TARGET_TEMPERATURE, + SUPPORT_TARGET_TEMPERATURE_HIGH, SUPPORT_TARGET_TEMPERATURE_LOW, + SUPPORT_OPERATION_MODE, SUPPORT_AWAY_MODE, SUPPORT_FAN_MODE) from homeassistant.const import ( TEMP_CELSIUS, TEMP_FAHRENHEIT, CONF_SCAN_INTERVAL, STATE_ON, STATE_OFF, STATE_UNKNOWN) @@ -28,6 +30,10 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ STATE_ECO = 'eco' STATE_HEAT_COOL = 'heat-cool' +SUPPORT_FLAGS = (SUPPORT_TARGET_TEMPERATURE | SUPPORT_TARGET_TEMPERATURE_HIGH | + SUPPORT_TARGET_TEMPERATURE_LOW | SUPPORT_OPERATION_MODE | + SUPPORT_AWAY_MODE | SUPPORT_FAN_MODE) + def setup_platform(hass, config, add_devices, discovery_info=None): """Set up the Nest thermostat.""" @@ -87,6 +93,11 @@ class NestThermostat(ClimateDevice): self._min_temperature = None self._max_temperature = None + @property + def supported_features(self): + """Return the list of supported features.""" + return SUPPORT_FLAGS + @property def name(self): """Return the name of the nest, if any.""" diff --git a/homeassistant/components/climate/netatmo.py b/homeassistant/components/climate/netatmo.py index 369b01e53de..2166070a572 100755 --- a/homeassistant/components/climate/netatmo.py +++ b/homeassistant/components/climate/netatmo.py @@ -10,7 +10,8 @@ import voluptuous as vol from homeassistant.const import TEMP_CELSIUS, ATTR_TEMPERATURE from homeassistant.components.climate import ( - STATE_HEAT, STATE_IDLE, ClimateDevice, PLATFORM_SCHEMA) + STATE_HEAT, STATE_IDLE, ClimateDevice, PLATFORM_SCHEMA, + SUPPORT_TARGET_TEMPERATURE, SUPPORT_OPERATION_MODE, SUPPORT_AWAY_MODE) from homeassistant.util import Throttle from homeassistant.loader import get_component import homeassistant.helpers.config_validation as cv @@ -35,6 +36,9 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ vol.All(cv.ensure_list, [cv.string]), }) +SUPPORT_FLAGS = (SUPPORT_TARGET_TEMPERATURE | SUPPORT_OPERATION_MODE | + SUPPORT_AWAY_MODE) + def setup_platform(hass, config, add_devices, discovery_info=None): """Set up the NetAtmo Thermostat.""" @@ -65,6 +69,11 @@ class NetatmoThermostat(ClimateDevice): self._target_temperature = None self._away = None + @property + def supported_features(self): + """Return the list of supported features.""" + return SUPPORT_FLAGS + @property def name(self): """Return the name of the sensor.""" diff --git a/homeassistant/components/climate/oem.py b/homeassistant/components/climate/oem.py index 5909f26eb4f..0cbdc8f2ce6 100644 --- a/homeassistant/components/climate/oem.py +++ b/homeassistant/components/climate/oem.py @@ -14,7 +14,8 @@ import voluptuous as vol # Import the device class from the component that you want to support from homeassistant.components.climate import ( - ClimateDevice, PLATFORM_SCHEMA, STATE_HEAT, STATE_IDLE, ATTR_TEMPERATURE) + ClimateDevice, PLATFORM_SCHEMA, STATE_HEAT, STATE_IDLE, ATTR_TEMPERATURE, + SUPPORT_TARGET_TEMPERATURE, SUPPORT_AWAY_MODE) from homeassistant.const import (CONF_HOST, CONF_USERNAME, CONF_PASSWORD, CONF_PORT, TEMP_CELSIUS, CONF_NAME) import homeassistant.helpers.config_validation as cv @@ -34,6 +35,8 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ vol.Optional(CONF_AWAY_TEMP, default=14): vol.Coerce(float) }) +SUPPORT_FLAGS = SUPPORT_TARGET_TEMPERATURE | SUPPORT_AWAY_MODE + def setup_platform(hass, config, add_devices, discovery_info=None): """Set up the oemthermostat platform.""" @@ -77,6 +80,11 @@ class ThermostatDevice(ClimateDevice): self._temperature = None self._setpoint = None + @property + def supported_features(self): + """Return the list of supported features.""" + return SUPPORT_FLAGS + @property def name(self): """Return the name of this Thermostat.""" diff --git a/homeassistant/components/climate/proliphix.py b/homeassistant/components/climate/proliphix.py index f168df04158..34fcfd667b6 100644 --- a/homeassistant/components/climate/proliphix.py +++ b/homeassistant/components/climate/proliphix.py @@ -8,7 +8,7 @@ import voluptuous as vol from homeassistant.components.climate import ( PRECISION_TENTHS, STATE_COOL, STATE_HEAT, STATE_IDLE, - ClimateDevice, PLATFORM_SCHEMA) + ClimateDevice, PLATFORM_SCHEMA, SUPPORT_TARGET_TEMPERATURE) from homeassistant.const import ( CONF_HOST, CONF_PASSWORD, CONF_USERNAME, TEMP_FAHRENHEIT, ATTR_TEMPERATURE) import homeassistant.helpers.config_validation as cv @@ -46,6 +46,11 @@ class ProliphixThermostat(ClimateDevice): self._pdp.update() self._name = self._pdp.name + @property + def supported_features(self): + """Return the list of supported features.""" + return SUPPORT_TARGET_TEMPERATURE + @property def should_poll(self): """Set up polling needed for thermostat.""" diff --git a/homeassistant/components/climate/radiotherm.py b/homeassistant/components/climate/radiotherm.py index 5de6478133c..2b31ca93d22 100644 --- a/homeassistant/components/climate/radiotherm.py +++ b/homeassistant/components/climate/radiotherm.py @@ -12,7 +12,8 @@ import voluptuous as vol from homeassistant.components.climate import ( STATE_AUTO, STATE_COOL, STATE_HEAT, STATE_IDLE, STATE_ON, STATE_OFF, - ClimateDevice, PLATFORM_SCHEMA) + ClimateDevice, PLATFORM_SCHEMA, SUPPORT_TARGET_TEMPERATURE, + SUPPORT_OPERATION_MODE, SUPPORT_FAN_MODE, SUPPORT_AWAY_MODE) from homeassistant.const import ( CONF_HOST, TEMP_FAHRENHEIT, ATTR_TEMPERATURE, PRECISION_HALVES) import homeassistant.helpers.config_validation as cv @@ -78,6 +79,9 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ vol.All(vol.Coerce(float), round_temp), }) +SUPPORT_FLAGS = (SUPPORT_TARGET_TEMPERATURE | SUPPORT_OPERATION_MODE | + SUPPORT_FAN_MODE | SUPPORT_AWAY_MODE) + def setup_platform(hass, config, add_devices, discovery_info=None): """Set up the Radio Thermostat.""" @@ -136,6 +140,11 @@ class RadioThermostat(ClimateDevice): self._is_model_ct80 = isinstance(self.device, radiotherm.thermostat.CT80) + @property + def supported_features(self): + """Return the list of supported features.""" + return SUPPORT_FLAGS + @asyncio.coroutine def async_added_to_hass(self): """Register callbacks.""" diff --git a/homeassistant/components/climate/sensibo.py b/homeassistant/components/climate/sensibo.py index 4c1d0a8b9fc..624729249aa 100644 --- a/homeassistant/components/climate/sensibo.py +++ b/homeassistant/components/climate/sensibo.py @@ -15,7 +15,10 @@ import voluptuous as vol from homeassistant.const import ( ATTR_TEMPERATURE, CONF_API_KEY, CONF_ID, TEMP_CELSIUS, TEMP_FAHRENHEIT) from homeassistant.components.climate import ( - ATTR_CURRENT_HUMIDITY, ClimateDevice, PLATFORM_SCHEMA) + ATTR_CURRENT_HUMIDITY, ClimateDevice, PLATFORM_SCHEMA, + SUPPORT_TARGET_TEMPERATURE, SUPPORT_OPERATION_MODE, + SUPPORT_FAN_MODE, SUPPORT_AWAY_MODE, SUPPORT_SWING_MODE, + SUPPORT_AUX_HEAT) from homeassistant.exceptions import PlatformNotReady from homeassistant.helpers import config_validation as cv from homeassistant.helpers.aiohttp_client import async_get_clientsession @@ -38,6 +41,10 @@ _FETCH_FIELDS = ','.join([ 'acState', 'connectionStatus{isAlive}', 'temperatureUnit']) _INITIAL_FETCH_FIELDS = 'id,' + _FETCH_FIELDS +SUPPORT_FLAGS = (SUPPORT_TARGET_TEMPERATURE | SUPPORT_OPERATION_MODE | + SUPPORT_FAN_MODE | SUPPORT_AWAY_MODE | SUPPORT_SWING_MODE | + SUPPORT_AUX_HEAT) + @asyncio.coroutine def async_setup_platform(hass, config, async_add_devices, discovery_info=None): @@ -75,6 +82,11 @@ class SensiboClimate(ClimateDevice): self._id = data['id'] self._do_update(data) + @property + def supported_features(self): + """Return the list of supported features.""" + return SUPPORT_FLAGS + def _do_update(self, data): self._name = data['room']['name'] self._measurements = data['measurements'] diff --git a/homeassistant/components/climate/tado.py b/homeassistant/components/climate/tado.py index 00bed936bd7..d58acac5373 100644 --- a/homeassistant/components/climate/tado.py +++ b/homeassistant/components/climate/tado.py @@ -7,7 +7,8 @@ https://home-assistant.io/components/climate.tado/ import logging from homeassistant.const import TEMP_CELSIUS -from homeassistant.components.climate import ClimateDevice +from homeassistant.components.climate import ( + ClimateDevice, SUPPORT_TARGET_TEMPERATURE, SUPPORT_OPERATION_MODE) from homeassistant.const import ATTR_TEMPERATURE from homeassistant.components.tado import DATA_TADO @@ -43,6 +44,8 @@ OPERATION_LIST = { CONST_MODE_OFF: 'Off', } +SUPPORT_FLAGS = SUPPORT_TARGET_TEMPERATURE | SUPPORT_OPERATION_MODE + def setup_platform(hass, config, add_devices, discovery_info=None): """Set up the Tado climate platform.""" @@ -127,6 +130,11 @@ class TadoClimate(ClimateDevice): self._current_operation = CONST_MODE_SMART_SCHEDULE self._overlay_mode = CONST_MODE_SMART_SCHEDULE + @property + def supported_features(self): + """Return the list of supported features.""" + return SUPPORT_FLAGS + @property def name(self): """Return the name of the device.""" diff --git a/homeassistant/components/climate/tesla.py b/homeassistant/components/climate/tesla.py index 684d131d960..6295b85a1b7 100644 --- a/homeassistant/components/climate/tesla.py +++ b/homeassistant/components/climate/tesla.py @@ -7,7 +7,9 @@ https://home-assistant.io/components/climate.tesla/ import logging from homeassistant.const import STATE_ON, STATE_OFF -from homeassistant.components.climate import ClimateDevice, ENTITY_ID_FORMAT +from homeassistant.components.climate import ( + ClimateDevice, ENTITY_ID_FORMAT, SUPPORT_TARGET_TEMPERATURE, + SUPPORT_OPERATION_MODE) from homeassistant.components.tesla import DOMAIN as TESLA_DOMAIN, TeslaDevice from homeassistant.const import ( TEMP_FAHRENHEIT, TEMP_CELSIUS, ATTR_TEMPERATURE) @@ -18,6 +20,8 @@ DEPENDENCIES = ['tesla'] OPERATION_LIST = [STATE_ON, STATE_OFF] +SUPPORT_FLAGS = SUPPORT_TARGET_TEMPERATURE | SUPPORT_OPERATION_MODE + def setup_platform(hass, config, add_devices, discovery_info=None): """Set up the Tesla climate platform.""" @@ -36,6 +40,11 @@ class TeslaThermostat(TeslaDevice, ClimateDevice): self._target_temperature = None self._temperature = None + @property + def supported_features(self): + """Return the list of supported features.""" + return SUPPORT_FLAGS + @property def current_operation(self): """Return current operation ie. On or Off.""" diff --git a/homeassistant/components/climate/toon.py b/homeassistant/components/climate/toon.py index 72e6ecb1fdb..0ff9f129081 100644 --- a/homeassistant/components/climate/toon.py +++ b/homeassistant/components/climate/toon.py @@ -10,9 +10,11 @@ https://home-assistant.io/components/climate.toon/ import homeassistant.components.toon as toon_main from homeassistant.components.climate import ( ClimateDevice, ATTR_TEMPERATURE, STATE_PERFORMANCE, STATE_HEAT, STATE_ECO, - STATE_COOL) + STATE_COOL, SUPPORT_TARGET_TEMPERATURE, SUPPORT_OPERATION_MODE) from homeassistant.const import TEMP_CELSIUS +SUPPORT_FLAGS = SUPPORT_TARGET_TEMPERATURE | SUPPORT_OPERATION_MODE + def setup_platform(hass, config, add_devices, discovery_info=None): """Set up the Toon thermostat.""" @@ -38,6 +40,11 @@ class ThermostatDevice(ClimateDevice): STATE_COOL, ] + @property + def supported_features(self): + """Return the list of supported features.""" + return SUPPORT_FLAGS + @property def name(self): """Name of this Thermostat.""" diff --git a/homeassistant/components/climate/vera.py b/homeassistant/components/climate/vera.py index 06325ae0561..4644f86cba2 100644 --- a/homeassistant/components/climate/vera.py +++ b/homeassistant/components/climate/vera.py @@ -7,7 +7,9 @@ https://home-assistant.io/components/switch.vera/ import logging from homeassistant.util import convert -from homeassistant.components.climate import ClimateDevice, ENTITY_ID_FORMAT +from homeassistant.components.climate import ( + ClimateDevice, ENTITY_ID_FORMAT, SUPPORT_TARGET_TEMPERATURE, + SUPPORT_OPERATION_MODE, SUPPORT_FAN_MODE) from homeassistant.const import ( TEMP_FAHRENHEIT, TEMP_CELSIUS, @@ -23,6 +25,9 @@ _LOGGER = logging.getLogger(__name__) OPERATION_LIST = ['Heat', 'Cool', 'Auto Changeover', 'Off'] FAN_OPERATION_LIST = ['On', 'Auto', 'Cycle'] +SUPPORT_FLAGS = (SUPPORT_TARGET_TEMPERATURE | SUPPORT_OPERATION_MODE | + SUPPORT_FAN_MODE) + def setup_platform(hass, config, add_devices_callback, discovery_info=None): """Set up of Vera thermostats.""" @@ -39,6 +44,11 @@ class VeraThermostat(VeraDevice, ClimateDevice): VeraDevice.__init__(self, vera_device, controller) self.entity_id = ENTITY_ID_FORMAT.format(self.vera_id) + @property + def supported_features(self): + """Return the list of supported features.""" + return SUPPORT_FLAGS + @property def current_operation(self): """Return current operation ie. heat, cool, idle.""" diff --git a/homeassistant/components/climate/wink.py b/homeassistant/components/climate/wink.py index 54d8d8617c7..33ba0f56d33 100644 --- a/homeassistant/components/climate/wink.py +++ b/homeassistant/components/climate/wink.py @@ -11,7 +11,10 @@ from homeassistant.components.climate import ( STATE_ECO, STATE_GAS, STATE_AUTO, STATE_COOL, STATE_HEAT, STATE_ELECTRIC, STATE_FAN_ONLY, STATE_HEAT_PUMP, ATTR_TEMPERATURE, STATE_HIGH_DEMAND, STATE_PERFORMANCE, ATTR_TARGET_TEMP_LOW, ATTR_CURRENT_HUMIDITY, - ATTR_TARGET_TEMP_HIGH, ClimateDevice) + ATTR_TARGET_TEMP_HIGH, ClimateDevice, SUPPORT_TARGET_TEMPERATURE, + SUPPORT_TARGET_TEMPERATURE_HIGH, SUPPORT_TARGET_TEMPERATURE_LOW, + SUPPORT_OPERATION_MODE, SUPPORT_AWAY_MODE, SUPPORT_FAN_MODE, + SUPPORT_AUX_HEAT) from homeassistant.components.wink import DOMAIN, WinkDevice from homeassistant.const import ( STATE_ON, STATE_OFF, TEMP_CELSIUS, STATE_UNKNOWN, PRECISION_TENTHS) @@ -50,6 +53,17 @@ HA_STATE_TO_WINK = { WINK_STATE_TO_HA = {value: key for key, value in HA_STATE_TO_WINK.items()} +SUPPORT_FLAGS_THERMOSTAT = ( + SUPPORT_TARGET_TEMPERATURE | SUPPORT_TARGET_TEMPERATURE_HIGH | + SUPPORT_TARGET_TEMPERATURE_LOW | SUPPORT_OPERATION_MODE | + SUPPORT_AWAY_MODE | SUPPORT_FAN_MODE | SUPPORT_AUX_HEAT) + +SUPPORT_FLAGS_AC = (SUPPORT_TARGET_TEMPERATURE | SUPPORT_OPERATION_MODE | + SUPPORT_FAN_MODE) + +SUPPORT_FLAGS_HEATER = (SUPPORT_TARGET_TEMPERATURE | SUPPORT_OPERATION_MODE | + SUPPORT_AWAY_MODE) + def setup_platform(hass, config, add_devices, discovery_info=None): """Set up the Wink climate devices.""" @@ -72,6 +86,11 @@ def setup_platform(hass, config, add_devices, discovery_info=None): class WinkThermostat(WinkDevice, ClimateDevice): """Representation of a Wink thermostat.""" + @property + def supported_features(self): + """Return the list of supported features.""" + return SUPPORT_FLAGS_THERMOSTAT + @asyncio.coroutine def async_added_to_hass(self): """Callback when entity is added to hass.""" @@ -353,6 +372,11 @@ class WinkThermostat(WinkDevice, ClimateDevice): class WinkAC(WinkDevice, ClimateDevice): """Representation of a Wink air conditioner.""" + @property + def supported_features(self): + """Return the list of supported features.""" + return SUPPORT_FLAGS_AC + @property def temperature_unit(self): """Return the unit of measurement.""" @@ -471,6 +495,11 @@ class WinkAC(WinkDevice, ClimateDevice): class WinkWaterHeater(WinkDevice, ClimateDevice): """Representation of a Wink water heater.""" + @property + def supported_features(self): + """Return the list of supported features.""" + return SUPPORT_FLAGS_HEATER + @property def temperature_unit(self): """Return the unit of measurement.""" diff --git a/homeassistant/components/climate/zwave.py b/homeassistant/components/climate/zwave.py index 497916a3e4d..acc3eda1194 100755 --- a/homeassistant/components/climate/zwave.py +++ b/homeassistant/components/climate/zwave.py @@ -7,8 +7,9 @@ https://home-assistant.io/components/climate.zwave/ # Because we do not compile openzwave on CI # pylint: disable=import-error import logging -from homeassistant.components.climate import DOMAIN -from homeassistant.components.climate import ClimateDevice +from homeassistant.components.climate import ( + DOMAIN, ClimateDevice, SUPPORT_TARGET_TEMPERATURE, SUPPORT_FAN_MODE, + SUPPORT_OPERATION_MODE, SUPPORT_SWING_MODE) from homeassistant.components.zwave import ZWaveDeviceEntity from homeassistant.components.zwave import async_setup_platform # noqa # pylint: disable=unused-import from homeassistant.const import ( @@ -70,6 +71,18 @@ class ZWaveClimate(ZWaveDeviceEntity, ClimateDevice): self._zxt_120 = 1 self.update_properties() + @property + def supported_features(self): + """Return the list of supported features.""" + support = SUPPORT_TARGET_TEMPERATURE + if self.values.fan_mode: + support |= SUPPORT_FAN_MODE + if self.values.mode: + support |= SUPPORT_OPERATION_MODE + if self._zxt_120 == 1 and self.values.zxt_120_swing_mode: + support |= SUPPORT_SWING_MODE + return support + def update_properties(self): """Handle the data changes for node values.""" # Operation Mode diff --git a/tests/components/climate/test_mqtt.py b/tests/components/climate/test_mqtt.py index 9b70138908d..43f90eeee20 100644 --- a/tests/components/climate/test_mqtt.py +++ b/tests/components/climate/test_mqtt.py @@ -8,7 +8,10 @@ from homeassistant.util.unit_system import ( from homeassistant.setup import setup_component from homeassistant.components import climate from homeassistant.const import STATE_OFF - +from homeassistant.components.climate import ( + SUPPORT_OPERATION_MODE, SUPPORT_TARGET_TEMPERATURE, + SUPPORT_FAN_MODE, SUPPORT_SWING_MODE, SUPPORT_HOLD_MODE, + SUPPORT_AWAY_MODE, SUPPORT_AUX_HEAT) from tests.common import (get_test_home_assistant, mock_mqtt_component, fire_mqtt_message, mock_component) @@ -51,6 +54,17 @@ class TestMQTTClimate(unittest.TestCase): self.assertEqual("off", state.attributes.get('swing_mode')) self.assertEqual("off", state.attributes.get('operation_mode')) + def test_supported_features(self): + """Test the supported_features.""" + assert setup_component(self.hass, climate.DOMAIN, DEFAULT_CONFIG) + + state = self.hass.states.get(ENTITY_CLIMATE) + support = (SUPPORT_TARGET_TEMPERATURE | SUPPORT_OPERATION_MODE | + SUPPORT_SWING_MODE | SUPPORT_FAN_MODE | SUPPORT_AWAY_MODE | + SUPPORT_HOLD_MODE | SUPPORT_AUX_HEAT) + + self.assertEqual(state.attributes.get("supported_features"), support) + def test_get_operation_modes(self): """Test that the operation list returns the correct modes.""" assert setup_component(self.hass, climate.DOMAIN, DEFAULT_CONFIG)