Refactor logbook data to use a dataclass (#89534)
parent
fccdd7b102
commit
01e1221443
|
@ -19,7 +19,7 @@ from homeassistant.const import (
|
|||
ATTR_NAME,
|
||||
EVENT_LOGBOOK_ENTRY,
|
||||
)
|
||||
from homeassistant.core import Context, Event, HomeAssistant, ServiceCall, callback
|
||||
from homeassistant.core import Context, HomeAssistant, ServiceCall, callback
|
||||
from homeassistant.helpers import config_validation as cv
|
||||
from homeassistant.helpers.entityfilter import (
|
||||
INCLUDE_EXCLUDE_BASE_FILTER_SCHEMA,
|
||||
|
@ -35,7 +35,6 @@ from . import rest_api, websocket_api
|
|||
from .const import ( # noqa: F401
|
||||
ATTR_MESSAGE,
|
||||
DOMAIN,
|
||||
LOGBOOK_ENTITIES_FILTER,
|
||||
LOGBOOK_ENTRY_CONTEXT_ID,
|
||||
LOGBOOK_ENTRY_DOMAIN,
|
||||
LOGBOOK_ENTRY_ENTITY_ID,
|
||||
|
@ -43,9 +42,8 @@ from .const import ( # noqa: F401
|
|||
LOGBOOK_ENTRY_MESSAGE,
|
||||
LOGBOOK_ENTRY_NAME,
|
||||
LOGBOOK_ENTRY_SOURCE,
|
||||
LOGBOOK_FILTERS,
|
||||
)
|
||||
from .models import LazyEventPartialState # noqa: F401
|
||||
from .models import LazyEventPartialState, LogbookConfig
|
||||
|
||||
CONFIG_SCHEMA = vol.Schema(
|
||||
{DOMAIN: INCLUDE_EXCLUDE_BASE_FILTER_SCHEMA}, extra=vol.ALLOW_EXTRA
|
||||
|
@ -97,7 +95,6 @@ def async_log_entry(
|
|||
|
||||
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
||||
"""Logbook setup."""
|
||||
hass.data[DOMAIN] = {}
|
||||
|
||||
@callback
|
||||
def log_message(service: ServiceCall) -> None:
|
||||
|
@ -134,8 +131,11 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
|||
else:
|
||||
filters = None
|
||||
entities_filter = None
|
||||
hass.data[LOGBOOK_FILTERS] = filters
|
||||
hass.data[LOGBOOK_ENTITIES_FILTER] = entities_filter
|
||||
|
||||
external_events: dict[
|
||||
str, tuple[str, Callable[[LazyEventPartialState], dict[str, Any]]]
|
||||
] = {}
|
||||
hass.data[DOMAIN] = LogbookConfig(external_events, filters, entities_filter)
|
||||
websocket_api.async_setup(hass)
|
||||
rest_api.async_setup(hass, config, filters, entities_filter)
|
||||
hass.services.async_register(DOMAIN, "log", log_message, schema=LOG_MESSAGE_SCHEMA)
|
||||
|
@ -149,14 +149,16 @@ async def _process_logbook_platform(
|
|||
hass: HomeAssistant, domain: str, platform: Any
|
||||
) -> None:
|
||||
"""Process a logbook platform."""
|
||||
logbook_config: LogbookConfig = hass.data[DOMAIN]
|
||||
external_events = logbook_config.external_events
|
||||
|
||||
@callback
|
||||
def _async_describe_event(
|
||||
domain: str,
|
||||
event_name: str,
|
||||
describe_callback: Callable[[Event], dict[str, Any]],
|
||||
describe_callback: Callable[[LazyEventPartialState], dict[str, Any]],
|
||||
) -> None:
|
||||
"""Teach logbook how to describe a new event."""
|
||||
hass.data[DOMAIN][event_name] = (domain, describe_callback)
|
||||
external_events[event_name] = (domain, describe_callback)
|
||||
|
||||
platform.async_describe_events(hass, _async_describe_event)
|
||||
|
|
|
@ -44,6 +44,3 @@ AUTOMATION_EVENTS = {EVENT_AUTOMATION_TRIGGERED, EVENT_SCRIPT_STARTED}
|
|||
|
||||
# Events that are built-in to the logbook or core
|
||||
BUILT_IN_EVENTS = {EVENT_LOGBOOK_ENTRY, EVENT_CALL_SERVICE}
|
||||
|
||||
LOGBOOK_FILTERS = "logbook_filters"
|
||||
LOGBOOK_ENTITIES_FILTER = "entities_filter"
|
||||
|
|
|
@ -27,7 +27,7 @@ from homeassistant.helpers.entityfilter import EntityFilter
|
|||
from homeassistant.helpers.event import async_track_state_change_event
|
||||
|
||||
from .const import ALWAYS_CONTINUOUS_DOMAINS, AUTOMATION_EVENTS, BUILT_IN_EVENTS, DOMAIN
|
||||
from .models import LazyEventPartialState
|
||||
from .models import LogbookConfig
|
||||
|
||||
|
||||
def async_filter_entities(hass: HomeAssistant, entity_ids: list[str]) -> list[str]:
|
||||
|
@ -63,9 +63,8 @@ def async_determine_event_types(
|
|||
hass: HomeAssistant, entity_ids: list[str] | None, device_ids: list[str] | None
|
||||
) -> tuple[str, ...]:
|
||||
"""Reduce the event types based on the entity ids and device ids."""
|
||||
external_events: dict[
|
||||
str, tuple[str, Callable[[LazyEventPartialState], dict[str, Any]]]
|
||||
] = hass.data.get(DOMAIN, {})
|
||||
logbook_config: LogbookConfig = hass.data[DOMAIN]
|
||||
external_events = logbook_config.external_events
|
||||
if not entity_ids and not device_ids:
|
||||
return (*BUILT_IN_EVENTS, *external_events)
|
||||
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
"""Event parser and human readable log generator."""
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Callable
|
||||
from dataclasses import dataclass
|
||||
from typing import Any, cast
|
||||
|
||||
from sqlalchemy.engine.row import Row
|
||||
|
||||
from homeassistant.components.recorder.filters import Filters
|
||||
from homeassistant.components.recorder.models import (
|
||||
bytes_to_ulid_or_none,
|
||||
bytes_to_uuid_hex_or_none,
|
||||
|
@ -14,11 +16,23 @@ from homeassistant.components.recorder.models import (
|
|||
)
|
||||
from homeassistant.const import ATTR_ICON, EVENT_STATE_CHANGED
|
||||
from homeassistant.core import Context, Event, State, callback
|
||||
from homeassistant.helpers.entityfilter import EntityFilter
|
||||
import homeassistant.util.dt as dt_util
|
||||
from homeassistant.util.json import json_loads
|
||||
from homeassistant.util.ulid import ulid_to_bytes
|
||||
|
||||
|
||||
@dataclass
|
||||
class LogbookConfig:
|
||||
"""Configuration for the logbook integration."""
|
||||
|
||||
external_events: dict[
|
||||
str, tuple[str, Callable[[LazyEventPartialState], dict[str, Any]]]
|
||||
]
|
||||
sqlalchemy_filter: Filters | None = None
|
||||
entity_filter: EntityFilter | None = None
|
||||
|
||||
|
||||
class LazyEventPartialState:
|
||||
"""A lazy version of core Event with limited State joined in."""
|
||||
|
||||
|
|
|
@ -52,10 +52,9 @@ from .const import (
|
|||
LOGBOOK_ENTRY_SOURCE,
|
||||
LOGBOOK_ENTRY_STATE,
|
||||
LOGBOOK_ENTRY_WHEN,
|
||||
LOGBOOK_FILTERS,
|
||||
)
|
||||
from .helpers import is_sensor_continuous
|
||||
from .models import EventAsRow, LazyEventPartialState, async_event_to_row
|
||||
from .models import EventAsRow, LazyEventPartialState, LogbookConfig, async_event_to_row
|
||||
from .queries import statement_for_request
|
||||
from .queries.common import PSEUDO_EVENT_STATE_CHANGED
|
||||
|
||||
|
@ -97,16 +96,14 @@ class EventProcessor:
|
|||
self.entity_ids = entity_ids
|
||||
self.device_ids = device_ids
|
||||
self.context_id = context_id
|
||||
self.filters: Filters | None = hass.data[LOGBOOK_FILTERS]
|
||||
logbook_config: LogbookConfig = hass.data[DOMAIN]
|
||||
self.filters: Filters | None = logbook_config.sqlalchemy_filter
|
||||
format_time = (
|
||||
_row_time_fired_timestamp if timestamp else _row_time_fired_isoformat
|
||||
)
|
||||
external_events: dict[
|
||||
str, tuple[str, Callable[[LazyEventPartialState], dict[str, Any]]]
|
||||
] = hass.data.get(DOMAIN, {})
|
||||
self.logbook_run = LogbookRun(
|
||||
context_lookup=ContextLookup(hass),
|
||||
external_events=external_events,
|
||||
external_events=logbook_config.external_events,
|
||||
event_cache=EventCache({}),
|
||||
entity_name_cache=EntityNameCache(self.hass),
|
||||
include_entity_name=include_entity_name,
|
||||
|
|
|
@ -20,13 +20,13 @@ from homeassistant.helpers.event import async_track_point_in_utc_time
|
|||
from homeassistant.helpers.json import JSON_DUMP
|
||||
import homeassistant.util.dt as dt_util
|
||||
|
||||
from .const import LOGBOOK_ENTITIES_FILTER
|
||||
from .const import DOMAIN
|
||||
from .helpers import (
|
||||
async_determine_event_types,
|
||||
async_filter_entities,
|
||||
async_subscribe_events,
|
||||
)
|
||||
from .models import async_event_to_row
|
||||
from .models import LogbookConfig, async_event_to_row
|
||||
from .processor import EventProcessor
|
||||
|
||||
MAX_PENDING_LOGBOOK_EVENTS = 2048
|
||||
|
@ -361,7 +361,8 @@ async def ws_event_stream(
|
|||
|
||||
entities_filter: EntityFilter | None = None
|
||||
if not event_processor.limited_select:
|
||||
entities_filter = hass.data[LOGBOOK_ENTITIES_FILTER]
|
||||
logbook_config: LogbookConfig = hass.data[DOMAIN]
|
||||
entities_filter = logbook_config.entity_filter
|
||||
|
||||
async_subscribe_events(
|
||||
hass,
|
||||
|
|
|
@ -6,6 +6,7 @@ from typing import Any
|
|||
|
||||
from homeassistant.components import logbook
|
||||
from homeassistant.components.logbook import processor
|
||||
from homeassistant.components.logbook.models import LogbookConfig
|
||||
from homeassistant.components.recorder.models import (
|
||||
process_timestamp_to_utc_isoformat,
|
||||
ulid_to_bytes_or_none,
|
||||
|
@ -64,7 +65,8 @@ def mock_humanify(hass_, rows):
|
|||
ent_reg = er.async_get(hass_)
|
||||
event_cache = processor.EventCache({})
|
||||
context_lookup = processor.ContextLookup(hass_)
|
||||
external_events = hass_.data.get(logbook.DOMAIN, {})
|
||||
logbook_config = hass_.data.get(logbook.DOMAIN, LogbookConfig({}, None, None))
|
||||
external_events = logbook_config.external_events
|
||||
logbook_run = processor.LogbookRun(
|
||||
context_lookup,
|
||||
external_events,
|
||||
|
|
Loading…
Reference in New Issue