Ignore attribute changes in automation trigger from/to (#7651)

* Ignore attribute changes in automation trigger from/to

* Quote names in deprecation warnings

This makes it somewhat easier to read if the suggestion happens to be
named "to".

* Add test with same state, new attribute value
This commit is contained in:
Anders Melchiorsen 2017-05-20 21:18:59 +02:00 committed by Adam Mills
parent adde9e6231
commit 81f0826550
3 changed files with 30 additions and 8 deletions

View File

@ -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

View File

@ -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)

View File

@ -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, {