Conecte ao dispositivo bluetooth a partir da linha de comando

22

Antecedentes: estou usando meu fone de ouvido bluetooth como saída de áudio. Consegui fazê-lo funcionar pela longa lista de instruções na documentação da comunidade BluetoothHeadset e automatizei o processo de ativação do fone de ouvido como saída de áudio padrão em um script, graças a outra pergunta .

No entanto, como eu uso o fone de ouvido bluetooth com o telefone e o computador (e o fone de ouvido não suporta duas conexões de entrada) para que o telefone não "roube" a conexão quando o aparelho está ligado, forço o fone de ouvido a modo de descoberta ao se conectar ao computador (o telefone pode se conectar a ele automaticamente).

Portanto, mesmo que o fone de ouvido esteja emparelhado e funcione automaticamente no cenário "normal", tenho que usar sempre o pequeno ícone de bluetooth na área de notificação para realmente conectar-me ao dispositivo (veja a captura de tela).

O que eu quero evitar: Esta GUI para conectar-se a um dispositivo bluetooth conhecido e emparelhado :

Conexão ao fone de ouvido Bluetooth usando o ícone

O que eu quero: quero que o bluetooth faça exatamente o que o clique no item de conexão na GUI faz, apenas usando a linha de comando. Desejo usar a linha de comando para poder criar um atalho de pressionamento de tecla único para a ação e não precisarei navegar na GUI toda vez que desejar estabelecer uma conexão com o dispositivo.

A pergunta: como posso conectar-me a um dispositivo bluetooth específico, conhecido e emparelhado na linha de comando?

Pergunta adicional: Como posso saber se a conexão foi bem-sucedida ou não?

Ilari Kajaste
fonte
Que ferramenta de bandeja é essa? é o ícone da bandeja do Blueman Manager? O applet da bandeja do gerenciador do Blueman deve listar dispositivos bluetooth emparelhados?
cipricus 26/06

Respostas:

10

Daemon Bluetooth

