Simplify logbook duplicate handling (#32572)
parent
a0787cd9be
commit
17215709e1
|
@ -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):
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue