Skip to content

Commit

Permalink
move things to pyacaia
Browse files Browse the repository at this point in the history
  • Loading branch information
zweckj committed Nov 22, 2023
1 parent f2a4472 commit 0aebe16
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 9 deletions.
56 changes: 48 additions & 8 deletions pyacaia_async/acaiascale.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
import asyncio
import logging
import time

from collections.abc import Awaitable, Callable
from typing import Any

from bleak import BleakClient, BleakGATTCharacteristic, BLEDevice
from bleak.exc import BleakDeviceNotFoundError, BleakError
Expand All @@ -16,6 +18,8 @@
OLD_STYLE_CHAR_ID,
)
from .exceptions import AcaiaDeviceNotFound, AcaiaError
from .const import BATTERY_LEVEL, GRAMS, WEIGHT, UNITS
from .decode import Message, Settings, decode
from .helpers import encode, encode_id, encode_notification_request

_LOGGER = logging.getLogger(__name__)
Expand All @@ -36,7 +40,12 @@ class AcaiaScale:
"notificationRequest": encode_notification_request(),
}

def __init__(self, mac: str | None = None, is_new_style_scale: bool = True) -> None:
def __init__(
self,
mac: str | None = None,
is_new_style_scale: bool = True,
notify_callback: Callable[[], None] | None = None,
) -> None:
"""Initialize the scale."""

self._mac = mac
Expand All @@ -49,6 +58,7 @@ def __init__(self, mac: str | None = None, is_new_style_scale: bool = True) -> N
self._timestamp_last_command: float | None = None
self._timer_start: float | None = None
self._timer_stop: float | None = None
self._data: dict[str, Any] = {BATTERY_LEVEL: None, UNITS: GRAMS, WEIGHT: 0.0}

self._queue: asyncio.Queue = asyncio.Queue()

Expand All @@ -58,6 +68,8 @@ def __init__(self, mac: str | None = None, is_new_style_scale: bool = True) -> N
# for old style scales, the default char id is the same as the notify char id
self._default_char_id = self._notify_char_id = OLD_STYLE_CHAR_ID

self._notify_callback: Callable[[], None] | None = notify_callback

@property
def mac(self) -> str:
"""Return the mac address of the scale in upper case."""
Expand All @@ -84,6 +96,11 @@ 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."""
return self._data

@classmethod
async def create(
cls,
Expand All @@ -103,6 +120,8 @@ async def create(
else:
raise ValueError("Either mac or bleDevice must be specified")

if callback is None:
callback = self.on_bluetooth_data_received
await self.connect(callback)
asyncio.create_task(
self._send_heartbeats(
Expand Down Expand Up @@ -195,13 +214,14 @@ async def connect(
self._connected = True
_LOGGER.debug("Connected to Acaia Scale")

if callback is not None:
try:
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)
raise AcaiaError("Error subscribing to notifications") from ex
if callback is None:
callback = self.on_bluetooth_data_received
try:
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)
raise AcaiaError("Error subscribing to notifications") from ex

await self.auth()

Expand Down Expand Up @@ -293,3 +313,23 @@ async def reset_timer(self) -> None:
if self._timer_running:
await self._queue.put((self._default_char_id, self.msg_types["startTimer"]))
self._timer_start = time.time()

async def on_bluetooth_data_received(
self, characteristic: BleakGATTCharacteristic, data: bytearray
) -> None:
"""Receive data from scale."""
msg = decode(data)[0]

if isinstance(msg, Settings):
self._data[BATTERY_LEVEL] = msg.battery
self._data[UNITS] = msg.units
_LOGGER.debug(
"Got battery level %s, units %s", str(msg.battery), str(msg.units)
)

elif isinstance(msg, Message):
self._data[WEIGHT] = msg.value
_LOGGER.debug("Got weight %s", str(msg.value))

if self._notify_callback is not None:
self._notify_callback()
7 changes: 7 additions & 0 deletions pyacaia_async/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,10 @@
HEADER2: Final = 0xDD
HEARTBEAT_INTERVAL: Final = 5
SCALE_START_NAMES: Final = ["ACAIA", "PYXIS", "LUNAR", "PROCH"]

BATTERY_LEVEL: Final = "battery_level"
WEIGHT: Final = "weight"
UNITS: Final = "units"

GRAMS: Final = "grams"
OUNCE: Final = "ounces"
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.11b2",
version="0.0.11b3",
description="An async implementation of PyAcaia",
long_description=readme,
long_description_content_type="text/markdown",
Expand Down

0 comments on commit 0aebe16

Please sign in to comment.