Refactor homekit device linking to use the device index (#114145)

Now that we have an index of devices in the entity registry
we can avoid generating a lookup for devices we do
not care about
This commit is contained in:
J. Nick Koston 2024-03-25 02:28:56 -10:00 committed by GitHub
parent 95ddade83c
commit 3acb505456
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -803,18 +803,10 @@ class HomeKit:
"""Configure accessories for the included states."""
dev_reg = dr.async_get(self.hass)
ent_reg = er.async_get(self.hass)
device_lookup = ent_reg.async_get_device_class_lookup(
{
(BINARY_SENSOR_DOMAIN, BinarySensorDeviceClass.BATTERY_CHARGING),
(BINARY_SENSOR_DOMAIN, BinarySensorDeviceClass.MOTION),
(BINARY_SENSOR_DOMAIN, BinarySensorDeviceClass.OCCUPANCY),
(SENSOR_DOMAIN, SensorDeviceClass.BATTERY),
(SENSOR_DOMAIN, SensorDeviceClass.HUMIDITY),
}
)
device_lookup: dict[str, dict[tuple[str, str | None], str]] = {}
entity_states: list[State] = []
entity_filter = self._filter.get_filter()
entries = ent_reg.entities
for state in self.hass.states.async_all():
entity_id = state.entity_id
if not entity_filter(entity_id):
@ -830,7 +822,18 @@ class HomeKit:
await self._async_set_device_info_attributes(
ent_reg_ent, dev_reg, entity_id
)
self._async_configure_linked_sensors(ent_reg_ent, device_lookup, state)
if device_id := ent_reg_ent.device_id:
if device_id not in device_lookup:
device_lookup[device_id] = {
(
entry.domain,
entry.device_class or entry.original_device_class,
): entry.entity_id
for entry in entries.get_entries_for_device_id(device_id)
}
self._async_configure_linked_sensors(
ent_reg_ent, device_lookup[device_id], state
)
entity_states.append(state)
@ -1073,64 +1076,59 @@ class HomeKit:
def _async_configure_linked_sensors(
self,
ent_reg_ent: er.RegistryEntry,
device_lookup: dict[str, dict[tuple[str, str | None], str]],
device_lookup: dict[tuple[str, str | None], str],
state: State,
) -> None:
if (
ent_reg_ent is None
or ent_reg_ent.device_id is None
or ent_reg_ent.device_id not in device_lookup
or (ent_reg_ent.device_class or ent_reg_ent.original_device_class)
in (BinarySensorDeviceClass.BATTERY_CHARGING, SensorDeviceClass.BATTERY)
if (ent_reg_ent.device_class or ent_reg_ent.original_device_class) in (
BinarySensorDeviceClass.BATTERY_CHARGING,
SensorDeviceClass.BATTERY,
):
return
if ATTR_BATTERY_CHARGING not in state.attributes:
battery_charging_binary_sensor_entity_id = device_lookup[
ent_reg_ent.device_id
].get((BINARY_SENSOR_DOMAIN, BinarySensorDeviceClass.BATTERY_CHARGING))
if battery_charging_binary_sensor_entity_id:
self._config.setdefault(state.entity_id, {}).setdefault(
CONF_LINKED_BATTERY_CHARGING_SENSOR,
battery_charging_binary_sensor_entity_id,
)
domain = state.domain
attributes = state.attributes
if ATTR_BATTERY_LEVEL not in state.attributes:
battery_sensor_entity_id = device_lookup[ent_reg_ent.device_id].get(
if ATTR_BATTERY_CHARGING not in attributes and (
battery_charging_binary_sensor_entity_id := device_lookup.get(
(BINARY_SENSOR_DOMAIN, BinarySensorDeviceClass.BATTERY_CHARGING)
)
):
self._config.setdefault(state.entity_id, {}).setdefault(
CONF_LINKED_BATTERY_CHARGING_SENSOR,
battery_charging_binary_sensor_entity_id,
)
if ATTR_BATTERY_LEVEL not in attributes and (
battery_sensor_entity_id := device_lookup.get(
(SENSOR_DOMAIN, SensorDeviceClass.BATTERY)
)
if battery_sensor_entity_id:
self._config.setdefault(state.entity_id, {}).setdefault(
CONF_LINKED_BATTERY_SENSOR, battery_sensor_entity_id
)
):
self._config.setdefault(state.entity_id, {}).setdefault(
CONF_LINKED_BATTERY_SENSOR, battery_sensor_entity_id
)
if state.entity_id.startswith(f"{CAMERA_DOMAIN}."):
motion_binary_sensor_entity_id = device_lookup[ent_reg_ent.device_id].get(
if domain == CAMERA_DOMAIN:
if motion_binary_sensor_entity_id := device_lookup.get(
(BINARY_SENSOR_DOMAIN, BinarySensorDeviceClass.MOTION)
)
if motion_binary_sensor_entity_id:
):
self._config.setdefault(state.entity_id, {}).setdefault(
CONF_LINKED_MOTION_SENSOR,
motion_binary_sensor_entity_id,
CONF_LINKED_MOTION_SENSOR, motion_binary_sensor_entity_id
)
doorbell_binary_sensor_entity_id = device_lookup[ent_reg_ent.device_id].get(
if doorbell_binary_sensor_entity_id := device_lookup.get(
(BINARY_SENSOR_DOMAIN, BinarySensorDeviceClass.OCCUPANCY)
)
if doorbell_binary_sensor_entity_id:
):
self._config.setdefault(state.entity_id, {}).setdefault(
CONF_LINKED_DOORBELL_SENSOR,
doorbell_binary_sensor_entity_id,
CONF_LINKED_DOORBELL_SENSOR, doorbell_binary_sensor_entity_id
)
if state.entity_id.startswith(f"{HUMIDIFIER_DOMAIN}."):
current_humidity_sensor_entity_id = device_lookup[
ent_reg_ent.device_id
].get((SENSOR_DOMAIN, SensorDeviceClass.HUMIDITY))
if current_humidity_sensor_entity_id:
self._config.setdefault(state.entity_id, {}).setdefault(
CONF_LINKED_HUMIDITY_SENSOR,
current_humidity_sensor_entity_id,
)
if domain == HUMIDIFIER_DOMAIN and (
current_humidity_sensor_entity_id := device_lookup.get(
(SENSOR_DOMAIN, SensorDeviceClass.HUMIDITY)
)
):
self._config.setdefault(state.entity_id, {}).setdefault(
CONF_LINKED_HUMIDITY_SENSOR, current_humidity_sensor_entity_id
)
async def _async_set_device_info_attributes(
self,