ukBaz / python-bluezero

A simple Python interface to Bluez
MIT License
387 stars 112 forks source link

Error "dbus.exceptions.DBusException: org.bluez.Error.NotAvailable: Operation currently not available" on central #395

Closed wallem89 closed 11 months ago

wallem89 commented 1 year ago

When running heartrate_monitor_peripheral.py on one Raspberry PI and heartrate_monitor_central.py on another one I get the following error: dbus.exceptions.DBusException: org.bluez.Error.NotAvailable: Operation currently not available.

So other device is found but then when trying to monitor the heartrate something is wrong.

Full trace:

$ python3 heartrate_monitor_central.py
dbus.Array([dbus.String('0000180d-0000-1000-8000-00805f9b34fb'), dbus.String('00001800-0000-1000-8000-00805f9b34fb'), dbus.String('00001801-0000-1000-8000-00805f9b34fb'), dbus.String('0000180a-0000-1000-8000-00805f9b34fb'), dbus.String('0000110e-0000-1000-8000-00805f9b34fb'), dbus.String('0000110c-0000-1000-8000-00805f9b34fb')], signature=dbus.Signature('s'), variant_level=1)
Heart Rate Measurement Device Found!
Connecting to raspberrypi
Traceback (most recent call last):
  File "/home/pi/git/python-bluezero/examples/heartrate_monitor_central.py", line 197, in <module>
    connect_and_run(hrm)
  File "/home/pi/git/python-bluezero/examples/heartrate_monitor_central.py", line 156, in connect_and_run
    monitor.connect()
  File "/home/pi/.local/lib/python3.9/site-packages/bluezero/central.py", line 91, in connect
    self.rmt_device.connect(timeout=timeout)
  File "/home/pi/.local/lib/python3.9/site-packages/bluezero/device.py", line 303, in connect
    raise dbus_exception
  File "/home/pi/.local/lib/python3.9/site-packages/bluezero/device.py", line 287, in connect
    self.bus.call_blocking(constants.BLUEZ_SERVICE_NAME,
  File "/usr/lib/python3/dist-packages/dbus/connection.py", line 652, in call_blocking
    reply_message = self.send_message_with_reply_and_block(
dbus.exceptions.DBusException: org.bluez.Error.NotAvailable: Operation currently not available
ukBaz commented 1 year ago

To help debug this can you try the following:

When running heartrate_monitor_peripheral.py have separate terminals open with the following running to get more debug information:

wallem89 commented 1 year ago

Device 1

bluetoothctl:

Agent registered
[CHG] Controller E4:5F:01:A8:21:50 Pairable: yes

service bluetooth status:

● bluetooth.service - Bluetooth service
     Loaded: loaded (/lib/systemd/system/bluetooth.service; enabled; vendor preset: enabled)
     Active: active (running) since Thu 2023-03-30 14:39:48 CEST; 1h 24min ago
       Docs: man:bluetoothd(8)
   Main PID: 708 (bluetoothd)
     Status: "Running"
      Tasks: 1 (limit: 4471)
        CPU: 59ms
     CGroup: /system.slice/bluetooth.service
             └─708 /usr/libexec/bluetooth/bluetoothd

Mar 30 14:39:48 raspberrypi systemd[1]: Starting Bluetooth service...
Mar 30 14:39:48 raspberrypi bluetoothd[708]: Bluetooth daemon 5.55
Mar 30 14:39:48 raspberrypi systemd[1]: Started Bluetooth service.
Mar 30 14:39:48 raspberrypi bluetoothd[708]: Starting SDP server
Mar 30 14:39:48 raspberrypi bluetoothd[708]: Bluetooth management interface 1.22 initialized
Mar 30 14:39:48 raspberrypi bluetoothd[708]: profiles/sap/server.c:sap_server_register() Sap driver initialization failed.
Mar 30 14:39:48 raspberrypi bluetoothd[708]: sap-server: Operation not permitted (1)
Mar 30 14:39:48 raspberrypi bluetoothd[708]: Failed to set privacy: Rejected (0x0

Device 2

bluetoothctl:

Agent registered
[CHG] Controller E4:5F:01:A8:21:8A Pairable: yes

service bluetooth status:

● bluetooth.service - Bluetooth service
     Loaded: loaded (/lib/systemd/system/bluetooth.service; enabled; vendor preset: enabled)
     Active: active (running) since Thu 2023-03-30 14:39:47 CEST; 1h 25min ago
       Docs: man:bluetoothd(8)
   Main PID: 636 (bluetoothd)
     Status: "Running"
      Tasks: 1 (limit: 3933)
        CPU: 57ms
     CGroup: /system.slice/bluetooth.service
             └─636 /usr/libexec/bluetooth/bluetoothd

Mar 30 14:39:47 raspberrypi4 systemd[1]: Starting Bluetooth service...
Mar 30 14:39:47 raspberrypi4 bluetoothd[636]: Bluetooth daemon 5.55
Mar 30 14:39:47 raspberrypi4 systemd[1]: Started Bluetooth service.
Mar 30 14:39:47 raspberrypi4 bluetoothd[636]: Starting SDP server
Mar 30 14:39:47 raspberrypi4 bluetoothd[636]: Bluetooth management interface 1.22 initialized
Mar 30 14:39:47 raspberrypi4 bluetoothd[636]: profiles/sap/server.c:sap_server_register() Sap driver initialization failed.
Mar 30 14:39:47 raspberrypi4 bluetoothd[636]: sap-server: Operation not permitted (1)
Mar 30 14:39:47 raspberrypi4 bluetoothd[636]: Failed to set privacy: Rejected (0x0b)

Running your suggestion on Device 2 and then connect with heartrate_monitor_peripheral.py for device 1 I get the following output on the 4 different terminals: image

I am not sure what to look for, there is a lot of stuff printed in the sudo busctl monitor org.bluez and the ```sudo btmon```` terminals.

What is interesting that heartrate_monitor_peripheral.py sometimes runs without an error. But then nothing is printed nor seen on those terminals so I guess the connections is not established then.

ukBaz commented 1 year ago

Rather than referring to device1 and device2, it would be clearer if we could use peripheral and central for clarity.

It looks like the image that has the four terminals shown is of the peripheral RPi. The btmon log suggests that the central disconnected from the peripheral.

Remote User Terminated Connection (0x13) error message often means that the client can't find what it is looking for or there is an issue with the pairing

Let's try and break this down in to smaller steps to check what is working and what is not.

Firstly, only start the peripheral. Then use a generic Bluetooth Low Energy scanning and exploration tool like nRF Connect. Connect to the peripheral and check all the services are there. You should be able to select the services and read/get-notifications from them.

If that works fine, then move on to the RPi where the central will be run. Don't run the script, use the bluetoothctl tool to connect to the peripheral device and introspect the GATT characteristics.

If that all works then we should have established that the peripheral is working and the central Raspberry Pi is working. We can then focus in on the Python for the central

wallem89 commented 1 year ago

I have to admit that I am new to BLE and when reading about it I think that I need a central device and one peripheral device both in connected mode. Because I need data to be exchanged between both devices.

I actually don't care about the energy consumption since the central device will be connected to the grid and the peripheral device to the a big battery. So it might be that I took the wrong example to play around with because I cannot use a predefined Generic Attribute Profile (GATT). Unless I can use one or more generic one (like fixed string 64, generic level and Boolean) or define my own if there is an easy way to so.

I need some proprietary communication between both devices so originally I was just thinking about sending bytes over BLE which are a combination of an identifier and the data and both sides know how to encode and decode this data based on the identifier (like ISO 11898 Controller area network (CAN)).

But again I am just trying to read myself into BLE so not sure what the best approach would be for my use case.

ukBaz commented 1 year ago

If it it is just the two RPi's that you are communicating between and you want to send arbitrary data between the two then it might be a more gentle learning curve to use Bluetooth Classic.

That can be done with standard Python socket library: https://blog.kevindoran.co/bluetooth-programming-with-python-3/

Or the Bluedot library has packaged up client server examples very well: https://www.stuffaboutcode.com/2017/07/python-bluetooth-rfcomm-client-server.html

If you want BLE then this might be a better example to start from for the peripheral: https://github.com/ukBaz/python-bluezero/blob/main/examples/ble_uart.py And that should work with https://www.nordicsemi.com/Products/Development-tools/nRF-Connect-for-mobile or https://play.google.com/store/apps/details?id=de.kai_morich.serial_bluetooth_terminal&hl=en_GB&gl=US So you can test one end before moving on to the central.

I think you should be able to leverage the microbit module in Bluezero as the central: https://github.com/ukBaz/python-bluezero/blob/main/examples/microbit_uart.py

wallem89 commented 1 year ago

Thanks for the links, myself I couldn't find that much regarding this topic. I have PyBluez up and running with a client and server on both sides but not in BLE mode.

Found through your links the BlueDot Bluetooth Comm API seems also really simple and something I want. I will take a look at this too.

From your repositories I found BLE GATT which seems interesting for the client on the central. But I am not sure if this can also be used for a client on the peripheral. And what can be used as a server.

ukBaz commented 1 year ago

BLE_GATT and PyBluez do not support creating a BLE Peripheral. BlueDoT seems like it might be a good fit for your project.

ukBaz commented 11 months ago

Closing because of inactivity