Add the ability to reload filter platforms from yaml (#39267)

* Add the ability to reload filter platforms from yaml

* force in memory db

* fix listener leak on un-load
This commit is contained in:
J. Nick Koston 2020-08-25 20:55:45 -05:00 committed by GitHub
parent 215e3f2dab
commit eaac00acfc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 81 additions and 3 deletions

View File

@ -1 +1,4 @@
"""The filter component."""
DOMAIN = "filter"
PLATFORMS = ["sensor"]

View File

@ -25,9 +25,12 @@ from homeassistant.core import callback
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entity import Entity
from homeassistant.helpers.event import async_track_state_change_event
from homeassistant.helpers.reload import async_setup_reload_service
from homeassistant.util.decorator import Registry
import homeassistant.util.dt as dt_util
from . import DOMAIN, PLATFORMS
_LOGGER = logging.getLogger(__name__)
FILTER_NAME_RANGE = "range"
@ -150,6 +153,9 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
"""Set up the template sensors."""
await async_setup_reload_service(hass, DOMAIN, PLATFORMS)
name = config.get(CONF_NAME)
entity_id = config.get(CONF_ENTITY_ID)
@ -279,8 +285,10 @@ class SensorFilter(Entity):
for state in history_list:
self._update_filter_sensor_state(state, False)
async_track_state_change_event(
self.hass, [self._entity], self._update_filter_sensor_state_event
self.async_on_remove(
async_track_state_change_event(
self.hass, [self._entity], self._update_filter_sensor_state_event
)
)
@property

View File

@ -0,0 +1,2 @@
reload:
description: Reload all filter entities.

View File

@ -1,8 +1,11 @@
"""The test for the data filter sensor platform."""
from datetime import timedelta
from os import path
import unittest
from homeassistant import config as hass_config
from homeassistant.components.filter.sensor import (
DOMAIN,
LowPassFilter,
OutlierFilter,
RangeFilter,
@ -10,8 +13,9 @@ from homeassistant.components.filter.sensor import (
TimeSMAFilter,
TimeThrottleFilter,
)
from homeassistant.const import SERVICE_RELOAD
import homeassistant.core as ha
from homeassistant.setup import setup_component
from homeassistant.setup import async_setup_component, setup_component
import homeassistant.util.dt as dt_util
from tests.async_mock import patch
@ -307,3 +311,53 @@ class TestFilterSensor(unittest.TestCase):
for state in self.values:
filtered = filt.filter_state(state)
assert 21.5 == filtered.state
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": "filter",
"name": "test",
"entity_id": "sensor.test_monitored",
"filters": [
{"filter": "outlier", "window_size": 10, "radius": 4.0},
{"filter": "lowpass", "time_constant": 10, "precision": 2},
{"filter": "throttle", "window_size": 1},
],
}
},
)
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", "filter/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.filtered_realistic_humidity")
def _get_fixtures_base_path():
return path.dirname(path.dirname(path.dirname(__file__)))

View File

@ -0,0 +1,11 @@
sensor:
- platform: filter
name: "filtered realistic humidity"
entity_id: sensor.realistic_humidity
filters:
- filter: outlier
window_size: 4
radius: 4.0
- filter: lowpass
time_constant: 10
precision: 2