Odpowiedzi:
Nie podobało mi się podejście do głosowania, więc zacząłem kopać na bluez i DBus. Skończyło się na napisaniu następującego skryptu:
#!/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()
DEV_ID
wcześniej połączenie ... ale co, jeśli chcesz otrzymywać powiadomienia o wszystkich zdarzeniach związanych z połączeniem?
Aby odkryć udane połączenie Bluetooth, możemy uruchomić
sdptool browse xx:xx:xx:xx:xx:xx
W ten sposób połączenie SDB zostanie przetestowane pod kątem połączenia z danym adresem MAC. Może minąć sporo czasu, zanim przeglądanie się skończy z takim błędem jak
Failed to connect to SDP server on 00:0C:78:4F:B6:B5: Host is down
Nie znamy dokładnego celu skryptu, ale najprawdopodobniej chcesz odtwarzać dźwięk za pośrednictwem Clementine, gdy podłączony jest zestaw słuchawkowy.
Wtedy moglibyśmy zobaczyć, czy jest zlew audio Bluetooth
pacmd list-sinks | grep xx_xx_xx_xx_xx_xx
Gdzie xx_xx_xx_xx_xx_xx
jest adres MAC ( :
należy go zastąpić _
). Wyjście powie ci wtedy, czy dostępny jest zlew audio Bluetooth, czy nic, jeśli nie.
Zobacz odpowiedź na temat przełączania audio na ten zlew.
Za pomocą stream2ip możemy zdefiniować polecenie powłoki lub skrypt, który będzie uruchamiany po ustanowieniu połączenia. Istnieje również opcja automatycznego uruchomienia obsługiwanego odtwarzacza multimedialnego po ustanowieniu połączenia:
Stream2ip spróbuje również ponownie połączyć aktualnie uruchomiony strumień odtwarzania z urządzeniem audio Bluetooth w przypadku przerwania połączenia.
sdptool browse <device-id>
dopóki nie otrzymam kodu powrotu 0, a następnie nie uruchomię skryptu, prawda? Czy można to zrobić bez odpytywania?
@Erigami Twoja odpowiedź bardzo pomogła, ale żeby to zadziałało, zrobię kilka zmian. Używam 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()
Jeśli jednak to nie zadziała, użyj i monitoruj system dbus systemu.
dbus-monitor --system
d-feet
można dalej wykorzystywać. Jest to narzędzie GUI do oglądania obiektów dbus.
Oto kolejny przykład monitorowania wszystkich urządzeń Bluetooth. Nie musi określać określonego adresu MAC. Takie podejście sprawia, że ustawienie xinput jest trwałe nawet po zalogowaniu / wylogowaniu, zawieszeniu / wybudzeniu i podłączeniu / odłączeniu urządzenia Bluetooth.
Mam kompaktową klawiaturę Bluetooth Thinkpad i chcę uruchamiać polecenie xinput za każdym razem, gdy klawiatura jest podłączona, aby dostosować prędkość punktu ścieżki. Oto kroki.
Pobierz kod z Github bluetooth-ruunner . Podziękowania przyznane tutaj, który jako pierwszy napisał to dla Raspberry Pi. Zmodyfikuj następującą sekcję kodu, aby uruchomić niestandardowe komponenty.
subprocess.call(['xinput', 'set-prop',
'ThinkPad Compact Bluetooth Keyboard with TrackPoint',
'Device Accel Constant Deceleration', '0.6'])
W moim przypadku jest to równoważne z telefonowaniem z terminala.
$ xinput set-prop 'ThinkPad Compact Bluetooth Keyboard with TrackPoint' 'Device Accel Constant Deceleration' 0.6
Zapisz modyfikację. Spróbuj uruchomić swoje skrypty
$ python bluetooth-runner.py
Podłącz i odłącz urządzenie Bluethooth. Powinien zostać wyświetlony odpowiedni komunikat wydrukowany na ekranie.
Teraz uczyń swój plik wykonywalnym i skopiuj go do jednego z katalogów $PATH
, powiedzmy, twojego ~/bin/
.
$ chmod +x bluetooth-runner.py
$ mkdir ~/bin # if you dont have it yet
$ cp bluetooth-runner.py ~/bin
Teraz upewnij się, że możesz uruchomić skrypt z dowolnego miejsca w terminalu (upewnij się, że znajduje się on na ścieżce wyszukiwania).
Odpal Startup Applications
z menu ubuntu. Dodaj swoje skrypty do startu.
Teraz pozostaje tylko jeden problem, w momencie logowania skrypty mogą nie wychwycić pierwszego zdarzenia Bluetooth. Wynika to z faktu, że urządzenie Bluetooth mogło zostać podłączone przed zainicjowaniem skryptu w tle.
Aby rozwiązać ten problem, dodaj swoje niestandardowe polecenie bezpośrednio w Startup Applications
. W moim przypadku jest to następujące polecenie:
xinput set-prop 'ThinkPad Compact Bluetooth Keyboard with TrackPoint' 'Device Accel Constant Deceleration' 0.6
A teraz będziesz mógł cieszyć się urządzeniem Bluetooth z Ubuntu.
Piszesz „kiedy zestaw słuchawkowy łączy się z komputerem”. Jak to robi automatycznie? Gdy musisz uruchomić go ręcznie, równie dobrze możesz ustawić go jako skrypt, a następnie uruchomić skrypt po ustanowieniu połączenia. Oto, co zrobiłem, aby ustawić domyślne urządzenie wyjściowe w moim odbiorniku Bluetooth (dzięki czemu mogę zmienić głośność za pomocą klawiszy sprzętowych):
bluetooth-connect && pactl set-default-sink bluez_sink.0C_A6_94_9A_37_4D
Gdzie bluetooth-connect
wygląda to tak: https://github.com/sblask/dotfiles/blob/c39d37ad67947b358b4a079cb41ae6f9e4a081d8/.bin/bluetooth-connect.symlink Zakłada, że wszystko zostało sparowane i jest gotowe do połączenia. Adres MAC można znaleźć w blueman lub uruchamiając, pacmd list-sinks | grep -e 'name:' -e 'index'
gdy urządzenie Bluetooth jest podłączone. Chciałbyś uciec bluetooth-connect && your-script
. your-script
będzie uruchamiany tylko po pomyślnym nawiązaniu połączenia.