Как запустить скрипт при подключении устройства Bluetooth?

16

Я хотел бы запустить свой музыкальный проигрыватель (Clementine), когда моя Bluetooth-гарнитура подключается к моему компьютеру. Как определить подключение устройства Bluetooth, чтобы я мог запустить скрипт для запуска проигрывателя?

Erigami
источник

Ответы:

12

Мне не понравился подход к опросу, поэтому я немного покопался в bluez и DBus. В итоге я написал следующий скрипт:

#!/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()
Erigami
источник
Конечно, Bluez и PulseAudio работают через опрос DBus. Пока ваша гарнитура является адаптером по умолчанию, это будет нормально работать в большинстве случаев. Убедитесь, что вы также подключили PulseAudio к гарнитуре, если хотите что-то услышать. Спасибо, что поделились своим решением :)
Takkat
это замечательно, если вы знаете DEV_IDдо подключения ... но что, если вы хотите получать уведомления обо всех событиях подключения?
pstanton
4

Чтобы обнаружить успешно установленное соединение Bluetooth, мы можем запустить

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

Таким образом, соединение SDB будет проверено на соединение с данным MAC-адресом. Это может занять значительное время, пока время просмотра не закончится с ошибкой вроде

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

Мы не знаем точное назначение вашего сценария, но, скорее всего, вы хотите воспроизводить звук через Clementine, когда подключена гарнитура.

Тогда мы могли бы просто увидеть, есть ли аудио-приемник Bluetooth с

pacmd list-sinks | grep xx_xx_xx_xx_xx_xx

Где xx_xx_xx_xx_xx_xxнаходится MAC-адрес ( :необходимо заменить на _). Затем на выходе будет указано, доступен ли приемник звука Bluetooth, или ничего, если нет.

Смотрите этот ответ о том, как переключить аудио на этот приемник.


Stream2ip

С помощью stream2ip мы можем определить команду оболочки или скрипт для запуска после установления соединения. Также существует возможность автоматического запуска поддерживаемого медиаплеера после установления соединения:

введите описание изображения здесь

Stream2ip также попытается повторно подключить текущий воспроизводимый поток к аудиоустройству Bluetooth в случае, если соединение было прервано.

Takkat
источник
Спасибо за Ваш ответ. Вы предлагаете мне опросить, sdptool browse <device-id>пока я не получу код возврата 0, а затем запустить свой сценарий, верно? Есть ли способ сделать это без опроса?
Erigami
Sdptool медленный. Я бы пошел на pulaudio. Вам нужен цикл, потому что мы не знаем, когда ваше устройство там.
Таккат
2

@Erigami Ваш ответ очень помог, но чтобы это сработало, я бы внес некоторые изменения. Я использую 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()

Тем не менее, если это не работает, тогда используйте и контролируйте систему dbus.

dbus-monitor --system

d-feetможно использовать дальше. Это графический инструмент для наблюдения за объектами dbus.

Hitul
источник
1
Если вы хотите улучшить другой ответ, предложите изменить его и не создавайте новый ответ.
Дэвид Фёрстер
1

Вот еще один пример для мониторинга всех устройств Bluetooth. Не нужно указывать конкретный MAC-адрес. Этот подход делает настройки xinput постоянными даже при входе / выходе, приостановке / пробуждении и подключении / отключении устройства Bluetooth.

У меня есть компактная Bluetooth-клавиатура Thinkpad, и я хочу запускать команду xinput всякий раз, когда подключена клавиатура, для регулировки скорости трекпойнта. Вот шаги.

  1. Скачать код с Github bluetooth-ruunner . Кредиты даны здесь, кто первым написал это для Raspberry Pi. Измените следующий раздел кода для запуска ваших пользовательских команд.

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

    В моем случае это эквивалентно звонку с терминала.

    $ xinput set-prop 'ThinkPad Compact Bluetooth Keyboard with TrackPoint' 'Device Accel Constant Deceleration' 0.6
  2. Сохраните модификацию. Попробуйте запустить ваши сценарии

    $ python bluetooth-runner.py

    Подключите и отключите устройство Bluethooth. Вы должны увидеть соответствующее сообщение, напечатанное на экране.

  3. Теперь сделайте ваш файл исполняемым и скопируйте его в одну из папок $PATH, скажем, в ~/bin/.

    $ chmod +x bluetooth-runner.py
    $ mkdir ~/bin # if you dont have it yet
    $ cp bluetooth-runner.py ~/bin
  4. Теперь убедитесь, что вы можете запустить скрипт из любой точки терминала (убедитесь, что он находится в вашем пути поиска).

  5. Запустите Startup Applicationsиз меню убунту. Добавьте свои скрипты в автозагрузку.

    Добавить автозагрузку приложений

  6. Теперь осталась только одна проблема: во время входа в систему сценарии могут не перехватить самое первое событие Bluetooth. Это связано с тем, что ваше устройство Bluetooth может быть подключено до инициализации сценария в фоновом режиме.

    Чтобы решить эту проблему, добавьте свою команду непосредственно в Startup Applications. В моем случае это следующая команда:

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

И теперь вы сможете наслаждаться своим устройством Bluetooth с Ubuntu.

Исин
источник
Сценарий Python не контролировал соединения Bluetooth.
Пауло Педросо
0

Вы пишете «когда ваша гарнитура подключается к вашему компьютеру». Как это происходит автоматически? Когда вам нужно запустить его вручную, вы можете также сделать его сценарием, а затем запустить свой сценарий после установления соединения. Вот что я сделал, чтобы установить устройство вывода по умолчанию для моего Bluetooth-приемника (чтобы я мог изменить громкость с помощью аппаратных клавиш):

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

Где это bluetooth-connectвыглядит так: https://github.com/sblask/dotfiles/blob/c39d37ad67947b358b4a079cb41ae6f9e4a081d8/.bin/bluetooth-connect.symlink Предполагается, что все сопряжено и готово к подключению. Вы найдете MAC-адрес в blueman или запустив его, pacmd list-sinks | grep -e 'name:' -e 'index'когда подключено устройство Bluetooth. Вы хотели бы бежать bluetooth-connect && your-script. your-scriptбудет запущен только после успешного установления соединения.

Себастьян Бласк
источник