Połącz się z urządzeniem bluetooth z linii poleceń

22

Tło: Używam zestawu słuchawkowego Bluetooth jako wyjścia audio. Udało mi się go uruchomić dzięki długiej liście instrukcji na temat dokumentacji społeczności BluetoothHeadset i zautomatyzowałem proces aktywacji zestawu słuchawkowego jako domyślnego wyjścia audio w skrypcie, dzięki innym pytaniom .

Ponieważ jednak używam zestawu słuchawkowego Bluetooth zarówno z telefonem, jak i komputerem (a zestaw słuchawkowy nie obsługuje dwóch połączeń wejściowych), aby telefon nie „kradł” połączenia po włączeniu zestawu słuchawkowego, zmuszam zestaw słuchawkowy do tryb wykrywania podczas łączenia się z komputerem (telefon automatycznie łączy się z nim).

Więc nawet jeśli zestaw słuchawkowy jest sparowany ok i w „normalnym” przypadku automatycznego połączenia, zawsze muszę używać małej ikony bluetooth w obszarze powiadomień, aby faktycznie połączyć się z moim urządzeniem (patrz zrzut ekranu).

Czego chcę uniknąć: Ten GUI do łączenia ze znanym i sparowanym urządzeniem Bluetooth:

Podłączanie do zestawu słuchawkowego Bluetooth za pomocą ikony

Co chcę zamiast tego: chciałbym, aby bluetooth robił dokładnie to, co robi kliknięcie elementu połączenia w GUI, tylko przy użyciu wiersza polecenia. Chcę użyć wiersza polecenia, dzięki czemu mogę wykonać pojedynczy skrót klawiaturowy dla akcji i nie będę musiał nawigować w interfejsie GUI za każdym razem, gdy chcę ustanowić połączenie z urządzeniem.

Pytanie: Jak mogę spróbować połączyć się z określonym, znanym i sparowanym urządzeniem Bluetooth z wiersza poleceń?

Dalsze pytanie: Jak sprawdzić, czy połączenie się powiodło, czy nie?

Ilari Kajaste
źródło
Co to za taca? czy to ikona zasobnika Blueman Manager? Czy aplet zasobnika menedżera Blueman powinien sparować urządzenia Bluetooth?
Cypr

Odpowiedzi:

10

Demon Bluetooth

