From 77490287e95323c75d777a87703ab250c1d53386 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 27 Aug 2020 23:59:49 -0500 Subject: [PATCH] Add the ability to reload generic_thermostat platforms from yaml (#39291) --- .../components/generic_thermostat/__init__.py | 3 ++ .../components/generic_thermostat/climate.py | 24 +++++++--- .../generic_thermostat/services.yaml | 2 + .../generic_thermostat/test_climate.py | 44 +++++++++++++++++++ .../generic_thermostat/configuration.yaml | 5 +++ 5 files changed, 72 insertions(+), 6 deletions(-) create mode 100644 tests/fixtures/generic_thermostat/configuration.yaml diff --git a/homeassistant/components/generic_thermostat/__init__.py b/homeassistant/components/generic_thermostat/__init__.py index d0bc392e4f4..69acb5bb1a5 100644 --- a/homeassistant/components/generic_thermostat/__init__.py +++ b/homeassistant/components/generic_thermostat/__init__.py @@ -1 +1,4 @@ """The generic_thermostat component.""" + +DOMAIN = "generic_thermostat" +PLATFORMS = ["climate"] diff --git a/homeassistant/components/generic_thermostat/climate.py b/homeassistant/components/generic_thermostat/climate.py index 31231d1ffb2..4072c43bc27 100644 --- a/homeassistant/components/generic_thermostat/climate.py +++ b/homeassistant/components/generic_thermostat/climate.py @@ -40,8 +40,11 @@ from homeassistant.helpers.event import ( async_track_state_change_event, async_track_time_interval, ) +from homeassistant.helpers.reload import async_setup_reload_service from homeassistant.helpers.restore_state import RestoreEntity +from . import DOMAIN, PLATFORMS + _LOGGER = logging.getLogger(__name__) DEFAULT_TOLERANCE = 0.3 @@ -88,6 +91,9 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( async def async_setup_platform(hass, config, async_add_entities, discovery_info=None): """Set up the generic thermostat platform.""" + + await async_setup_reload_service(hass, DOMAIN, PLATFORMS) + name = config.get(CONF_NAME) heater_entity_id = config.get(CONF_HEATER) sensor_entity_id = config.get(CONF_SENSOR) @@ -182,16 +188,22 @@ class GenericThermostat(ClimateEntity, RestoreEntity): await super().async_added_to_hass() # Add listener - async_track_state_change_event( - self.hass, [self.sensor_entity_id], self._async_sensor_changed + self.async_on_remove( + async_track_state_change_event( + self.hass, [self.sensor_entity_id], self._async_sensor_changed + ) ) - async_track_state_change_event( - self.hass, [self.heater_entity_id], self._async_switch_changed + self.async_on_remove( + async_track_state_change_event( + self.hass, [self.heater_entity_id], self._async_switch_changed + ) ) if self._keep_alive: - async_track_time_interval( - self.hass, self._async_control_heating, self._keep_alive + self.async_on_remove( + async_track_time_interval( + self.hass, self._async_control_heating, self._keep_alive + ) ) @callback diff --git a/homeassistant/components/generic_thermostat/services.yaml b/homeassistant/components/generic_thermostat/services.yaml index e69de29bb2d..fedcd268253 100644 --- a/homeassistant/components/generic_thermostat/services.yaml +++ b/homeassistant/components/generic_thermostat/services.yaml @@ -0,0 +1,2 @@ +reload: + description: Reload all generic_thermostat entities. diff --git a/tests/components/generic_thermostat/test_climate.py b/tests/components/generic_thermostat/test_climate.py index 313ff43ca6a..71842cf3b6d 100644 --- a/tests/components/generic_thermostat/test_climate.py +++ b/tests/components/generic_thermostat/test_climate.py @@ -1,10 +1,12 @@ """The tests for the generic_thermostat.""" import datetime +from os import path import pytest import pytz import voluptuous as vol +from homeassistant import config as hass_config from homeassistant.components import input_boolean, switch from homeassistant.components.climate.const import ( ATTR_PRESET_MODE, @@ -15,8 +17,12 @@ from homeassistant.components.climate.const import ( PRESET_AWAY, PRESET_NONE, ) +from homeassistant.components.generic_thermostat import ( + DOMAIN as GENERIC_THERMOSTAT_DOMAIN, +) from homeassistant.const import ( ATTR_TEMPERATURE, + SERVICE_RELOAD, SERVICE_TURN_OFF, SERVICE_TURN_ON, STATE_OFF, @@ -1246,3 +1252,41 @@ def _mock_restore_cache(hass, temperature=20, hvac_mode=HVAC_MODE_OFF): ), ), ) + + +async def test_reload(hass): + """Test we can reload.""" + + assert await async_setup_component( + hass, + DOMAIN, + { + "climate": { + "platform": "generic_thermostat", + "name": "test", + "heater": "switch.any", + "target_sensor": "sensor.any", + } + }, + ) + + await hass.async_block_till_done() + assert len(hass.states.async_all()) == 1 + assert hass.states.get("climate.test") is not None + + yaml_path = path.join( + _get_fixtures_base_path(), "fixtures", "generic_thermostat/configuration.yaml", + ) + with patch.object(hass_config, "YAML_CONFIG_FILE", yaml_path): + await hass.services.async_call( + GENERIC_THERMOSTAT_DOMAIN, SERVICE_RELOAD, {}, blocking=True, + ) + await hass.async_block_till_done() + + assert len(hass.states.async_all()) == 1 + assert hass.states.get("climate.test") is None + assert hass.states.get("climate.reload") + + +def _get_fixtures_base_path(): + return path.dirname(path.dirname(path.dirname(__file__))) diff --git a/tests/fixtures/generic_thermostat/configuration.yaml b/tests/fixtures/generic_thermostat/configuration.yaml new file mode 100644 index 00000000000..48b5ee2ed7b --- /dev/null +++ b/tests/fixtures/generic_thermostat/configuration.yaml @@ -0,0 +1,5 @@ +climate: + - platform: generic_thermostat + name: reload + heater: switch.any + target_sensor: sensor.any