Check battery level of connected bluetooth device on linux

For me running this in terminal worked:

upower --dump

You don't see Battery Level in the list of GATT characteristics since Bluez v5.48 because this specific GATT characteristic was moved into DBUS org.bluez.Battery1 interface.

From the command line:

  1. Connect to your target BLE device with bluetoothctl
  2. And then request DBUS by running: dbus-send --print-reply=literal --system --dest=org.bluez /org/bluez/hci0/dev_<mac_address_of_your_ble_peripheral> org.freedesktop.DBus.Properties.Get string:"org.bluez.Battery1" string:"Percentage"

In my case with my BLE peripheral with the following MAC address C3:41:A6:C8:93:42:

$ dbus-send --print-reply=literal --system --dest=org.bluez \
    /org/bluez/hci0/dev_C3_41_A6_C8_93_42 org.freedesktop.DBus.Properties.Get \
    string:"org.bluez.Battery1" string:"Percentage"
   variant       byte 94

Note: You could potentially scan and connect to your device using Bluez DBUS API.


This is such a great question, ahead of development and tools that are available at the moment.

The short answer (in October 2018)

you have to write it yourself! It won't be a one liner in the terminal. I am going to write this for myself in Python, but C has a little more documentation, so if you are skilled with C go for it.

The long answer, but it's more a recommended starting point:

  1. Tony D: https://youtu.be/5fQR2PHMDWE?t=4644 managed to use bluetoothctl to read attributes and send data to a bluetooth device. Definitely check the video information, you will find great links and references: https://learn.adafruit.com/introduction-to-bluetooth-low-energy/gatt
  2. Szymon Janc: https://youtu.be/VMDyebKT5c4 developer and contributer to the LINUX Bluetooth Stack
  3. Definitely check out how this question is answered on Mobile devices. For Android it's the BAS (Battery Service): https://android.stackexchange.com/questions/106073/displaying-bluetooth-gadgets-battery-status-on-the-phone

    On Android 8.0.1


This might be a bit late to the party but for me this Python project has worked fine:

https://github.com/TheWeirdDev/Bluetooth_Headset_Battery_Level

I only had to change the port in line 57 to 3 for my no-name X5 headset. If it hangs or errors with "connection refused" try a different port.

The Python program uses AT commands via RFCOMM and should work while Pulseaudio is using the A2DP sink (mine reconnects). Python 3 is needed as 2 doesn't have BT-Serial sockets. Windows will probably not work as it lacks bluez. It basically does the same thing as the Pulseaudio hack here: https://stackoverflow.com/a/56390625/920122

If you want to look at the commands as they are exchanged, try my debug fork: https://github.com/clst/Bluetooth_Headset_Battery_Level