W domyślnej instalacji w tle działa demon ( bluetoothd ) (uruchamiany z pliku /etc/init.d/bluetooth). Ten demon dba o rozpoznawanie i łączenie się ze znanymi urządzeniami Bluetooth i może być skonfigurowany z plikami konfiguracyjnymi w /etc/bluetooth. W przypadku automatycznego łączenia zestawu słuchawkowego audio.confnależy odkomentować (usunąć #):

AutoConnect=true

Aby zrestartować typ demona sudo /etc/init.d/bluetooth restart.

Uwaga: Użycie narzędzia wiersza poleceń sudo hcitool cc <MAC-Adress>nie doprowadziło do stabilnego połączenia ze znanym urządzeniem w środowisku testowym, gdy demon był uruchomiony.


DBus

Aby podłączyć odłączony, ale fizycznie obecny i sparowany zestaw słuchawkowy, możemy użyć D-Bus ze skryptu. Oto przykład w pythonie:

#!/usr/bin/python
# Toggles headset connection

import dbus
from dbus.mainloop.glib import DBusGMainLoop

dbus_loop = DBusGMainLoop()
bus = dbus.SystemBus(mainloop=dbus_loop)

#Get dbus interface for headset
manager = bus.get_object('org.bluez', '/')
iface_m = dbus.Interface(manager, 'org.bluez.Manager')
adapterPath = iface_m.DefaultAdapter()
adapter = bus.get_object('org.bluez', adapterPath)
iface_a = dbus.Interface(adapter, 'org.bluez.Adapter')
devicePath = iface_a.ListDevices()[0]  # assuming first device
device = bus.get_object('org.bluez', devicePath)
iface_h = dbus.Interface(device, 'org.bluez.Headset')

#Check state of connection
connected = iface_h.IsConnected()
print 'Toggling connection. Please wait'
# toggle connection
if not connected:
    try:
        iface_h.Connect()
        print 'Connecting: ', devicePath
    except:
        print 'Device not found'
else:
    iface_h.Disconnect()
    print 'Disconnecting: ', devicePath

W przypadku, gdy mamy więcej niż jedno urządzenie Bluetooth, musimy devicePathoczywiście odpowiednio się dostosować . Powyższy przykład połączy a Headset. Zmień interfejs na inny protokół dla dowolnej innej usługi (np AudioSink.).


Pulseaudio

Jeśli znasz adres MAC urządzenia Bluetooth, możesz podłączyć go jako zlew wyjściowy dla pulseaudio poprzez:

pacmd set-default-sink bluez_sink.xx_xx_xx_xx_xx_xx

Gdzie xx_xx_xx_xx_xx_xx to adres MAC (zamień „:” na „_”, aby pulseaudio go rozpoznał).

Zobacz także tę odpowiedź, aby uzyskać więcej informacji.

Takkat
źródło
Znam adres i zastąpiłem go xx. Dostaję tylko Sink bluez_sink.xx_xx_xx_xx_xx_xx does not exist.wypróbowane wielkie i małe litery.
Ilari Kajaste
1
Tak, pulseaudio-moduł-bluetooth jest isntalle. Nie, nic nie pasuje btlub nie bluejest wymienione w pacmd list-sinks. (Podaje tylko 1 zlew dostępny.)
Ilari Kajaste
2
Więc to nie jest rozpoznane. Jest to warunek wstępny, aby móc się połączyć za pomocą wiersza polecenia. Spróbuj ponownie uruchomić BT lub spróbuj ponownie uruchomić pulsaudio. Nie dowiedziałem się jeszcze, dlaczego czasami nie jest to wykryte.
Takkat,
Co? Więc może być w stanie, że można połączyć się z GUI, ale nie z CLI?
Ilari Kajaste,
1
@Takkat Oh, tak, dobra uwaga. Mój błąd! Używam zestawu słuchawkowego w odkrywaniu więcej, więc nie będzie się łączyć automatycznie. Zredagowałem pytanie, aby to odzwierciedlić. Przepraszam, że doprowadziłem cię do złej ścieżki.
Ilari Kajaste
6

Używam tego skryptu, aby podłączyć urządzenie audio Bluetooth. Jeśli zestaw słuchawkowy jest już sparowany, połączenie powinno być możliwe w ten sam sposób za pomocą org.bluez.Headset.Connect / Disconnect zamiast org.bluez.Audiosink.Connect / Disconnect .

#!/bin/bash

MAC_ADD="C8:84:47:10:11:CD"

MAC_ADD="dev_${MAC_ADD//:/_}"
BT_ADAPTER=`dbus-send --system --print-reply --dest=org.bluez / \
org.bluez.Manager.DefaultAdapter|awk '/object path/ {print $3}'`

BT_ADAPTER="${BT_ADAPTER//\"/}/$MAC_ADD"
echo "Connecting to $BT_ADAPTER..."

if [ "$1" == "on" ]; then
    dbus-send --print-reply --system --dest=org.bluez $BT_ADAPTER org.bluez.AudioSink.Connect
elif [ "$1" == "off" ]; then
    dbus-send --print-reply --system --dest=org.bluez $BT_ADAPTER org.bluez.AudioSink.Disconnect
fi

HTH!

doublerebel
źródło
to też działało dla mnie 16.04, dziękuję! inni, nie zapomnij przekazać onopcji do skryptu!
Minner
2

Używam i3 jako menedżera okien, więc nie mam dostępnej ikony zasobnika bluetooth. Z jakiegoś powodu przycisk wyboru w ustawieniach jedności nie jest wrażliwy, dlatego potrzebuję sposobu, aby to zrobić od czasu do czasu, gdy moje słuchawki się nie łączą.

wprowadź opis zdjęcia tutaj

Wydaje się, że blueznie zmienili dbus API . Wydaje się, że wykorzystująca odpowiedź org.bluez.Managerjuż nie działa. Zamiast tego zaleca się użycie ObjectManager.

Oto zaktualizowany skrypt Pythona, który połączy pierwszy znaleziony niepodłączony zestaw słuchawkowy Bluetooth (przypuszczalnie lista obejmuje wszystkie sparowane urządzenia?):

#!/usr/bin/env python
# Toggles headset connection

from __future__ import print_function
from __future__ import unicode_literals

import dbus
from dbus.mainloop.glib import DBusGMainLoop

def find_headset(bus):
  manager = dbus.Interface(bus.get_object("org.bluez", "/"),
                           "org.freedesktop.DBus.ObjectManager")
  objects = manager.GetManagedObjects()

  for path, ifaces in objects.items():
    if ("org.bluez.Device1" in ifaces and
        "org.freedesktop.DBus.Properties" in ifaces):
      iprops = dbus.Interface(
          bus.get_object("org.bluez", path),
          "org.freedesktop.DBus.Properties")
      props = iprops.GetAll("org.bluez.Device1")
      # Looking for a headset. Could also match on other properties like
      # "Name". See bluez docs for whats available.
      if props.get("Class") == 0x240404:
        if props.get("Connected"):
          print("Found headset {} ({}) but it is already connected"
                .format(props.get("Name"), props.get("Address")))
          continue
        return path

dbus_loop = DBusGMainLoop()
bus = dbus.SystemBus(mainloop=dbus_loop)
hpath = find_headset(bus)

if hpath:
  adapter = dbus.Interface(
      bus.get_object("org.bluez", hpath), "org.bluez.Device1")
  adapter.Connect()

ten przykład, podobnie jak inny przykład w tym wątku, używa dbuspakietu python. Na Ubuntu 16.04 zainstalowałem to przez apt-get install python-dbus.

Jeśli chcesz spełnić inne kryteria, ten dokument wydaje się wyświetlać listę właściwości, które mogą być sprawdzane przez dbus.

Mam zapisany skrypt, w ~/.local/bin/bt-connect-headsetktórym jest on, PATHwięc mogę go uruchomić z programu uruchamiającego i3. Ustaw go jako wykonywalny ( chmod +x bt-connect-headset), jeśli zamierzasz używać go jako polecenia.

Ten skrypt został przetestowany tylko na aktualnym Ubuntu 16.04 od 28.09.2018.

Cheshirekow
źródło
1
Używał twojego skryptu na Ubuntu 18.10. Dzięki!
Brombomb
1
Super, to zadziałało dla mnie w Linux Mint 19 Cinnamon. Jednak 2360344zamiast tego użyłem klasy urządzenia 0x240404.
dom_watson
1
działa jako taki w Mint Xfce 19.2. Jestem pewien, że działa w Xubuntu. - A co ze skryptem do odłączania bluetooth?
Cypr
1
@cipricus To jest poprawne i zostało już wspomniane w odpowiedzi. W odpowiedzi znajduje się link, w jaki sposób dopasować inne kryteria, jeśli potrzebujesz czegoś bardziej zaawansowanego (np. Dopasowanie urządzenia o określonej nazwie). Ten link zawiera również listę metod dostępnych w tym interfejsie. Aby się rozłączyć, domyślam się użyć Disconnect()metody. Nie próbowałem, ale to pewnie bezpieczny zakład;).
cheshirekow
Myliłem się. Myślałem, że nigdy nie wykracza poza pierwszy na liście sparowanych urządzeń, ale tak jest. Mogłem również przeoczyć fakt, że mówisz first unconnected bluetooth headset : czy zawsze będzie używać zestawu słuchawkowego (jeśli jest zasilany) przed innymi urządzeniami, takimi jak głośniki bluetooth (bez względu na pozycję na liście)? Tak dzieje się w moim przypadku. - Ponadto, aby się rozłączyć, nie mogę tego zrobić, po prostu zmieniając ostatnią linię na adapter.Disconnect().)
Cypr
1

