Refactor logbook helpers to reduce splits and lookups (#108933)
Co-authored-by: Paulus Schoutsen <balloob@gmail.com>pull/108942/head
parent
61c6c70a7d
commit
5dac5d5c7e
|
@ -39,7 +39,8 @@ def async_filter_entities(hass: HomeAssistant, entity_ids: list[str]) -> list[st
|
|||
return [
|
||||
entity_id
|
||||
for entity_id in entity_ids
|
||||
if not _is_entity_id_filtered(hass, ent_reg, entity_id)
|
||||
if split_entity_id(entity_id)[0] not in ALWAYS_CONTINUOUS_DOMAINS
|
||||
and not is_sensor_continuous(hass, ent_reg, entity_id)
|
||||
]
|
||||
|
||||
|
||||
|
@ -216,18 +217,37 @@ def async_subscribe_events(
|
|||
)
|
||||
|
||||
|
||||
def is_sensor_continuous(ent_reg: er.EntityRegistry, entity_id: str) -> bool:
|
||||
"""Determine if a sensor is continuous by checking its state class.
|
||||
def is_sensor_continuous(
|
||||
hass: HomeAssistant, ent_reg: er.EntityRegistry, entity_id: str
|
||||
) -> bool:
|
||||
"""Determine if a sensor is continuous.
|
||||
|
||||
Sensors with a unit_of_measurement are also considered continuous, but are filtered
|
||||
already by the SQL query generated by _get_events
|
||||
Sensors with a unit_of_measurement or state_class are considered continuous.
|
||||
|
||||
The unit_of_measurement check will already happen if this is
|
||||
called for historical data because the SQL query generated by _get_events
|
||||
will filter out any sensors with a unit_of_measurement.
|
||||
|
||||
If the state still exists in the state machine, this function still
|
||||
checks for ATTR_UNIT_OF_MEASUREMENT since the live mode is not filtered
|
||||
by the SQL query.
|
||||
"""
|
||||
if not (entry := ent_reg.async_get(entity_id)):
|
||||
# Entity not registered, so can't have a state class
|
||||
return False
|
||||
return (
|
||||
entry.capabilities is not None
|
||||
and entry.capabilities.get(ATTR_STATE_CLASS) is not None
|
||||
# If it is in the state machine we can quick check if it
|
||||
# has a unit_of_measurement or state_class, and filter if
|
||||
# it does
|
||||
if (state := hass.states.get(entity_id)) and (attributes := state.attributes):
|
||||
return ATTR_UNIT_OF_MEASUREMENT in attributes or ATTR_STATE_CLASS in attributes
|
||||
# If its not in the state machine, we need to check
|
||||
# the entity registry to see if its a sensor
|
||||
# filter with a state class. We do not check
|
||||
# for unit_of_measurement since the SQL query
|
||||
# will filter out any sensors with a unit_of_measurement
|
||||
# and we should never get here in live mode because
|
||||
# the state machine will always have the state.
|
||||
return bool(
|
||||
(entry := ent_reg.async_get(entity_id))
|
||||
and entry.capabilities
|
||||
and entry.capabilities.get(ATTR_STATE_CLASS)
|
||||
)
|
||||
|
||||
|
||||
|
@ -239,24 +259,8 @@ def _is_state_filtered(new_state: State, old_state: State) -> bool:
|
|||
"""
|
||||
return bool(
|
||||
new_state.state == old_state.state
|
||||
or split_entity_id(new_state.entity_id)[0] in ALWAYS_CONTINUOUS_DOMAINS
|
||||
or new_state.last_changed != new_state.last_updated
|
||||
or new_state.domain in ALWAYS_CONTINUOUS_DOMAINS
|
||||
or ATTR_UNIT_OF_MEASUREMENT in new_state.attributes
|
||||
or ATTR_STATE_CLASS in new_state.attributes
|
||||
)
|
||||
|
||||
|
||||
def _is_entity_id_filtered(
|
||||
hass: HomeAssistant, ent_reg: er.EntityRegistry, entity_id: str
|
||||
) -> bool:
|
||||
"""Check if the logbook should filter an entity.
|
||||
|
||||
Used to setup listeners and which entities to select
|
||||
from the database when a list of entities is requested.
|
||||
"""
|
||||
return bool(
|
||||
split_entity_id(entity_id)[0] in ALWAYS_CONTINUOUS_DOMAINS
|
||||
or (state := hass.states.get(entity_id))
|
||||
and (ATTR_UNIT_OF_MEASUREMENT in state.attributes)
|
||||
or is_sensor_continuous(ent_reg, entity_id)
|
||||
)
|
||||
|
|
|
@ -175,6 +175,7 @@ class EventProcessor:
|
|||
"""Humanify rows."""
|
||||
return list(
|
||||
_humanify(
|
||||
self.hass,
|
||||
rows,
|
||||
self.ent_reg,
|
||||
self.logbook_run,
|
||||
|
@ -184,6 +185,7 @@ class EventProcessor:
|
|||
|
||||
|
||||
def _humanify(
|
||||
hass: HomeAssistant,
|
||||
rows: Generator[EventAsRow, None, None] | Sequence[Row] | Result,
|
||||
ent_reg: er.EntityRegistry,
|
||||
logbook_run: LogbookRun,
|
||||
|
@ -219,7 +221,7 @@ def _humanify(
|
|||
if (
|
||||
is_continuous := continuous_sensors.get(entity_id)
|
||||
) is None and split_entity_id(entity_id)[0] == SENSOR_DOMAIN:
|
||||
is_continuous = is_sensor_continuous(ent_reg, entity_id)
|
||||
is_continuous = is_sensor_continuous(hass, ent_reg, entity_id)
|
||||
continuous_sensors[entity_id] = is_continuous
|
||||
if is_continuous:
|
||||
continue
|
||||
|
|
|
@ -77,6 +77,7 @@ def mock_humanify(hass_, rows):
|
|||
context_augmenter = processor.ContextAugmenter(logbook_run)
|
||||
return list(
|
||||
processor._humanify(
|
||||
hass_,
|
||||
rows,
|
||||
ent_reg,
|
||||
logbook_run,
|
||||
|
|
Loading…
Reference in New Issue