Add set_operation_mode support to generic_thermostat (#8392)

This commit adds support for the set_operation_mode system call to the
generic thermostat component. This enables users to set whether the
thermostat is enabled or not by either setting it to auto or off.
This commit is contained in:
Matthew Treinish 2017-07-08 12:21:10 -04:00 committed by Paulus Schoutsen
parent c5bf4fe339
commit cb298123d4
2 changed files with 81 additions and 1 deletions

View file

@ -12,7 +12,8 @@ import voluptuous as vol
from homeassistant.core import callback
from homeassistant.components import switch
from homeassistant.components.climate import (
STATE_HEAT, STATE_COOL, STATE_IDLE, ClimateDevice, PLATFORM_SCHEMA)
STATE_HEAT, STATE_COOL, STATE_IDLE, ClimateDevice, PLATFORM_SCHEMA,
STATE_AUTO)
from homeassistant.const import (
ATTR_UNIT_OF_MEASUREMENT, STATE_ON, STATE_OFF, ATTR_TEMPERATURE,
CONF_NAME)
@ -87,6 +88,7 @@ class GenericThermostat(ClimateDevice):
self.min_cycle_duration = min_cycle_duration
self._tolerance = tolerance
self._keep_alive = keep_alive
self._enabled = True
self._active = False
self._cur_temp = None
@ -131,6 +133,8 @@ class GenericThermostat(ClimateDevice):
@property
def current_operation(self):
"""Return current operation ie. heat, cool, idle."""
if not self._enabled:
return STATE_OFF
if self.ac_mode:
cooling = self._active and self._is_device_active
return STATE_COOL if cooling else STATE_IDLE
@ -143,6 +147,25 @@ class GenericThermostat(ClimateDevice):
"""Return the temperature we try to reach."""
return self._target_temp
@property
def operation_list(self):
"""List of available operation modes."""
return [STATE_AUTO, STATE_OFF]
def set_operation_mode(self, operation_mode):
"""Set operation mode."""
if operation_mode == STATE_AUTO:
self._enabled = True
elif operation_mode == STATE_OFF:
self._enabled = False
if self._is_device_active:
switch.async_turn_off(self.hass, self.heater_entity_id)
else:
_LOGGER.error('Unrecognized operation mode: %s', operation_mode)
return
# Ensure we updae the current operation after changing the mode
self.schedule_update_ha_state()
@asyncio.coroutine
def async_set_temperature(self, **kwargs):
"""Set new target temperature."""
@ -221,6 +244,9 @@ class GenericThermostat(ClimateDevice):
if not self._active:
return
if not self._enabled:
return
if self.min_cycle_duration:
if self._is_device_active:
current_state = STATE_ON

View file

@ -108,6 +108,12 @@ class TestClimateGenericThermostat(unittest.TestCase):
self.assertEqual(35, state.attributes.get('max_temp'))
self.assertEqual(None, state.attributes.get('temperature'))
def test_get_operation_modes(self):
"""Test that the operation list returns the correct modes."""
state = self.hass.states.get(ENTITY)
modes = state.attributes.get('operation_list')
self.assertEqual([climate.STATE_AUTO, STATE_OFF], modes)
def test_set_target_temp(self):
"""Test the setting of the target temperature."""
climate.set_temperature(self.hass, 30)
@ -211,6 +217,30 @@ class TestClimateGenericThermostat(unittest.TestCase):
self.assertEqual(SERVICE_TURN_OFF, call.service)
self.assertEqual(ENT_SWITCH, call.data['entity_id'])
def test_running_when_operating_mode_is_off(self):
"""Test that the switch turns off when enabled is set False."""
self._setup_switch(True)
climate.set_temperature(self.hass, 30)
self.hass.block_till_done()
climate.set_operation_mode(self.hass, STATE_OFF)
self.hass.block_till_done()
self.assertEqual(1, len(self.calls))
call = self.calls[0]
self.assertEqual('switch', call.domain)
self.assertEqual(SERVICE_TURN_OFF, call.service)
self.assertEqual(ENT_SWITCH, call.data['entity_id'])
def test_no_state_change_when_operation_mode_off(self):
"""Test that the switch doesn't turn on when enabled is False."""
self._setup_switch(False)
climate.set_temperature(self.hass, 30)
self.hass.block_till_done()
climate.set_operation_mode(self.hass, STATE_OFF)
self.hass.block_till_done()
self._setup_sensor(25)
self.hass.block_till_done()
self.assertEqual(0, len(self.calls))
def _setup_sensor(self, temp, unit=TEMP_CELSIUS):
"""Setup the test sensor."""
self.hass.states.set(ENT_SENSOR, temp, {
@ -321,6 +351,30 @@ class TestClimateGenericThermostatACMode(unittest.TestCase):
self.assertEqual(SERVICE_TURN_ON, call.service)
self.assertEqual(ENT_SWITCH, call.data['entity_id'])
def test_running_when_operating_mode_is_off(self):
"""Test that the switch turns off when enabled is set False."""
self._setup_switch(True)
climate.set_temperature(self.hass, 30)
self.hass.block_till_done()
climate.set_operation_mode(self.hass, STATE_OFF)
self.hass.block_till_done()
self.assertEqual(1, len(self.calls))
call = self.calls[0]
self.assertEqual('switch', call.domain)
self.assertEqual(SERVICE_TURN_OFF, call.service)
self.assertEqual(ENT_SWITCH, call.data['entity_id'])
def test_no_state_change_when_operation_mode_off(self):
"""Test that the switch doesn't turn on when enabled is False."""
self._setup_switch(False)
climate.set_temperature(self.hass, 30)
self.hass.block_till_done()
climate.set_operation_mode(self.hass, STATE_OFF)
self.hass.block_till_done()
self._setup_sensor(35)
self.hass.block_till_done()
self.assertEqual(0, len(self.calls))
def _setup_sensor(self, temp, unit=TEMP_CELSIUS):
"""Setup the test sensor."""
self.hass.states.set(ENT_SENSOR, temp, {