Binary sensor for detecting linear trends (#9808)

* Trend sensor now uses linear regression to calculate trend

* Added numpy to trend sensor test requirements

* Added trendline tests

* Trend sensor now has max_samples attribute

* Trend sensor uses utcnow from HA utils

* Trend sensor now completes setup in async_added_to_hass

* Fixed linter issues

* Fixed broken import

* Trend tests make use of max_samples

* Added @asyncio.coroutine decorator to trend update callback

* Update trend.py
This commit is contained in:
Sam Birch 2017-10-26 04:33:17 +13:00 committed by Pascal Vizeli
parent 63c9d59d54
commit fc8940111d
5 changed files with 199 additions and 49 deletions

View file

@ -10,7 +10,7 @@ class TestTrendBinarySensor:
hass = None
def setup_method(self, method):
"""Setup things to be run when tests are started."""
"""Set up things to be run when tests are started."""
self.hass = get_test_home_assistant()
def teardown_method(self, method):
@ -38,6 +38,67 @@ class TestTrendBinarySensor:
state = self.hass.states.get('binary_sensor.test_trend_sensor')
assert state.state == 'on'
def test_up_using_trendline(self):
"""Test up trend using multiple samples and trendline calculation."""
assert setup.setup_component(self.hass, 'binary_sensor', {
'binary_sensor': {
'platform': 'trend',
'sensors': {
'test_trend_sensor': {
'entity_id': "sensor.test_state",
'sample_duration': 300,
'min_gradient': 1,
'max_samples': 25,
}
}
}
})
for val in [1, 0, 2, 3]:
self.hass.states.set('sensor.test_state', val)
self.hass.block_till_done()
state = self.hass.states.get('binary_sensor.test_trend_sensor')
assert state.state == 'on'
for val in [0, 1, 0, 0]:
self.hass.states.set('sensor.test_state', val)
self.hass.block_till_done()
state = self.hass.states.get('binary_sensor.test_trend_sensor')
assert state.state == 'off'
def test_down_using_trendline(self):
"""Test down trend using multiple samples and trendline calculation."""
assert setup.setup_component(self.hass, 'binary_sensor', {
'binary_sensor': {
'platform': 'trend',
'sensors': {
'test_trend_sensor': {
'entity_id': "sensor.test_state",
'sample_duration': 300,
'min_gradient': 1,
'max_samples': 25,
'invert': 'Yes'
}
}
}
})
for val in [3, 2, 3, 1]:
self.hass.states.set('sensor.test_state', val)
self.hass.block_till_done()
state = self.hass.states.get('binary_sensor.test_trend_sensor')
assert state.state == 'on'
for val in [4, 2, 4, 4]:
self.hass.states.set('sensor.test_state', val)
self.hass.block_till_done()
state = self.hass.states.get('binary_sensor.test_trend_sensor')
assert state.state == 'off'
def test_down(self):
"""Test down trend."""
assert setup.setup_component(self.hass, 'binary_sensor', {
@ -59,7 +120,7 @@ class TestTrendBinarySensor:
state = self.hass.states.get('binary_sensor.test_trend_sensor')
assert state.state == 'off'
def test__invert_up(self):
def test_invert_up(self):
"""Test up trend with custom message."""
assert setup.setup_component(self.hass, 'binary_sensor', {
'binary_sensor': {
@ -142,11 +203,33 @@ class TestTrendBinarySensor:
self.hass.states.set('sensor.test_state', 'State', {'attr': '2'})
self.hass.block_till_done()
self.hass.states.set('sensor.test_state', 'State', {'attr': '1'})
self.hass.block_till_done()
state = self.hass.states.get('binary_sensor.test_trend_sensor')
assert state.state == 'off'
def test_max_samples(self):
"""Test that sample count is limited correctly."""
assert setup.setup_component(self.hass, 'binary_sensor', {
'binary_sensor': {
'platform': 'trend',
'sensors': {
'test_trend_sensor': {
'entity_id': "sensor.test_state",
'max_samples': 3,
'min_gradient': -1,
}
}
}
})
for val in [0, 1, 2, 3, 2, 1]:
self.hass.states.set('sensor.test_state', val)
self.hass.block_till_done()
state = self.hass.states.get('binary_sensor.test_trend_sensor')
assert state.state == 'on'
assert state.attributes['sample_count'] == 3
def test_non_numeric(self):
"""Test up trend."""
assert setup.setup_component(self.hass, 'binary_sensor', {
@ -186,7 +269,6 @@ class TestTrendBinarySensor:
self.hass.states.set('sensor.test_state', 'State', {'attr': '2'})
self.hass.block_till_done()
self.hass.states.set('sensor.test_state', 'State', {'attr': '1'})
self.hass.block_till_done()
state = self.hass.states.get('binary_sensor.test_trend_sensor')
assert state.state == 'off'