Come posso eseguire uno script quando si connette un dispositivo Bluetooth?


16

Vorrei avviare il mio lettore musicale (Clementine) quando le mie cuffie bluetooth si collegano al mio computer. Come posso rilevare la connessione del dispositivo Bluetooth in modo da poter eseguire uno script per avviare il lettore?

Risposte:


12

Non mi piaceva l'approccio al polling, quindi ho scavato su Bluez e DBus. Ho finito per scrivere il seguente script:

#!/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()

Ovviamente Bluez e PulseAudio operano tramite polling DBus. Finché l'auricolare è l'adattatore predefinito, nella maggior parte dei casi funzionerà perfettamente. Assicurati di collegare anche PulseAudio all'auricolare se vuoi sentire qualcosa. Grazie per aver condiviso la tua soluzione :)
Takkat,

è fantastico se conosci la DEV_IDconnessione precedente .. ma cosa succede se vuoi essere avvisato di tutti gli eventi di connessione?
Pstanton,

4

Per scoprire una connessione Bluetooth stabilita con successo possiamo eseguire

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

In questo modo la connessione SDB verrà testata per una connessione all'indirizzo MAC specificato. Potrebbe volerci molto tempo prima che la navigazione scada con un errore simile

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

Non conosciamo lo scopo esatto della tua sceneggiatura, ma molto probabilmente desideri riprodurre l'audio tramite Clementine quando è stata collegata una cuffia.

Quindi potremmo solo vedere se c'è un lavandino audio Bluetooth con

pacmd list-sinks | grep xx_xx_xx_xx_xx_xx

Dove si xx_xx_xx_xx_xx_xxtrova l'indirizzo MAC ( :deve essere sostituito con _). L'output ti dirà quindi se è disponibile un sink audio Bluetooth o nulla in caso contrario.

Vedi questa risposta su come passare l'audio a questo sink.


Stream2ip

Con stream2ip possiamo definire un comando shell o uno script da eseguire dopo aver stabilito una connessione. C'è anche un'opzione per avviare automaticamente un lettore multimediale supportato dopo aver stabilito una connessione:

inserisci qui la descrizione dell'immagine

Stream2ip proverà anche a riconnettere il flusso di riproduzione attualmente in esecuzione al dispositivo audio Bluetooth nel caso in cui la connessione fosse interrotta.


Grazie per la tua risposta. Stai suggerendo che dovrei effettuare il polling sdptool browse <device-id>fino a quando non ottengo un codice di ritorno 0 e quindi dare il via al mio script, giusto? C'è un modo per farlo senza polling?
Erigami,

Sdptool è lento. Preferirei pulseaudio. Hai bisogno di un loop perché non sappiamo quando il tuo dispositivo è lì.
Takkat,

2

@Erigami La tua risposta mi è stata di grande aiuto, ma per farlo funzionare farei alcune modifiche. Sto usando 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()

Tuttavia, se non funziona, utilizzare e monitorare il dbus di sistema.

dbus-monitor --system

d-feetpuò essere utilizzato ulteriormente. È lo strumento GUI per guardare oggetti dbus.


1
Se vuoi migliorare un'altra risposta, ti preghiamo di suggerire una modifica e non creare una nuova risposta.
David Foerster,

1

Ecco un altro esempio per il monitoraggio di tutti i dispositivi Bluetooth. Non è necessario specificare un indirizzo MAC specifico. Questo approccio rende persistente l'impostazione xinput anche quando si effettua il login / out, la sospensione / riattivazione e la connessione / disconnessione del dispositivo bluetooth.

Ho una tastiera Bluetooth compatta Thinkpad e desidero eseguire un comando xinput ogni volta che la tastiera è collegata per regolare la velocità del trackpoint. Ecco i passaggi.

  1. Scarica il codice da Github bluetooth-ruunner . Ringraziamenti qui assegnati per la prima volta a Raspberry Pi. Modifica la seguente sezione del codice per eseguire i tuoi comandi personalizzati.

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

    Nel mio caso, questo equivale a chiamare dal terminale.

    $ xinput set-prop 'ThinkPad Compact Bluetooth Keyboard with TrackPoint' 'Device Accel Constant Deceleration' 0.6
  2. Salva la modifica. Prova a eseguire i tuoi script da

    $ python bluetooth-runner.py

    Connetti e disconnetti il ​​tuo dispositivo Bluethooth. Dovresti vedere il messaggio corrispondente stampato sullo schermo.

  3. Ora, rendi il tuo file eseguibile e copialo in una delle directory nella tua $PATH, diciamo ~/bin/.

    $ chmod +x bluetooth-runner.py
    $ mkdir ~/bin # if you dont have it yet
    $ cp bluetooth-runner.py ~/bin
  4. Ora, assicurati di poter eseguire lo script da qualsiasi parte del terminale (assicurati che sia nel tuo percorso di ricerca).

  5. Avvia il Startup Applicationsdal menu di Ubuntu. Aggiungi i tuoi script all'avvio.

    Aggiungi applicazioni di avvio

  6. Ora, rimane solo un problema, al momento del login, gli script potrebbero non rilevare il primo evento bluetooth. Questo perché il dispositivo Bluetooth potrebbe essere collegato prima che lo script venga inizializzato in background.

    Per risolvere questo, aggiungi il tuo comando personalizzato direttamente in Startup Applications. Nel mio caso, è il seguente comando:

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

E ora sarai in grado di goderti il ​​tuo dispositivo Bluetooth con Ubuntu.


lo script python non ha monitorato le connessioni bluetooth.
Paulo Pedroso,

0

Scrivi "quando l'auricolare si collega al computer". Come lo fa automaticamente? Quando devi attivarlo manualmente, potresti anche renderlo uno script e quindi eseguire lo script dopo aver stabilito la connessione. Questo è quello che ho fatto per impostare il dispositivo di output predefinito sul mio ricevitore bluetooth (quindi posso cambiare il volume con le chiavi hardware):

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

Dove si bluetooth-connectpresenta così: https://github.com/sblask/dotfiles/blob/c39d37ad67947b358b4a079cb41ae6f9e4a081d8/.bin/bluetooth-connect.symlink Presuppone che tutto sia stato accoppiato ed è pronto per la connessione. Puoi trovare l'indirizzo MAC in blueman o eseguendolo pacmd list-sinks | grep -e 'name:' -e 'index'quando il dispositivo bluetooth è collegato. Vorresti correre bluetooth-connect && your-script. your-scriptverrà eseguito solo quando la connessione è stata stabilita correttamente.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.