diff --git a/homeassistant/components/automation/state.py b/homeassistant/components/automation/state.py index 9c12a37f9b8..185d44808c3 100644 --- a/homeassistant/components/automation/state.py +++ b/homeassistant/components/automation/state.py @@ -12,6 +12,7 @@ import homeassistant.util.dt as dt_util from homeassistant.const import MATCH_ALL, CONF_PLATFORM from homeassistant.helpers.event import ( async_track_state_change, async_track_point_in_utc_time) +from homeassistant.helpers.deprecation import get_deprecated import homeassistant.helpers.config_validation as cv CONF_ENTITY_ID = 'entity_id' @@ -40,7 +41,7 @@ def async_trigger(hass, config, action): """Listen for state changes based on configuration.""" entity_id = config.get(CONF_ENTITY_ID) from_state = config.get(CONF_FROM, MATCH_ALL) - to_state = config.get(CONF_TO) or config.get(CONF_STATE) or MATCH_ALL + to_state = get_deprecated(config, CONF_TO, CONF_STATE, MATCH_ALL) time_delta = config.get(CONF_FOR) async_remove_state_for_cancel = None async_remove_state_for_listener = None @@ -75,12 +76,13 @@ def async_trigger(hass, config, action): } }) - if time_delta is None: - call_action() + # Ignore changes to state attributes if from/to is in use + match_all = (from_state == MATCH_ALL and to_state == MATCH_ALL) + if not match_all and from_s.last_changed == to_s.last_changed: return - # If only state attributes changed, ignore this event - if from_s.last_changed == to_s.last_changed: + if time_delta is None: + call_action() return @callback diff --git a/homeassistant/helpers/deprecation.py b/homeassistant/helpers/deprecation.py index 88de3a48aa0..ee4176a8937 100644 --- a/homeassistant/helpers/deprecation.py +++ b/homeassistant/helpers/deprecation.py @@ -23,8 +23,8 @@ def deprecated_substitute(substitute_name): if not warnings.get(module_name): logger = logging.getLogger(module_name) logger.warning( - "%s is deprecated. Please rename %s to " - "%s in '%s' to ensure future support.", + "'%s' is deprecated. Please rename '%s' to " + "'%s' in '%s' to ensure future support.", substitute_name, substitute_name, func.__name__, inspect.getfile(self.__class__)) warnings[module_name] = True @@ -49,7 +49,7 @@ def get_deprecated(config, new_name, old_name, default=None): module_name = inspect.getmodule(inspect.stack()[1][0]).__name__ logger = logging.getLogger(module_name) logger.warning( - "%s is deprecated. Please rename %s to %s in your " + "'%s' is deprecated. Please rename '%s' to '%s' in your " "configuration file.", old_name, old_name, new_name) return config.get(old_name) return config.get(new_name, default) diff --git a/tests/components/automation/test_state.py b/tests/components/automation/test_state.py index cf715bc5e32..28473511e29 100644 --- a/tests/components/automation/test_state.py +++ b/tests/components/automation/test_state.py @@ -110,6 +110,26 @@ class TestAutomationState(unittest.TestCase): self.hass.block_till_done() self.assertEqual(1, len(self.calls)) + def test_if_fires_on_attribute_change_with_to_filter(self): + """Test for not firing on attribute change.""" + assert setup_component(self.hass, automation.DOMAIN, { + automation.DOMAIN: { + 'trigger': { + 'platform': 'state', + 'entity_id': 'test.entity', + 'to': 'world' + }, + 'action': { + 'service': 'test.automation' + } + } + }) + + self.hass.states.set('test.entity', 'world', {'test_attribute': 11}) + self.hass.states.set('test.entity', 'world', {'test_attribute': 12}) + self.hass.block_till_done() + self.assertEqual(1, len(self.calls)) + def test_if_fires_on_entity_change_with_state_filter(self): """Test for firing on entity change with state filter.""" assert setup_component(self.hass, automation.DOMAIN, {