diff --git a/homeassistant/components/climate/generic_thermostat.py b/homeassistant/components/climate/generic_thermostat.py index 0c0c837b850..4b86fa4067b 100644 --- a/homeassistant/components/climate/generic_thermostat.py +++ b/homeassistant/components/climate/generic_thermostat.py @@ -10,13 +10,13 @@ import logging import voluptuous as vol from homeassistant.core import callback -from homeassistant.components import switch +from homeassistant.core import DOMAIN as HA_DOMAIN from homeassistant.components.climate import ( 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) + CONF_NAME, ATTR_ENTITY_ID, SERVICE_TURN_ON, SERVICE_TURN_OFF) from homeassistant.helpers import condition from homeassistant.helpers.event import ( async_track_state_change, async_track_time_interval) @@ -167,7 +167,7 @@ class GenericThermostat(ClimateDevice): elif operation_mode == STATE_OFF: self._enabled = False if self._is_device_active: - switch.async_turn_off(self.hass, self.heater_entity_id) + self._heater_turn_off() else: _LOGGER.error('Unrecognized operation mode: %s', operation_mode) return @@ -225,9 +225,9 @@ class GenericThermostat(ClimateDevice): def _async_keep_alive(self, time): """Call at constant intervals for keep-alive purposes.""" if self.current_operation in [STATE_COOL, STATE_HEAT]: - switch.async_turn_on(self.hass, self.heater_entity_id) + self._heater_turn_on() else: - switch.async_turn_off(self.hass, self.heater_entity_id) + self._heater_turn_off() @callback def _async_update_temp(self, state): @@ -273,13 +273,13 @@ class GenericThermostat(ClimateDevice): self._cold_tolerance if too_cold: _LOGGER.info('Turning off AC %s', self.heater_entity_id) - switch.async_turn_off(self.hass, self.heater_entity_id) + self._heater_turn_off() else: too_hot = self._cur_temp - self._target_temp >= \ self._hot_tolerance if too_hot: _LOGGER.info('Turning on AC %s', self.heater_entity_id) - switch.async_turn_on(self.hass, self.heater_entity_id) + self._heater_turn_on() else: is_heating = self._is_device_active if is_heating: @@ -288,15 +288,29 @@ class GenericThermostat(ClimateDevice): if too_hot: _LOGGER.info('Turning off heater %s', self.heater_entity_id) - switch.async_turn_off(self.hass, self.heater_entity_id) + self._heater_turn_off() else: too_cold = self._target_temp - self._cur_temp >= \ self._cold_tolerance if too_cold: _LOGGER.info('Turning on heater %s', self.heater_entity_id) - switch.async_turn_on(self.hass, self.heater_entity_id) + self._heater_turn_on() @property def _is_device_active(self): """If the toggleable device is currently active.""" - return switch.is_on(self.hass, self.heater_entity_id) + return self.hass.states.is_state(self.heater_entity_id, STATE_ON) + + @callback + def _heater_turn_on(self): + """Turn heater toggleable device on.""" + data = {ATTR_ENTITY_ID: self.heater_entity_id} + self.hass.async_add_job( + self.hass.services.async_call(HA_DOMAIN, SERVICE_TURN_ON, data)) + + @callback + def _heater_turn_off(self): + """Turn heater toggleable device off.""" + data = {ATTR_ENTITY_ID: self.heater_entity_id} + self.hass.async_add_job( + self.hass.services.async_call(HA_DOMAIN, SERVICE_TURN_OFF, data)) diff --git a/tests/components/climate/test_generic_thermostat.py b/tests/components/climate/test_generic_thermostat.py index bb42ef177f0..25887211253 100644 --- a/tests/components/climate/test_generic_thermostat.py +++ b/tests/components/climate/test_generic_thermostat.py @@ -16,9 +16,11 @@ from homeassistant.const import ( STATE_OFF, TEMP_CELSIUS, ) +from homeassistant import loader from homeassistant.util.unit_system import METRIC_SYSTEM -from homeassistant.components import climate - +from homeassistant.util.async import run_coroutine_threadsafe +from homeassistant.components import climate, input_boolean, switch +import homeassistant.components as comps from tests.common import assert_setup_component, get_test_home_assistant @@ -82,6 +84,82 @@ class TestSetupClimateGenericThermostat(unittest.TestCase): self.assertEqual(22.0, state.attributes.get('current_temperature')) +class TestGenericThermostatHeaterSwitching(unittest.TestCase): + """Test the Generic thermostat heater switching. + + Different toggle type devices are tested. + """ + + def setUp(self): # pylint: disable=invalid-name + """Setup things to be run when tests are started.""" + self.hass = get_test_home_assistant() + self.hass.config.units = METRIC_SYSTEM + self.assertTrue(run_coroutine_threadsafe( + comps.async_setup(self.hass, {}), self.hass.loop + ).result()) + + def tearDown(self): # pylint: disable=invalid-name + """Stop down everything that was started.""" + self.hass.stop() + + def test_heater_input_boolean(self): + """Test heater switching input_boolean.""" + heater_switch = 'input_boolean.test' + assert setup_component(self.hass, input_boolean.DOMAIN, + {'input_boolean': {'test': None}}) + + assert setup_component(self.hass, climate.DOMAIN, {'climate': { + 'platform': 'generic_thermostat', + 'name': 'test', + 'heater': heater_switch, + 'target_sensor': ENT_SENSOR + }}) + + self.assertEqual(STATE_OFF, + self.hass.states.get(heater_switch).state) + + self._setup_sensor(18) + self.hass.block_till_done() + climate.set_temperature(self.hass, 23) + self.hass.block_till_done() + + self.assertEqual(STATE_ON, + self.hass.states.get(heater_switch).state) + + def test_heater_switch(self): + """Test heater switching test switch.""" + platform = loader.get_component('switch.test') + platform.init() + self.switch_1 = platform.DEVICES[1] + assert setup_component(self.hass, switch.DOMAIN, {'switch': { + 'platform': 'test'}}) + heater_switch = self.switch_1.entity_id + + assert setup_component(self.hass, climate.DOMAIN, {'climate': { + 'platform': 'generic_thermostat', + 'name': 'test', + 'heater': heater_switch, + 'target_sensor': ENT_SENSOR + }}) + + self.assertEqual(STATE_OFF, + self.hass.states.get(heater_switch).state) + + self._setup_sensor(18) + self.hass.block_till_done() + climate.set_temperature(self.hass, 23) + self.hass.block_till_done() + + self.assertEqual(STATE_ON, + self.hass.states.get(heater_switch).state) + + def _setup_sensor(self, temp, unit=TEMP_CELSIUS): + """Setup the test sensor.""" + self.hass.states.set(ENT_SENSOR, temp, { + ATTR_UNIT_OF_MEASUREMENT: unit + }) + + class TestClimateGenericThermostat(unittest.TestCase): """Test the Generic thermostat.""" @@ -161,7 +239,7 @@ class TestClimateGenericThermostat(unittest.TestCase): self.hass.block_till_done() self.assertEqual(1, len(self.calls)) call = self.calls[0] - self.assertEqual('switch', call.domain) + self.assertEqual('homeassistant', call.domain) self.assertEqual(SERVICE_TURN_ON, call.service) self.assertEqual(ENT_SWITCH, call.data['entity_id']) @@ -174,7 +252,7 @@ class TestClimateGenericThermostat(unittest.TestCase): self.hass.block_till_done() self.assertEqual(1, len(self.calls)) call = self.calls[0] - self.assertEqual('switch', call.domain) + self.assertEqual('homeassistant', call.domain) self.assertEqual(SERVICE_TURN_OFF, call.service) self.assertEqual(ENT_SWITCH, call.data['entity_id']) @@ -196,7 +274,7 @@ class TestClimateGenericThermostat(unittest.TestCase): self.hass.block_till_done() self.assertEqual(1, len(self.calls)) call = self.calls[0] - self.assertEqual('switch', call.domain) + self.assertEqual('homeassistant', call.domain) self.assertEqual(SERVICE_TURN_ON, call.service) self.assertEqual(ENT_SWITCH, call.data['entity_id']) @@ -218,7 +296,7 @@ class TestClimateGenericThermostat(unittest.TestCase): self.hass.block_till_done() self.assertEqual(1, len(self.calls)) call = self.calls[0] - self.assertEqual('switch', call.domain) + self.assertEqual('homeassistant', call.domain) self.assertEqual(SERVICE_TURN_OFF, call.service) self.assertEqual(ENT_SWITCH, call.data['entity_id']) @@ -231,7 +309,7 @@ class TestClimateGenericThermostat(unittest.TestCase): self.hass.block_till_done() self.assertEqual(1, len(self.calls)) call = self.calls[0] - self.assertEqual('switch', call.domain) + self.assertEqual('homeassistant', call.domain) self.assertEqual(SERVICE_TURN_OFF, call.service) self.assertEqual(ENT_SWITCH, call.data['entity_id']) @@ -267,7 +345,7 @@ class TestClimateGenericThermostat(unittest.TestCase): self.hass.block_till_done() self.assertEqual(1, len(self.calls)) call = self.calls[0] - self.assertEqual('switch', call.domain) + self.assertEqual('homeassistant', call.domain) self.assertEqual(SERVICE_TURN_ON, call.service) self.assertEqual(ENT_SWITCH, call.data['entity_id']) @@ -287,8 +365,8 @@ class TestClimateGenericThermostat(unittest.TestCase): """Log service calls.""" self.calls.append(call) - self.hass.services.register('switch', SERVICE_TURN_ON, log_call) - self.hass.services.register('switch', SERVICE_TURN_OFF, log_call) + self.hass.services.register(ha.DOMAIN, SERVICE_TURN_ON, log_call) + self.hass.services.register(ha.DOMAIN, SERVICE_TURN_OFF, log_call) class TestClimateGenericThermostatACMode(unittest.TestCase): @@ -321,7 +399,7 @@ class TestClimateGenericThermostatACMode(unittest.TestCase): self.hass.block_till_done() self.assertEqual(1, len(self.calls)) call = self.calls[0] - self.assertEqual('switch', call.domain) + self.assertEqual('homeassistant', call.domain) self.assertEqual(SERVICE_TURN_OFF, call.service) self.assertEqual(ENT_SWITCH, call.data['entity_id']) @@ -334,7 +412,7 @@ class TestClimateGenericThermostatACMode(unittest.TestCase): self.hass.block_till_done() self.assertEqual(1, len(self.calls)) call = self.calls[0] - self.assertEqual('switch', call.domain) + self.assertEqual('homeassistant', call.domain) self.assertEqual(SERVICE_TURN_ON, call.service) self.assertEqual(ENT_SWITCH, call.data['entity_id']) @@ -356,7 +434,7 @@ class TestClimateGenericThermostatACMode(unittest.TestCase): self.hass.block_till_done() self.assertEqual(1, len(self.calls)) call = self.calls[0] - self.assertEqual('switch', call.domain) + self.assertEqual('homeassistant', call.domain) self.assertEqual(SERVICE_TURN_OFF, call.service) self.assertEqual(ENT_SWITCH, call.data['entity_id']) @@ -378,7 +456,7 @@ class TestClimateGenericThermostatACMode(unittest.TestCase): self.hass.block_till_done() self.assertEqual(1, len(self.calls)) call = self.calls[0] - self.assertEqual('switch', call.domain) + self.assertEqual('homeassistant', call.domain) self.assertEqual(SERVICE_TURN_ON, call.service) self.assertEqual(ENT_SWITCH, call.data['entity_id']) @@ -391,7 +469,7 @@ class TestClimateGenericThermostatACMode(unittest.TestCase): self.hass.block_till_done() self.assertEqual(1, len(self.calls)) call = self.calls[0] - self.assertEqual('switch', call.domain) + self.assertEqual('homeassistant', call.domain) self.assertEqual(SERVICE_TURN_OFF, call.service) self.assertEqual(ENT_SWITCH, call.data['entity_id']) @@ -422,8 +500,8 @@ class TestClimateGenericThermostatACMode(unittest.TestCase): """Log service calls.""" self.calls.append(call) - self.hass.services.register('switch', SERVICE_TURN_ON, log_call) - self.hass.services.register('switch', SERVICE_TURN_OFF, log_call) + self.hass.services.register(ha.DOMAIN, SERVICE_TURN_ON, log_call) + self.hass.services.register(ha.DOMAIN, SERVICE_TURN_OFF, log_call) class TestClimateGenericThermostatACModeMinCycle(unittest.TestCase): @@ -470,7 +548,7 @@ class TestClimateGenericThermostatACModeMinCycle(unittest.TestCase): self.hass.block_till_done() self.assertEqual(1, len(self.calls)) call = self.calls[0] - self.assertEqual('switch', call.domain) + self.assertEqual('homeassistant', call.domain) self.assertEqual(SERVICE_TURN_ON, call.service) self.assertEqual(ENT_SWITCH, call.data['entity_id']) @@ -496,7 +574,7 @@ class TestClimateGenericThermostatACModeMinCycle(unittest.TestCase): self.hass.block_till_done() self.assertEqual(1, len(self.calls)) call = self.calls[0] - self.assertEqual('switch', call.domain) + self.assertEqual('homeassistant', call.domain) self.assertEqual(SERVICE_TURN_OFF, call.service) self.assertEqual(ENT_SWITCH, call.data['entity_id']) @@ -516,8 +594,8 @@ class TestClimateGenericThermostatACModeMinCycle(unittest.TestCase): """Log service calls.""" self.calls.append(call) - self.hass.services.register('switch', SERVICE_TURN_ON, log_call) - self.hass.services.register('switch', SERVICE_TURN_OFF, log_call) + self.hass.services.register(ha.DOMAIN, SERVICE_TURN_ON, log_call) + self.hass.services.register(ha.DOMAIN, SERVICE_TURN_OFF, log_call) class TestClimateGenericThermostatMinCycle(unittest.TestCase): @@ -572,7 +650,7 @@ class TestClimateGenericThermostatMinCycle(unittest.TestCase): self.hass.block_till_done() self.assertEqual(1, len(self.calls)) call = self.calls[0] - self.assertEqual('switch', call.domain) + self.assertEqual('homeassistant', call.domain) self.assertEqual(SERVICE_TURN_ON, call.service) self.assertEqual(ENT_SWITCH, call.data['entity_id']) @@ -589,7 +667,7 @@ class TestClimateGenericThermostatMinCycle(unittest.TestCase): self.hass.block_till_done() self.assertEqual(1, len(self.calls)) call = self.calls[0] - self.assertEqual('switch', call.domain) + self.assertEqual('homeassistant', call.domain) self.assertEqual(SERVICE_TURN_OFF, call.service) self.assertEqual(ENT_SWITCH, call.data['entity_id']) @@ -609,8 +687,8 @@ class TestClimateGenericThermostatMinCycle(unittest.TestCase): """Log service calls.""" self.calls.append(call) - self.hass.services.register('switch', SERVICE_TURN_ON, log_call) - self.hass.services.register('switch', SERVICE_TURN_OFF, log_call) + self.hass.services.register(ha.DOMAIN, SERVICE_TURN_ON, log_call) + self.hass.services.register(ha.DOMAIN, SERVICE_TURN_OFF, log_call) class TestClimateGenericThermostatACKeepAlive(unittest.TestCase): @@ -654,7 +732,7 @@ class TestClimateGenericThermostatACKeepAlive(unittest.TestCase): self.hass.block_till_done() self.assertEqual(1, len(self.calls)) call = self.calls[0] - self.assertEqual('switch', call.domain) + self.assertEqual('homeassistant', call.domain) self.assertEqual(SERVICE_TURN_ON, call.service) self.assertEqual(ENT_SWITCH, call.data['entity_id']) @@ -677,7 +755,7 @@ class TestClimateGenericThermostatACKeepAlive(unittest.TestCase): self.hass.block_till_done() self.assertEqual(1, len(self.calls)) call = self.calls[0] - self.assertEqual('switch', call.domain) + self.assertEqual('homeassistant', call.domain) self.assertEqual(SERVICE_TURN_OFF, call.service) self.assertEqual(ENT_SWITCH, call.data['entity_id']) @@ -701,8 +779,8 @@ class TestClimateGenericThermostatACKeepAlive(unittest.TestCase): """Log service calls.""" self.calls.append(call) - self.hass.services.register('switch', SERVICE_TURN_ON, log_call) - self.hass.services.register('switch', SERVICE_TURN_OFF, log_call) + self.hass.services.register(ha.DOMAIN, SERVICE_TURN_ON, log_call) + self.hass.services.register(ha.DOMAIN, SERVICE_TURN_OFF, log_call) class TestClimateGenericThermostatKeepAlive(unittest.TestCase): @@ -745,7 +823,7 @@ class TestClimateGenericThermostatKeepAlive(unittest.TestCase): self.hass.block_till_done() self.assertEqual(1, len(self.calls)) call = self.calls[0] - self.assertEqual('switch', call.domain) + self.assertEqual('homeassistant', call.domain) self.assertEqual(SERVICE_TURN_ON, call.service) self.assertEqual(ENT_SWITCH, call.data['entity_id']) @@ -768,7 +846,7 @@ class TestClimateGenericThermostatKeepAlive(unittest.TestCase): self.hass.block_till_done() self.assertEqual(1, len(self.calls)) call = self.calls[0] - self.assertEqual('switch', call.domain) + self.assertEqual('homeassistant', call.domain) self.assertEqual(SERVICE_TURN_OFF, call.service) self.assertEqual(ENT_SWITCH, call.data['entity_id']) @@ -792,8 +870,8 @@ class TestClimateGenericThermostatKeepAlive(unittest.TestCase): """Log service calls.""" self.calls.append(call) - self.hass.services.register('switch', SERVICE_TURN_ON, log_call) - self.hass.services.register('switch', SERVICE_TURN_OFF, log_call) + self.hass.services.register(ha.DOMAIN, SERVICE_TURN_ON, log_call) + self.hass.services.register(ha.DOMAIN, SERVICE_TURN_OFF, log_call) @asyncio.coroutine