diff --git a/homeassistant/components/history.py b/homeassistant/components/history.py index 578cb265a27..210590ea58c 100644 --- a/homeassistant/components/history.py +++ b/homeassistant/components/history.py @@ -11,7 +11,7 @@ from collections import defaultdict from datetime import timedelta from itertools import groupby -import homeassistant.components.recorder as recorder +from homeassistant.components import recorder, script import homeassistant.util.dt as dt_util from homeassistant.const import HTTP_BAD_REQUEST @@ -19,6 +19,7 @@ DOMAIN = 'history' DEPENDENCIES = ['recorder', 'http'] SIGNIFICANT_DOMAINS = ('thermostat',) +IGNORE_DOMAINS = ('zone', 'scene',) URL_HISTORY_PERIOD = re.compile( r'/api/history/period(?:/(?P\d{4}-\d{1,2}-\d{1,2})|)') @@ -46,9 +47,10 @@ def get_significant_states(start_time, end_time=None, entity_id=None): """ where = """ - (domain in ({}) or last_changed=last_updated) - AND last_updated > ? - """.format(",".join(["'%s'" % x for x in SIGNIFICANT_DOMAINS])) + (domain IN ({}) OR last_changed=last_updated) + AND domain NOT IN ({}) AND last_updated > ? + """.format(",".join("'%s'" % x for x in SIGNIFICANT_DOMAINS), + ",".join("'%s'" % x for x in IGNORE_DOMAINS)) data = [start_time] @@ -63,7 +65,8 @@ def get_significant_states(start_time, end_time=None, entity_id=None): query = ("SELECT * FROM states WHERE {} " "ORDER BY entity_id, last_updated ASC").format(where) - states = recorder.query_states(query, data) + states = (state for state in recorder.query_states(query, data) + if _is_significant(state)) return states_to_json(states, start_time, entity_id) @@ -200,3 +203,13 @@ def _api_history_period(handler, path_match, data): handler.write_json( get_significant_states(start_time, end_time, entity_id).values()) + + +def _is_significant(state): + """Test if state is significant for history charts. + + Will only test for things that are not filtered out in SQL. + """ + # scripts that are not cancellable will never change state + return (state.domain != 'script' or + state.attributes.get(script.ATTR_CAN_CANCEL)) diff --git a/tests/components/test_history.py b/tests/components/test_history.py index db0c154283d..3f781b9d30c 100644 --- a/tests/components/test_history.py +++ b/tests/components/test_history.py @@ -148,7 +148,7 @@ class TestComponentHistory(unittest.TestCase): """test that only significant states are returned with get_significant_states. - We inject a bunch of state updates from media player and + We inject a bunch of state updates from media player, zone and thermostat. We should get back every thermostat change that includes an attribute change, but only the state updates for media player (attribute changes are not significant and not returned). @@ -157,6 +157,9 @@ class TestComponentHistory(unittest.TestCase): self.init_recorder() mp = 'media_player.test' therm = 'thermostat.test' + zone = 'zone.home' + script_nc = 'script.cannot_cancel_this_one' + script_c = 'script.can_cancel_this_one' def set_state(entity_id, state, **kwargs): self.hass.states.set(entity_id, state, **kwargs) @@ -169,7 +172,7 @@ class TestComponentHistory(unittest.TestCase): three = two + timedelta(seconds=1) four = three + timedelta(seconds=1) - states = {therm: [], mp: []} + states = {therm: [], mp: [], script_c: []} with patch('homeassistant.components.recorder.dt_util.utcnow', return_value=one): states[mp].append( @@ -186,6 +189,11 @@ class TestComponentHistory(unittest.TestCase): # this state will be skipped only different in time set_state(mp, 'YouTube', attributes={'media_title': str(sentinel.mt3)}) + # this state will be skipped because domain blacklisted + set_state(zone, 'zoning') + set_state(script_nc, 'off') + states[script_c].append( + set_state(script_c, 'off', attributes={'can_cancel': True})) states[therm].append( set_state(therm, 21, attributes={'current_temperature': 19.8})) @@ -199,4 +207,4 @@ class TestComponentHistory(unittest.TestCase): set_state(therm, 21, attributes={'current_temperature': 20})) hist = history.get_significant_states(zero, four) - self.assertEqual(states, hist) + assert states == hist