From d5198d424253fe6f241dbfec757bcf2df08c53e2 Mon Sep 17 00:00:00 2001 From: Stefan Jonasson Date: Mon, 14 Sep 2015 20:33:01 +0200 Subject: [PATCH] Implemented the if condition support in numeric state --- .../components/automation/numeric_state.py | 71 +++++++++++++------ .../automation/test_numeric_state.py | 37 +++++++++- 2 files changed, 84 insertions(+), 24 deletions(-) diff --git a/homeassistant/components/automation/numeric_state.py b/homeassistant/components/automation/numeric_state.py index 127f3cc99a1..417ffffff7d 100644 --- a/homeassistant/components/automation/numeric_state.py +++ b/homeassistant/components/automation/numeric_state.py @@ -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,27 +33,7 @@ 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: - """ - - try: - value = float(value) - except ValueError: - _LOGGER.warn("Missing value in numeric check") - return False - - if range_start is not None and range_end is not None: - return float(range_start) <= value < float(range_end) - elif range_end is not None: - return value < float(range_end) - else: - return float(range_start) <= value - + # pylint: disable=unused-argument def state_automation_listener(entity, from_s, to_s): """ Listens for state changes and calls action. """ @@ -66,3 +46,48 @@ def trigger(hass, config, action): 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) + except ValueError: + _LOGGER.warn("Missing value in numeric check") + return False + + if range_start is not None and range_end is not None: + return float(range_start) <= value < float(range_end) + elif range_end is not None: + return value < float(range_end) + else: + return float(range_start) <= value diff --git a/tests/components/automation/test_numeric_state.py b/tests/components/automation/test_numeric_state.py index 0b3a0bfba63..19a0f183876 100644 --- a/tests/components/automation/test_numeric_state.py +++ b/tests/components/automation/test_numeric_state.py @@ -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))