Skip to content

Instantly share code, notes, and snippets.

@altbrace
Last active April 5, 2024 06:38
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save altbrace/52ae1783b31257021520673fadb95b6e to your computer and use it in GitHub Desktop.
Save altbrace/52ae1783b31257021520673fadb95b6e to your computer and use it in GitHub Desktop.
Automatic sound profile change on Bluetooth device connect
#!/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
Copy link

tonikelope commented Nov 25, 2023

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!

@altbrace
Copy link
Author

@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
Copy link

@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!

@altbrace
Copy link
Author

@tonikelope added dynamic discovery

@tonikelope
Copy link

@tonikelope added dynamic discovery

Thank you!

@sbrl
Copy link

sbrl commented Apr 4, 2024

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 :-)

@altbrace
Copy link
Author

altbrace commented Apr 5, 2024

@sbrl done, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment