Simplify logbook duplicate handling (#32572)

pull/32578/head
Anders Melchiorsen 2020-03-08 05:27:51 +01:00 committed by GitHub
parent a0787cd9be
commit 17215709e1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 39 additions and 64 deletions

View File

@ -203,9 +203,6 @@ def humanify(hass, events):
"""
domain_prefixes = tuple(f"{dom}." for dom in CONTINUOUS_DOMAINS)
# Track last states to filter out duplicates
last_state = {}
# Group events in batches of GROUP_BY_MINUTES
for _, g_events in groupby(
events, lambda event: event.time_fired.minute // GROUP_BY_MINUTES
@ -255,13 +252,6 @@ def humanify(hass, events):
if event.event_type == EVENT_STATE_CHANGED:
to_state = State.from_dict(event.data.get("new_state"))
# Filter out states that become same state again (force_update=True)
# or light becoming different color
if last_state.get(to_state.entity_id) == to_state.state:
continue
last_state[to_state.entity_id] = to_state.state
domain = to_state.domain
# Skip all but the last sensor state
@ -468,25 +458,21 @@ def _keep_event(hass, event, entities_filter):
return False
# Do not report on new entities
if event.data.get("old_state") is None:
old_state = event.data.get("old_state")
if old_state is None:
return False
new_state = event.data.get("new_state")
# Do not report on entity removal
if not new_state:
new_state = event.data.get("new_state")
if new_state is None:
return False
attributes = new_state.get("attributes", {})
# If last_changed != last_updated only attributes have changed
# we do not report on that yet.
last_changed = new_state.get("last_changed")
last_updated = new_state.get("last_updated")
if last_changed != last_updated:
# Do not report on only attribute changes
if new_state.get("state") == old_state.get("state"):
return False
domain = split_entity_id(entity_id)[0]
attributes = new_state.get("attributes", {})
# Also filter auto groups.
if domain == "group" and attributes.get("auto", False):

View File

@ -568,14 +568,35 @@ class TestComponentLogbook(unittest.TestCase):
def test_exclude_attribute_changes(self):
"""Test if events of attribute changes are filtered."""
entity_id = "switch.bla"
entity_id2 = "switch.blu"
pointA = dt_util.utcnow()
pointB = pointA + timedelta(minutes=1)
pointC = pointB + timedelta(minutes=1)
eventA = self.create_state_changed_event(pointA, entity_id, 10)
eventB = self.create_state_changed_event(
pointA, entity_id2, 20, last_changed=pointA, last_updated=pointB
state_off = ha.State("light.kitchen", "off", {}, pointA, pointA).as_dict()
state_100 = ha.State(
"light.kitchen", "on", {"brightness": 100}, pointB, pointB
).as_dict()
state_200 = ha.State(
"light.kitchen", "on", {"brightness": 200}, pointB, pointC
).as_dict()
eventA = ha.Event(
EVENT_STATE_CHANGED,
{
"entity_id": "light.kitchen",
"old_state": state_off,
"new_state": state_100,
},
time_fired=pointB,
)
eventB = ha.Event(
EVENT_STATE_CHANGED,
{
"entity_id": "light.kitchen",
"old_state": state_100,
"new_state": state_200,
},
time_fired=pointC,
)
entities_filter = logbook._generate_filter_from_config({})
@ -588,7 +609,7 @@ class TestComponentLogbook(unittest.TestCase):
assert 1 == len(entries)
self.assert_entry(
entries[0], pointA, "bla", domain="switch", entity_id=entity_id
entries[0], pointB, "kitchen", domain="light", entity_id="light.kitchen"
)
def test_home_assistant_start_stop_grouped(self):
@ -1231,15 +1252,16 @@ class TestComponentLogbook(unittest.TestCase):
last_updated=None,
):
"""Create state changed event."""
# Logbook only cares about state change events that
# contain an old state but will not actually act on it.
state = ha.State(
old_state = ha.State(
entity_id, "old", attributes, last_changed, last_updated
).as_dict()
new_state = ha.State(
entity_id, state, attributes, last_changed, last_updated
).as_dict()
return ha.Event(
EVENT_STATE_CHANGED,
{"entity_id": entity_id, "old_state": state, "new_state": state},
{"entity_id": entity_id, "old_state": old_state, "new_state": new_state},
time_fired=event_time_fired,
)
@ -1435,39 +1457,6 @@ async def test_humanify_script_started_event(hass):
assert event2["entity_id"] == "script.bye"
async def test_humanify_same_state(hass):
"""Test humanifying Script Run event."""
state_50 = ha.State("light.kitchen", "on", {"brightness": 50}).as_dict()
state_100 = ha.State("light.kitchen", "on", {"brightness": 100}).as_dict()
state_200 = ha.State("light.kitchen", "on", {"brightness": 200}).as_dict()
events = list(
logbook.humanify(
hass,
[
ha.Event(
EVENT_STATE_CHANGED,
{
"entity_id": "light.kitchen",
"old_state": state_50,
"new_state": state_100,
},
),
ha.Event(
EVENT_STATE_CHANGED,
{
"entity_id": "light.kitchen",
"old_state": state_100,
"new_state": state_200,
},
),
],
)
)
assert len(events) == 1
async def test_logbook_describe_event(hass, hass_client):
"""Test teaching logbook about a new event."""
await hass.async_add_executor_job(init_recorder_component, hass)