Ensure bluetooth disconnect callback fires if esphome config entry is reloaded (#79389)

This commit is contained in:
J. Nick Koston 2022-10-01 14:42:54 -10:00 committed by GitHub
parent d03553bbf0
commit dac60990ee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -15,10 +15,9 @@ from bleak.backends.device import BLEDevice
from bleak.backends.service import BleakGATTServiceCollection from bleak.backends.service import BleakGATTServiceCollection
from bleak.exc import BleakError from bleak.exc import BleakError
from homeassistant.core import CALLBACK_TYPE, async_get_hass, callback as hass_callback from homeassistant.core import CALLBACK_TYPE, async_get_hass
from ..domain_data import DomainData from ..domain_data import DomainData
from ..entry_data import RuntimeEntryData
from .characteristic import BleakGATTCharacteristicESPHome from .characteristic import BleakGATTCharacteristicESPHome
from .descriptor import BleakGATTDescriptorESPHome from .descriptor import BleakGATTDescriptorESPHome
from .service import BleakGATTServiceESPHome from .service import BleakGATTServiceESPHome
@ -85,7 +84,9 @@ class ESPHomeClient(BaseBleakClient):
assert self._ble_device.details is not None assert self._ble_device.details is not None
self._source = self._ble_device.details["source"] self._source = self._ble_device.details["source"]
self.domain_data = DomainData.get(async_get_hass()) self.domain_data = DomainData.get(async_get_hass())
self._client = self._async_get_entry_data().client config_entry = self.domain_data.get_by_unique_id(self._source)
self.entry_data = self.domain_data.get_entry_data(config_entry)
self._client = self.entry_data.client
self._is_connected = False self._is_connected = False
self._mtu: int | None = None self._mtu: int | None = None
self._cancel_connection_state: CALLBACK_TYPE | None = None self._cancel_connection_state: CALLBACK_TYPE | None = None
@ -108,12 +109,6 @@ class ESPHomeClient(BaseBleakClient):
) )
self._cancel_connection_state = None self._cancel_connection_state = None
@hass_callback
def _async_get_entry_data(self) -> RuntimeEntryData:
"""Get the entry data."""
config_entry = self.domain_data.get_by_unique_id(self._source)
return self.domain_data.get_entry_data(config_entry)
def _async_ble_device_disconnected(self) -> None: def _async_ble_device_disconnected(self) -> None:
"""Handle the BLE device disconnecting from the ESP.""" """Handle the BLE device disconnecting from the ESP."""
_LOGGER.debug("%s: BLE device disconnected", self._source) _LOGGER.debug("%s: BLE device disconnected", self._source)
@ -125,8 +120,7 @@ class ESPHomeClient(BaseBleakClient):
def _async_esp_disconnected(self) -> None: def _async_esp_disconnected(self) -> None:
"""Handle the esp32 client disconnecting from hass.""" """Handle the esp32 client disconnecting from hass."""
_LOGGER.debug("%s: ESP device disconnected", self._source) _LOGGER.debug("%s: ESP device disconnected", self._source)
entry_data = self._async_get_entry_data() self.entry_data.disconnect_callbacks.remove(self._async_esp_disconnected)
entry_data.disconnect_callbacks.remove(self._async_esp_disconnected)
self._async_ble_device_disconnected() self._async_ble_device_disconnected()
def _async_call_bleak_disconnected_callback(self) -> None: def _async_call_bleak_disconnected_callback(self) -> None:
@ -179,8 +173,7 @@ class ESPHomeClient(BaseBleakClient):
connected_future.set_exception(BleakError("Disconnected")) connected_future.set_exception(BleakError("Disconnected"))
return return
entry_data = self._async_get_entry_data() self.entry_data.disconnect_callbacks.append(self._async_esp_disconnected)
entry_data.disconnect_callbacks.append(self._async_esp_disconnected)
connected_future.set_result(connected) connected_future.set_result(connected)
timeout = kwargs.get("timeout", self._timeout) timeout = kwargs.get("timeout", self._timeout)
@ -203,14 +196,13 @@ class ESPHomeClient(BaseBleakClient):
async def _wait_for_free_connection_slot(self, timeout: float) -> None: async def _wait_for_free_connection_slot(self, timeout: float) -> None:
"""Wait for a free connection slot.""" """Wait for a free connection slot."""
entry_data = self._async_get_entry_data() if self.entry_data.ble_connections_free:
if entry_data.ble_connections_free:
return return
_LOGGER.debug( _LOGGER.debug(
"%s: Out of connection slots, waiting for a free one", self._source "%s: Out of connection slots, waiting for a free one", self._source
) )
async with async_timeout.timeout(timeout): async with async_timeout.timeout(timeout):
await entry_data.wait_for_ble_connections_free() await self.entry_data.wait_for_ble_connections_free()
@property @property
def is_connected(self) -> bool: def is_connected(self) -> bool: