Last active
October 11, 2024 11:27
-
-
Save altbrace/52ae1783b31257021520673fadb95b6e to your computer and use it in GitHub Desktop.
Automatic sound profile change on Bluetooth device connect
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
# Ref https://gist.github.com/altbrace/52ae1783b31257021520673fadb95b6e | |
from pydbus import SystemBus | |
from gi.repository import GLib # don't mind the import error if you get one, it should work | |
import subprocess | |
import time | |
import re | |
ADDRESS = '74_5C_4B_0C_C4_41' # your Bluetooth device's MAC separated by underscores | |
def pc_handler(sender=None, iface=None, signal=None, object=None, arg0=None): | |
dev_api = dev['org.bluez.Device1'] | |
if dev_api.Connected: | |
print(f"Device {ADDRESS} connected, sleeping...") | |
time.sleep(6) # the system needs some time before the profile can be changed. You can experiment with this value. | |
subprocess.call(['pactl', 'set-card-profile', | |
f'bluez_card.{ADDRESS}', | |
'headset-head-unit-msbc']) # profile change command | |
# You can call whichever command you wish, just change the subprocess call accordingly | |
print("Profile changed to mSBC.") | |
else: | |
print(f"Device {ADDRESS} disconnected.") | |
bus = SystemBus() | |
bluez_desc = bus.get('org.bluez').Introspect() # get bluez object description, there are defined connected adapters | |
ifaces = re.findall("node name=\"(hci.)\"", bluez_desc) # get adapter ids | |
if not ifaces: | |
raise Exception("No bluetooth interfaces available, check your adapter") | |
dev = "" | |
dev_iface = "" | |
print(f"Running lookup for {ADDRESS}...") | |
for iface in ifaces: | |
print(f"Checking {iface}...") # checking each available bluez interface for our device present | |
try: | |
dev = bus.get('org.bluez', f'/org/bluez/{iface}/dev_{ADDRESS}') # get the device by dbus path | |
print(f"Device {ADDRESS} was found at {iface}.") | |
dev_iface = iface | |
break | |
except KeyError: | |
print(f"Device {ADDRESS} was not found at {iface}, continuing.") | |
if not dev: | |
raise Exception(f"Device {ADDRESS} was not found in the system, please make sure to pair it first") | |
listener = bus.subscribe(iface='org.freedesktop.DBus.Properties', signal='PropertiesChanged', | |
object=f'/org/bluez/{dev_iface}/dev_{ADDRESS}', | |
arg0='org.bluez.Device1', signal_fired=pc_handler) | |
loop = GLib.MainLoop() | |
loop.run() |
@tonikelope thanks for pointing that out! Didn’t even think that the bluetooth adapter device id can change. I’ll make sure to test it out later and make a change in the code
@tonikelope thanks for pointing that out! Didn’t even think that the bluetooth adapter device id can change. I’ll make sure to test it out later and make a change in the code
Great!
@tonikelope added dynamic discovery
@tonikelope added dynamic discovery
Thank you!
Suggestion: Put the following just below the shebang:
# Ref https://gist.github.com/altbrace/52ae1783b31257021520673fadb95b6e
....so that those downloading it can find this gist again later :-)
@sbrl done, thanks!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I have been using this script for months with no problem. Today I changed the USB bluetooth adapter and it stopped working. It turns out that by doing :
$ busctl list
$ busctl tree org.bluez
i saw that /hci0/ had to be changed to /hci1/ in script (two places).
Now it's working again.
Thank you!