Como executo um script quando um dispositivo Bluetooth é conectado?

13

Gostaria de iniciar meu music player (Clementine) quando meu fone de ouvido bluetooth se conecta ao meu computador. Como faço para detectar o dispositivo bluetooth conectando para que eu possa executar um script para iniciar o player?

    
por Erigami 17.05.2012 / 19:30

5 respostas

10

Eu não gostei da abordagem de pesquisa, então fiz algumas pesquisas sobre bluez e DBus. Acabei escrevendo o seguinte 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()
    
por Erigami 22.05.2012 / 00:14
4

Para descobrir uma conexão Bluetooth estabelecida com sucesso, podemos executar

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

Por isso, a conexão SDB será testada para uma conexão com o endereço MAC fornecido. Pode levar um tempo considerável até que a navegação expire com um erro como

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

Não sabemos o objetivo exato do seu script, mas provavelmente você deseja reproduzir áudio via Clementine quando um fone de ouvido estiver conectado.

Então poderíamos ver se há um coletor de áudio Bluetooth com

pacmd list-sinks | grep xx_xx_xx_xx_xx_xx

Em que xx_xx_xx_xx_xx_xx é o endereço MAC ( : precisa ser substituído por _ ). A saída informará se existe um coletor de áudio Bluetooth disponível ou nada, se não.

Veja esta resposta sobre como mudar o áudio para este sumidouro.

Stream2ip

Com stream2ip podemos definir um comando shell ou um script para ser executado depois que uma conexão foi estabelecida. Há também uma opção para iniciar automaticamente um media player compatível depois que uma conexão foi estabelecida:

O Stream2ip também tentará reconectar o fluxo de reprodução atualmente em execução no dispositivo de áudio Bluetooth, caso a conexão tenha sido interrompida.

    
por Takkat 17.05.2012 / 21:34
1

Aqui está outro exemplo para monitorar todos os dispositivos Bluetooth. Não precisa especificar um endereço MAC específico. Essa abordagem torna a configuração do xinput persistente mesmo quando você faz login / out, suspende / acorda e conecta / desconecta seu dispositivo bluetooth.

Eu tenho um Teclado Bluetooth compacto Thinkpad e desejo executar um comando xinput sempre que o teclado estiver conectado para ajustar a velocidade do trackpoint. Aqui estão os passos.

  1. Faça o download do código do Github bluetooth-ruunner . Créditos concedidos a aqui que primeiro escreveu isso para Raspberry Pi. Modifique a seguinte seção do código para executar o seu comamnds personalizado.

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

    No meu caso, isso equivale a chamar do terminal.

    $ xinput set-prop 'ThinkPad Compact Bluetooth Keyboard with TrackPoint' 'Device Accel Constant Deceleration' 0.6
    
  2. Salve a modificação. Tente executar seus scripts por

    $ python bluetooth-runner.py
    

    Conecte e desconecte seu dispositivo Bluethooth. Você deve ver a mensagem correspondente impressa na tela.

  3. Agora, torne seu arquivo executável e copie-o em um dos diretórios em $PATH , digamos ~/bin/ .

    $ chmod +x bluetooth-runner.py
    $ mkdir ~/bin # if you dont have it yet
    $ cp bluetooth-runner.py ~/bin
    
  4. Agora, certifique-se de poder executar o script de qualquer lugar no terminal (verifique se ele está no caminho de pesquisa).

  5. Acione o Startup Applications no menu do Ubuntu. Adicione seus scripts para a inicialização.

  6. Agora, resta apenas um problema, no momento em que você faz login, os scripts podem não detectar o primeiro evento bluetooth. Isso ocorre porque seu dispositivo Bluetooth pode estar conectado antes que o script seja inicializado em segundo plano.

    Para resolver isso, adicione seu comando personalizado diretamente em Startup Applications . No meu caso, é o seguinte comando:

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

E agora você poderá aproveitar seu dispositivo Bluetooth com o Ubuntu.

    
por Yixing 05.07.2015 / 14:37
1

@Erigami Sua resposta ajudou muito, mas para dar certo eu fiz algumas mudanças. Estou usando o 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()

Ainda se isso não funcionar, use e monitore o dbus do sistema.

dbus-monitor --system

d-feet pode ser usado posteriormente. É uma ferramenta GUI para assistir objetos dbus.

    
por Hitul 14.08.2016 / 16:24
0

Você escreve "quando seu fone de ouvido se conecta ao seu computador". Como isso acontece automaticamente? Quando você precisar ativá-lo manualmente, é melhor criar um script e depois executar o script depois que a conexão tiver sido estabelecida. Isto é o que eu fiz para definir o dispositivo de saída padrão para o meu receptor bluetooth (para que eu possa mudar o volume com as chaves de hardware):

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

Onde bluetooth-connect se parece com isto: link Ele assume tudo foi emparelhado e está pronto para se conectar. Você encontra o endereço MAC em blueman ou executando pacmd list-sinks | grep -e 'name:' -e 'index' quando o dispositivo Bluetooth está conectado. Você deseja executar bluetooth-connect && your-script . your-script só será executado quando a conexão for estabelecida com sucesso.

    
por Sebastian Blask 31.08.2016 / 21:06