Bluetooth_Headset_Battery_Level
Bluetooth_Headset_Battery_Level copied to clipboard
Sony WH-1000XM3 Connection refused on first connect
When running the script for the first time after connecting the headset, it fails with an OSError:
$ ./bluetooth_battery.py 38:18:4C:XX:XX:XX
38:18:4C:XX:XX:XX is offline (111, 'Connection refused')
The headset is properly connected and my laptop is transmitting sound, no problems there. If i run the script again it works as intended, also for any subsequent executions of the program... I don't know much about bluetooth at this point, but my guess would be that the socket is somehow not properly connecting (just a random guess).
If the device is already connected, it means there is an open socket between the laptop and the headset. This script opens a new socket and some devices don't like that and act weird. Some don't even work until you disconnect them first. The only solution for these kinds of issues that comes to my mind is to integrate the functionality of this script into the actual program that's responsible for Bluetooth connections (e.g. pulseaudio-bluetooth or something like that) so there is only one socket. I think there are some open merge requests on those projects that will eventually deprecate this one.
But for now, I suggest you use this script to connect in the first place. If the device kept being connected after running the script, then that's probably good enough and won't show any errors.
yes, my workaround is to always call the script twice atm, but i might look into the whole problem soon. maybe i'll add a check in the code that tries to connect to a device a few times before giving up and then we'll see if this is a general solution that also helps other users, not just me:D
I lost interest in this project a long time ago, but it's great seeing how many people contribute and work together to keep it moving forward. I hope you find a solution for this problem. Any pull-request is always welcome.
Same headset. Since I only have this one headset I went the tried and true method of just running it again as part of the error handling
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:
sock = bluetooth.BluetoothSocket(bluetooth.RFCOMM)
sock.connect((device, port))
while get_at_command(sock, sock.recv(128), device):
pass
sock.close()
Just put the connection in the error. Works 100% of the time now :)
I got WH1000-XM3 to just work by adding --experimental
flag to Bluez bluethoothd
. That option was kinda under the rock but after adding that everything just started working.
$ bluetooth-headset-battery-level <MAC>.10
Battery level for <MAC> is 50%
$ dbus-send --print-reply=literal --system --dest=org.bluez /org/bluez/hci0/dev_<MAC> org.freedesktop.DBus.Properties.Get string:"org.bluez.Battery1" string:"Percentage"
variant byte 50
$ bluetoothctl info <MAC>
Device <MAC> (public)
Name: LE_WH-1000XM3
Alias: LE_WH-1000XM3
...
Battery Percentage: 0x32 (50)
before adding the flag the DBus interface was missing, this script reported that the device was in use and bluetoothctl did not have the battery percentage field. However reading battery level when not connected worked.
@Jaakkonen You are probably running a recent version of pipwire after this MR was merged, or PulseAudio built with this MR locally? Both use bluetoothd
's experimental BatteryProvider
API and parse the AT commands internally hence don't need this script nor cut the RFCOMM connection. It appears this script doesn't report its findings through a BatteryProvider
anyway, hence doesn't make it available to bluetoothctl
nor DBus nor UPower.
@MarijnS95 I'm running pipewire 1:0.3.39 and this is not working for me - the battery level field doesn't appear.
@gshpychka As per the above: Have you enabled BlueZ experimental features/interfaces?
Yes, I've edited the unit file to add the --experimental
flag, rebuilt the unit and restarted the service.
@gshpychka Your best bet is to check and share debug logs for both bluetoothd and pipewire right after connecting headphones. That usually gives some hints though I'm unfamiliar with PipeWire to give you anything conclusive to check.
What type of headphones/speakers do you have - do they support battery reporting at all?
Same headphones as OP. I have this in the pipewire-media-session logs: BlueZ Battery Provider is not available, won't try to register it. Make sure you are running BlueZ 5.56
I'm running BlueZ 5.62
@gshpychka That sounds like bluetoothd
wasn't properly restarted with -E
(or --experimental
) after all?
You can check the status to see if it's indeed running with the desired flags:
$ systemctl status bluetooth
● bluetooth.service - Bluetooth service
Loaded: loaded (/usr/lib/systemd/system/bluetooth.service; enabled; vendor preset: disabled)
Drop-In: /etc/systemd/system/bluetooth.service.d
└─override.conf
Active: active (running) since Mon 2021-10-25 13:55:40 CEST; 3s ago
Docs: man:bluetoothd(8)
Main PID: 235559 (bluetoothd)
Status: "Running"
Tasks: 1 (limit: 154391)
Memory: 964.0K
CPU: 19ms
CGroup: /system.slice/bluetooth.service
└─235559 /usr/lib/bluetooth/bluetoothd -d -E
I locally use -d
to also see verbose debug logs. If the backend is enabled, this should also show the following in bluetoothd
unit logs:
bluetoothd[235559]: src/battery.c:register_battery_provider() register battery provider path = /org/pulseaudio/bluez/hci0
FWIW to prevent conflicts with the main unit file installed by your package manager, you should use an override file with systemctl edit bluetooth
: this opens a file editor where you should paste the following between the comment tags:
[Service]
ExecStart=
ExecStart=/usr/lib/bluetooth/bluetoothd -d -E
Im seeing that this is happening when I am in experimental mode:
systemctl status bluetooth
● bluetooth.service - Bluetooth service
Loaded: loaded (/etc/systemd/system/bluetooth.service; enabled; vendor preset: disabled)
Active: active (running) since Mon 2021-12-13 09:29:52 GMT; 49min ago
Docs: man:bluetoothd(8)
Main PID: 26472 (bluetoothd)
Status: "Running"
Tasks: 1 (limit: 28699)
Memory: 2.2M
CPU: 2.379s
CGroup: /system.slice/bluetooth.service
└─26472 /usr/lib/bluetooth/bluetoothd --experimental
And interestingly bluetoothctl
doesn't show there to be any battery information exposed?
bluetoothctl info
Device 38:18:4C:BF:46:FE (public)
Name: WH-1000XM3
Alias: WH-1000XM3
Class: 0x00240404
Icon: audio-headset
Paired: yes
Trusted: no
Blocked: no
Connected: yes
LegacyPairing: no
UUID: Vendor specific (00000000-deca-fade-deca-deafdecacaff)
UUID: Headset (00001108-0000-1000-8000-00805f9b34fb)
UUID: Audio Sink (0000110b-0000-1000-8000-00805f9b34fb)
UUID: A/V Remote Control Target (0000110c-0000-1000-8000-00805f9b34fb)
UUID: A/V Remote Control (0000110e-0000-1000-8000-00805f9b34fb)
UUID: Handsfree (0000111e-0000-1000-8000-00805f9b34fb)
UUID: PnP Information (00001200-0000-1000-8000-00805f9b34fb)
UUID: Generic Access Profile (00001800-0000-1000-8000-00805f9b34fb)
UUID: Generic Attribute Profile (00001801-0000-1000-8000-00805f9b34fb)
UUID: Amazon.com Services, Inc. (0000fe03-0000-1000-8000-00805f9b34fb)
UUID: Vendor specific (5b833e05-6bc7-4802-8e9a-723ceca4bd8f)
UUID: Vendor specific (5b833e06-6bc7-4802-8e9a-723ceca4bd8f)
UUID: Vendor specific (69a7f243-e52f-4443-a7f9-cb4d053c74d6)
UUID: Vendor specific (7b265b0e-2232-4d45-bef4-bb8ae62f813d)
UUID: Vendor specific (81c2e72a-0591-443e-a1ff-05f988593351)
UUID: Vendor specific (91c10d9c-aaef-42bd-b6d6-8a648c19213d)
UUID: Vendor specific (931c7e8a-540f-4686-b798-e8df0a2ad9f7)
UUID: Vendor specific (96cc203e-5068-46ad-b32d-e316f5e069ba)
UUID: Vendor specific (b9b213ce-eeab-49e4-8fd9-aa478ed1b26b)
UUID: Vendor specific (f8d1fbe4-7966-4334-8024-ff96c9330e15)
UUID: Vendor specific (fe59bfa8-7fe3-4a05-9d94-99fadc69faff)
Modalias: usb:v054Cp0CD3d0452
As well as failing to be shared when using dbus-send
:
dbus-send
mac="38:18:4C:BF:46:FE"
mac="${mac//:/_}"
dbus-send --print-reply=literal --system --dest=org.bluez /org/bluez/hci0/dev_$mac org.freedesktop.DBus.Properties.Get string:"org.bluez.Battery1" string:"Percentage"
Error org.freedesktop.DBus.Error.InvalidArgs: No such interface 'org.bluez.Battery1'
@jamietanna Is PulseAudio or PipeWire running, and built from recent enough source to report this battery level to BlueZ in the first place? Perhaps their logs might clarify what is missing, as BlueZ
will only expose this org.bluez.Battery1
interface when a BatteryProvider
has been registered for that device.
@MarijnS95 I'm running a fairly up-to-date Arch Linux install, with these versions:
% uname -a
Linux TheColonel 5.15.5-arch1-1 #1 SMP PREEMPT Thu, 25 Nov 2021 22:09:33 +0000 x86_64 GNU/Linux
% pacman -Qi pulseaudio{,-bluetooth} bluez{,-libs,-utils}
Name : pulseaudio
Version : 15.0-1
Description : A featureful, general-purpose sound server
Architecture : x86_64
URL : https://www.freedesktop.org/wiki/Software/PulseAudio/
Licenses : GPL
Groups : None
Provides : None
Depends On : libpulse=15.0-1 rtkit libltdl speexdsp tdb orc libsoxr webrtc-audio-processing libxtst
Optional Deps : pulseaudio-alsa: ALSA configuration (recommended)
pulseaudio-zeroconf: Zeroconf support
pulseaudio-lirc: IR (lirc) support
pulseaudio-jack: Jack support
pulseaudio-bluetooth: Bluetooth support [installed]
pulseaudio-equalizer: Graphical equalizer
pulseaudio-rtp: RTP and RAOP support
Required By : pulseaudio-bluetooth pulseaudio-ctl
Optional For : firefox-nightly-en-gb pavucontrol
Conflicts With : None
Replaces : pulseaudio-xen<=9.0 pulseaudio-gconf<=11.1
Installed Size : 5.81 MiB
Packager : Jan Alexander Steffens (heftig) <[email protected]>
Build Date : Wed 28 Jul 2021 13:14:50 BST
Install Date : Mon 02 Aug 2021 10:25:07 BST
Install Reason : Installed as a dependency for another package
Install Script : Yes
Validated By : Signature
Name : pulseaudio-bluetooth
Version : 15.0-1
Description : Bluetooth support for PulseAudio
Architecture : x86_64
URL : https://www.freedesktop.org/wiki/Software/PulseAudio/
Licenses : GPL
Groups : None
Provides : None
Depends On : pulseaudio=15.0-1 bluez bluez-libs sbc
Optional Deps : None
Required By : None
Optional For : pulseaudio
Conflicts With : None
Replaces : None
Installed Size : 256.75 KiB
Packager : Jan Alexander Steffens (heftig) <[email protected]>
Build Date : Wed 28 Jul 2021 13:14:50 BST
Install Date : Mon 13 Dec 2021 09:23:06 GMT
Install Reason : Explicitly installed
Install Script : No
Validated By : Signature
Name : bluez
Version : 5.62-1
Description : Daemons for the bluetooth protocol stack
Architecture : x86_64
URL : http://www.bluez.org/
Licenses : GPL2
Groups : None
Provides : None
Depends On : libical dbus glib2 alsa-lib json-c
Optional Deps : None
Required By : pulseaudio-bluetooth
Optional For : None
Conflicts With : obexd-client obexd-server
Replaces : None
Installed Size : 2.68 MiB
Packager : Andreas Radke <[email protected]>
Build Date : Wed 13 Oct 2021 20:21:34 BST
Install Date : Wed 10 Nov 2021 08:31:19 GMT
Install Reason : Explicitly installed
Install Script : No
Validated By : Signature
Name : bluez-libs
Version : 5.62-1
Description : Deprecated libraries for the bluetooth protocol stack
Architecture : x86_64
URL : http://www.bluez.org/
Licenses : LGPL2.1
Groups : None
Provides : libbluetooth.so=3-64
Depends On : glibc
Optional Deps : None
Required By : pipewire pulseaudio-bluetooth python-pybluez
Optional For : None
Conflicts With : None
Replaces : None
Installed Size : 325.74 KiB
Packager : Andreas Radke <[email protected]>
Build Date : Wed 13 Oct 2021 20:21:34 BST
Install Date : Wed 10 Nov 2021 08:31:19 GMT
Install Reason : Installed as a dependency for another package
Install Script : No
Validated By : Signature
Name : bluez-utils
Version : 5.62-1
Description : Development and debugging utilities for the bluetooth protocol stack
Architecture : x86_64
URL : http://www.bluez.org/
Licenses : GPL2
Groups : None
Provides : bluez-hcidump
Depends On : dbus systemd glib2
Optional Deps : ell: for btpclient
Required By : None
Optional For : None
Conflicts With : bluez-hcidump
Replaces : bluez-hcidump bluez<=4.101
Installed Size : 7.43 MiB
Packager : Andreas Radke <[email protected]>
Build Date : Wed 13 Oct 2021 20:21:34 BST
Install Date : Wed 10 Nov 2021 08:31:20 GMT
Install Reason : Explicitly installed
Install Script : No
Validated By : Signature
@jamietanna As mentioned above PulseAudio must be built with this MR in order to have the feature; it'll only land in 16.0 which should ~be out~ go into feature freeze soon :crossed_fingers:
Oh sorry I totally didn't read that right - awesome will keel an eye out for that release then!