mirror of
https://github.com/home-assistant/core.git
synced 2025-07-20 03:37:07 +00:00
Prevent executor overload when starting many homekit instances (#59950)
This commit is contained in:
parent
073bf6d6fd
commit
2f00f8d3de
@ -1,4 +1,6 @@
|
|||||||
"""Support for Apple HomeKit."""
|
"""Support for Apple HomeKit."""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
import ipaddress
|
import ipaddress
|
||||||
import logging
|
import logging
|
||||||
@ -91,6 +93,7 @@ from .const import (
|
|||||||
HOMEKIT_PAIRING_QR,
|
HOMEKIT_PAIRING_QR,
|
||||||
HOMEKIT_PAIRING_QR_SECRET,
|
HOMEKIT_PAIRING_QR_SECRET,
|
||||||
MANUFACTURER,
|
MANUFACTURER,
|
||||||
|
PERSIST_LOCK,
|
||||||
SERVICE_HOMEKIT_RESET_ACCESSORY,
|
SERVICE_HOMEKIT_RESET_ACCESSORY,
|
||||||
SERVICE_HOMEKIT_START,
|
SERVICE_HOMEKIT_START,
|
||||||
SERVICE_HOMEKIT_UNPAIR,
|
SERVICE_HOMEKIT_UNPAIR,
|
||||||
@ -171,6 +174,15 @@ UNPAIR_SERVICE_SCHEMA = vol.All(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _async_all_homekit_instances(hass: HomeAssistant) -> list[HomeKit]:
|
||||||
|
"""All active HomeKit instances."""
|
||||||
|
return [
|
||||||
|
data[HOMEKIT]
|
||||||
|
for data in hass.data[DOMAIN].values()
|
||||||
|
if isinstance(data, dict) and HOMEKIT in data
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
def _async_get_entries_by_name(current_entries):
|
def _async_get_entries_by_name(current_entries):
|
||||||
"""Return a dict of the entries by name."""
|
"""Return a dict of the entries by name."""
|
||||||
|
|
||||||
@ -181,7 +193,7 @@ def _async_get_entries_by_name(current_entries):
|
|||||||
|
|
||||||
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
||||||
"""Set up the HomeKit from yaml."""
|
"""Set up the HomeKit from yaml."""
|
||||||
hass.data.setdefault(DOMAIN, {})
|
hass.data.setdefault(DOMAIN, {})[PERSIST_LOCK] = asyncio.Lock()
|
||||||
|
|
||||||
_async_register_events_and_services(hass)
|
_async_register_events_and_services(hass)
|
||||||
|
|
||||||
@ -360,10 +372,7 @@ def _async_register_events_and_services(hass: HomeAssistant):
|
|||||||
|
|
||||||
async def async_handle_homekit_reset_accessory(service):
|
async def async_handle_homekit_reset_accessory(service):
|
||||||
"""Handle reset accessory HomeKit service call."""
|
"""Handle reset accessory HomeKit service call."""
|
||||||
for entry_id in hass.data[DOMAIN]:
|
for homekit in _async_all_homekit_instances(hass):
|
||||||
if HOMEKIT not in hass.data[DOMAIN][entry_id]:
|
|
||||||
continue
|
|
||||||
homekit = hass.data[DOMAIN][entry_id][HOMEKIT]
|
|
||||||
if homekit.status != STATUS_RUNNING:
|
if homekit.status != STATUS_RUNNING:
|
||||||
_LOGGER.warning(
|
_LOGGER.warning(
|
||||||
"HomeKit is not running. Either it is waiting to be "
|
"HomeKit is not running. Either it is waiting to be "
|
||||||
@ -393,16 +402,11 @@ def _async_register_events_and_services(hass: HomeAssistant):
|
|||||||
for ctype, cval in dev_reg_ent.connections
|
for ctype, cval in dev_reg_ent.connections
|
||||||
if ctype == device_registry.CONNECTION_NETWORK_MAC
|
if ctype == device_registry.CONNECTION_NETWORK_MAC
|
||||||
]
|
]
|
||||||
domain_data = hass.data[DOMAIN]
|
|
||||||
matching_instances = [
|
matching_instances = [
|
||||||
domain_data[entry_id][HOMEKIT]
|
homekit
|
||||||
for entry_id in domain_data
|
for homekit in _async_all_homekit_instances(hass)
|
||||||
if HOMEKIT in domain_data[entry_id]
|
if homekit.driver
|
||||||
and domain_data[entry_id][HOMEKIT].driver
|
and device_registry.format_mac(homekit.driver.state.mac) in macs
|
||||||
and device_registry.format_mac(
|
|
||||||
domain_data[entry_id][HOMEKIT].driver.state.mac
|
|
||||||
)
|
|
||||||
in macs
|
|
||||||
]
|
]
|
||||||
if not matching_instances:
|
if not matching_instances:
|
||||||
raise HomeAssistantError(
|
raise HomeAssistantError(
|
||||||
@ -421,10 +425,7 @@ def _async_register_events_and_services(hass: HomeAssistant):
|
|||||||
async def async_handle_homekit_service_start(service):
|
async def async_handle_homekit_service_start(service):
|
||||||
"""Handle start HomeKit service call."""
|
"""Handle start HomeKit service call."""
|
||||||
tasks = []
|
tasks = []
|
||||||
for entry_id in hass.data[DOMAIN]:
|
for homekit in _async_all_homekit_instances(hass):
|
||||||
if HOMEKIT not in hass.data[DOMAIN][entry_id]:
|
|
||||||
continue
|
|
||||||
homekit = hass.data[DOMAIN][entry_id][HOMEKIT]
|
|
||||||
if homekit.status == STATUS_RUNNING:
|
if homekit.status == STATUS_RUNNING:
|
||||||
_LOGGER.debug("HomeKit is already running")
|
_LOGGER.debug("HomeKit is already running")
|
||||||
continue
|
continue
|
||||||
@ -707,7 +708,8 @@ class HomeKit:
|
|||||||
self._async_register_bridge()
|
self._async_register_bridge()
|
||||||
_LOGGER.debug("Driver start for %s", self._name)
|
_LOGGER.debug("Driver start for %s", self._name)
|
||||||
await self.driver.async_start()
|
await self.driver.async_start()
|
||||||
self.driver.async_persist()
|
async with self.hass.data[DOMAIN][PERSIST_LOCK]:
|
||||||
|
await self.hass.async_add_executor_job(self.driver.persist)
|
||||||
self.status = STATUS_RUNNING
|
self.status = STATUS_RUNNING
|
||||||
|
|
||||||
if self.driver.state.paired:
|
if self.driver.state.paired:
|
||||||
|
@ -12,6 +12,7 @@ HOMEKIT_PAIRING_QR_SECRET = "homekit-pairing-qr-secret"
|
|||||||
HOMEKIT = "homekit"
|
HOMEKIT = "homekit"
|
||||||
SHUTDOWN_TIMEOUT = 30
|
SHUTDOWN_TIMEOUT = 30
|
||||||
CONF_ENTRY_INDEX = "index"
|
CONF_ENTRY_INDEX = "index"
|
||||||
|
PERSIST_LOCK = "persist_lock"
|
||||||
|
|
||||||
# ### Codecs ####
|
# ### Codecs ####
|
||||||
VIDEO_CODEC_COPY = "copy"
|
VIDEO_CODEC_COPY = "copy"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user