Support HomeKit Controller Thread Provisioning (#87809)
This commit is contained in:
parent
402170d49e
commit
f5a05c1bd2
7 changed files with 220 additions and 4 deletions
|
@ -9,6 +9,7 @@ from types import MappingProxyType
|
|||
from typing import Any
|
||||
|
||||
from aiohomekit import Controller
|
||||
from aiohomekit.controller import TransportType
|
||||
from aiohomekit.exceptions import (
|
||||
AccessoryDisconnectedError,
|
||||
AccessoryNotFoundError,
|
||||
|
@ -16,11 +17,13 @@ from aiohomekit.exceptions import (
|
|||
)
|
||||
from aiohomekit.model import Accessories, Accessory, Transport
|
||||
from aiohomekit.model.characteristics import Characteristic
|
||||
from aiohomekit.model.services import Service
|
||||
from aiohomekit.model.services import Service, ServicesTypes
|
||||
|
||||
from homeassistant.components.thread.dataset_store import async_get_preferred_dataset
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import ATTR_VIA_DEVICE, EVENT_HOMEASSISTANT_STARTED
|
||||
from homeassistant.core import CoreState, Event, HomeAssistant, callback
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.helpers import device_registry as dr, entity_registry as er
|
||||
from homeassistant.helpers.debounce import Debouncer
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_send
|
||||
|
@ -772,6 +775,59 @@ class HKDevice:
|
|||
"""Control a HomeKit device state from Home Assistant."""
|
||||
await self.pairing.put_characteristics(characteristics)
|
||||
|
||||
@property
|
||||
def is_unprovisioned_thread_device(self) -> bool:
|
||||
"""Is this a thread capable device not connected by CoAP."""
|
||||
if self.pairing.controller.transport_type != TransportType.BLE:
|
||||
return False
|
||||
|
||||
if not self.entity_map.aid(1).services.first(
|
||||
service_type=ServicesTypes.THREAD_TRANSPORT
|
||||
):
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
async def async_thread_provision(self) -> None:
|
||||
"""Migrate a HomeKit pairing to CoAP (Thread)."""
|
||||
if self.pairing.controller.transport_type == TransportType.COAP:
|
||||
raise HomeAssistantError("Already connected to a thread network")
|
||||
|
||||
if not (dataset := await async_get_preferred_dataset(self.hass)):
|
||||
raise HomeAssistantError("No thread network credentials available")
|
||||
|
||||
await self.pairing.thread_provision(dataset)
|
||||
|
||||
try:
|
||||
discovery = (
|
||||
await self.hass.data[CONTROLLER]
|
||||
.transports[TransportType.COAP]
|
||||
.async_find(self.unique_id, timeout=30)
|
||||
)
|
||||
self.hass.config_entries.async_update_entry(
|
||||
self.config_entry,
|
||||
data={
|
||||
**self.config_entry.data,
|
||||
"Connection": "CoAP",
|
||||
"AccessoryIP": discovery.description.address,
|
||||
"AccessoryPort": discovery.description.port,
|
||||
},
|
||||
)
|
||||
_LOGGER.debug(
|
||||
"%s: Found device on local network, migrating integration to Thread",
|
||||
self.unique_id,
|
||||
)
|
||||
|
||||
except AccessoryNotFoundError as exc:
|
||||
_LOGGER.debug(
|
||||
"%s: Failed to appear on local network as a Thread device, reverting to BLE",
|
||||
self.unique_id,
|
||||
)
|
||||
raise HomeAssistantError("Could not migrate device to Thread") from exc
|
||||
|
||||
finally:
|
||||
await self.hass.config_entries.async_reload(self.config_entry.entry_id)
|
||||
|
||||
@property
|
||||
def unique_id(self) -> str:
|
||||
"""Return a unique id for this accessory or bridge.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue