Skip to content

Commit 1e6dd6f

Browse files
authored
Merge pull request #1808 from hbldh/release/v1.1.0
Release/v1.1.0
2 parents df55dcd + edc9c51 commit 1e6dd6f

File tree

15 files changed

+254
-14
lines changed

15 files changed

+254
-14
lines changed

AUTHORS.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ Contributors
2424
* David Johansen <[email protected]>
2525
* JP Hutchins <[email protected]>
2626
* Bram Duvigneau <[email protected]>
27+
* Dmytro Yaroshenko <[email protected]>
2728

2829
And many others who did not wish to be named here.
2930

CHANGELOG.rst

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,19 @@ and this project adheres to `Semantic Versioning <https://semver.org/spec/v2.0.0
1010
`Unreleased`_
1111
=============
1212

13+
`1.1.0`_ (2025-08-10)
14+
=====================
15+
16+
Added
17+
-----
18+
- Added support for Pythonista iOS app backend.
19+
- Added ``BleakClient.name`` property for getting the peripheral's name. Fixes #1802.
20+
21+
Fixed
22+
-----
23+
- Fixed ``BleakClient.connect()`` on Android when service characteristics have descriptors. Fixes #1803.
24+
- Fixed disconnect callback not called on Windows when Bleak initiates disconnection.
25+
1326
`1.0.1`_ (2025-06-30)
1427
=====================
1528

@@ -1098,7 +1111,8 @@ Fixed
10981111
* Bleak created.
10991112

11001113

1101-
.. _Unreleased: https://github.com/hbldh/bleak/compare/v1.0.1...develop
1114+
.. _Unreleased: https://github.com/hbldh/bleak/compare/v1.1.0...develop
1115+
.. _1.1.0: https://github.com/hbldh/bleak/compare/v1.0.1...v1.1.0
11021116
.. _1.0.1: https://github.com/hbldh/bleak/compare/v1.0.0...v1.0.1
11031117
.. _1.0.0: https://github.com/hbldh/bleak/compare/v0.22.3...v1.0.0
11041118
.. _0.22.3: https://github.com/hbldh/bleak/compare/v0.22.2...v0.22.3

bleak/__init__.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,20 @@ def __init__(
512512

513513
# device info
514514

515+
@property
516+
def name(self) -> str:
517+
"""
518+
Gets a human-readable name for the peripheral device.
519+
520+
The name can be somewhat OS-dependent. It is usually the name provided
521+
by the standard Device Name characteristic, if present or the name
522+
provided by the advertising data. If neither is available, it will be
523+
a Bluetooth address separated with dashes (``-``) instead of colons
524+
(``:``) (or a UUID on Apple devices). It may also be possible to override
525+
the device name using the OS's Bluetooth settings.
526+
"""
527+
return self._backend.name
528+
515529
@property
516530
def address(self) -> str:
517531
"""

bleak/backends/bluezdbus/client.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ def __init__(
7979
# kwarg "device" is for backwards compatibility
8080
self._adapter: Optional[str] = kwargs.get("adapter", kwargs.get("device"))
8181

82+
self._device_info: Optional[dict[str, Any]]
83+
8284
# Backend specific, D-Bus objects and data
8385
if isinstance(address_or_ble_device, BLEDevice):
8486
self._device_path = address_or_ble_device.details["path"]
@@ -666,6 +668,14 @@ async def _get_device_path(self) -> str:
666668
bluez_address = self.address.upper().replace(":", "_")
667669
return f"{adapter_path}/dev_{bluez_address}"
668670

671+
@property
672+
@override
673+
def name(self) -> str:
674+
"""See :meth:`bleak.BleakClient.name`."""
675+
if self._device_info is None:
676+
raise BleakError("Not connected")
677+
return self._device_info["Alias"]
678+
669679
@property
670680
@override
671681
def mtu_size(self) -> int:

bleak/backends/client.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,13 @@ def __init__(self, address_or_ble_device: Union[BLEDevice, str], **kwargs: Any):
5252
"disconnected_callback"
5353
)
5454

55+
# NB: this is not marked as @abc.abstractmethod because that would break
56+
# 3rd-party backends. We might change this in the future to make it required.
57+
@property
58+
def name(self) -> str:
59+
"""See :meth:`bleak.BleakClient.name`."""
60+
raise NotImplementedError
61+
5562
@property
5663
@abc.abstractmethod
5764
def mtu_size(self) -> int:
@@ -216,6 +223,19 @@ def get_platform_client_backend_type() -> type[BaseBleakClient]:
216223

217224
return BleakClientBlueZDBus
218225

226+
if sys.platform == "ios" and "Pythonista3.app" in sys.executable:
227+
# Must be resolved before checking for "Darwin" (macOS),
228+
# as both the Pythonista app for iOS and macOS
229+
# return "Darwin" from platform.system()
230+
try:
231+
from bleak_pythonista import BleakClientPythonistaCB
232+
233+
return BleakClientPythonistaCB
234+
except ImportError as e:
235+
raise ImportError(
236+
"Ensure you have `bleak-pythonista` package installed."
237+
) from e
238+
219239
if platform.system() == "Darwin":
220240
from bleak.backends.corebluetooth.client import BleakClientCoreBluetooth
221241

bleak/backends/corebluetooth/client.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,14 @@ def is_connected(self) -> bool:
163163
else self._peripheral.state() == CBPeripheralStateConnected
164164
)
165165

166+
@property
167+
@override
168+
def name(self) -> str:
169+
"""Get the name of the connected peripheral"""
170+
if self._peripheral is None:
171+
raise BleakError("Not connected")
172+
return self._peripheral.name()
173+
166174
@property
167175
@override
168176
def mtu_size(self) -> int:

bleak/backends/p4android/client.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ async def _get_services(self) -> BleakGATTServiceCollection:
281281
descriptor = BleakGATTDescriptor(
282282
java_descriptor,
283283
characteristic.handle + 1 + descriptor_index,
284-
self.obj.getUuid().toString(),
284+
java_descriptor.getUuid().toString(),
285285
characteristic,
286286
)
287287
services.add_descriptor(descriptor)

bleak/backends/scanner.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import inspect
44
import os
55
import platform
6+
import sys
67
from collections.abc import Callable, Coroutine, Hashable
78
from typing import Any, NamedTuple, Optional
89

@@ -295,6 +296,19 @@ def get_platform_scanner_backend_type() -> type[BaseBleakScanner]:
295296

296297
return BleakScannerBlueZDBus
297298

299+
if sys.platform == "ios" and "Pythonista3.app" in sys.executable:
300+
# Must be resolved before checking for "Darwin" (macOS),
301+
# as both the Pythonista app for iOS and macOS
302+
# return "Darwin" from platform.system()
303+
try:
304+
from bleak_pythonista import BleakScannerPythonistaCB
305+
306+
return BleakScannerPythonistaCB
307+
except ImportError as e:
308+
raise ImportError(
309+
"Ensure you have `bleak-pythonista` package installed."
310+
) from e
311+
298312
if platform.system() == "Darwin":
299313
from bleak.backends.corebluetooth.scanner import BleakScannerCoreBluetooth
300314

bleak/backends/winrt/client.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,17 @@ async def disconnect(self) -> None:
475475
gatt_char.remove_value_changed(event_handler_token)
476476
self._notification_callbacks.clear()
477477

478+
# Since we can't wait for the session close event (it may never come)
479+
# we need to synthesize the disconnect event
480+
if self._session and self._session_status_changed_token:
481+
self._session.remove_session_status_changed(
482+
self._session_status_changed_token
483+
)
484+
self._session_status_changed_token = None
485+
486+
if self._disconnected_callback:
487+
self._disconnected_callback()
488+
478489
# Dispose all service components that we have requested and created.
479490
if self.services:
480491
# HACK: sometimes GattDeviceService.Close() hangs forever, so we
@@ -509,6 +520,14 @@ def is_connected(self) -> bool:
509520
else self._session.session_status == GattSessionStatus.ACTIVE
510521
)
511522

523+
@property
524+
@override
525+
def name(self) -> str:
526+
"""See :meth:`bleak.BleakClient.name`."""
527+
if self._requester is None:
528+
raise BleakError("Not connected")
529+
return self._requester.name
530+
512531
@property
513532
@override
514533
def mtu_size(self) -> int:

docs/backends/index.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ Bleak supports the following operating systems:
77
* Linux distributions with BlueZ >= 5.55 (See :ref:`linux-backend` for more details)
88
* OS X/macOS support via Core Bluetooth API, from at least version 10.13
99
* Partial Android support mostly using Python-for-Android/Kivy.
10+
* Partial, optional iOS support using Pythonista iOS app.
1011

1112
These pages document platform specific differences from the interface API.
1213

@@ -19,6 +20,7 @@ Contents:
1920
linux
2021
macos
2122
android
23+
pythonista
2224

2325
Shared Backend API
2426
------------------

0 commit comments

Comments
 (0)