Skip to content

Commit

Permalink
Merge pull request #3 from elupus/coalesce
Browse files Browse the repository at this point in the history
Coalesce bluetooth connections
  • Loading branch information
elupus authored Sep 30, 2022
2 parents 614d553 + 92eb2da commit 09ebcb7
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 19 deletions.
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

setup(
name="fjaraskupan",
version="2.0.1",
version="2.1.0",
description="A python library for speaking to fjäråskupan",
long_description=long_description,
long_description_content_type="text/x-rst",
Expand Down
48 changes: 30 additions & 18 deletions src/fjaraskupan/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from __future__ import annotations

import asyncio
from contextlib import asynccontextmanager
from contextlib import AsyncExitStack, asynccontextmanager
from dataclasses import dataclass, replace
import logging
from typing import Any, AsyncIterator
Expand Down Expand Up @@ -148,28 +148,40 @@ def __init__(self, address: str, keycode=b"1234") -> None:
self._keycode = keycode
self.state = State()
self._lock = asyncio.Lock()
self._client: BleakClient | None
self._client: BleakClient | None = None
self._client_count = 0
self._client_stack = AsyncExitStack()

@asynccontextmanager
async def connect(self, address_or_ble_device: BLEDevice | str | None = None) -> AsyncIterator[Device]:
if address_or_ble_device is None:
address_or_ble_device = self.address

async with self._lock:
if not self._client:
_LOGGER.debug("Connecting")
try:
self._client = await self._client_stack.enter_async_context(BleakClient(address_or_ble_device))
except asyncio.TimeoutError as exc:
_LOGGER.debug("Timeout on connect", exc_info=True)
raise FjaraskupanTimeout("Timeout on connect") from exc
except BleakError as exc:
_LOGGER.debug("Error on connect", exc_info=True)
raise FjaraskupanBleakError("Error on connect") from exc
else:
_LOGGER.debug("Connection reused")
self._client_count += 1

try:
async with self._lock:
if address_or_ble_device is None:
address_or_ble_device = self.address

async with BleakClient(address_or_ble_device) as client:
self._client = client
try:
yield self
finally:
self._client = None

except asyncio.TimeoutError as exc:
_LOGGER.debug("Timeout on connect", exc_info=True)
raise FjaraskupanTimeout("Timeout on connect") from exc
except BleakError as exc:
_LOGGER.debug("Error on connect", exc_info=True)
raise FjaraskupanBleakError("Error on connect") from exc
yield self
finally:
async with self._lock:
self._client_count -= 1
if self._client_count == 0:
self._client = None
_LOGGER.debug("Disconnected")
await self._client_stack.pop_all().aclose()

def characteristic_callback(self, data: bytearray):
"""Handle callback on characteristic change."""
Expand Down

0 comments on commit 09ebcb7

Please sign in to comment.