Skip to content

Commit

Permalink
add unavailable callback
Browse files Browse the repository at this point in the history
  • Loading branch information
zweckj committed Dec 5, 2023
1 parent 2bfaeb9 commit 994ca42
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 42 deletions.
85 changes: 44 additions & 41 deletions pyacaia_async/acaiascale.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ def __init__(
self._client: BleakClient | None = None
self._connected = False
self._disconnecting = False
self._last_disconnect_time: float | None = None
self._timer_running = False
self._timestamp_last_command: float | None = None
self._timer_start: float | None = None
Expand All @@ -63,7 +64,6 @@ def __init__(
self._queue: asyncio.Queue = asyncio.Queue()
self._heartbeat_task: asyncio.Task | None = None
self._process_queue_task: asyncio.Task | None = None
self._tasks_initialized = False

self._msg_types["auth"] = encode_id(is_pyxis_style=is_new_style_scale)

Expand Down Expand Up @@ -94,11 +94,6 @@ def connected(self) -> bool:
"""Return whether the scale is connected."""
return self._connected

@connected.setter
def connected(self, value: bool) -> None:
"""Set connected state."""
self._connected = value

@property
def data(self) -> dict[str, Any]:
"""Return the data of the scale."""
Expand All @@ -117,9 +112,15 @@ async def create(
self = cls(mac, is_new_style_scale)

if ble_device:
self._client = BleakClient(ble_device)
self._client = BleakClient(
address_or_ble_device=ble_device,
disconnected_callback=self._device_disconnected_callback,
)
elif mac:
self._client = BleakClient(mac)
self._client = BleakClient(
address_or_ble_device=mac,
disconnected_callback=self._device_disconnected_callback,
)
else:
raise ValueError("Either mac or bleDevice must be specified")

Expand All @@ -143,30 +144,37 @@ def timer(self) -> int:

return int(self._timer_stop - self._timer_start)

def _device_disconnected_callback(self, client: BleakClient) -> None:
"""Callback for device disconnected."""
_LOGGER.debug("Device disconnected")
self._connected = False
self._last_disconnect_time = time.time()
if self._notify_callback:
self._notify_callback()

def new_client_from_ble_device(self, ble_device: BLEDevice) -> None:
"""Create a new client from a BLEDevice, used for Home Assistant"""
self._client = BleakClient(ble_device)
self._client = BleakClient(
address_or_ble_device=ble_device,
disconnected_callback=self._device_disconnected_callback,
)

async def _write_msg(self, char_id: str, payload: bytearray) -> None:
"""wrapper for writing to the device."""
try:
if not self._connected:
return
assert self._client
_LOGGER.debug("Writing to device...")
await self._client.write_gatt_char(char_id, payload)
self._timestamp_last_command = time.time()
except BleakDeviceNotFoundError as ex:
self._connected = False
raise AcaiaDeviceNotFound("Device not found") from ex
except BleakError as ex:
self._connected = False
raise AcaiaError("Error writing to device") from ex
except TimeoutError as ex:
self._connected = False
raise AcaiaError("Timeout writing to device") from ex
except Exception as ex:
self._connected = False
raise AcaiaError("Unknown error writing to device") from ex
except (BleakDeviceNotFoundError, BleakError, TimeoutError) as ex:
if self._connected:
self._connected = False
self._last_disconnect_time = time.time()
if isinstance(ex, BleakDeviceNotFoundError):
raise AcaiaDeviceNotFound("Device not found") from ex
raise AcaiaError("Error writing to device") from ex

async def _process_queue(self) -> None:
"""Task to process the queue in the background."""
Expand All @@ -190,7 +198,8 @@ async def _process_queue(self) -> None:
except asyncio.CancelledError:
return
except (AcaiaDeviceNotFound, AcaiaError) as ex:
_LOGGER.debug("Error writing to device: %s", ex)
if self.connected:
_LOGGER.warning("Error writing to device: %s", ex)
return

async def connect(
Expand All @@ -201,18 +210,14 @@ async def connect(
"""Initiate connection to the scale"""
if not self._client:
raise AcaiaError("Client not initialized")
if self.connected:
return
try:
try:
await self._client.connect()
except BleakError as ex:
_LOGGER.exception("Error during connecting to device: %s", ex)
except (BleakError, TimeoutError) as ex:
_LOGGER.debug("Error during connecting to device: %s", ex)
raise AcaiaError("Error during connecting to device") from ex
except TimeoutError as ex:
_LOGGER.exception("Timeout during connecting to device: %s", ex)
raise AcaiaError("Timeout during connecting to device") from ex
except Exception as ex:
_LOGGER.exception("Unknown error during connecting to device: %s", ex)
raise AcaiaError("Unknown error during connecting to device") from ex

self._connected = True
_LOGGER.debug("Connected to Acaia Scale")
Expand All @@ -224,7 +229,7 @@ async def connect(
await self._client.start_notify(self._notify_char_id, callback)
await asyncio.sleep(0.5)
except BleakError as ex:
_LOGGER.exception("Error subscribing to notifications: %s", ex)
_LOGGER.debug("Error subscribing to notifications: %s", ex)
raise AcaiaError("Error subscribing to notifications") from ex

await self.auth()
Expand All @@ -237,17 +242,15 @@ async def connect(

def _setup_tasks(self) -> None:
"""Setup background tasks"""
if self._tasks_initialized:
return

self._heartbeat_task = asyncio.create_task(
self._send_heartbeats(
interval=HEARTBEAT_INTERVAL if not self._is_new_style_scale else 1,
new_style_heartbeat=self._is_new_style_scale,
if not self._heartbeat_task or self._heartbeat_task.done():
self._heartbeat_task = asyncio.create_task(
self._send_heartbeats(
interval=HEARTBEAT_INTERVAL if not self._is_new_style_scale else 1,
new_style_heartbeat=self._is_new_style_scale,
)
)
)
self._process_queue_task = asyncio.create_task(self._process_queue())
self._tasks_initialized = True
if not self._process_queue_task or self._process_queue_task.done():
self._process_queue_task = asyncio.create_task(self._process_queue())

async def auth(self) -> None:
"""Send auth message to scale, if subscribed to notifications returns Settings object"""
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

setuptools.setup(
name="pyacaia_async",
version="0.0.11b9",
version="0.0.11b10",
description="An async implementation of PyAcaia",
long_description=readme,
long_description_content_type="text/markdown",
Expand Down

0 comments on commit 994ca42

Please sign in to comment.