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


16

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

Réponses:


12

Je n'aimais pas l'approche par sondage, alors j'ai creusé 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()

Bien sûr, Bluez et PulseAudio fonctionnent via l'interrogation de DBus. Tant que votre casque est l'adaptateur par défaut, cela fonctionnera bien dans la plupart des cas. Assurez-vous de connecter également PulseAudio au casque si vous souhaitez entendre quelque chose. Merci de partager votre solution :)
Takkat

c'est super si vous connaissez la DEV_IDconnexion avant .. mais que faire si vous voulez être averti de tous les événements de connexion?
pstanton

4

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

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

Par cela, la connexion SDB sera testée pour une connexion à l'adresse MAC donnée. Cela peut prendre un temps considérable avant que la navigation ne se termine avec une erreur comme

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

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

Ensuite, nous pourrions simplement voir s'il y a 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ée par _). La sortie vous indiquera alors si un récepteur audio Bluetooth est disponible ou rien sinon.

Consultez cette réponse pour savoir comment basculer l'audio vers ce récepteur.


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 pour démarrer automatiquement un lecteur multimédia pris en charge une fois la connexion établie:

entrez la description de l'image ici

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


Merci pour votre réponse. Vous suggérez que je devrais interroger sdptool browse <device-id>jusqu'à ce que j'obtienne un code retour 0, puis lancer mon script, non? Existe-t-il un moyen de le faire sans sondage?
Erigami

Sdptool est lent. J'irais pour pulseaudio. Vous avez besoin d'une boucle car nous ne savons pas quand votre appareil est là.
Takkat

2

@Erigami Votre réponse a beaucoup aidé, mais pour que cela fonctionne, je ferais 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-feetpeut être utilisé plus loin. C'est un outil GUI pour regarder les objets dbus.


1
Si vous souhaitez améliorer une autre réponse, veuillez suggérer une modification et ne pas créer de nouvelle réponse.
David Foerster

1

Voici un autre exemple de surveillance de tous les appareils Bluetooth. Il n'a pas besoin de spécifier une adresse MAC spécifique. Cette approche rend le paramètre xinput persistant même lorsque vous vous connectez / déconnectez, suspendez / réveillez et connectez / déconnectez votre appareil Bluetooth.

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

  1. Téléchargez le code depuis Github bluetooth-ruunner . Crédits donnés ici qui a d' abord écrit cela 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 à appeler 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 en

    $ python bluetooth-runner.py

    Connectez et déconnectez votre appareil 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 depuis n'importe où dans le terminal (assurez-vous qu'il se trouve dans votre chemin de recherche).

  5. Lancez le Startup Applicationsdepuis le menu ubuntu. Ajoutez vos scripts au démarrage.

    Ajouter des applications de démarrage

  6. Maintenant, il n'y a qu'un seul problème, au moment où vous vous connectez, les scripts peuvent ne pas intercepter le tout premier événement Bluetooth. En effet, votre appareil 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.


Le script Python ne surveillait pas les connexions Bluetooth.
Paulo Pedroso

0

Vous écrivez «lorsque votre casque se connecte à votre ordinateur». Comment fait-il cela, automatiquement? Lorsque vous devez le déclencher manuellement, vous pouvez tout aussi bien 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 changer le volume avec les touches matérielles):

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

bluetooth-connect ressemble à ceci: https://github.com/sblask/dotfiles/blob/c39d37ad67947b358b4a079cb41ae6f9e4a081d8/.bin/bluetooth-connect.symlink Il suppose que tout a été couplé et est prêt à se connecter. 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 courir bluetooth-connect && your-script. your-scriptne sera exécuté que lorsque la connexion aura été établie avec succès.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.