From 4eba1250e9c9b7db3d2e979feb59d3a8d1f84c0a Mon Sep 17 00:00:00 2001 From: Stefan Jonasson Date: Sat, 12 Sep 2015 21:42:52 +0200 Subject: [PATCH] Added a numeric_state automation platform --- .../components/automation/numeric_state.py | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 homeassistant/components/automation/numeric_state.py diff --git a/homeassistant/components/automation/numeric_state.py b/homeassistant/components/automation/numeric_state.py new file mode 100644 index 00000000000..96c0dc5a5ce --- /dev/null +++ b/homeassistant/components/automation/numeric_state.py @@ -0,0 +1,61 @@ +""" +homeassistant.components.automation.state +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Offers state listening automation rules. +""" +import logging + +from homeassistant.helpers.event import track_state_change +from homeassistant.const import MATCH_ALL + + +CONF_ENTITY_ID = "state_entity_id" +CONF_BELOW = "state_below" +CONF_ABOVE = "state_above" + + +def register(hass, config, action): + """ Listen for state changes based on `config`. """ + entity_id = config.get(CONF_ENTITY_ID) + + if entity_id is None: + logging.getLogger(__name__).error( + "Missing configuration key %s", CONF_ENTITY_ID) + return False + + below = config.get(CONF_BELOW) + above = config.get(CONF_ABOVE) + + if below is None and above is None: + logging.getLogger(__name__).error( + "Missing configuration key %s or %s", CONF_BELOW, CONF_ABOVE) + + def numeric_in_range(value, range_start, range_end): + """ Checks if value is inside the range + :param value: + :param range_start: + :param range_end: + :return: + """ + value = float(value) + + 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 value > float(range_start) + + 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 numeric_in_range(to_s.state, above, below) and \ + from_s is None or not numeric_in_range(from_s.state, above, below): + action() + + track_state_change( + hass, entity_id, state_automation_listener) + + return True