web-dev-qa-db-fra.com

Comment exécuter un script lorsqu'un périphérique Bluetooth se connecte?

J'aimerais démarrer mon lecteur de musique (Clementine) lorsque mon casque Bluetooth se connecte à mon ordinateur. Comment détecter le périphérique Bluetooth connecté pour pouvoir exécuter un script afin de démarrer le lecteur?

15
Erigami

Je n’aimais pas l’approche par sondage, alors j’ai fait quelques recherches sur bluez et DBus. J'ai fini par écrire le script suivant:

#!/usr/bin/python

import dbus
from dbus.mainloop.glib import DBusGMainLoop
import gobject

import subprocess

# ID of the device we care about
DEV_ID = '00_1D_54_AB_DC_72'

dbus_loop = DBusGMainLoop()
bus = dbus.SystemBus(mainloop=dbus_loop)

# Figure out the path to the headset
man = bus.get_object('org.bluez', '/')
iface = dbus.Interface(man, 'org.bluez.Manager')
adapterPath = iface.DefaultAdapter()

headset = bus.get_object('org.bluez', adapterPath + '/dev_' + DEV_ID)
    # ^^^ I'm not sure if that's kosher. But it works.

def cb(iface=None, mbr=None, path=None):

    if ("org.bluez.Headset" == iface and path.find(DEV_ID) > -1):
        print 'iface: %s' % iface
        print 'mbr: %s' % mbr
        print 'path: %s' % path
        print "\n"
        print "matched"

        if mbr == "Connected":
            subprocess.call(["clementine", "--play"])
            print 'conn'

        Elif mbr == "Disconnected":
            subprocess.call(["clementine", "--stop"])
            print 'dconn'

headset.connect_to_signal("Connected", cb, interface_keyword='iface', member_keyword='mbr', path_keyword='path')
headset.connect_to_signal("Disconnected", cb, interface_keyword='iface', member_keyword='mbr', path_keyword='path')

loop = gobject.MainLoop()
loop.run()
11
Erigami

Pour découvrir une connexion Bluetooth établie avec succès, nous pouvons exécuter

sdptool browse xx:xx:xx:xx:xx:xx

Ainsi, la connexion SDB sera testée pour une connexion à l'adresse MAC donnée. Cela peut prendre beaucoup de temps avant que la navigation ne s'éteigne avec une erreur comme

Failed to connect to SDP server on 00:0C:78:4F:B6:B5: Host is down

Nous ne connaissons pas l'objectif exact de votre script, mais vous souhaiterez probablement lire de l'audio via Clementine lorsqu'un casque est connecté.

Ensuite, nous pourrions simplement voir s’il existe un récepteur audio Bluetooth avec

pacmd list-sinks | grep xx_xx_xx_xx_xx_xx

xx_xx_xx_xx_xx_xx est l'adresse MAC (: doit être remplacé par _). La sortie vous indiquera alors si un récepteur audio Bluetooth est disponible ou rien sinon.

Voir cette réponse pour savoir comment basculer l'audio sur cet évier.


Stream2ip

Avec stream2ip , nous pouvons définir une commande Shell ou un script à exécuter après l'établissement d'une connexion. Il existe également une option permettant de démarrer automatiquement un lecteur multimédia pris en charge après l’établissement d’une connexion:

enter image description here

Stream2ip essaiera également de reconnecter le flux de lecture en cours au périphérique audio Bluetooth au cas où la connexion serait interrompue.

4
Takkat

Voici un autre exemple de surveillance de tous les périphériques Bluetooth. Il n'est pas nécessaire de spécifier une adresse MAC spécifique. Cette approche rend le paramètre xinput persistant même lors de la connexion/déconnexion, de la suspension/de la réactivation et de la connexion/déconnexion de votre périphérique Bluetooth.

