Implemented the if condition support in numeric state

This commit is contained in:
Stefan Jonasson 2015-09-14 20:33:01 +02:00
parent dd71e4fdd1
commit d5198d4242
2 changed files with 84 additions and 24 deletions

View file

@ -1,8 +1,8 @@
"""
homeassistant.components.automation.state
homeassistant.components.automation.numeric_state
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Offers state listening automation rules.
Offers numeric state listening automation rules.
"""
import logging
@ -33,13 +33,51 @@ def trigger(hass, config, action):
CONF_BELOW, CONF_ABOVE)
return False
def _in_range(value, range_start, range_end):
""" Checks if value is inside the range
:param value:
:param range_start:
:param range_end:
:return:
"""
# pylint: disable=unused-argument
def state_automation_listener(entity, from_s, to_s):
""" Listens for state changes and calls action. """
# Fire action if we go from outside range into range
if _in_range(to_s.state, above, below) and \
(from_s is None or not _in_range(from_s.state, above, below)):
action()
track_state_change(
hass, entity_id, state_automation_listener)
return True
def if_action(hass, config, action):
""" Wraps action method with state based condition. """
entity_id = config.get(CONF_ENTITY_ID)
if entity_id is None:
_LOGGER.error("Missing configuration key %s", CONF_ENTITY_ID)
return action
below = config.get(CONF_BELOW)
above = config.get(CONF_ABOVE)
if below is None and above is None:
_LOGGER.error("Missing configuration key."
" One of %s or %s is required",
CONF_BELOW, CONF_ABOVE)
return action
def state_if():
""" Execute action if state matches. """
state = hass.states.get(entity_id)
if state is None or _in_range(state.state, above, below):
action()
return state_if
def _in_range(value, range_start, range_end):
""" Checks if value is inside the range """
try:
value = float(value)
@ -53,16 +91,3 @@ def trigger(hass, config, action):
return value < float(range_end)
else:
return float(range_start) <= value
def state_automation_listener(entity, from_s, to_s):
""" Listens for state changes and calls action. """
# Fire action if we go from outside range into range
if _in_range(to_s.state, above, below) and \
(from_s is None or not _in_range(from_s.state, above, below)):
action()
track_state_change(
hass, entity_id, state_automation_listener)
return True

View file

@ -8,7 +8,7 @@ import unittest
import homeassistant.core as ha
import homeassistant.components.automation as automation
import homeassistant.components.automation.numeric_state as numeric_state
from homeassistant.components.automation import event, numeric_state
from homeassistant.const import CONF_PLATFORM
@ -232,3 +232,38 @@ class TestAutomationNumericState(unittest.TestCase):
self.hass.states.set('test.entity', 11)
self.hass.pool.block_till_done()
self.assertEqual(0, len(self.calls))
def test_if_action(self):
entity_id = 'domain.test_entity'
test_state = 10
automation.setup(self.hass, {
automation.DOMAIN: {
CONF_PLATFORM: 'event',
event.CONF_EVENT_TYPE: 'test_event',
automation.CONF_SERVICE: 'test.automation',
automation.CONF_IF: [{
CONF_PLATFORM: 'numeric_state',
numeric_state.CONF_ENTITY_ID: entity_id,
numeric_state.CONF_ABOVE: test_state,
numeric_state.CONF_BELOW: test_state + 2,
}]
}
})
self.hass.states.set(entity_id, test_state )
self.hass.bus.fire('test_event')
self.hass.pool.block_till_done()
self.assertEqual(1, len(self.calls))
self.hass.states.set(entity_id, test_state - 1)
self.hass.bus.fire('test_event')
self.hass.pool.block_till_done()
self.assertEqual(1, len(self.calls))
self.hass.states.set(entity_id, test_state + 1)
self.hass.bus.fire('test_event')
self.hass.pool.block_till_done()
self.assertEqual(2, len(self.calls))