Skip to content

Commit f23c2f7

Browse files
authored
Reset the connection on error during transaction (#81)
1 parent 7e9da59 commit f23c2f7

File tree

1 file changed

+32
-4
lines changed

1 file changed

+32
-4
lines changed

switchbot/devices/device.py

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import async_timeout
1111

1212
from bleak import BleakError
13+
from bleak.exc import BleakDBusError
1314
from bleak.backends.device import BLEDevice
1415
from bleak.backends.service import BleakGATTCharacteristic, BleakGATTServiceCollection
1516
from bleak_retry_connector import (
@@ -164,7 +165,7 @@ async def _ensure_connected(self):
164165
self.name,
165166
self._disconnected,
166167
cached_services=self._cached_services,
167-
ble_device_callback=lambda: self._device
168+
ble_device_callback=lambda: self._device,
168169
)
169170
self._cached_services = client.services
170171
_LOGGER.debug("%s: Connected; RSSI: %s", self.name, self.rssi)
@@ -199,15 +200,19 @@ def _disconnected(self, client: BleakClientWithServiceCache) -> None:
199200
def _disconnect(self):
200201
"""Disconnect from device."""
201202
self._disconnect_timer = None
202-
asyncio.create_task(self._execute_disconnect())
203+
asyncio.create_task(self._execute_timed_disconnect())
203204

204-
async def _execute_disconnect(self):
205-
"""Execute disconnection."""
205+
async def _execute_timed_disconnect(self):
206+
"""Execute timed disconnection."""
206207
_LOGGER.debug(
207208
"%s: Disconnecting after timeout of %s",
208209
self.name,
209210
DISCONNECT_DELAY,
210211
)
212+
await self._execute_disconnect()
213+
214+
async def _execute_disconnect(self):
215+
"""Execute disconnection."""
211216
async with self._connect_lock:
212217
if not self._client or not self._client.is_connected:
213218
return
@@ -220,6 +225,29 @@ async def _execute_disconnect(self):
220225
async def _send_command_locked(self, key: str, command: bytes) -> bytes:
221226
"""Send command to device and read response."""
222227
await self._ensure_connected()
228+
try:
229+
return await self._execute_command_locked(key, command)
230+
except BleakDBusError as ex:
231+
# Disconnect so we can reset state and try again
232+
await asyncio.sleep(0.25)
233+
_LOGGER.debug(
234+
"%s: RSSI: %s; Backing off %ss; Disconnecting due to error: %s",
235+
self.name,
236+
self.rssi,
237+
0.25,
238+
ex,
239+
)
240+
await self._execute_disconnect()
241+
except BleakError as ex:
242+
# Disconnect so we can reset state and try again
243+
_LOGGER.debug(
244+
"%s: RSSI: %s; Disconnecting due to error: %s", self.name, self.rssi, ex
245+
)
246+
await self._execute_disconnect()
247+
raise
248+
249+
async def _execute_command_locked(self, key: str, command: bytes) -> bytes:
250+
"""Execute command and read response."""
223251
assert self._client is not None
224252
assert self._read_char is not None
225253
assert self._write_char is not None

0 commit comments

Comments
 (0)