Skip to content

Commit ed87807

Browse files
authored
Fix connecting with bleak 0.15 (#54)
* Use an asyncio.Future for commands instead of a sleep * fixes * Fix connecting with bleak 0.15
1 parent b8d4a37 commit ed87807

File tree

1 file changed

+24
-21
lines changed

1 file changed

+24
-21
lines changed

switchbot/__init__.py

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -290,11 +290,6 @@ def __init__(
290290
self._password_encoded = "%x" % (
291291
binascii.crc32(password.encode("ascii")) & 0xFFFFFFFF
292292
)
293-
self._last_notification = bytearray()
294-
295-
async def _notification_handler(self, sender: int, data: bytearray) -> None:
296-
"""Handle notification responses."""
297-
self._last_notification = data
298293

299294
def _commandkey(self, key: str) -> str:
300295
"""Add password to key if set."""
@@ -325,33 +320,41 @@ async def _sendcommand(self, key: str, retry: int) -> bytes:
325320

326321
raise RuntimeError("Unreachable")
327322

323+
@property
324+
def name(self) -> str:
325+
"""Return device name."""
326+
return f"{self._device.name} ({self._device.address})"
327+
328328
async def _send_command_locked(self, key: str, command: bytes) -> bytes:
329329
"""Send command to device and read response."""
330330
client: BleakClient | None = None
331331
try:
332-
_LOGGER.debug("Connnecting to switchbot: %s", self._device.address)
333-
332+
_LOGGER.debug("%s: Connnecting to switchbot", self.name)
334333
client = await establish_connection(
335-
BleakClient, self._device.address, self._device, max_attempts=1
334+
BleakClient, self._device, self.name, max_attempts=1
336335
)
337-
_LOGGER.debug("Connnected to switchbot: %s", client.is_connected)
338-
339-
_LOGGER.debug("Subscribe to notifications")
340-
await client.start_notify(
341-
_sb_uuid(comms_type="rx"), self._notification_handler
336+
_LOGGER.debug(
337+
"%s: Connnected to switchbot: %s", self.name, client.is_connected
342338
)
339+
future: asyncio.Future[bytearray] = asyncio.Future()
343340

344-
_LOGGER.debug("Sending command, %s", key)
345-
await client.write_gatt_char(_sb_uuid(comms_type="tx"), command, False)
341+
def _notification_handler(sender: int, data: bytearray) -> None:
342+
"""Handle notification responses."""
343+
if future.done():
344+
_LOGGER.debug("%s: Notification handler already done", self.name)
345+
return
346+
future.set_result(data)
347+
348+
_LOGGER.debug("%s: Subscribe to notifications", self.name)
349+
await client.start_notify(_sb_uuid(comms_type="rx"), _notification_handler)
346350

347-
await asyncio.sleep(
348-
1.0
349-
) # Bot needs pause. Otherwise notification could be missed.
351+
_LOGGER.debug("%s: Sending command, %s", self.name, key)
352+
await client.write_gatt_char(_sb_uuid(comms_type="tx"), command, False)
350353

351-
notify_msg = self._last_notification
352-
_LOGGER.info("Notification received: %s", notify_msg)
354+
notify_msg = await asyncio.wait_for(future, timeout=5)
355+
_LOGGER.info("%s: Notification received: %s", self.name, notify_msg)
353356

354-
_LOGGER.debug("UnSubscribe to notifications")
357+
_LOGGER.debug("%s: UnSubscribe to notifications", self.name)
355358
await client.stop_notify(_sb_uuid(comms_type="rx"))
356359

357360
finally:

0 commit comments

Comments
 (0)