mirror of
https://github.com/esphome/aioesphomeapi.git
synced 2024-12-26 17:27:40 +01:00
Fix BLE connection timing out on failure instead of raising (#429)
This commit is contained in:
parent
85e19020fa
commit
7b8ed9fd03
@ -529,8 +529,10 @@ class APIClient:
|
||||
resp = BluetoothDeviceConnection.from_pb(msg)
|
||||
if address == resp.address:
|
||||
on_bluetooth_connection_state(resp.connected, resp.mtu, resp.error)
|
||||
if resp.connected:
|
||||
event.set()
|
||||
# Resolve on ANY connection state since we do not want
|
||||
# to wait the whole timeout if the device disconnects
|
||||
# or we get an error.
|
||||
event.set()
|
||||
|
||||
assert self._connection is not None
|
||||
if has_cache:
|
||||
@ -570,26 +572,27 @@ class APIClient:
|
||||
# Disconnect before raising the exception to ensure
|
||||
# the slot is recovered before the timeout is raised
|
||||
# to avoid race were we run out even though we have a slot.
|
||||
await self.bluetooth_device_disconnect(address)
|
||||
addr = to_human_readable_address(address)
|
||||
_LOGGER.debug("%s: Connecting timed out, waiting for disconnect", addr)
|
||||
disconnect_timed_out = False
|
||||
try:
|
||||
async with async_timeout.timeout(disconnect_timeout):
|
||||
await event.wait()
|
||||
disconnect_timed_out = False
|
||||
except asyncio.TimeoutError:
|
||||
disconnect_timed_out = True
|
||||
_LOGGER.debug(
|
||||
"%s: Disconnect timed out: %s", addr, disconnect_timed_out
|
||||
)
|
||||
try:
|
||||
unsub()
|
||||
except (KeyError, ValueError):
|
||||
_LOGGER.warning(
|
||||
"%s: Bluetooth device connection timed out but already unsubscribed "
|
||||
"(likely due to unexpected disconnect)",
|
||||
addr,
|
||||
await self.bluetooth_device_disconnect(
|
||||
address, timeout=disconnect_timeout
|
||||
)
|
||||
except TimeoutAPIError:
|
||||
disconnect_timed_out = True
|
||||
_LOGGER.debug(
|
||||
"%s: Disconnect timed out: %s", addr, disconnect_timed_out
|
||||
)
|
||||
finally:
|
||||
try:
|
||||
unsub()
|
||||
except (KeyError, ValueError):
|
||||
_LOGGER.warning(
|
||||
"%s: Bluetooth device connection timed out but already unsubscribed "
|
||||
"(likely due to unexpected disconnect)",
|
||||
addr,
|
||||
)
|
||||
raise TimeoutAPIError(
|
||||
f"Timeout waiting for connect response while connecting to {addr} "
|
||||
f"after {timeout}s, disconnect timed out: {disconnect_timed_out}, "
|
||||
@ -693,15 +696,24 @@ class APIClient:
|
||||
|
||||
return BluetoothDeviceClearCache.from_pb(response)
|
||||
|
||||
async def bluetooth_device_disconnect(self, address: int) -> None:
|
||||
async def bluetooth_device_disconnect(
|
||||
self, address: int, timeout: float = DEFAULT_BLE_DISCONNECT_TIMEOUT
|
||||
) -> None:
|
||||
self._check_authenticated()
|
||||
|
||||
def predicate_func(msg: BluetoothDeviceConnectionResponse) -> bool:
|
||||
return bool(msg.address == address and not msg.connected)
|
||||
|
||||
assert self._connection is not None
|
||||
self._connection.send_message(
|
||||
await self._connection.send_message_await_response_complex(
|
||||
BluetoothDeviceRequest(
|
||||
address=address,
|
||||
request_type=BluetoothDeviceRequestType.DISCONNECT,
|
||||
)
|
||||
),
|
||||
predicate_func,
|
||||
predicate_func,
|
||||
(BluetoothDeviceConnectionResponse,),
|
||||
timeout=timeout,
|
||||
)
|
||||
|
||||
async def bluetooth_gatt_get_services(
|
||||
|
Loading…
Reference in New Issue
Block a user