Skip to content

Commit

Permalink
added BleakDeviceNotFoundError
Browse files Browse the repository at this point in the history
  • Loading branch information
jochenjagers committed Sep 27, 2022
1 parent 1e48ddb commit 42c5066
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 19 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Added
-----
* Added support for Python 3.11.
* Added better error message for Bluetooth not authorized on macOS.
* ``BleakDeviceNotFoundError`` which should be raised if a device can not be found by ``connect``, ``pair`` and ``unpair``

Fixed
-----
Expand Down
18 changes: 14 additions & 4 deletions bleak/backends/bluezdbus/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@

import async_timeout
from dbus_fast.aio import MessageBus
from dbus_fast.constants import BusType, ErrorType
from dbus_fast.constants import BusType, ErrorType, MessageType
from dbus_fast.message import Message
from dbus_fast.signature import Variant

from ... import BleakScanner
from ...exc import BleakDBusError, BleakError
from ...exc import BleakDBusError, BleakError, BleakDeviceNotFoundError
from ..characteristic import BleakGATTCharacteristic
from ..client import BaseBleakClient, NotifyCallback
from ..device import BLEDevice
Expand Down Expand Up @@ -116,8 +116,9 @@ async def connect(self, dangerous_use_bleak_cache: bool = False, **kwargs) -> bo
self._device_info = device.details.get("props")
self._device_path = device.details["path"]
else:
raise BleakError(
"Device with address {0} was not found.".format(self.address)
raise BleakDeviceNotFoundError(
BLEDevice(self.address),
f"Device with address {self.address} was not found.",
)

manager = await get_global_bluez_manager()
Expand Down Expand Up @@ -176,6 +177,15 @@ def on_value_changed(char_path: str, value: bytes) -> None:
member="Connect",
)
)
if (
reply is not None
and reply.message_type == MessageType.ERROR
and reply.error_name == ErrorType.UNKNOWN_OBJECT
):
raise BleakDeviceNotFoundError(
BLEDevice(self.address),
f"Device with address {self.address} was not found.",
)
assert_reply(reply)

self._is_connected = True
Expand Down
17 changes: 13 additions & 4 deletions bleak/backends/corebluetooth/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from Foundation import NSArray, NSData

from ... import BleakScanner
from ...exc import BleakError
from ...exc import BleakError, BleakDeviceNotFoundError
from ..characteristic import BleakGATTCharacteristic
from ..client import BaseBleakClient, NotifyCallback
from ..device import BLEDevice
Expand Down Expand Up @@ -80,8 +80,9 @@ async def connect(self, **kwargs) -> bool:
self._peripheral = device.details
self._central_manager_delegate = device.metadata["delegate"]
else:
raise BleakError(
"Device with address {} was not found".format(self.address)
raise BleakDeviceNotFoundError(
BLEDevice(self.address),
f"Device with address {self.address} was not found",
)

if self._delegate is None:
Expand Down Expand Up @@ -112,7 +113,15 @@ def disconnect_callback():
manager = self._central_manager_delegate
logger.debug("CentralManagerDelegate at {}".format(manager))
logger.debug("Connecting to BLE device @ {}".format(self.address))
await manager.connect(self._peripheral, disconnect_callback, timeout=timeout)
try:
await manager.connect(
self._peripheral, disconnect_callback, timeout=timeout
)
except asyncio.TimeoutError as error:
raise BleakDeviceNotFoundError(
BLEDevice(self.address),
f"Device with address {self.address} was not found",
) from error

# Now get services
await self.get_services()
Expand Down
2 changes: 1 addition & 1 deletion bleak/backends/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class BLEDevice:
- When using macOS backend, ``details`` attribute will be a CBPeripheral object.
"""

def __init__(self, address, name, details=None, rssi=0, **kwargs):
def __init__(self, address, name=None, details=None, rssi=0, **kwargs):
#: The Bluetooth address of the device on this machine.
self.address = address
#: The advertised name of the device.
Expand Down
26 changes: 16 additions & 10 deletions bleak/backends/winrt/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
from bleak_winrt.windows.storage.streams import Buffer

from ... import BleakScanner
from ...exc import PROTOCOL_ERROR_CODES, BleakError
from ...exc import PROTOCOL_ERROR_CODES, BleakError, BleakDeviceNotFoundError
from ..characteristic import BleakGATTCharacteristic
from ..client import BaseBleakClient, NotifyCallback
from ..device import BLEDevice
Expand Down Expand Up @@ -197,7 +197,7 @@ def __str__(self):

# Connectivity methods

def _create_requester(self, bluetooth_address: int):
def _create_requester(self, bluetooth_address: int) -> BluetoothLEDevice:
args = [
bluetooth_address,
]
Expand All @@ -207,7 +207,13 @@ def _create_requester(self, bluetooth_address: int):
if self._address_type == "public"
else BluetoothAddressType.RANDOM
)
return BluetoothLEDevice.from_bluetooth_address_async(*args)
requester = BluetoothLEDevice.from_bluetooth_address_async(*args)
if requester is None:
raise BleakDeviceNotFoundError(
BLEDevice(self.address),
f"Device with address {self.address} was not found.",
)
return requester

async def connect(self, **kwargs) -> bool:
"""Connect to the specified GATT server.
Expand All @@ -226,10 +232,13 @@ async def connect(self, **kwargs) -> bool:
self.address, timeout=timeout, backend=BleakScannerWinRT
)

if device:
self._device_info = device.details.adv.bluetooth_address
else:
raise BleakError(f"Device with address {self.address} was not found.")
if device is None:
raise BleakDeviceNotFoundError(
BLEDevice(self.address),
f"Device with address {self.address} was not found.",
)

self._device_info = device.details.adv.bluetooth_address

logger.debug("Connecting to BLE device @ %s", self.address)

Expand Down Expand Up @@ -476,9 +485,6 @@ async def unpair(self) -> bool:
else _address_to_int(self.address)
)

if device is None:
raise BleakError(f"Device with address {self.address} was not found.")

try:
unpairing_result = await device.device_information.pairing.unpair_async()
if unpairing_result.status not in (
Expand Down
19 changes: 19 additions & 0 deletions bleak/exc.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,32 @@
# -*- coding: utf-8 -*-
from typing import Optional

from bleak.backends.device import BLEDevice


class BleakError(Exception):
"""Base Exception for bleak."""

pass


class BleakDeviceNotFoundError(BleakError):
"""
Exception which is raised if a device can not be found by ``connect``, ``pair`` and ``unpair``.
This is the case if the OS Bluetooth stack has never seen this device or it was removed and forgotten.
"""

ble_device: BLEDevice

def __init__(self, ble_device: BLEDevice, *args: object) -> None:
"""
Args:
ble_device (BLEDevice): device object which contains details about the device which was not found
"""
super().__init__(*args)
self.ble_device = ble_device


class BleakDBusError(BleakError):
"""Specialized exception type for D-Bus errors."""

Expand Down

0 comments on commit 42c5066

Please sign in to comment.