Skip to content

Commit

Permalink
fix: ensure adv updates are processed (#25)
Browse files Browse the repository at this point in the history
  • Loading branch information
bdraco authored Aug 2, 2022
1 parent 6a0842a commit b655379
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 27 deletions.
11 changes: 10 additions & 1 deletion poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ myst-parser = {version = "^0.18", optional = true}
bleak = ">=0.14.3"
pycryptodome = "^3.15.0"
bleak-retry-connector = ">=1.1.0"
async-timeout = ">=4.0.1"

[tool.poetry.extras]
docs = [
Expand Down
7 changes: 7 additions & 0 deletions src/yalexs_ble/lock.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,13 @@ def __init__(self, device: BLEDevice, keyString: str, keyIndex: int) -> None:
def set_name(self, name: str) -> None:
self.name = name

async def __aenter__(self) -> Lock:
await self.connect()
return self

async def __aexit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> None:
await self.disconnect()

def disconnected(self, *args: Any, **kwargs: Any) -> None:
_LOGGER.debug("%s: Disconnected from lock callback", self.name)
assert self._disconnected_event is not None # nosec
Expand Down
51 changes: 26 additions & 25 deletions src/yalexs_ble/push.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,13 +187,11 @@ async def lock(self) -> None:
self._callback_state(LockState(LockStatus.LOCKING, self.door_status))
lock = self._get_lock_instance()
try:
await lock.connect()
await lock.force_lock()
async with lock:
await lock.force_lock()
except Exception:
self._callback_state(LockState(LockStatus.UNKNOWN, self.door_status))
raise
finally:
await lock.disconnect()
self._callback_state(LockState(LockStatus.LOCKED, self.door_status))
await self._cancel_any_update()
_LOGGER.debug("Finished lock")
Expand All @@ -207,13 +205,11 @@ async def unlock(self) -> None:
self._callback_state(LockState(LockStatus.UNLOCKING, self.door_status))
lock = self._get_lock_instance()
try:
await lock.connect()
await lock.force_unlock()
async with lock:
await lock.force_unlock()
except Exception:
self._callback_state(LockState(LockStatus.UNKNOWN, self.door_status))
raise
finally:
await lock.disconnect()
self._callback_state(LockState(LockStatus.UNLOCKED, self.door_status))
await self._cancel_any_update()
_LOGGER.debug("Finished unlock")
Expand All @@ -224,17 +220,15 @@ async def update(self) -> LockState:
"""Update the lock state."""
lock = self._get_lock_instance()
try:
await lock.connect()
if not self._lock_info:
self._lock_info = await lock.lock_info()
state = await lock.status()
async with lock:
if not self._lock_info:
self._lock_info = await lock.lock_info()
state = await lock.status()
except asyncio.CancelledError:
_LOGGER.debug(
"%s: In-progress update canceled due to lock operation", self.name
)
raise
finally:
await lock.disconnect()
_LOGGER.debug("%s: Updating lock state", self.name)
self._callback_state(state)
return state
Expand Down Expand Up @@ -278,18 +272,25 @@ def update_advertisement(
if YALE_MFR_ID in mfr_data:
current_value = mfr_data[YALE_MFR_ID][0]
if current_value != self._last_adv_value:
if next_update:
next_update = min(next_update, ADV_UPDATE_COALESCE_SECONDS)
if not next_update:
next_update = ADV_UPDATE_COALESCE_SECONDS
self._last_adv_value = current_value
_LOGGER.debug(
"%s: State: (current_state: %s) (hk_state: %s) "
"(adv_value: %s) (next_update: %s)",
self.name,
self._lock_state,
self._last_hk_state,
self._last_adv_value,
next_update,
)
if _LOGGER.isEnabledFor(logging.DEBUG):
scheduled_update = None
if self._cancel_deferred_update:
scheduled_update = (
self._cancel_deferred_update.when() - self.loop.time()
)
_LOGGER.debug(
"%s: State: (current_state: %s) (hk_state: %s) "
"(adv_value: %s) (next_update: %s) (scheduled_update: %s)",
self.name,
self._lock_state,
self._last_hk_state,
self._last_adv_value,
next_update,
scheduled_update,
)
if next_update:
self._schedule_update(next_update)

Expand Down
4 changes: 3 additions & 1 deletion src/yalexs_ble/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import logging
from typing import Callable

import async_timeout
from bleak import BleakClient
from bleak_retry_connector import BleakError
from Crypto.Cipher import AES # nosec
Expand Down Expand Up @@ -139,7 +140,8 @@ async def _locked_write(self, command: bytearray) -> bytes:
)
await self.client.write_gatt_char(self.write_characteristic, command, True)
_LOGGER.debug("%s: Waiting for response", self.name)
result = await asyncio.wait_for(future, timeout=5)
async with async_timeout.timeout(5):
result = await future
_LOGGER.debug("%s: Got response: %s", self.name, result.hex())
return result

Expand Down

0 comments on commit b655379

Please sign in to comment.