Po wypróbowaniu niektórych z powyższych (skrypty nie działały dla mnie) znalazłem następujące rozwiązanie.

Najpierw dowiedz się, jaki jest adres MAC urządzenia, z którym chcesz się połączyć

bluetoothctl

to wejdzie do powłoki i wyświetli listę wszystkich dostępnych urządzeń z adresem. („quit”, aby wyjść z powłoki i wrócić do monitu)

Następnie podłącz urządzenie Bluetooth: XX: XX: XX: XX: XX: XX:

echo -e 'connect XX:XX:XX:XX:XX:XX' | bluetoothctl

rozłączyć

echo -e 'disconnect XX:XX:XX:XX:XX:XX' | bluetoothctl

szukałem tego od dłuższego czasu - nic nie działało, poczułem ulgę, gdy się dowiedziałem. Myślałem, że inni też mogą chcieć o tym wiedzieć. :))

Joseph
źródło
Czy możesz edytować swoją odpowiedź, aby dodać sposób uzyskania adresu urządzenia, aby odpowiedź była bardziej kompletna?
user3140225,
1
@ user3140225 właśnie to zrobił.
Joseph
I dostać ~$ bluetoothctl Agent registered [UE BOOM 2]#. Potem disconnect "UE BOOM 2" Device UE BOOM 2 not available.
Cypr
@cipricus @ user3140225 Czy możesz opublikować wynik bluetoothctl? Musisz podać polecenia z adresem MAC urządzenia - który jest kombinacją wartości HEX w formacie XX: XX: XX: XX: XX: XX, gdzie X jest literą lub cyfrą.
Joseph
Widzę MAC, jak powiedziano tutaj . Następnie próbuję echo -e 'connect CC:AF:78:AF:59:03' | bluetoothctluzyskać:Agent registered [bluetooth]# connect CC:AF:78:AF:59:03 Device CC:AF:78:AF:59:03 not available
cipricus