Stellen Sie über die Befehlszeile eine Verbindung zum Bluetooth-Gerät her

22

Hintergrund: Ich verwende mein Bluetooth-Headset als Audioausgang. Ich habe es durch die lange Liste von Anweisungen in der Dokumentation der BluetoothHeadset-Community zum Funktionieren gebracht und den Prozess der Aktivierung des Headsets als Standardaudioausgabe in einem Skript dank einer weiteren Frage automatisiert .

Da ich das Bluetooth-Headset jedoch sowohl mit meinem Telefon als auch mit meinem Computer verwende (und das Headset zwei Eingabeverbindungen nicht unterstützt), damit das Telefon die Verbindung nicht "stiehlt", wenn das Mobilteil eingeschaltet ist, zwinge ich das Headset in eine Erkennungsmodus, wenn eine Verbindung zum Computer hergestellt wird (das Telefon kann automatisch eine Verbindung herstellen).

Obwohl das Headset in Ordnung gepaart ist und sich in einem "normalen" Szenario automatisch verbinden würde, muss ich immer das kleine Bluetooth-Symbol im Infobereich verwenden, um eine Verbindung zu meinem Gerät herzustellen (siehe Screenshot).

Was ich vermeiden möchte: Diese GUI für die Verbindung zu einem bekannten und gekoppelten Bluetooth-Gerät:

Verbindung zum Bluetooth-Headset über das Symbol

Was ich stattdessen möchte: Ich möchte, dass Bluetooth genau das macht, was das Klicken auf das Verbindungselement in der GUI bewirkt, nur über die Befehlszeile. Ich möchte die Befehlszeile verwenden, um eine einzelne Tastenkombination für die Aktion zu erstellen, und muss nicht jedes Mal in der Benutzeroberfläche navigieren, wenn ich eine Verbindung zum Gerät herstellen möchte.

Die Frage: Wie kann ich versuchen, über die Befehlszeile eine Verbindung zu einem bestimmten, bekannten und gekoppelten Bluetooth-Gerät herzustellen ?

Weitere Frage: Wie kann ich feststellen, ob die Verbindung erfolgreich war oder nicht?

Ilari Kajaste
quelle
Welches Tray-Tool ist das? ist es das Blueman Manager Tray Icon? Sollte das Applet "Blueman Manager Tray" gekoppelte Bluetooth-Geräte auflisten?
Cipricus

Antworten:

10

Bluetooth-Daemon

