From dc84196202a4683881ddac9942fe1c9af6de3b5b Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Wed, 26 Aug 2020 07:52:19 -0500 Subject: [PATCH] Add the ability to reload statistics platforms from yaml (#39268) --- .../components/statistics/__init__.py | 3 + homeassistant/components/statistics/sensor.py | 12 +++- .../components/statistics/services.yaml | 2 + tests/components/statistics/test_sensor.py | 59 ++++++++++++++++++- tests/fixtures/statistics/configuration.yaml | 4 ++ 5 files changed, 75 insertions(+), 5 deletions(-) create mode 100644 homeassistant/components/statistics/services.yaml create mode 100644 tests/fixtures/statistics/configuration.yaml diff --git a/homeassistant/components/statistics/__init__.py b/homeassistant/components/statistics/__init__.py index 3f0f03b4909..ce5f959d731 100644 --- a/homeassistant/components/statistics/__init__.py +++ b/homeassistant/components/statistics/__init__.py @@ -1 +1,4 @@ """The statistics component.""" + +DOMAIN = "statistics" +PLATFORMS = ["sensor"] diff --git a/homeassistant/components/statistics/sensor.py b/homeassistant/components/statistics/sensor.py index 945e5ff89d1..11cddc88c87 100644 --- a/homeassistant/components/statistics/sensor.py +++ b/homeassistant/components/statistics/sensor.py @@ -23,8 +23,11 @@ from homeassistant.helpers.event import ( async_track_point_in_utc_time, async_track_state_change_event, ) +from homeassistant.helpers.reload import async_setup_reload_service from homeassistant.util import dt as dt_util +from . import DOMAIN, PLATFORMS + _LOGGER = logging.getLogger(__name__) ATTR_AVERAGE_CHANGE = "average_change" @@ -66,6 +69,9 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( async def async_setup_platform(hass, config, async_add_entities, discovery_info=None): """Set up the Statistics sensor.""" + + await async_setup_reload_service(hass, DOMAIN, PLATFORMS) + entity_id = config.get(CONF_ENTITY_ID) name = config.get(CONF_NAME) sampling_size = config.get(CONF_SAMPLING_SIZE) @@ -124,8 +130,10 @@ class StatisticsSensor(Entity): """Add listener and get recorded state.""" _LOGGER.debug("Startup for %s", self.entity_id) - async_track_state_change_event( - self.hass, [self._entity_id], async_stats_sensor_state_listener + self.async_on_remove( + async_track_state_change_event( + self.hass, [self._entity_id], async_stats_sensor_state_listener + ) ) if "recorder" in self.hass.config.components: diff --git a/homeassistant/components/statistics/services.yaml b/homeassistant/components/statistics/services.yaml new file mode 100644 index 00000000000..608e2991334 --- /dev/null +++ b/homeassistant/components/statistics/services.yaml @@ -0,0 +1,2 @@ +reload: + description: Reload all statistics entities. diff --git a/tests/components/statistics/test_sensor.py b/tests/components/statistics/test_sensor.py index 6d7f0963fa2..7a96ec4e2a4 100644 --- a/tests/components/statistics/test_sensor.py +++ b/tests/components/statistics/test_sensor.py @@ -1,14 +1,21 @@ """The test for the statistics sensor platform.""" from datetime import datetime, timedelta +from os import path import statistics import unittest import pytest +from homeassistant import config as hass_config from homeassistant.components import recorder -from homeassistant.components.statistics.sensor import StatisticsSensor -from homeassistant.const import ATTR_UNIT_OF_MEASUREMENT, STATE_UNKNOWN, TEMP_CELSIUS -from homeassistant.setup import setup_component +from homeassistant.components.statistics.sensor import DOMAIN, StatisticsSensor +from homeassistant.const import ( + ATTR_UNIT_OF_MEASUREMENT, + SERVICE_RELOAD, + STATE_UNKNOWN, + TEMP_CELSIUS, +) +from homeassistant.setup import async_setup_component, setup_component from homeassistant.util import dt as dt_util from tests.async_mock import patch @@ -442,3 +449,49 @@ class TestStatisticsSensor(unittest.TestCase): assert mock_data["return_time"] == state.attributes.get("max_age") + timedelta( hours=1 ) + + +async def test_reload(hass): + """Verify we can reload filter sensors.""" + await hass.async_add_executor_job( + init_recorder_component, hass + ) # force in memory db + + hass.states.async_set("sensor.test_monitored", 12345) + await async_setup_component( + hass, + "sensor", + { + "sensor": { + "platform": "statistics", + "name": "test", + "entity_id": "sensor.test_monitored", + "sampling_size": 100, + } + }, + ) + await hass.async_block_till_done() + await hass.async_start() + await hass.async_block_till_done() + + assert len(hass.states.async_all()) == 2 + + assert hass.states.get("sensor.test") + + yaml_path = path.join( + _get_fixtures_base_path(), "fixtures", "statistics/configuration.yaml", + ) + with patch.object(hass_config, "YAML_CONFIG_FILE", yaml_path): + await hass.services.async_call( + DOMAIN, SERVICE_RELOAD, {}, blocking=True, + ) + await hass.async_block_till_done() + + assert len(hass.states.async_all()) == 2 + + assert hass.states.get("sensor.test") is None + assert hass.states.get("sensor.cputest") + + +def _get_fixtures_base_path(): + return path.dirname(path.dirname(path.dirname(__file__))) diff --git a/tests/fixtures/statistics/configuration.yaml b/tests/fixtures/statistics/configuration.yaml new file mode 100644 index 00000000000..a6ce34377a0 --- /dev/null +++ b/tests/fixtures/statistics/configuration.yaml @@ -0,0 +1,4 @@ +sensor: + - platform: statistics + entity_id: sensor.cpu + name: cputest