Reduce overhead to write HomeKit Controller state (#102365)

This commit is contained in:
J. Nick Koston 2023-10-19 20:50:07 -10:00 committed by GitHub
parent 84d0907fc8
commit 3014a651c3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 33 additions and 30 deletions

View file

@ -437,9 +437,10 @@ class HKDevice:
@callback
def async_migrate_unique_id(
self, old_unique_id: str, new_unique_id: str, platform: str
self, old_unique_id: str, new_unique_id: str | None, platform: str
) -> None:
"""Migrate legacy unique IDs to new format."""
assert new_unique_id is not None
_LOGGER.debug(
"Checking if unique ID %s on %s needs to be migrated",
old_unique_id,

View file

@ -42,6 +42,7 @@ class HomeKitEntity(Entity):
self._char_name: str | None = None
self._char_subscription: CALLBACK_TYPE | None = None
self.async_setup()
self._attr_unique_id = f"{accessory.unique_id}_{self._aid}_{self._iid}"
super().__init__()
@callback
@ -190,11 +191,6 @@ class HomeKitEntity(Entity):
# Some accessories do not have a serial number
return f"homekit-{self._accessory.unique_id}-{self._aid}-{self._iid}"
@property
def unique_id(self) -> str:
"""Return the ID of this device."""
return f"{self._accessory.unique_id}_{self._aid}_{self._iid}"
@property
def default_name(self) -> str | None:
"""Return the default name of the device."""
@ -206,10 +202,9 @@ class HomeKitEntity(Entity):
accessory_name = self.accessory.name
# If the service has a name char, use that, if not
# fallback to the default name provided by the subclass
device_name = self._char_name or self.default_name
folded_device_name = folded_name(device_name or "")
folded_accessory_name = folded_name(accessory_name)
if device_name:
if device_name := self._char_name or self.default_name:
folded_device_name = folded_name(device_name)
folded_accessory_name = folded_name(accessory_name)
# Sometimes the device name includes the accessory
# name already like My ecobee Occupancy / My ecobee
if folded_device_name.startswith(folded_accessory_name):
@ -243,17 +238,17 @@ class HomeKitEntity(Entity):
class AccessoryEntity(HomeKitEntity):
"""A HomeKit entity that is related to an entire accessory rather than a specific service or characteristic."""
def __init__(self, accessory: HKDevice, devinfo: ConfigType) -> None:
"""Initialise a generic HomeKit accessory."""
super().__init__(accessory, devinfo)
self._attr_unique_id = f"{accessory.unique_id}_{self._aid}"
@property
def old_unique_id(self) -> str:
"""Return the old ID of this device."""
serial = self.accessory_info.value(CharacteristicsTypes.SERIAL_NUMBER)
return f"homekit-{serial}-aid:{self._aid}"
@property
def unique_id(self) -> str:
"""Return the ID of this device."""
return f"{self._accessory.unique_id}_{self._aid}"
class BaseCharacteristicEntity(HomeKitEntity):
"""A HomeKit entity that is related to an single characteristic rather than a whole service.
@ -299,13 +294,17 @@ class CharacteristicEntity(BaseCharacteristicEntity):
the service entity.
"""
def __init__(
self, accessory: HKDevice, devinfo: ConfigType, char: Characteristic
) -> None:
"""Initialise a generic single characteristic HomeKit entity."""
super().__init__(accessory, devinfo, char)
self._attr_unique_id = (
f"{accessory.unique_id}_{self._aid}_{char.service.iid}_{char.iid}"
)
@property
def old_unique_id(self) -> str:
"""Return the old ID of this device."""
serial = self.accessory_info.value(CharacteristicsTypes.SERIAL_NUMBER)
return f"homekit-{serial}-aid:{self._aid}-sid:{self._char.service.iid}-cid:{self._char.iid}"
@property
def unique_id(self) -> str:
"""Return the ID of this device."""
return f"{self._accessory.unique_id}_{self._aid}_{self._char.service.iid}_{self._char.iid}"

View file

@ -19,6 +19,7 @@ from homeassistant.config_entries import ConfigEntry
from homeassistant.const import Platform
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import ConfigType
from . import KNOWN_DEVICES
from .connection import HKDevice
@ -152,6 +153,11 @@ class HomeKitDehumidifier(HomeKitEntity, HumidifierEntity):
_attr_device_class = HumidifierDeviceClass.DEHUMIDIFIER
_attr_supported_features = HumidifierEntityFeature.MODES
def __init__(self, accessory: HKDevice, devinfo: ConfigType) -> None:
"""Initialise the dehumidifier."""
super().__init__(accessory, devinfo)
self._attr_unique_id = f"{accessory.unique_id}_{self._iid}_{self.device_class}"
def get_characteristic_types(self) -> list[str]:
"""Define the homekit characteristics the entity cares about."""
return [
@ -260,11 +266,6 @@ class HomeKitDehumidifier(HomeKitEntity, HumidifierEntity):
serial = self.accessory_info.value(CharacteristicsTypes.SERIAL_NUMBER)
return f"homekit-{serial}-{self._iid}-{self.device_class}"
@property
def unique_id(self) -> str:
"""Return the ID of this device."""
return f"{self._accessory.unique_id}_{self._iid}_{self.device_class}"
async def async_setup_entry(
hass: HomeAssistant,

View file

@ -581,6 +581,11 @@ class RSSISensor(HomeKitEntity, SensorEntity):
_attr_native_unit_of_measurement = SIGNAL_STRENGTH_DECIBELS_MILLIWATT
_attr_should_poll = False
def __init__(self, accessory: HKDevice, devinfo: ConfigType) -> None:
"""Initialise a HomeKit Controller RSSI sensor."""
super().__init__(accessory, devinfo)
self._attr_unique_id = f"{accessory.unique_id}_rssi"
def get_characteristic_types(self) -> list[str]:
"""Define the homekit characteristics the entity cares about."""
return []
@ -602,11 +607,6 @@ class RSSISensor(HomeKitEntity, SensorEntity):
serial = self.accessory_info.value(CharacteristicsTypes.SERIAL_NUMBER)
return f"homekit-{serial}-rssi"
@property
def unique_id(self) -> str:
"""Return the ID of this device."""
return f"{self._accessory.unique_id}_rssi"
@property
def native_value(self) -> int | None:
"""Return the current rssi value."""

View file

@ -1,4 +1,5 @@
"""Helper functions for the homekit_controller component."""
from functools import lru_cache
from typing import cast
from aiohomekit import Controller
@ -11,6 +12,7 @@ from .const import CONTROLLER
from .storage import async_get_entity_storage
@lru_cache
def folded_name(name: str) -> str:
"""Return a name that is used for matching a similar string."""
return name.casefold().replace(" ", "")