From dda4cf4d580ca5b41f1d4b028494b1edccda6b84 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 30 Aug 2020 02:20:31 -0500 Subject: [PATCH] Tune logbook performance to accomodate recent changes (#39348) --- .../components/automation/logbook.py | 11 +++--- homeassistant/components/logbook/__init__.py | 39 ++++++++++++++----- homeassistant/components/script/logbook.py | 5 ++- tests/components/logbook/test_init.py | 10 +++++ 4 files changed, 48 insertions(+), 17 deletions(-) diff --git a/homeassistant/components/automation/logbook.py b/homeassistant/components/automation/logbook.py index cc44296eaa6..3c9671af18f 100644 --- a/homeassistant/components/automation/logbook.py +++ b/homeassistant/components/automation/logbook.py @@ -12,14 +12,15 @@ def async_describe_events(hass, async_describe_event): # type: ignore @callback def async_describe_logbook_event(event): # type: ignore """Describe a logbook event.""" + data = event.data message = "has been triggered" - if ATTR_SOURCE in event.data: - message = f"{message} by {event.data[ATTR_SOURCE]}" + if ATTR_SOURCE in data: + message = f"{message} by {data[ATTR_SOURCE]}" return { - "name": event.data.get(ATTR_NAME), + "name": data.get(ATTR_NAME), "message": message, - "source": event.data.get(ATTR_SOURCE), - "entity_id": event.data.get(ATTR_ENTITY_ID), + "source": data.get(ATTR_SOURCE), + "entity_id": data.get(ATTR_ENTITY_ID), } async_describe_event( diff --git a/homeassistant/components/logbook/__init__.py b/homeassistant/components/logbook/__init__.py index fb219de0d8c..03dc1ffdef9 100644 --- a/homeassistant/components/logbook/__init__.py +++ b/homeassistant/components/logbook/__init__.py @@ -3,6 +3,7 @@ from datetime import timedelta from itertools import groupby import json import logging +import re import sqlalchemy from sqlalchemy.orm import aliased @@ -50,6 +51,9 @@ from homeassistant.helpers.integration_platform import ( from homeassistant.loader import bind_hass import homeassistant.util.dt as dt_util +ENTITY_ID_JSON_EXTRACT = re.compile('"entity_id": "([^"]+)"') +DOMAIN_JSON_EXTRACT = re.compile('"domain": "([^"]+)"') + _LOGGER = logging.getLogger(__name__) ATTR_MESSAGE = "message" @@ -485,20 +489,17 @@ def _keep_event(hass, event, entities_filter): entity_id = event.entity_id elif event.event_type in HOMEASSISTANT_EVENTS: entity_id = f"{HA_DOMAIN}." - elif event.event_type in hass.data[DOMAIN] and ATTR_ENTITY_ID not in event.data: - # 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 domain is None: - return False - entity_id = f"{domain}." elif event.event_type == EVENT_CALL_SERVICE: return False else: - event_data = event.data - entity_id = event_data.get(ATTR_ENTITY_ID) + entity_id = event.data_entity_id if not entity_id: - domain = event_data.get(ATTR_DOMAIN) + if event.event_type in hass.data[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] + else: + domain = event.data_domain if domain is None: return False entity_id = f"{domain}." @@ -689,6 +690,24 @@ class LazyEventPartialState: self.context_user_id = self._row.context_user_id self.time_fired_minute = self._row.time_fired.minute + @property + def data_entity_id(self): + """Extract the entity id from the decoded data or json.""" + if self._event_data: + return self._event_data.get(ATTR_ENTITY_ID) + + result = ENTITY_ID_JSON_EXTRACT.search(self._row.event_data) + return result and result.group(1) + + @property + def data_domain(self): + """Extract the domain from the decoded data or json.""" + if self._event_data: + return self._event_data.get(ATTR_DOMAIN) + + result = DOMAIN_JSON_EXTRACT.search(self._row.event_data) + return result and result.group(1) + @property def attributes(self): """State attributes.""" diff --git a/homeassistant/components/script/logbook.py b/homeassistant/components/script/logbook.py index 72ff0d15fc7..f75584540d3 100644 --- a/homeassistant/components/script/logbook.py +++ b/homeassistant/components/script/logbook.py @@ -12,10 +12,11 @@ def async_describe_events(hass, async_describe_event): @callback def async_describe_logbook_event(event): """Describe the logbook event.""" + data = event.data return { - "name": event.data.get(ATTR_NAME), + "name": data.get(ATTR_NAME), "message": "started", - "entity_id": event.data.get(ATTR_ENTITY_ID), + "entity_id": data.get(ATTR_ENTITY_ID), } async_describe_event(DOMAIN, EVENT_SCRIPT_STARTED, async_describe_logbook_event) diff --git a/tests/components/logbook/test_init.py b/tests/components/logbook/test_init.py index 78753e2a67e..4edf630322a 100644 --- a/tests/components/logbook/test_init.py +++ b/tests/components/logbook/test_init.py @@ -2084,6 +2084,16 @@ async def test_logbook_context_from_template(hass, hass_client): class MockLazyEventPartialState(ha.Event): """Minimal mock of a Lazy event.""" + @property + def data_entity_id(self): + """Lookup entity id.""" + return self.data.get(ATTR_ENTITY_ID) + + @property + def data_domain(self): + """Lookup domain.""" + return self.data.get(ATTR_DOMAIN) + @property def time_fired_minute(self): """Minute the event was fired."""