Bagaimana cara menjalankan skrip saat perangkat Bluetooth terhubung?

16

Saya ingin memulai pemutar musik saya (Clementine) ketika headset bluetooth saya terhubung ke komputer saya. Bagaimana cara mendeteksi koneksi perangkat bluetooth sehingga saya dapat menjalankan skrip untuk memulai pemutar?

Erigami
sumber

Jawaban:

12

Saya tidak suka pendekatan polling, jadi saya melakukan penggalian pada bluez dan DBus. Saya akhirnya menulis skrip berikut:

#!/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
sumber
Tentu saja Bluez, dan PulseAudio beroperasi melalui polling DBus. Selama headset Anda adalah adaptor default, itu akan berfungsi dengan baik dalam banyak kasus. Pastikan Anda juga menghubungkan PulseAudio ke headset jika Anda ingin mendengar sesuatu. Terima kasih telah berbagi solusi Anda :)
Takkat
itu bagus jika Anda tahu DEV_IDsebelum koneksi .. tetapi bagaimana jika Anda ingin diberitahu tentang semua peristiwa koneksi?
pstanton
4

Untuk menemukan koneksi Bluetooth yang berhasil dibuat, kita dapat menjalankannya

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

Dengan ini koneksi SDB akan diuji untuk koneksi ke alamat MAC yang diberikan. Mungkin butuh waktu yang cukup lama hingga waktu penelusuran habis dengan kesalahan seperti

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

Kami tidak tahu tujuan pasti skrip Anda, tetapi kemungkinan besar Anda ingin memutar audio melalui Clementine ketika headset terhubung.

Kemudian kita bisa melihat apakah ada wastafel audio Bluetooth

pacmd list-sinks | grep xx_xx_xx_xx_xx_xx

Di mana xx_xx_xx_xx_xx_xxalamat MAC ( :perlu diganti dengan _). Output kemudian akan memberi tahu Anda apakah ada audio sink Bluetooth yang tersedia atau tidak sama sekali jika tidak.

Lihat jawaban ini tentang cara mengalihkan audio ke wastafel ini.


Stream2ip

Dengan stream2ip kita dapat mendefinisikan perintah shell atau skrip untuk dijalankan setelah koneksi dibuat. Ada juga opsi untuk memulai pemutar media yang didukung secara otomatis setelah koneksi dibuat:

masukkan deskripsi gambar di sini

Stream2ip juga akan mencoba untuk menyambungkan kembali aliran pemutaran yang sedang berjalan ke perangkat audio Bluetooth seandainya koneksi terputus.

Takkat
sumber
Terima kasih atas jawaban anda. Anda menyarankan agar saya melakukan polling sdptool browse <device-id>sampai saya mendapatkan kode pengembalian 0 dan kemudian memulai skrip saya, kan? Apakah ada cara untuk melakukannya tanpa pemungutan suara?
Erigami
Sdptool lambat. Saya akan menggunakan pulseaudio. Anda perlu pengulangan karena kami tidak tahu kapan perangkat Anda ada di sana.
Takkat
2

@ Erigami Jawaban Anda banyak membantu tetapi untuk membuatnya berfungsi, saya akan melakukan beberapa perubahan. Saya menggunakan 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()

Masih jika ini tidak berhasil maka gunakan dan pantau sistem dbus.

dbus-monitor --system

d-feetdapat digunakan lebih lanjut. Ini adalah alat GUI untuk menonton objek dbus.

Hitul
sumber
1
Jika Anda ingin meningkatkan jawaban lain, harap sarankan edit untuk itu dan jangan membuat jawaban baru.
David Foerster
1

Berikut adalah contoh lain untuk memantau semua perangkat Bluetooth. Tidak perlu menentukan alamat MAC tertentu. Pendekatan ini membuat pengaturan xinput tetap ada bahkan ketika masuk / keluar, menangguhkan / membangunkan dan menghubungkan / menonaktifkan koneksi perangkat bluetooth Anda.

Saya memiliki Thinkpad Compact Bluetooth Keyboard, dan saya ingin menjalankan perintah xinput setiap kali keyboard terhubung untuk menyesuaikan kecepatan trackpoint. Inilah langkah-langkahnya.

  1. Unduh kode dari Github bluetooth-ruunner . Kredit yang diberikan di sini yang pertama kali menulis ini untuk Raspberry Pi. Ubah bagian kode berikut untuk menjalankan comamnds khusus Anda.

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

    Dalam kasus saya, ini sama dengan menelepon dari terminal.

    $ xinput set-prop 'ThinkPad Compact Bluetooth Keyboard with TrackPoint' 'Device Accel Constant Deceleration' 0.6
  2. Simpan modifikasinya. Coba jalankan skrip Anda dengan

    $ python bluetooth-runner.py

    Hubungkan dan lepaskan perangkat Bluethooth Anda. Anda akan melihat pesan terkait dicetak di layar.

  3. Sekarang, buat file Anda dapat dieksekusi dan salin di salah satu direktori di $PATH, katakanlah ~/bin/.

    $ chmod +x bluetooth-runner.py
    $ mkdir ~/bin # if you dont have it yet
    $ cp bluetooth-runner.py ~/bin
  4. Sekarang, pastikan Anda dapat menjalankan skrip dari mana saja di terminal (pastikan ada di jalur pencarian Anda).

  5. Jalankan Startup Applicationsdari menu ubuntu. Tambahkan skrip Anda ke startup.

    Tambahkan aplikasi startup

  6. Sekarang, hanya ada satu masalah yang tersisa, pada saat Anda login, skrip mungkin tidak menangkap acara bluetooth pertama . Ini karena perangkat bluetooth Anda mungkin terhubung sebelum skrip Anda diinisialisasi di latar belakang.

    Untuk mengatasi ini, tambahkan perintah khusus Anda langsung di Startup Applications. Dalam kasus saya, ini adalah perintah follow:

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

Dan sekarang Anda akan dapat menikmati perangkat Bluetooth Anda dengan Ubuntu.

Yixing
sumber
skrip python tidak memonitor koneksi bluetooth.
Paulo Pedroso
0

Anda menulis "ketika headset Anda terhubung ke komputer Anda". Bagaimana cara melakukannya, secara otomatis? Saat Anda harus memicunya secara manual, Anda bisa membuatnya menjadi skrip dan kemudian menjalankan skrip Anda setelah koneksi dibuat. Inilah yang saya lakukan untuk mengatur perangkat output default ke penerima bluetooth saya (jadi saya dapat mengubah volume dengan tombol perangkat keras):

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

Di mana bluetooth-connectterlihat seperti ini: https://github.com/sblask/dotfiles/blob/c39d37ad67947b358b4a079cb41ae6f9e4a081d8/.bin/bluetooth-connect.symlink Ini mengasumsikan semuanya telah dipasangkan dan siap untuk terhubung. Anda menemukan alamat MAC dalam blueman atau dengan menjalankan pacmd list-sinks | grep -e 'name:' -e 'index'ketika perangkat bluetooth terhubung. Anda ingin lari bluetooth-connect && your-script. your-scripthanya akan berjalan ketika koneksi berhasil dibuat.

Sebastian Blask
sumber