3

I have a bluetooth headset and I need to execute a .sh file everytime I connect it to make it work. I don't want to troubleshoot this bug since I know there's already people looking into it.

But I'm interested on a way to run that .sh script every time I connect a bluetooth device. And, if it's possible, every time I connect a headset/this specific headset.

Maccer
  • 243
  • 2
  • 8

3 Answers3

4

Look into udev rules. See the ArchWiki article on udev rules and this question about running a script when a USB device is plugged in.

There are also already many questions on this site regarding bluetooth and udev rules. See:

jayhendren
  • 8,224
  • 2
  • 30
  • 55
  • The +Run key in a Udev-Rule is not longer working under systemd. `ps -p 1 -o comm=` –  Nov 11 '16 at 19:09
1

For me this worked (ubuntu 22.04 on Raspberry PI 4):

#!/usr/bin/env python3
# Toggles headset connection
import dbus
from gi.repository import GLib
from dbus.mainloop.glib import DBusGMainLoop

dev_id = '74_A3_4A_DF_BB_8A'

def signal_handler(*args, **kwargs):
  if (dev_id in kwargs['path']) & (args[0] == 'org.bluez.MediaControl1'):
    if args[1]['Connected']:
      print('connected')
    else:
      print('disconnected')

DBusGMainLoop(set_as_default=True)
bus = dbus.SystemBus()
#register your signal callback
bus.add_signal_receiver(signal_handler,
                        bus_name='org.bluez',
                        interface_keyword='interface',
                        member_keyword='member',
                        path_keyword='path',
                        message_keyword='msg')
loop = GLib.MainLoop()
loop.run()

About how to automatically run this script on boot. When I first tried this with the systemd unit, it didn't work for me. The unit was started before device hci0 appeared. The working solution turned out to be adding the line:

ExecStartPre=hciconfig hci0 up

Here is an example:

[Unit]
Description=Служба управления phasetimer.
After=sound.target
After=bluetooth.target
 
[Service]
Type=simple
KillSignal=SIGINT
WorkingDirectory=/home/zenbooster/git/phasetimer
ExecStartPre=hciconfig hci0 up
ExecStart=python3 /home/zenbooster/git/phasetimer/guardian.py
Restart=on-failure
SyslogIdentifier=phasetimer-guardian
RestartSec=5
TimeoutStartSec=infinity

[Install]
WantedBy=multi-user.target
zenbooster
  • 11
  • 2
-1

Well, I would try this:

  1. Open a shell (bash, sh, ksh) and type: set -e (enables errorhandling)
  2. Insert Your BT- device
  3. Type: echo $?

You should get a number larger than 0, which is an errorcode. Depending on which shell you use, there might be set some environment variables:

  • ERR=$?=Errorcode
  • ERL=Linenumber if trap was detected in a script.
  • $?=0 then there is no errorcode, and U dont need to read further.

Write a script, or test by hand:

trap 'ERR=$?;errorhandler' listofcodes

errorhandler is the script that decides what todo when any of the listofcodes occur.

The list could be 1 10 14 15 (17 18 ...) or just 1 number, the one you want to catch.

# script errorhandler
errorhandler(){
case $ERR in
    1)
#    here U can take action or perhaps just ignore
    return
    ;;
    *) 
#    action if errorcode was different from 1

    ;;


esac
}

You would place line 1-4 in /etc/profile or similar to make it systemwide.

In /etc there should be an rc.d or init.d containg start and stop scripts related to boot and change in runstate. There should be a scriptfile for your BT device, check it out, but don't change content unless ...

If the errorcode in line 2 is zero then you must dig deeper.

jasonwryan
  • 71,734
  • 34
  • 193
  • 226