From bf95658e24c51d7d1ca009618224691e49682620 Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Fri, 12 Jun 2020 20:45:17 +0200 Subject: [PATCH] Fix logbook filtering for described events (#36727) --- homeassistant/components/logbook/__init__.py | 16 ++--- tests/components/logbook/test_init.py | 65 ++++++++++++++++++++ 2 files changed, 73 insertions(+), 8 deletions(-) diff --git a/homeassistant/components/logbook/__init__.py b/homeassistant/components/logbook/__init__.py index 7204fd3ef5e..6f2a159d2d6 100644 --- a/homeassistant/components/logbook/__init__.py +++ b/homeassistant/components/logbook/__init__.py @@ -340,7 +340,7 @@ def _get_related_entity_ids(session, entity_filter): query = session.query(States).with_entities(States.entity_id).distinct() - for tryno in range(0, RETRIES): + for tryno in range(RETRIES): try: result = [row.entity_id for row in query if entity_filter(row.entity_id)] @@ -419,11 +419,12 @@ def _get_events(hass, config, start_day, end_day, entity_id=None): def _keep_event(hass, event, entities_filter): - domain, entity_id = None, None + domain = event.data.get(ATTR_DOMAIN) + entity_id = event.data.get("entity_id") + if entity_id: + domain = split_entity_id(entity_id)[0] if event.event_type == EVENT_STATE_CHANGED: - entity_id = event.data.get("entity_id") - if entity_id is None: return False @@ -441,7 +442,6 @@ def _keep_event(hass, event, entities_filter): 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. @@ -455,13 +455,13 @@ def _keep_event(hass, event, entities_filter): elif event.event_type == EVENT_LOGBOOK_ENTRY: domain = event.data.get(ATTR_DOMAIN) - entity_id = event.data.get(ATTR_ENTITY_ID) elif event.event_type == EVENT_SCRIPT_STARTED: domain = "script" - entity_id = event.data.get(ATTR_ENTITY_ID) - elif event.event_type in hass.data.get(DOMAIN, {}): + elif not entity_id and event.event_type in hass.data.get(DOMAIN, {}): + # If the entity_id isn't described, use the domain that describes + # the event for filtering. domain = hass.data[DOMAIN][event.event_type][0] if not entity_id and domain: diff --git a/tests/components/logbook/test_init.py b/tests/components/logbook/test_init.py index 91b90426d3f..7e92e7be69c 100644 --- a/tests/components/logbook/test_init.py +++ b/tests/components/logbook/test_init.py @@ -1352,6 +1352,71 @@ async def test_logbook_describe_event(hass, hass_client): assert event["domain"] == "test_domain" +async def test_exclude_described_event(hass, hass_client): + """Test exclusions of events that are described by another integration.""" + name = "My Automation Rule" + entity_id = "automation.excluded_rule" + entity_id2 = "automation.included_rule" + entity_id3 = "sensor.excluded_domain" + + await hass.async_add_executor_job(init_recorder_component, hass) + assert await async_setup_component( + hass, + logbook.DOMAIN, + { + logbook.DOMAIN: { + logbook.CONF_EXCLUDE: { + logbook.CONF_DOMAINS: ["sensor"], + logbook.CONF_ENTITIES: [entity_id], + } + } + }, + ) + + with patch( + "homeassistant.util.dt.utcnow", + return_value=dt_util.utcnow() - timedelta(seconds=5), + ): + hass.bus.async_fire( + "some_automation_event", + {logbook.ATTR_NAME: name, logbook.ATTR_ENTITY_ID: entity_id}, + ) + hass.bus.async_fire( + "some_automation_event", + {logbook.ATTR_NAME: name, logbook.ATTR_ENTITY_ID: entity_id2}, + ) + hass.bus.async_fire( + "some_event", {logbook.ATTR_NAME: name, logbook.ATTR_ENTITY_ID: entity_id3} + ) + await hass.async_block_till_done() + await hass.async_add_executor_job( + hass.data[recorder.DATA_INSTANCE].block_till_done + ) + + def _describe(event): + """Describe an event.""" + return { + "name": "Test Name", + "message": "tested a message", + "entity_id": event.data.get(ATTR_ENTITY_ID), + } + + hass.components.logbook.async_describe_event( + "automation", "some_automation_event", _describe + ) + hass.components.logbook.async_describe_event("sensor", "some_event", _describe) + + client = await hass_client() + response = await client.get("/api/logbook") + results = await response.json() + assert len(results) == 1 + event = results[0] + assert event["name"] == "Test Name" + assert event["message"] == "tested a message" + assert event["domain"] == "automation" + assert event["entity_id"] == "automation.included_rule" + + async def test_logbook_view_end_time_entity(hass, hass_client): """Test the logbook view with end_time and entity.""" await hass.async_add_executor_job(init_recorder_component, hass)