From 1dec3b87d3db74d01f30ebbaf637036108476903 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 10 Sep 2022 08:07:39 -0500 Subject: [PATCH 1/5] Handle a device already being connected Fixes #992 --- bleak/backends/bluezdbus/client.py | 19 ++++++++++--------- bleak/backends/bluezdbus/manager.py | 12 ++++++++++++ 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/bleak/backends/bluezdbus/client.py b/bleak/backends/bluezdbus/client.py index c75813b6..c1c116e5 100644 --- a/bleak/backends/bluezdbus/client.py +++ b/bleak/backends/bluezdbus/client.py @@ -155,16 +155,17 @@ def on_value_changed(char_path: str, value: bytes) -> None: try: try: - async with async_timeout.timeout(timeout): - reply = await self._bus.call( - Message( - destination=defs.BLUEZ_SERVICE, - interface=defs.DEVICE_INTERFACE, - path=self._device_path, - member="Connect", + if not manager.is_connected(self._device_path): + async with async_timeout.timeout(timeout): + reply = await self._bus.call( + Message( + destination=defs.BLUEZ_SERVICE, + interface=defs.DEVICE_INTERFACE, + path=self._device_path, + member="Connect", + ) ) - ) - assert_reply(reply) + assert_reply(reply) self._is_connected = True diff --git a/bleak/backends/bluezdbus/manager.py b/bleak/backends/bluezdbus/manager.py index 6569c129..932784c8 100644 --- a/bleak/backends/bluezdbus/manager.py +++ b/bleak/backends/bluezdbus/manager.py @@ -597,6 +597,18 @@ def get_device_name(self, device_path: str) -> str: """ return self._properties[device_path][defs.DEVICE_INTERFACE]["Name"] + def is_connected(self, device_path: str) -> bool: + """ + Gets the value of the "Connected" property for a device. + + Args: + device_path: The D-Bus object path of the device. + + Returns: + The current property value. + """ + return self._properties[device_path][defs.DEVICE_INTERFACE]["Connected"] + async def _wait_condition( self, device_path: str, property_name: str, property_value: Any ) -> None: From ea39b7335dc96ac4d102f585550795505ce96445 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 10 Sep 2022 15:19:17 -0500 Subject: [PATCH 2/5] guard check, update changelog --- CHANGELOG.rst | 1 + bleak/backends/bluezdbus/manager.py | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 82e88c8a..1b95212e 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -20,6 +20,7 @@ Changed To use the cache, call ``connect`` and ``get_services`` with the ``dangerous_use_bleak_cache`` argument to avoid services being resolved again. * The BlueZ D-Bus backend now uses ``dbus-fast`` instead of ``dbus-next`` which significantly improves performance. +* The BlueZ D-Bus backend will not avoid trying to connect to devices that are already connected. Fixed ----- diff --git a/bleak/backends/bluezdbus/manager.py b/bleak/backends/bluezdbus/manager.py index 932784c8..6fb06ea2 100644 --- a/bleak/backends/bluezdbus/manager.py +++ b/bleak/backends/bluezdbus/manager.py @@ -607,7 +607,11 @@ def is_connected(self, device_path: str) -> bool: Returns: The current property value. """ - return self._properties[device_path][defs.DEVICE_INTERFACE]["Connected"] + return bool( + device_path in self._properties + and defs.DEVICE_INTERFACE in self._properties[device_path] + and self._properties[device_path][defs.DEVICE_INTERFACE]["Connected"] + ) async def _wait_condition( self, device_path: str, property_name: str, property_value: Any From a4ed7f8cfdea2752ed4ff14957ebf503be293d66 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 10 Sep 2022 15:21:17 -0500 Subject: [PATCH 3/5] comment is_connected check --- bleak/backends/bluezdbus/client.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/bleak/backends/bluezdbus/client.py b/bleak/backends/bluezdbus/client.py index c1c116e5..94067b13 100644 --- a/bleak/backends/bluezdbus/client.py +++ b/bleak/backends/bluezdbus/client.py @@ -155,6 +155,14 @@ def on_value_changed(char_path: str, value: bytes) -> None: try: try: + # + # The BlueZ backend does not disconnect devices when the + # application closes or crashes. This can cause problems + # when trying to reconnect to the same device. To work + # around this, we check if the device is already connected. + # + # For additional details see https://github.com/bluez/bluez/issues/89 + # if not manager.is_connected(self._device_path): async with async_timeout.timeout(timeout): reply = await self._bus.call( From d0e91214f3ae81914690375df4eb6ba07f8db1fd Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 10 Sep 2022 15:48:50 -0500 Subject: [PATCH 4/5] Update bleak/backends/bluezdbus/manager.py Co-authored-by: David Lechner --- bleak/backends/bluezdbus/manager.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/bleak/backends/bluezdbus/manager.py b/bleak/backends/bluezdbus/manager.py index 6fb06ea2..bac215fe 100644 --- a/bleak/backends/bluezdbus/manager.py +++ b/bleak/backends/bluezdbus/manager.py @@ -607,11 +607,10 @@ def is_connected(self, device_path: str) -> bool: Returns: The current property value. """ - return bool( - device_path in self._properties - and defs.DEVICE_INTERFACE in self._properties[device_path] - and self._properties[device_path][defs.DEVICE_INTERFACE]["Connected"] - ) + try: + return self._properties[device_path][defs.DEVICE_INTERFACE]["Connected"] + except KeyError: + return False async def _wait_condition( self, device_path: str, property_name: str, property_value: Any From 9e8888be032b6e21ad62de7cbec6f59b4d794ac2 Mon Sep 17 00:00:00 2001 From: David Lechner Date: Sat, 10 Sep 2022 15:53:27 -0500 Subject: [PATCH 5/5] Update CHANGELOG.rst --- CHANGELOG.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 1b95212e..758726e2 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -20,7 +20,7 @@ Changed To use the cache, call ``connect`` and ``get_services`` with the ``dangerous_use_bleak_cache`` argument to avoid services being resolved again. * The BlueZ D-Bus backend now uses ``dbus-fast`` instead of ``dbus-next`` which significantly improves performance. -* The BlueZ D-Bus backend will not avoid trying to connect to devices that are already connected. +* The BlueZ D-Bus backend will not avoid trying to connect to devices that are already connected. Fixes #992. Fixed -----