Conéctese al dispositivo bluetooth desde la línea de comando

22

Antecedentes: estoy usando mi auricular bluetooth como salida de audio. Logré que funcione mediante la larga lista de instrucciones en la documentación de la comunidad de BluetoothHeadset , y he automatizado el proceso de activación de los auriculares como salida de audio predeterminada en un script, gracias a otra pregunta .

Sin embargo, dado que uso el auricular bluetooth con mi teléfono y mi computadora (y el auricular no admite dos conexiones de entrada) para que el teléfono no "robe" la conexión cuando el teléfono está encendido, forcé el auricular a modo de descubrimiento cuando se conecta a la computadora (el teléfono se conecta automáticamente).

Entonces, aunque el auricular está bien emparejado y se conectaría automáticamente en el escenario "normal", siempre tengo que usar el pequeño icono de Bluetooth en el área de notificación para conectarme realmente a mi dispositivo (ver captura de pantalla).

Lo que quiero evitar: esta GUI para conectarse a un dispositivo bluetooth conocido y emparejado :

Conexión a auriculares Bluetooth mediante el icono

Lo que quiero en cambio: me gustaría hacer que el bluetooth haga exactamente lo que hace hacer clic en el elemento de conexión en la GUI, solo usando la línea de comando. Quiero usar la línea de comando para poder hacer un solo atajo de pulsación de tecla para la acción, y no necesitaría navegar por la GUI cada vez que quiera establecer una conexión con el dispositivo.

La pregunta: ¿Cómo puedo intentar conectarme a un dispositivo bluetooth específico, conocido y emparejado desde la línea de comandos?

Pregunta adicional: ¿Cómo puedo saber si la conexión fue exitosa o no?

Ilari Kajaste
fuente
¿Qué herramienta de bandeja es esa? ¿Es el icono de la bandeja de Blueman Manager? ¿Debería Blueman manager tray applet listar dispositivos bluetooth emparejados?
cipricus

Respuestas:

10

Demonio Bluetooth