Na instalação padrão, um daemon ( bluetoothd ) é executado em segundo plano (executado a partir do arquivo /etc/init.d/bluetooth). Este daemon cuida do reconhecimento e conexão com dispositivos Bluetooth conhecidos e pode ser configurado com os arquivos de configuração /etc/bluetooth. Para conectar automaticamente um fone de ouvido, a seguinte entrada de linha audio.confdeve ser descomentada (remover #):

AutoConnect=true

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

Observação: o uso da ferramenta de linha de comando sudo hcitool cc <MAC-Adress>não levou a uma conexão estável com um dispositivo conhecido no ambiente de teste aqui quando o daemon estava em execução.


DBus

Para conectar um fone de ouvido desconectado, mas fisicamente presente e emparelhado, podemos usar o D-Bus a partir de um script. Aqui está um exemplo em 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

Caso tenhamos mais de um dispositivo Bluetooth, teremos que adaptar o dispositivo devicePathadequadamente, é claro. O exemplo acima irá conectar a Headset. Mude a interface para um protocolo diferente para qualquer outro serviço (por exemplo AudioSink).


Pulseaudio

Se você conhece o endereço MAC do seu dispositivo Bluetooth, pode conectá-lo como um coletor de saída para o pulseaudio:

pacmd set-default-sink bluez_sink.xx_xx_xx_xx_xx_xx

Onde xx_xx_xx_xx_xx_xx é o endereço MAC (substitua ':' por '_' para que o pulseaudio o reconheça).

Veja também esta resposta para mais detalhes.

Takkat
fonte
Eu sei o endereço e substituí o xx por ele. Eu só Sink bluez_sink.xx_xx_xx_xx_xx_xx does not exist.tentei maiúsculas e minúsculas.
Ilari Kajaste
1
Sim, o pulseaudio-module-bluetooth não é atual. Não, nada corresponde btou blueestá listado em pacmd list-sinks. (Ele relata apenas 1 afundar disponível.)
Ilari Kajaste
2
Portanto, não é reconhecido. Este é um pré-requisito para poder se conectar por linha de comando. Tente reiniciar o BT ou tente reiniciar o pulsaudio. Ainda não descobri por que às vezes não é detectado.
Takkat 10/06/11
Hã? Portanto, pode ser que seja possível conectar-se a partir da GUI, mas não da CLI?
Ilari Kajaste
1
@ Takkat Oh, sim, bom ponto. Minha culpa! Estou usando mais o headset na descoberta, para que ele não se conecte automaticamente. Eu editei a pergunta para refletir isso. Desculpe por levá-lo a um caminho errado.
Ilari Kajaste
6

Eu uso esse script para conectar meu dispositivo de áudio Bluetooth. Se o seu fone de ouvido já estiver emparelhado, você poderá conectá-lo da mesma maneira usando org.bluez.Headset.Connect / Disconnect no 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!

doublerebel
fonte
isso funcionou para mim também 16.04, obrigado! outros, não esqueça de passar a onopção para o script!
MInner
2

Como uso o i3 como gerenciador de janelas, não tenho o ícone da bandeja bluetooth disponível. Por alguma razão, o botão de seleção nas configurações da unidade não é sensível e, portanto, preciso de uma maneira de fazer isso de tempos em tempos quando meus fones de ouvido não se conectam.

insira a descrição da imagem aqui

Parece que blueztem mudado sua API dbus . A resposta que utiliza org.bluez.Managernão parece mais funcionar. Em vez disso, é recomendável usar ObjectManager.

Aqui está um script python atualizado que conectará o primeiro fone de ouvido bluetooth desconectado que encontrar (presumivelmente a lista inclui todos os dispositivos emparelhados?):

#!/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 exemplo, como o outro exemplo neste segmento, usa o dbuspacote python. No ubuntu 16.04 eu instalei isso completamente apt-get install python-dbus.

Se você deseja corresponder a outros critérios, este documento parece mostrar uma lista de propriedades que podem ser consultadas no dbus.

Eu tenho esse script salvo no ~/.local/bin/bt-connect-headsetqual está meu, PATHpara que eu possa executá-lo no iniciador do i3. Torne-o executável ( chmod +x bt-connect-headset) se você planeja usá-lo como um comando.

Este script foi testado apenas em um ubuntu 16.04 atualizado a partir de 28/09/2018.

cheshirekow
fonte
1
Usou seu script no Ubuntu 18.10. Obrigado!
Brombomb
1
Super, isso funcionou para mim no Linux Mint 19 Cinnamon. No entanto, usei uma classe de dispositivo em 2360344vez de 0x240404.
dom_watson
1
funciona como tal no Mint Xfce 19.2. Tenho certeza que funciona no Xubuntu. - Que tal um script para desconectar o bluetooth?
cipricus 30/08
1
@cipricus Isso está correto e já foi mencionado na resposta. Há um link na resposta sobre como corresponder a outros critérios, se você precisar de algo mais avançado (como a correspondência de um dispositivo com um nome específico). Esse link também inclui uma lista de métodos disponíveis nessa interface. Para desconectar, meu palpite é usar o Disconnect()método Eu não tentei, mas provavelmente é uma aposta segura;).
cheshirekow
Eu estava errado. Eu pensei que nunca ultrapassa o primeiro da lista de dispositivos emparelhados, mas é o que faz. Também posso ter esquecido o fato de você dizer first unconnected bluetooth headset : ele sempre usará o fone de ouvido (se ligado) antes de outro dispositivo, como alto-falantes bluetooth (não importa a posição na lista)? É o que acontece no meu caso. - Além disso, para desconectar, não posso fazer isso apenas alterando a última linha para adapter.Disconnect().)
cipricus
1

Depois de tentar algumas das opções acima (os scripts não funcionaram para mim), encontrei a seguinte solução.

Primeiro, descubra o endereço MAC do dispositivo ao qual você deseja se conectar

bluetoothctl

isso entrará em um shell e listará todos os dispositivos disponíveis com endereço. ("saia" para sair do shell e volte ao prompt)

Em seguida, conecte-se a XX: XX: XX: XX: XX: XX dispositivo bluetooth:

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

desconectar

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

procurava por isso há um bom tempo - nada parecia funcionar, senti-me tão aliviado quando descobri. Achei que os outros também gostariam de saber sobre isso. :))

Joseph
fonte
Você poderia editar sua resposta para adicionar como obter o endereço do dispositivo, para que a resposta seja mais completa?
user3140225 9/08
1
@ user3140225 acabou de fazer.
Joseph
Eu entendo ~$ bluetoothctl Agent registered [UE BOOM 2]#. Então disconnect "UE BOOM 2" Device UE BOOM 2 not available.
cipricus 02/09
@cipricus @ user3140225 Você poderia postar a saída de bluetoothctl? Você precisa alimentar os comandos com o endereço MAC do dispositivo - que é a combinação dos valores HEX no formato XX: XX: XX: XX: XX: XX, em que X é uma letra ou um número.
Joseph
Eu posso ver o MAC como dito aqui . Então, tentando echo -e 'connect CC:AF:78:AF:59:03' | bluetoothctlobter:Agent registered [bluetooth]# connect CC:AF:78:AF:59:03 Device CC:AF:78:AF:59:03 not available
cipricus 04/09