Python 3 Script to Get Bluetooth Headphones Battery Status in Command Line Full Project For Beginners

 

 

app.py

 

 

#!/usr/bin/env python3

"""
A python script to get battery level from Bluetooth headsets
"""

# License: GPL-3.0
# Author: @TheWeirdDev
# 29 Sept 2019

import sys
import bluetooth


def send(sock, message):
    """
    This function sends a message through a bluetooth socket
    """
    sock.send(b"\r\n" + message + b"\r\n")


def get_at_command(sock, line, device):
    """
    Will try to get and print the battery level of supported devices
    """
    blevel = -1

    if b"BRSF" in line:
        send(sock, b"+BRSF: 1024")
        send(sock, b"OK")
    elif b"CIND=" in line:
        send(sock, b"+CIND: (\"battchg\",(0-5))")
        send(sock, b"OK")
    elif b"CIND?" in line:
        send(sock, b"+CIND: 5")
        send(sock, b"OK")
    elif b"BIND=?" in line:
        # Announce that we support the battery level HF indicator
        # https://www.bluetooth.com/specifications/assigned-numbers/hands-free-profile/
        send(sock, b"+BIND: (2)")
        send(sock, b"OK")
    elif b"BIND?" in line:
        # Enable battery level HF indicator
        send(sock, b"+BIND: 2,1")
        send(sock, b"OK")
    elif b"XAPL=" in line:
        send(sock, b"+XAPL=iPhone,7")
        send(sock, b"OK")
    elif b"IPHONEACCEV" in line:
        parts = line.strip().split(b',')[1:]
        if len(parts) > 1 and (len(parts) % 2) == 0:
            parts = iter(parts)
            params = dict(zip(parts, parts))
            if b'1' in params:
                blevel = (int(params[b'1']) + 1) * 10
    elif b"BIEV=" in line:
        params = line.strip().split(b"=")[1].split(b",")
        if params[0] == b"2":
            blevel = int(params[1])
    elif b"XEVENT=BATTERY" in line:
        params = line.strip().split(b"=")[1].split(b",")
        blevel = int(params[1]) / int(params[2]) * 100
    else:
        send(sock, b"OK")

    if blevel != -1:
        print(f"Battery level for {device} is {blevel}%")
        return False

    return True


def find_rfcomm_port(device):
    """
    Find the RFCOMM port number for a given bluetooth device
    """
    uuid = "0000111e-0000-1000-8000-00805f9b34fb"
    proto = bluetooth.find_service(address=device, uuid=uuid)
    if len(proto) == 0:
        print("Couldn't find the RFCOMM port number")
        return 4

    for pr in proto:
        if 'protocol' in pr and pr['protocol'] == 'RFCOMM':
            port = pr['port']
            return port
    return 4


def main():
    """
    The starting point of the program. For each device address in the argument
    list a bluetooth socket will be opened and the battery level will be read
    and printed to stdout
    """
    if len(sys.argv) < 2:
        print("Usage: bluetooth_battery.py BT_MAC_ADDRESS_1.PORT ...")
        print("         Port number is optional")
        sys.exit()
    else:
        for device in sys.argv[1:]:
            i = device.find('.')
            if i == -1:
                port = find_rfcomm_port(device)
            else:
                port = int(device[i+1:])
                device = device[:i]
            try:
                sock = bluetooth.BluetoothSocket(bluetooth.RFCOMM)
                sock.connect((device, port))
                while get_at_command(sock, sock.recv(128), device):
                    pass
                sock.close()
            except OSError as err:
                print(f"{device} is offline", err)


if __name__ == "__main__":
    main()

 

See also  Python 3 Tkinter Entry Input Text Widget Get Value in Popup Message Dialog Window On Button Click in GUI Desktop App Full Project For Beginners

 

 

🔋🎧 Bluetooth Headset Battery Level

This is a python script to fetch the battery charge level of some Bluetooth headsets.

You need python 3.6 or newer to run the script.

▶️ How to run

There are three options:

Option 1: Install from PyPI

Please ensure you have the BlueZ and python libraries and header files if you are using Ubuntu/Debian based distros:

sudo apt install libbluetooth-dev python3-dev

If you are using OpenSUSE, you will need to install bluezbluez-develpython3-develpython3-pybluez

Then, install with pip:

pip3 install bluetooth_battery

bluetooth_battery BT_MAC_ADDRESS_1 ...

You can input addresses for as many devices as you want separated by space.

the dependency pybluez should be installed automatically, but if not, you may need to install it manually


Option 2: Download this repository

cd Bluetooth_Headset_Battery_Level
chmod +x bluetooth_battery.py

./bluetooth_battery.py BT_MAC_ADDRESS_1 ...

make sure you have python-pybluez or python3-pybluez or python3-bluez installed on your system.


Option 3: Docker

You must have docker installed on your system. Clone the repository using git clone command. Then run:

cd Bluetooth_Headset_Battery_Level
docker build -t bluetooth_battery_level .

Once the build is complete you can use the below command to run the program:

docker run --rm -ti --privileged --net=host bluetooth_battery_level "BT_MAC_ADDRESS"

GNOME Extension

There is also a GNOME extension for integrating this program with GNOME desktop environment: https://extensions.gnome.org/extension/3991/bluetooth-battery/

See also  Python 3 Tkinter Script to Display International Countries Information in GUI Desktop App Through JSON Module Full Project For Beginners

Finding MAC address

There are a variety of utilities that can find the MAC address of your bluetooth device. Here is one, this command is in the bluez package, and the given argument gets a list of all devices it knows about, even if not currently available.

$ bluetoothctl devices
Device E8:AB:FA:XX:XX:XX iTeknic IK-BH002
Device D0:77:14:XX:XX:XX Barak's Moto X4
Device E8:AB:FA:XX:XX:XX iTeknic IK-BH002

The 1st and 3rd would be relevant here, as those are headsets.

This shows devices that are actually connected.

$ bluetoothctl info
Device E8:AB:FA:XX:XX:XX (public)
	Name: iTeknic IK-BH002
	...

So you can use

bluetooth_battery.py $(bluetoothctl info | awk '/^Device/ {print $2}')

to query the battery of all connected devices.

It didn’t work?

You can set the port number manually by adding a dot at the end of mac address, like this: 00:00:00:00:00:00.3

Try port numbers 1 to 30 to find the one that works for your device. (wait a few seconds between each try)

If that didn’t work, disconnect your device first, and then try again.

 

Leave a Reply