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