mirror of
https://github.com/home-assistant/core.git
synced 2025-07-14 08:47:10 +00:00
Add time_throttle filter to sensor.filter (#20334)
* Added time_throttle filter * Added time_throttle filter test * Updated comments for time_throttle filter
This commit is contained in:
parent
c94834d8f6
commit
d4c7515681
@ -32,6 +32,7 @@ FILTER_NAME_RANGE = 'range'
|
|||||||
FILTER_NAME_LOWPASS = 'lowpass'
|
FILTER_NAME_LOWPASS = 'lowpass'
|
||||||
FILTER_NAME_OUTLIER = 'outlier'
|
FILTER_NAME_OUTLIER = 'outlier'
|
||||||
FILTER_NAME_THROTTLE = 'throttle'
|
FILTER_NAME_THROTTLE = 'throttle'
|
||||||
|
FILTER_NAME_TIME_THROTTLE = 'time_throttle'
|
||||||
FILTER_NAME_TIME_SMA = 'time_simple_moving_average'
|
FILTER_NAME_TIME_SMA = 'time_simple_moving_average'
|
||||||
FILTERS = Registry()
|
FILTERS = Registry()
|
||||||
|
|
||||||
@ -101,6 +102,12 @@ FILTER_THROTTLE_SCHEMA = FILTER_SCHEMA.extend({
|
|||||||
default=DEFAULT_WINDOW_SIZE): vol.Coerce(int),
|
default=DEFAULT_WINDOW_SIZE): vol.Coerce(int),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
FILTER_TIME_THROTTLE_SCHEMA = FILTER_SCHEMA.extend({
|
||||||
|
vol.Required(CONF_FILTER_NAME): FILTER_NAME_TIME_THROTTLE,
|
||||||
|
vol.Required(CONF_FILTER_WINDOW_SIZE): vol.All(cv.time_period,
|
||||||
|
cv.positive_timedelta)
|
||||||
|
})
|
||||||
|
|
||||||
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
||||||
vol.Required(CONF_ENTITY_ID): cv.entity_id,
|
vol.Required(CONF_ENTITY_ID): cv.entity_id,
|
||||||
vol.Optional(CONF_NAME): cv.string,
|
vol.Optional(CONF_NAME): cv.string,
|
||||||
@ -109,6 +116,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
|||||||
FILTER_LOWPASS_SCHEMA,
|
FILTER_LOWPASS_SCHEMA,
|
||||||
FILTER_TIME_SMA_SCHEMA,
|
FILTER_TIME_SMA_SCHEMA,
|
||||||
FILTER_THROTTLE_SCHEMA,
|
FILTER_THROTTLE_SCHEMA,
|
||||||
|
FILTER_TIME_THROTTLE_SCHEMA,
|
||||||
FILTER_RANGE_SCHEMA)])
|
FILTER_RANGE_SCHEMA)])
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -444,7 +452,7 @@ class TimeSMAFilter(Filter):
|
|||||||
The window_size is determined by time, and SMA is time weighted.
|
The window_size is determined by time, and SMA is time weighted.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
variant (enum): type of argorithm used to connect discrete values
|
type (enum): type of algorithm used to connect discrete values
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, window_size, precision, entity,
|
def __init__(self, window_size, precision, entity,
|
||||||
@ -502,3 +510,29 @@ class ThrottleFilter(Filter):
|
|||||||
self._skip_processing = True
|
self._skip_processing = True
|
||||||
|
|
||||||
return new_state
|
return new_state
|
||||||
|
|
||||||
|
|
||||||
|
@FILTERS.register(FILTER_NAME_TIME_THROTTLE)
|
||||||
|
class TimeThrottleFilter(Filter):
|
||||||
|
"""Time Throttle Filter.
|
||||||
|
|
||||||
|
One sample per time period.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, window_size, precision, entity):
|
||||||
|
"""Initialize Filter."""
|
||||||
|
super().__init__(FILTER_NAME_TIME_THROTTLE,
|
||||||
|
window_size, precision, entity)
|
||||||
|
self._time_window = window_size
|
||||||
|
self._last_emitted_at = None
|
||||||
|
|
||||||
|
def _filter_state(self, new_state):
|
||||||
|
"""Implement the filter."""
|
||||||
|
window_start = new_state.timestamp - self._time_window
|
||||||
|
if not self._last_emitted_at or self._last_emitted_at <= window_start:
|
||||||
|
self._last_emitted_at = new_state.timestamp
|
||||||
|
self._skip_processing = False
|
||||||
|
else:
|
||||||
|
self._skip_processing = True
|
||||||
|
|
||||||
|
return new_state
|
||||||
|
@ -5,7 +5,7 @@ from unittest.mock import patch
|
|||||||
|
|
||||||
from homeassistant.components.sensor.filter import (
|
from homeassistant.components.sensor.filter import (
|
||||||
LowPassFilter, OutlierFilter, ThrottleFilter, TimeSMAFilter,
|
LowPassFilter, OutlierFilter, ThrottleFilter, TimeSMAFilter,
|
||||||
RangeFilter)
|
RangeFilter, TimeThrottleFilter)
|
||||||
import homeassistant.util.dt as dt_util
|
import homeassistant.util.dt as dt_util
|
||||||
from homeassistant.setup import setup_component
|
from homeassistant.setup import setup_component
|
||||||
import homeassistant.core as ha
|
import homeassistant.core as ha
|
||||||
@ -178,6 +178,18 @@ class TestFilterSensor(unittest.TestCase):
|
|||||||
filtered.append(new_state)
|
filtered.append(new_state)
|
||||||
assert [20, 21] == [f.state for f in filtered]
|
assert [20, 21] == [f.state for f in filtered]
|
||||||
|
|
||||||
|
def test_time_throttle(self):
|
||||||
|
"""Test if lowpass filter works."""
|
||||||
|
filt = TimeThrottleFilter(window_size=timedelta(minutes=2),
|
||||||
|
precision=2,
|
||||||
|
entity=None)
|
||||||
|
filtered = []
|
||||||
|
for state in self.values:
|
||||||
|
new_state = filt.filter_state(state)
|
||||||
|
if not filt.skip_processing:
|
||||||
|
filtered.append(new_state)
|
||||||
|
assert [20, 18, 22] == [f.state for f in filtered]
|
||||||
|
|
||||||
def test_time_sma(self):
|
def test_time_sma(self):
|
||||||
"""Test if time_sma filter works."""
|
"""Test if time_sma filter works."""
|
||||||
filt = TimeSMAFilter(window_size=timedelta(minutes=2),
|
filt = TimeSMAFilter(window_size=timedelta(minutes=2),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user