mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 13:17:32 +00:00
Reduce recorder overhead when entity filter is empty (#119631)
This commit is contained in:
parent
9f41133bbc
commit
9082dc2a79
@ -127,15 +127,15 @@ def is_entity_recorded(hass: HomeAssistant, entity_id: str) -> bool:
|
|||||||
|
|
||||||
Async friendly.
|
Async friendly.
|
||||||
"""
|
"""
|
||||||
if DATA_INSTANCE not in hass.data:
|
instance = get_instance(hass)
|
||||||
return False
|
return instance.entity_filter is None or instance.entity_filter(entity_id)
|
||||||
return hass.data[DATA_INSTANCE].entity_filter(entity_id)
|
|
||||||
|
|
||||||
|
|
||||||
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
||||||
"""Set up the recorder."""
|
"""Set up the recorder."""
|
||||||
conf = config[DOMAIN]
|
conf = config[DOMAIN]
|
||||||
entity_filter = convert_include_exclude_filter(conf).get_filter()
|
_filter = convert_include_exclude_filter(conf)
|
||||||
|
entity_filter = None if _filter.empty_filter else _filter.get_filter()
|
||||||
auto_purge = conf[CONF_AUTO_PURGE]
|
auto_purge = conf[CONF_AUTO_PURGE]
|
||||||
auto_repack = conf[CONF_AUTO_REPACK]
|
auto_repack = conf[CONF_AUTO_REPACK]
|
||||||
keep_days = conf[CONF_PURGE_KEEP_DAYS]
|
keep_days = conf[CONF_PURGE_KEEP_DAYS]
|
||||||
|
@ -178,7 +178,7 @@ class Recorder(threading.Thread):
|
|||||||
uri: str,
|
uri: str,
|
||||||
db_max_retries: int,
|
db_max_retries: int,
|
||||||
db_retry_wait: int,
|
db_retry_wait: int,
|
||||||
entity_filter: Callable[[str], bool],
|
entity_filter: Callable[[str], bool] | None,
|
||||||
exclude_event_types: set[EventType[Any] | str],
|
exclude_event_types: set[EventType[Any] | str],
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Initialize the recorder."""
|
"""Initialize the recorder."""
|
||||||
@ -318,7 +318,10 @@ class Recorder(threading.Thread):
|
|||||||
if event.event_type in exclude_event_types:
|
if event.event_type in exclude_event_types:
|
||||||
return
|
return
|
||||||
|
|
||||||
if (entity_id := event.data.get(ATTR_ENTITY_ID)) is None:
|
if (
|
||||||
|
entity_filter is None
|
||||||
|
or (entity_id := event.data.get(ATTR_ENTITY_ID)) is None
|
||||||
|
):
|
||||||
queue_put(event)
|
queue_put(event)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -645,7 +645,7 @@ def _purge_filtered_data(instance: Recorder, session: Session) -> bool:
|
|||||||
for (metadata_id, entity_id) in session.query(
|
for (metadata_id, entity_id) in session.query(
|
||||||
StatesMeta.metadata_id, StatesMeta.entity_id
|
StatesMeta.metadata_id, StatesMeta.entity_id
|
||||||
).all()
|
).all()
|
||||||
if not entity_filter(entity_id)
|
if entity_filter and not entity_filter(entity_id)
|
||||||
]
|
]
|
||||||
if excluded_metadata_ids:
|
if excluded_metadata_ids:
|
||||||
has_more_states_to_purge = _purge_filtered_states(
|
has_more_states_to_purge = _purge_filtered_states(
|
||||||
@ -765,7 +765,9 @@ def _purge_filtered_events(
|
|||||||
|
|
||||||
@retryable_database_job("purge_entity_data")
|
@retryable_database_job("purge_entity_data")
|
||||||
def purge_entity_data(
|
def purge_entity_data(
|
||||||
instance: Recorder, entity_filter: Callable[[str], bool], purge_before: datetime
|
instance: Recorder,
|
||||||
|
entity_filter: Callable[[str], bool] | None,
|
||||||
|
purge_before: datetime,
|
||||||
) -> bool:
|
) -> bool:
|
||||||
"""Purge states and events of specified entities."""
|
"""Purge states and events of specified entities."""
|
||||||
database_engine = instance.database_engine
|
database_engine = instance.database_engine
|
||||||
@ -777,7 +779,7 @@ def purge_entity_data(
|
|||||||
for (metadata_id, entity_id) in session.query(
|
for (metadata_id, entity_id) in session.query(
|
||||||
StatesMeta.metadata_id, StatesMeta.entity_id
|
StatesMeta.metadata_id, StatesMeta.entity_id
|
||||||
).all()
|
).all()
|
||||||
if entity_filter(entity_id)
|
if entity_filter and entity_filter(entity_id)
|
||||||
]
|
]
|
||||||
_LOGGER.debug("Purging entity data for %s", selected_metadata_ids)
|
_LOGGER.debug("Purging entity data for %s", selected_metadata_ids)
|
||||||
if not selected_metadata_ids:
|
if not selected_metadata_ids:
|
||||||
|
@ -80,6 +80,7 @@ def _get_sensor_states(hass: HomeAssistant) -> list[State]:
|
|||||||
# We check for state class first before calling the filter
|
# We check for state class first before calling the filter
|
||||||
# function as the filter function is much more expensive
|
# function as the filter function is much more expensive
|
||||||
# than checking the state class
|
# than checking the state class
|
||||||
|
entity_filter = instance.entity_filter
|
||||||
return [
|
return [
|
||||||
state
|
state
|
||||||
for state in hass.states.all(DOMAIN)
|
for state in hass.states.all(DOMAIN)
|
||||||
@ -88,7 +89,7 @@ def _get_sensor_states(hass: HomeAssistant) -> list[State]:
|
|||||||
type(state_class) is SensorStateClass
|
type(state_class) is SensorStateClass
|
||||||
or try_parse_enum(SensorStateClass, state_class)
|
or try_parse_enum(SensorStateClass, state_class)
|
||||||
)
|
)
|
||||||
and instance.entity_filter(state.entity_id)
|
and (not entity_filter or entity_filter(state.entity_id))
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@ -680,6 +681,7 @@ def validate_statistics(
|
|||||||
sensor_entity_ids = {i.entity_id for i in sensor_states}
|
sensor_entity_ids = {i.entity_id for i in sensor_states}
|
||||||
sensor_statistic_ids = set(metadatas)
|
sensor_statistic_ids = set(metadatas)
|
||||||
instance = get_instance(hass)
|
instance = get_instance(hass)
|
||||||
|
entity_filter = instance.entity_filter
|
||||||
|
|
||||||
for state in sensor_states:
|
for state in sensor_states:
|
||||||
entity_id = state.entity_id
|
entity_id = state.entity_id
|
||||||
@ -689,7 +691,7 @@ def validate_statistics(
|
|||||||
state_unit = state.attributes.get(ATTR_UNIT_OF_MEASUREMENT)
|
state_unit = state.attributes.get(ATTR_UNIT_OF_MEASUREMENT)
|
||||||
|
|
||||||
if metadata := metadatas.get(entity_id):
|
if metadata := metadatas.get(entity_id):
|
||||||
if not instance.entity_filter(state.entity_id):
|
if entity_filter and not entity_filter(state.entity_id):
|
||||||
# Sensor was previously recorded, but no longer is
|
# Sensor was previously recorded, but no longer is
|
||||||
validation_result[entity_id].append(
|
validation_result[entity_id].append(
|
||||||
statistics.ValidationIssue(
|
statistics.ValidationIssue(
|
||||||
@ -739,7 +741,7 @@ def validate_statistics(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
elif state_class is not None:
|
elif state_class is not None:
|
||||||
if not instance.entity_filter(state.entity_id):
|
if entity_filter and not entity_filter(state.entity_id):
|
||||||
# Sensor is not recorded
|
# Sensor is not recorded
|
||||||
validation_result[entity_id].append(
|
validation_result[entity_id].append(
|
||||||
statistics.ValidationIssue(
|
statistics.ValidationIssue(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user