In der Standardinstallation wird im Hintergrund ein Daemon ( bluetoothd ) ausgeführt (aus der Datei ausgeführt /etc/init.d/bluetooth). Dieser Daemon kümmert sich um das Erkennen und Herstellen einer Verbindung zu bekannten Bluetooth-Geräten und kann mit Konfigurationsdateien in konfiguriert werden /etc/bluetooth. Zum automatischen Verbinden eines Headsets sollte der folgende Eingang nicht kommentiert audio.confsein (Entfernen #):

AutoConnect=true

So starten Sie den Daemon - Typ sudo /etc/init.d/bluetooth restart.

Anmerkung: Die Verwendung des Befehlszeilentools sudo hcitool cc <MAC-Adress>führte hier nicht zu einer stabilen Verbindung zu einem bekannten Gerät in der Testumgebung, als der Dämon ausgeführt wurde.


DBus

Um ein getrenntes, aber physisch vorhandenes und gekoppeltes Headset anzuschließen, können Sie den D-Bus aus einem Skript verwenden. Hier ist ein Beispiel in Python:

#!/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

Falls wir mehr als ein Bluetooth-Gerät haben, müssen wir das devicePathnatürlich entsprechend anpassen . Das obige Beispiel verbindet a Headset. Ändern Sie die Schnittstelle auf ein anderes Protokoll für einen anderen Dienst (z AudioSink. B. ).


Pulseaudio

Wenn Sie die MAC-Adresse Ihres Bluetooth-Geräts kennen, können Sie es wie folgt als Ausgangssenke für pulseaudio verbinden:

pacmd set-default-sink bluez_sink.xx_xx_xx_xx_xx_xx

Dabei ist xx_xx_xx_xx_xx_xx die MAC-Adresse (ersetzen Sie ':' durch '_', damit pulseaudio sie erkennt).

Siehe auch diese Antwort für weitere Details.

Takkat
quelle
Ich kenne die Adresse und habe die xx durch sie ersetzt. Ich bekomme nur Sink bluez_sink.xx_xx_xx_xx_xx_xx does not exist.Versucht sowohl Groß- als auch Kleinbuchstaben.
Ilari Kajaste
1
Ja, pulseaudio-module-bluetooth isntalle. Nein, nichts passendes btoder blueist in aufgeführt pacmd list-sinks. (Es meldet nur 1 Waschbecken zur Verfügung.)
Ilari Kajaste
2
Es wird also nicht erkannt. Dies ist eine Voraussetzung, um eine Verbindung über die Befehlszeile herstellen zu können. Versuchen Sie, BT neu zu starten, oder starten Sie pulsaudio neu. Ich habe noch nicht herausgefunden, warum es manchmal nicht erkannt wird.
Takkat
Huh? So kann es in einem Zustand sein, dass es möglich ist, eine Verbindung über die GUI herzustellen, aber nicht über die CLI?
Ilari Kajaste
1
@ Takkat Oh, ja, guter Punkt. Mein Fehler! Ich verwende das Headset in Discovery mehr, damit es sich nicht automatisch verbindet. Ich habe die Frage bearbeitet, um dies widerzuspiegeln. Tut mir leid, dass ich Sie auf einen falschen Weg geführt habe.
Ilari Kajaste
6

Mit diesem Skript verbinde ich mein Bluetooth-Audiogerät. Wenn Ihr Headset bereits gekoppelt ist, sollten Sie in der Lage sein, das Headset auf die gleiche Weise mit org.bluez.Headset.Connect / Disconnect anstelle von org.bluez.Audiosink.Connect / Disconnect anzuschließen .

#!/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!

Doppelbel
quelle
das hat auch bei mir geklappt 16.04, danke! andere, vergessen Sie nicht, die onOption an das Skript zu übergeben!
MInner
2

Ich verwende i3 als Fenstermanager, daher ist das Bluetooth-Symbol in der Taskleiste nicht verfügbar. Aus irgendeinem Grund ist das Kontrollkästchen in den Einstellungen für die Einheit nicht empfindlich. Daher muss ich dies von Zeit zu Zeit tun, wenn meine Kopfhörer keine Verbindung herstellen.

Bildbeschreibung hier eingeben

Es scheint, dass ihre Dbus-API geändertbluez hat . Die Antwort unter Verwendung von scheint nicht mehr zu funktionieren. Stattdessen wird empfohlen, zu verwenden .org.bluez.ManagerObjectManager

Hier ist ein aktualisiertes Python-Skript, das das erste nicht verbundene Bluetooth-Headset verbindet, das es findet (vermutlich enthält die Liste alle gekoppelten Geräte?):

#!/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()

Dieses Beispiel verwendet, wie das andere Beispiel in diesem Thread, das dbusPython-Paket. Auf Ubuntu 16.04 habe ich dies durch installiert apt-get install python-dbus.

Wenn Sie andere Kriterien erfüllen möchten, wird in diesem Dokument eine Liste der Eigenschaften angezeigt, die über dbus abgefragt werden können.

Ich habe dieses Skript in ~/.local/bin/bt-connect-headsetmeinem gespeichert, PATHdamit ich es über den i3-Launcher ausführen kann. Machen Sie es ausführbar ( chmod +x bt-connect-headset), wenn Sie es als Befehl verwenden möchten.

Dieses Skript wurde nur auf einem aktuellen Ubuntu 16.04 vom 28.09.2008 getestet.

cheshirekow
quelle
1
Benutzte dein Skript auf Ubuntu 18.10. Vielen Dank!
Brombomb
1
Super, das hat bei mir in Linux Mint 19 Cinnamon geklappt. Ich habe jedoch eine Geräteklasse von 2360344anstelle von verwendet 0x240404.
dom_watson
1
funktioniert so in Mint Xfce 19.2. Ich bin sicher, dass es in Xubuntu funktioniert. - Was ist mit einem Skript zum Trennen der Bluetooth-Verbindung?
Cipricus
1
@cipricus Das ist richtig und wird bereits in der Antwort erwähnt. In der Antwort finden Sie einen Link dazu, wie Sie andere Kriterien erfüllen können, wenn Sie etwas Fortgeschritteneres benötigen (z. B. ein Gerät mit einem bestimmten Namen suchen). Dieser Link enthält auch eine Liste der auf dieser Schnittstelle verfügbaren Methoden. Um die Verbindung zu trennen, verwende ich die Disconnect()Methode. Ich habe es nicht ausprobiert, aber es ist wahrscheinlich eine sichere Wette;).
Tscheschirekow
Ich lag falsch. Ich dachte, es geht nie über das erste in der Liste der gekoppelten Geräte hinaus, aber das tut es. Möglicherweise habe ich auch die Tatsache übersehen, dass Sie gesagt haben first unconnected bluetooth headset : Wird das Headset (sofern es mit Strom versorgt wird) immer vor anderen Geräten wie Bluetooth-Lautsprechern verwendet (unabhängig von der Position in der Liste)? Das passiert in meinem Fall. - Auch, um die Verbindung zu trennen, kann ich es nicht tun, indem ich nur die letzte Zeile auf adapter.Disconnect()
ändere
1

Nachdem ich einige der oben genannten Dinge ausprobiert hatte (Skripte funktionierten bei mir nicht), fand ich die folgende Lösung.

Ermitteln Sie zunächst die MAC-Adresse des Geräts, zu dem Sie eine Verbindung herstellen möchten

bluetoothctl

Dies öffnet eine Shell und listet alle verfügbaren Geräte mit Adresse auf. ("Beenden", um die Shell zu verlassen und zur Eingabeaufforderung zurückzukehren)

Stellen Sie dann eine Verbindung zu einem XX: XX: XX: XX: XX: XX-Bluetooth-Gerät her:

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

trennen

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

habe eine ganze Weile danach gesucht - nichts schien zu funktionieren, fühlte sich so erleichtert, als ich es herausfand. Dachten, andere möchten vielleicht auch davon erfahren. :))

Joseph
quelle
Könnten Sie Ihre Antwort bearbeiten, um hinzuzufügen, wie die Adresse des Geräts abgerufen werden kann, damit die Antwort vollständiger ist?
user3140225
1
@ user3140225 gerade getan.
Joseph
Ich verstehe ~$ bluetoothctl Agent registered [UE BOOM 2]#. Dann disconnect "UE BOOM 2" Device UE BOOM 2 not available.
Cipricus
@cipricus @ user3140225 Könnten Sie die Ausgabe von posten bluetoothctl? Sie müssen die Befehle mit der MAC-Adresse des Geräts versorgen - das ist die Kombination von HEX-Werten im Format XX: XX: XX: XX: XX: XX: XX, wobei X entweder ein Buchstabe oder eine Zahl ist.
Joseph
Ich kann den MAC wie hier gesagt sehen . Dann versuche echo -e 'connect CC:AF:78:AF:59:03' | bluetoothctlich zu bekommen:Agent registered [bluetooth]# connect CC:AF:78:AF:59:03 Device CC:AF:78:AF:59:03 not available
Cipricus