J'ai un clavier Bluetooth compact Thinkpad et je souhaite exécuter une commande xinput chaque fois que le clavier est connecté pour régler la vitesse du point de suivi. Voici les étapes.

  1. Téléchargez le code de Github bluetooth-ruunner . Crédits donnés à ici qui est le premier à l'avoir écrit pour Raspberry Pi. Modifiez la section suivante du code pour exécuter vos commandes personnalisées.

    subprocess.call(['xinput', 'set-prop',
                     'ThinkPad Compact Bluetooth Keyboard with TrackPoint',
                     'Device Accel Constant Deceleration', '0.6'])
    

    Dans mon cas, cela équivaut à un appel depuis le terminal.

    $ xinput set-prop 'ThinkPad Compact Bluetooth Keyboard with TrackPoint' 'Device Accel Constant Deceleration' 0.6
    
  2. Enregistrez la modification. Essayez d’exécuter vos scripts avec

    $ python bluetooth-runner.py
    

    Connectez et déconnectez votre périphérique Bluethooth. Vous devriez voir le message correspondant imprimé à l'écran.

  3. Maintenant, rendez votre fichier exécutable et copiez-le dans l’un des répertoires de votre $PATH, disons ~/bin/.

    $ chmod +x bluetooth-runner.py
    $ mkdir ~/bin # if you dont have it yet
    $ cp bluetooth-runner.py ~/bin
    
  4. Maintenant, assurez-vous que vous pouvez exécuter le script à partir de n’importe où dans le terminal (assurez-vous qu’il se trouve dans votre chemin de recherche).

  5. Lancez le Startup Applications à partir du menu Ubuntu. Ajoutez vos scripts au démarrage.

    Add startup applications

  6. Maintenant, il ne reste qu'un problème: au moment où vous vous connectez, les scripts risquent de ne pas capturer le premier événement bluetooth. Cela est dû au fait que votre périphérique Bluetooth peut être connecté avant que votre script ne soit initialisé en arrière-plan.

    Pour résoudre ce problème, ajoutez votre commande personnalisée directement dans Startup Applications. Dans mon cas, c'est la commande suivante:

     xinput set-prop 'ThinkPad Compact Bluetooth Keyboard with TrackPoint' 'Device Accel Constant Deceleration' 0.6
    

Et maintenant, vous pourrez profiter de votre appareil Bluetooth avec Ubuntu.

1
Yixing

@ Erigami Votre réponse a beaucoup aidé, mais pour que cela fonctionne, je devais faire quelques changements. J'utilise Ubuntu 14.04.

#!/usr/bin/python

import dbus
from dbus.mainloop.glib import DBusGMainLoop
import gobject

import subprocess

# ID of the device we care about
DEV_ID = 'CC:C3:EA:A5:16:90'.replace(":", "_")

dbus_loop = DBusGMainLoop()
bus = dbus.SystemBus(mainloop=dbus_loop)

# Figure out the path to the headset
man = bus.get_object('org.bluez', '/')
iface = dbus.Interface(man, 'org.bluez.Manager')
adapterPath = iface.DefaultAdapter()

print(adapterPath + '/dev_' + DEV_ID)
headset = bus.get_object('org.bluez', adapterPath + '/dev_' + DEV_ID)
# ^^^ I'm not sure if that's kosher. But it works.

def cb(*args, **kwargs):
    is_connected = args[-1]
    if isinstance(is_connected, dbus.Boolean) and is_connected:
        print("Connected")
    Elif isinstance(is_connected, dbus.Boolean) and not is_connected:
        print("Disconnected")

headset.connect_to_signal("PropertyChanged", cb, interface_keyword='iface', member_keyword='mbr', path_keyword='path')

loop = gobject.MainLoop()
loop.run()

Si cela ne fonctionne toujours pas, utilisez et surveillez le système dbus.

dbus-monitor --system

d-feet peut être utilisé plus loin. C'est un outil graphique pour regarder des objets dbus.

1
Hitul

Vous écrivez "lorsque votre oreillette se connecte à votre ordinateur". Comment fait-il cela automatiquement? Lorsque vous devez le déclencher manuellement, vous pouvez également en faire un script, puis l'exécuter une fois la connexion établie. Voici ce que j'ai fait pour régler le périphérique de sortie par défaut sur mon récepteur Bluetooth (afin que je puisse modifier le volume à l'aide des touches matérielles):

bluetooth-connect && pactl set-default-sink bluez_sink.0C_A6_94_9A_37_4D

bluetooth-connect se présente comme suit: https://github.com/sblask/dotfiles/blob/c39d37ad67947b35a4c041cb41a079cb41ae6f9e4a081d8/.bin/bluetooth-connect.symlink Il suppose que tout est prêt à être connecté. Vous trouvez l'adresse MAC dans blueman ou en exécutant pacmd list-sinks | grep -e 'name:' -e 'index' lorsque le périphérique Bluetooth est connecté. Vous voudriez exécuter bluetooth-connect && your-script. your-script ne sera exécuté que lorsque la connexion a été établie avec succès.

0
Sebastian Blask