Filter the history of device_tracker by location attributes (#33356)

* Add include_location_attributes

* Add check for different state

* Fix things

* Drop filter

* significant changes only

* Change default behavior

* Remove trailing commas
pull/33435/head
Santobert 2020-03-30 17:13:22 +02:00 committed by GitHub
parent f42804805c
commit 0186ce7896
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 71 additions and 7 deletions

View File

@ -39,7 +39,7 @@ CONFIG_SCHEMA = vol.Schema(
extra=vol.ALLOW_EXTRA,
)
SIGNIFICANT_DOMAINS = ("thermostat", "climate", "water_heater")
SIGNIFICANT_DOMAINS = ("climate", "device_tracker", "thermostat", "water_heater")
IGNORE_DOMAINS = ("zone", "scene")
@ -50,6 +50,7 @@ def get_significant_states(
entity_ids=None,
filters=None,
include_start_time_state=True,
significant_changes_only=True,
):
"""
Return states changes during UTC period start_time - end_time.
@ -61,13 +62,16 @@ def get_significant_states(
timer_start = time.perf_counter()
with session_scope(hass=hass) as session:
query = session.query(States).filter(
(
States.domain.in_(SIGNIFICANT_DOMAINS)
| (States.last_changed == States.last_updated)
if significant_changes_only:
query = session.query(States).filter(
(
States.domain.in_(SIGNIFICANT_DOMAINS)
| (States.last_changed == States.last_updated)
)
& (States.last_updated > start_time)
)
& (States.last_updated > start_time)
)
else:
query = session.query(States).filter(States.last_updated > start_time)
if filters:
query = filters.apply(query, entity_ids)
@ -327,6 +331,9 @@ class HistoryPeriodView(HomeAssistantView):
if entity_ids:
entity_ids = entity_ids.lower().split(",")
include_start_time_state = "skip_initial_state" not in request.query
significant_changes_only = (
request.query.get("significant_changes_only", "1") != "0"
)
hass = request.app["hass"]
@ -338,6 +345,7 @@ class HistoryPeriodView(HomeAssistantView):
entity_ids,
self.filters,
include_start_time_state,
significant_changes_only,
)
result = list(result.values())
if _LOGGER.isEnabledFor(logging.DEBUG):

View File

@ -522,6 +522,62 @@ class TestComponentHistory(unittest.TestCase):
)
assert list(hist.keys()) == entity_ids
def test_get_significant_states_only(self):
"""Test significant states when significant_states_only is set."""
self.init_recorder()
entity_id = "sensor.test"
def set_state(state, **kwargs):
"""Set the state."""
self.hass.states.set(entity_id, state, **kwargs)
wait_recording_done(self.hass)
return self.hass.states.get(entity_id)
start = dt_util.utcnow() - timedelta(minutes=4)
points = []
for i in range(1, 4):
points.append(start + timedelta(minutes=i))
states = []
with patch(
"homeassistant.components.recorder.dt_util.utcnow", return_value=start
):
set_state("123", attributes={"attribute": 10.64})
with patch(
"homeassistant.components.recorder.dt_util.utcnow", return_value=points[0]
):
# Attributes are different, state not
states.append(set_state("123", attributes={"attribute": 21.42}))
with patch(
"homeassistant.components.recorder.dt_util.utcnow", return_value=points[1]
):
# state is different, attributes not
states.append(set_state("32", attributes={"attribute": 21.42}))
with patch(
"homeassistant.components.recorder.dt_util.utcnow", return_value=points[2]
):
# everything is different
states.append(set_state("412", attributes={"attribute": 54.23}))
hist = history.get_significant_states(
self.hass, start, significant_changes_only=True
)
assert len(hist[entity_id]) == 2
assert states[0] not in hist[entity_id]
assert states[1] in hist[entity_id]
assert states[2] in hist[entity_id]
hist = history.get_significant_states(
self.hass, start, significant_changes_only=False
)
assert len(hist[entity_id]) == 3
assert states == hist[entity_id]
def check_significant_states(self, zero, four, states, config):
"""Check if significant states are retrieved."""
filters = history.Filters()