web-dev-qa-db-ja.com

コマンドラインからBluetoothデバイスに接続します

背景:Bluetoothヘッドセットをオーディオ出力として使用しています。 BluetoothHeadsetコミュニティドキュメンテーション の手順の長いリストによって何とか動作し、スクリプトへのデフォルトのオーディオ出力としてヘッドセットをアクティブ化するプロセスを自動化しました 別の質問

ただし、ハンドセットの電源を入れたときに電話が接続を「盗む」ことのないように、Bluetoothヘッドセットを電話とコンピューターの両方で使用し(ヘッドセットは2つの入力接続をサポートしていません)、コンピューターに接続するときの検出モード(電話は自動的に接続します)。

そのため、ヘッドセットのペアリングは問題なく、「通常」のシナリオでは自動接続されますが、実際にデバイスに接続するには、通知領域の小さなBluetoothアイコンを常に使用する必要があります(スクリーンショットを参照)。

避けたいこと:既知のペアリングされたBluetoothデバイスに接続するためのこのGUI:

Connecting to Bluetooth headset using icon

代わりに欲しいもの:コマンドラインを使用するだけで、GUIで接続項目をクリックするのとまったく同じようにbluetoothに実行させたいと思います。コマンドラインを使用してアクションのショートカットキーを1つ作成できるようにします。また、デバイスへの接続を確立するたびにGUIをナビゲートする必要はありません。

質問:特定の既知のペアリングされたBluetoothデバイスコマンドラインから?

さらに質問:接続が成功したかどうかを確認するにはどうすればよいですか?

22
Ilari Kajaste

Bluetoothデーモン

デフォルトのインストールでは、デーモン(bluetoothd)はバックグラウンドで実行されます(ファイル/etc/init.d/bluetoothから実行)。このデーモンは、既知のbluetoothデバイスの認識と接続に注意を払い、/etc/bluetoothの構成ファイルと一緒に構成できます。ヘッドセットを自動接続するには、audio.confの次の行のコメントを解除する必要があります(#を削除):

AutoConnect=true

デーモンを再起動するには、Sudo /etc/init.d/bluetooth restartと入力します。

備考:コマンドラインツールSudo hcitool cc <MAC-Adress>を使用しても、デーモンがテスト環境にある既知のデバイスへの安定した接続が得られなかったランニング。


DBus

切断されているが物理的に存在しペアリングされているヘッドセットを接続するには、スクリプトから D-Bus を使用できます。 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

もちろん、複数のBluetoothデバイスがある場合は、devicePathを適切に調整する必要があります。上記の例では、Headsetを接続します。インターフェイスを他のサービスの別のプロトコルに変更します(例:AudioSink)。


パルスオーディオ

BluetoothデバイスのMACアドレスがわかっている場合は、次の方法でpulseaudioの出力シンクとして接続できます。

pacmd set-default-sink bluez_sink.xx_xx_xx_xx_xx_xx

ここで、xx_xx_xx_xx_xx_xxはMACアドレスです(pulseaudioで認識するには、「:」を「_」で置き換えます)。

詳細については this answer もご覧ください。

10
Takkat

このスクリプトを使用して、Bluetoothオーディオデバイスを接続します。ヘッドセットが既にペアリングされている場合は、代わりにorg.bluez.Headset.Connect/Disconnectを使用してヘッドセットを同じ方法で接続できるはずです。 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!

6
doublerebel

i をウィンドウマネージャーとして使用するため、Bluetoothトレイアイコンを使用できません。何らかの理由で、統一設定のチェックボタンは敏感ではないため、ヘッドフォンが接続されていないときに時々これを行う方法が必要です。

enter image description here

bluezには dbus APIの変更 があるようです。 org.bluez.Managerを利用する答えはもはや機能していないようです。代わりに、ObjectManagerを使用することをお勧めします。

以下に、更新されたpythonスクリプトを示します。このスクリプトは、検出された最初の未接続のBluetoothヘッドセットを接続します(おそらく、リストにはすべてのペアリングされたデバイスが含まれますか?):

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

この例は、このスレッドの他の例と同様に、dbus pythonパッケージを使用します。 ubuntu 16.04では、apt-get install python-dbusを介してこれをインストールしました。

他の条件に一致させたい場合は、 このドキュメント が表示され、dbusでクエリできるプロパティのリストが表示されます。

このスクリプトを~/.local/bin/bt-connect-headsetに保存しています。これはPATHにあり、i3ランチャーから実行できます。コマンドとして使用する場合は、実行可能(chmod +x bt-connect-headset)にします。

このスクリプトは、2018年9月28日現在の最新のubuntu 16.04でのみテストされています。

2
cheshirekow

上記のいくつかを試した後(スクリプトはうまくいきませんでした)、次の解決策を見つけました。

まず、接続したいデバイスのMACアドレスを見つけます

bluetoothctl

これにより、シェルが開き、使用可能なすべてのデバイスがアドレスとともに一覧表示されます。 (シェルを終了してプロンプトに戻るには「終了」)

次に、XX:XX:XX:XX:XX:XX Bluetoothデバイスに接続します:

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

切断する

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

かなり長い間これを探していました-何も機能していないようで、私が見つけたときとても安心しました。他の人もそれについて知りたいと思うかもしれません。 :))

1
Joseph