mirror of
https://github.com/home-assistant/core.git
synced 2025-07-21 12:17:07 +00:00
Fix esphome ble client leaking notify on disconnect (#83106)
* Fix esphome ble client leaking notify on disconnect needs: https://github.com/esphome/aioesphomeapi/pull/329 * leak * more cleanup * more cleanup * bump
This commit is contained in:
parent
03154e1d83
commit
de1e97a81f
@ -142,7 +142,9 @@ class ESPHomeClient(BaseBleakClient):
|
||||
self._is_connected = False
|
||||
self._mtu: int | None = None
|
||||
self._cancel_connection_state: CALLBACK_TYPE | None = None
|
||||
self._notify_cancels: dict[int, Callable[[], Coroutine[Any, Any, None]]] = {}
|
||||
self._notify_cancels: dict[
|
||||
int, tuple[Callable[[], Coroutine[Any, Any, None]], Callable[[], None]]
|
||||
] = {}
|
||||
self._disconnected_event: asyncio.Event | None = None
|
||||
device_info = self.entry_data.device_info
|
||||
assert device_info is not None
|
||||
@ -169,15 +171,22 @@ class ESPHomeClient(BaseBleakClient):
|
||||
)
|
||||
self._cancel_connection_state = None
|
||||
|
||||
def _async_ble_device_disconnected(self) -> None:
|
||||
"""Handle the BLE device disconnecting from the ESP."""
|
||||
was_connected = self._is_connected
|
||||
def _async_disconnected_cleanup(self) -> None:
|
||||
"""Clean up on disconnect."""
|
||||
self.services = BleakGATTServiceCollection() # type: ignore[no-untyped-call]
|
||||
self._is_connected = False
|
||||
for _, notify_abort in self._notify_cancels.values():
|
||||
notify_abort()
|
||||
self._notify_cancels.clear()
|
||||
if self._disconnected_event:
|
||||
self._disconnected_event.set()
|
||||
self._disconnected_event = None
|
||||
self._unsubscribe_connection_state()
|
||||
|
||||
def _async_ble_device_disconnected(self) -> None:
|
||||
"""Handle the BLE device disconnecting from the ESP."""
|
||||
was_connected = self._is_connected
|
||||
self._async_disconnected_cleanup()
|
||||
if was_connected:
|
||||
_LOGGER.debug(
|
||||
"%s: %s - %s: BLE device disconnected",
|
||||
@ -186,7 +195,6 @@ class ESPHomeClient(BaseBleakClient):
|
||||
self._ble_device.address,
|
||||
)
|
||||
self._async_call_bleak_disconnected_callback()
|
||||
self._unsubscribe_connection_state()
|
||||
|
||||
def _async_esp_disconnected(self) -> None:
|
||||
"""Handle the esp32 client disconnecting from hass."""
|
||||
@ -316,7 +324,7 @@ class ESPHomeClient(BaseBleakClient):
|
||||
@api_error_as_bleak_error
|
||||
async def disconnect(self) -> bool:
|
||||
"""Disconnect from the peripheral device."""
|
||||
self._unsubscribe_connection_state()
|
||||
self._async_disconnected_cleanup()
|
||||
await self._client.bluetooth_device_disconnect(self._address_as_int)
|
||||
await self._wait_for_free_connection_slot(DISCONNECT_TIMEOUT)
|
||||
return True
|
||||
@ -551,12 +559,13 @@ class ESPHomeClient(BaseBleakClient):
|
||||
f"Characteristic {characteristic.uuid} does not have notify or indicate property set."
|
||||
)
|
||||
|
||||
cancel_coro = await self._client.bluetooth_gatt_start_notify(
|
||||
self._notify_cancels[
|
||||
ble_handle
|
||||
] = await self._client.bluetooth_gatt_start_notify(
|
||||
self._address_as_int,
|
||||
ble_handle,
|
||||
lambda handle, data: callback(data),
|
||||
)
|
||||
self._notify_cancels[ble_handle] = cancel_coro
|
||||
|
||||
if self._connection_version < MIN_BLUETOOTH_PROXY_VERSION_HAS_CACHE:
|
||||
return
|
||||
@ -604,8 +613,9 @@ class ESPHomeClient(BaseBleakClient):
|
||||
characteristic = self._resolve_characteristic(char_specifier)
|
||||
# Do not raise KeyError if notifications are not enabled on this characteristic
|
||||
# to be consistent with the behavior of the BlueZ backend
|
||||
if coro := self._notify_cancels.pop(characteristic.handle, None):
|
||||
await coro()
|
||||
if notify_cancel := self._notify_cancels.pop(characteristic.handle, None):
|
||||
notify_stop, _ = notify_cancel
|
||||
await notify_stop()
|
||||
|
||||
def __del__(self) -> None:
|
||||
"""Destructor to make sure the connection state is unsubscribed."""
|
||||
@ -617,4 +627,4 @@ class ESPHomeClient(BaseBleakClient):
|
||||
self._ble_device.address,
|
||||
)
|
||||
if not self._hass.loop.is_closed():
|
||||
self._hass.loop.call_soon_threadsafe(self._unsubscribe_connection_state)
|
||||
self._hass.loop.call_soon_threadsafe(self._async_disconnected_cleanup)
|
||||
|
@ -3,7 +3,7 @@
|
||||
"name": "ESPHome",
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/esphome",
|
||||
"requirements": ["aioesphomeapi==12.2.1"],
|
||||
"requirements": ["aioesphomeapi==13.0.0"],
|
||||
"zeroconf": ["_esphomelib._tcp.local."],
|
||||
"dhcp": [{ "registered_devices": true }],
|
||||
"codeowners": ["@OttoWinter", "@jesserockz"],
|
||||
|
@ -156,7 +156,7 @@ aioecowitt==2022.11.0
|
||||
aioemonitor==1.0.5
|
||||
|
||||
# homeassistant.components.esphome
|
||||
aioesphomeapi==12.2.1
|
||||
aioesphomeapi==13.0.0
|
||||
|
||||
# homeassistant.components.flo
|
||||
aioflo==2021.11.0
|
||||
|
@ -143,7 +143,7 @@ aioecowitt==2022.11.0
|
||||
aioemonitor==1.0.5
|
||||
|
||||
# homeassistant.components.esphome
|
||||
aioesphomeapi==12.2.1
|
||||
aioesphomeapi==13.0.0
|
||||
|
||||
# homeassistant.components.flo
|
||||
aioflo==2021.11.0
|
||||
|
Loading…
x
Reference in New Issue
Block a user