1 """Support for Homekit device discovery."""
3 from __future__
import annotations
10 from aiohomekit.const
import (
11 BLE_TRANSPORT_SUPPORTED,
12 COAP_TRANSPORT_SUPPORTED,
13 IP_TRANSPORT_SUPPORTED,
15 from aiohomekit.exceptions
import (
16 AccessoryDisconnectedError,
17 AccessoryNotFoundError,
29 from .config_flow
import normalize_hkid
30 from .connection
import HKDevice
31 from .const
import DOMAIN, KNOWN_DEVICES
32 from .utils
import async_get_controller
36 if BLE_TRANSPORT_SUPPORTED:
37 from aiohomekit.controller
import ble
38 if COAP_TRANSPORT_SUPPORTED:
39 from aiohomekit.controller
import coap
40 if IP_TRANSPORT_SUPPORTED:
41 from aiohomekit.controller
import ip
43 _LOGGER = logging.getLogger(__name__)
45 CONFIG_SCHEMA = cv.config_entry_only_config_schema(DOMAIN)
49 """Set up a HomeKit connection on a config entry."""
50 conn =
HKDevice(hass, entry, entry.data)
51 hass.data[KNOWN_DEVICES][conn.unique_id] = conn
54 if entry.unique_id
is None:
55 hass.config_entries.async_update_entry(
60 await conn.async_setup()
63 AccessoryNotFoundError,
65 AccessoryDisconnectedError,
67 del hass.data[KNOWN_DEVICES][conn.unique_id]
68 with contextlib.suppress(TimeoutError):
69 await conn.pairing.close()
70 raise ConfigEntryNotReady
from ex
75 async
def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
76 """Set up for Homekit devices."""
79 hass.data[KNOWN_DEVICES] = {}
81 async
def _async_stop_homekit_controller(event: Event) ->
None:
84 create_eager_task(connection.async_unload())
85 for connection
in hass.data[KNOWN_DEVICES].values()
89 hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, _async_stop_homekit_controller)
95 """Disconnect from HomeKit devices before unloading entry."""
96 hkid = entry.data[
"AccessoryPairingID"]
98 if hkid
in hass.data[KNOWN_DEVICES]:
99 connection: HKDevice = hass.data[KNOWN_DEVICES][hkid]
100 await connection.async_unload()
106 """Cleanup caches before removing config entry."""
107 hkid = entry.data[
"AccessoryPairingID"]
113 controller.load_pairing(hkid,
dict(entry.data))
115 await controller.remove_pairing(hkid)
116 except aiohomekit.AccessoryDisconnectedError:
119 "Accessory %s was removed from HomeAssistant but was not reachable "
120 "to properly unpair. It may need resetting before you can use it with "
128 hass: HomeAssistant, config_entry: ConfigEntry, device_entry: dr.DeviceEntry
130 """Remove homekit_controller config entry from a device."""
131 hkid = config_entry.data[
"AccessoryPairingID"]
132 connection: HKDevice = hass.data[KNOWN_DEVICES][hkid]
133 return not device_entry.identifiers.intersection(
135 for accessory
in connection.entity_map.accessories
136 for identifier
in connection.device_info_for_accessory(accessory)[
str normalize_hkid(str hkid)
Controller async_get_controller(HomeAssistant hass)
None async_remove_entry(HomeAssistant hass, ConfigEntry entry)
bool async_remove_config_entry_device(HomeAssistant hass, ConfigEntry config_entry, dr.DeviceEntry device_entry)
bool async_unload_entry(HomeAssistant hass, ConfigEntry entry)
bool async_setup_entry(HomeAssistant hass, ConfigEntry entry)
bool async_setup(HomeAssistant hass, ConfigType config)