En la instalación predeterminada, un demonio ( bluetoothd ) se ejecuta en segundo plano (se ejecuta desde el archivo /etc/init.d/bluetooth). Este demonio se encarga de reconocer y conectarse a dispositivos bluetooth conocidos y puede configurarse con archivos de configuración /etc/bluetooth. Para conectar automáticamente un auricular, la siguiente línea audio.confdebe estar descomentada (eliminar #):

AutoConnect=true

Para reiniciar el tipo de daemon sudo /etc/init.d/bluetooth restart.

Observación: el uso de la herramienta de línea de comandos sudo hcitool cc <MAC-Adress>no condujo a una conexión estable a un dispositivo conocido en el entorno de prueba aquí cuando el demonio se estaba ejecutando.


DBus

Para conectar un auricular desconectado pero físicamente presente y emparejado, podemos usar D-Bus desde un script. Aquí hay un ejemplo en 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

En caso de que tengamos más de un dispositivo Bluetooth, tendremos que adaptarlo devicePathadecuadamente, por supuesto. El ejemplo anterior conectará a Headset. Cambie la interfaz a un protocolo diferente para cualquier otro servicio (por ejemplo AudioSink).


Pulseaudio

Si conoce la dirección MAC de su dispositivo Bluetooth, puede conectarlo como un sumidero de salida para pulseaudio:

pacmd set-default-sink bluez_sink.xx_xx_xx_xx_xx_xx

Donde xx_xx_xx_xx_xx_xx es la dirección MAC (reemplace ':' por '_' para que pulseaudio lo reconozca).

Vea también esta respuesta para más detalles.

Takkat
fuente
Sé la dirección, y reemplacé el xx con ella. Solo me Sink bluez_sink.xx_xx_xx_xx_xx_xx does not exist.prueban tanto en mayúsculas como en minúsculas.
Ilari Kajaste
1
Sí, pulseaudio-module-bluetooth es isntalle. No, nada coincide bto blueestá en la lista pacmd list-sinks. (Reporta solo 1 sumidero disponible.)
Ilari Kajaste
2
Entonces no se reconoce. Este es un requisito previo para poder conectarse por línea de comandos. Intente reiniciar BT o intente reiniciar pulsaudio. Todavía no he descubierto por qué a veces no se detecta.
Takkat
¿Eh? Entonces, ¿puede estar en un estado que sea posible conectarse desde la GUI, pero no desde la CLI?
Ilari Kajaste
1
@Takkat Oh, sí, buen punto. ¡Mi error! Estoy usando los auriculares para descubrir más, por lo que no se conectará automáticamente. Edité la pregunta para reflejar esto. Perdón por llevarte a un camino equivocado.
Ilari Kajaste
6

Utilizo este script para conectar mi dispositivo de audio Bluetooth. Si sus auriculares ya están emparejados, debería poder conectarlos de la misma manera usando org.bluez.Headset.Connect / Disconnect en lugar de 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!

doble rebelde
fuente
esto funcionó para mí también 16.04, gracias! otros, no te olvides de pasar la onopción al script!
Minero
2

Uso i3 como administrador de ventanas, por lo que no tengo disponible el icono de la bandeja de Bluetooth. Por alguna razón, el botón de verificación en la configuración de la unidad no es sensible, por lo que necesito una forma de hacerlo de vez en cuando cuando mis auriculares no se conectan.

ingrese la descripción de la imagen aquí

Parece que bluezha cambiado su API dbus . La respuesta utilizando org.bluez.Managerya no parece funcionar. En cambio, se recomienda su uso ObjectManager.

Aquí hay un script de Python actualizado que conectará los primeros auriculares bluetooth no conectados que encuentre (¿presumiblemente la lista incluye todos los dispositivos emparejados?):

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

Este ejemplo, como el otro ejemplo en este hilo, utiliza el dbuspaquete Python. En ubuntu 16.04 instalé esto a través apt-get install python-dbus.

Si desea coincidir con otros criterios, este documento parece mostrar una lista de propiedades que se pueden consultar a través de dbus.

Tengo este script guardado en el ~/.local/bin/bt-connect-headsetque está en mi PATHpara poder ejecutarlo desde el iniciador i3. Haga que sea ejecutable ( chmod +x bt-connect-headset) si planea usarlo como un comando.

Este script solo se ha probado en un ubuntu actualizado 16.04 a partir del 28/09/2018.

Cheshirekow
fuente
1
Usó su script en Ubuntu 18.10. ¡Gracias!
Brombomb
1
Super, esto funcionó para mí en Linux Mint 19 Cinnamon. Sin embargo, usé una clase de dispositivo de en 2360344lugar de 0x240404.
dom_watson
1
funciona como tal en Mint Xfce 19.2. Estoy seguro de que funciona en Xubuntu. - ¿Qué tal un script para desconectar el bluetooth?
cipricus
1
@cipricus Eso es correcto y ya se menciona en la respuesta. Hay un enlace en la respuesta sobre cómo hacer coincidir otros criterios si necesita algo más avanzado (como hacer coincidir un dispositivo con un nombre en particular). Ese enlace también incluye una lista de métodos disponibles en esta interfaz. Para desconectar, mi suposición es utilizar el Disconnect()método. No lo he probado, pero probablemente sea una apuesta segura;).
Cheshirekow
Estaba equivocado. Pensé que nunca va más allá del primero en la lista de dispositivos emparejados, pero lo hace. También podría haber pasado por alto el hecho de que usted dice first unconnected bluetooth headset : ¿usará siempre el auricular (si está encendido) antes que otro dispositivo como altavoces bluetooth (sin importar la posición en la lista)? Eso es lo que pasa en mi caso. - Además, para desconectar no puedo hacerlo simplemente cambiando la última línea a adapter.Disconnect().)
cipricus
1

Después de probar algunos de los anteriores (los scripts no funcionaron para mí) encontré la siguiente solución.

Primero averigüe la dirección MAC del dispositivo al que desea conectarse

bluetoothctl

Esto ingresará un shell y enumerará todos los dispositivos disponibles con dirección. ("salir" para salir del shell y volver al indicador)

Luego, conéctese al dispositivo Bluetooth XX: XX: XX: XX: XX: XX:

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

para desconectar

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

He estado buscando esto durante bastante tiempo, nada parecía funcionar, me sentí tan aliviado cuando me enteré. Pensé que otros querrían saberlo también. :))

Joseph
fuente
¿Podría editar su respuesta para agregar cómo obtener la dirección del dispositivo, para que la respuesta sea más completa?
user3140225
1
@ user3140225 acaba de hacerlo.
Joseph
Consigo ~$ bluetoothctl Agent registered [UE BOOM 2]#. Entonces disconnect "UE BOOM 2" Device UE BOOM 2 not available.
Cipricus
@cipricus @ user3140225 ¿Podría publicar la salida de bluetoothctl? Debe alimentar los comandos con la dirección MAC del dispositivo, que es la combinación de valores HEX en el formato XX: XX: XX: XX: XX: XX, donde X es una letra o un número.
Joseph
Puedo ver el MAC como se dice aquí . Entonces, tratando de echo -e 'connect CC:AF:78:AF:59:03' | bluetoothctlobtener:Agent registered [bluetooth]# connect CC:AF:78:AF:59:03 Device CC:AF:78:AF:59:03 not available
cipricus