mirror of
https://github.com/esphome/aioesphomeapi.git
synced 2025-01-13 20:11:42 +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)
|
resp = BluetoothDeviceConnection.from_pb(msg)
|
||||||
if address == resp.address:
|
if address == resp.address:
|
||||||
on_bluetooth_connection_state(resp.connected, resp.mtu, resp.error)
|
on_bluetooth_connection_state(resp.connected, resp.mtu, resp.error)
|
||||||
if resp.connected:
|
# Resolve on ANY connection state since we do not want
|
||||||
event.set()
|
# to wait the whole timeout if the device disconnects
|
||||||
|
# or we get an error.
|
||||||
|
event.set()
|
||||||
|
|
||||||
assert self._connection is not None
|
assert self._connection is not None
|
||||||
if has_cache:
|
if has_cache:
|
||||||
@ -570,26 +572,27 @@ class APIClient:
|
|||||||
# Disconnect before raising the exception to ensure
|
# Disconnect before raising the exception to ensure
|
||||||
# the slot is recovered before the timeout is raised
|
# the slot is recovered before the timeout is raised
|
||||||
# to avoid race were we run out even though we have a slot.
|
# 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)
|
addr = to_human_readable_address(address)
|
||||||
_LOGGER.debug("%s: Connecting timed out, waiting for disconnect", addr)
|
_LOGGER.debug("%s: Connecting timed out, waiting for disconnect", addr)
|
||||||
|
disconnect_timed_out = False
|
||||||
try:
|
try:
|
||||||
async with async_timeout.timeout(disconnect_timeout):
|
await self.bluetooth_device_disconnect(
|
||||||
await event.wait()
|
address, timeout=disconnect_timeout
|
||||||
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,
|
|
||||||
)
|
)
|
||||||
|
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(
|
raise TimeoutAPIError(
|
||||||
f"Timeout waiting for connect response while connecting to {addr} "
|
f"Timeout waiting for connect response while connecting to {addr} "
|
||||||
f"after {timeout}s, disconnect timed out: {disconnect_timed_out}, "
|
f"after {timeout}s, disconnect timed out: {disconnect_timed_out}, "
|
||||||
@ -693,15 +696,24 @@ class APIClient:
|
|||||||
|
|
||||||
return BluetoothDeviceClearCache.from_pb(response)
|
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()
|
self._check_authenticated()
|
||||||
|
|
||||||
|
def predicate_func(msg: BluetoothDeviceConnectionResponse) -> bool:
|
||||||
|
return bool(msg.address == address and not msg.connected)
|
||||||
|
|
||||||
assert self._connection is not None
|
assert self._connection is not None
|
||||||
self._connection.send_message(
|
await self._connection.send_message_await_response_complex(
|
||||||
BluetoothDeviceRequest(
|
BluetoothDeviceRequest(
|
||||||
address=address,
|
address=address,
|
||||||
request_type=BluetoothDeviceRequestType.DISCONNECT,
|
request_type=BluetoothDeviceRequestType.DISCONNECT,
|
||||||
)
|
),
|
||||||
|
predicate_func,
|
||||||
|
predicate_func,
|
||||||
|
(BluetoothDeviceConnectionResponse,),
|
||||||
|
timeout=timeout,
|
||||||
)
|
)
|
||||||
|
|
||||||
async def bluetooth_gatt_get_services(
|
async def bluetooth_gatt_get_services(
|
||||||
|
Loading…
Reference in New Issue
Block a user