เชื่อมต่อกับอุปกรณ์บลูทู ธ จากบรรทัดคำสั่ง


22

พื้นหลัง:ฉันใช้ชุดหูฟังบลูทู ธ เป็นสัญญาณเสียง ฉันจัดการเพื่อให้มันทำงานโดยรายการยาวของคำแนะนำเกี่ยวกับเอกสารชุมชน BluetoothHeadsetและฉันได้อัตโนมัติกระบวนการของการเปิดใช้งานชุดหูฟังเป็นสัญญาณเสียงเริ่มต้นเข้าสู่สคริปต์ขอบคุณคำถามอื่น

อย่างไรก็ตามเนื่องจากฉันใช้ชุดหูฟังบลูทู ธ กับทั้งโทรศัพท์และคอมพิวเตอร์ของฉัน (และชุดหูฟังไม่รองรับการเชื่อมต่ออินพุตสองจุด) เพื่อให้โทรศัพท์ไม่ "ขโมย" การเชื่อมต่อเมื่อเปิดเครื่องฉันจึงบังคับให้ชุดหูฟัง โหมดการค้นพบเมื่อเชื่อมต่อกับคอมพิวเตอร์ (โทรศัพท์จะเชื่อมต่อกับมันโดยอัตโนมัติ)

ดังนั้นแม้ว่าชุดหูฟังจะถูกจับคู่ตกลงและจะเชื่อมต่ออัตโนมัติในสถานการณ์ "ปกติ" ฉันต้องใช้ไอคอนบลูทู ธ เล็ก ๆ ในพื้นที่แจ้งเตือนเพื่อเชื่อมต่อกับอุปกรณ์ของฉัน (ดูภาพหน้าจอ)

สิ่งที่ฉันต้องการหลีกเลี่ยง: GUI นี้สำหรับการเชื่อมต่อกับอุปกรณ์บลูทู ธ ที่รู้จักและจับคู่ :

การเชื่อมต่อกับชุดหูฟัง Bluetooth โดยใช้ไอคอน

สิ่งที่ฉันต้องการแทน:ฉันต้องการทำให้บลูทู ธ ทำสิ่งที่การคลิกที่รายการเชื่อมต่อใน GUI ทำได้โดยใช้บรรทัดคำสั่งเท่านั้น ฉันต้องการใช้บรรทัดคำสั่งเพื่อให้สามารถสร้างทางลัดคีย์ลัดเดียวสำหรับการดำเนินการและไม่จำเป็นต้องนำทาง GUI ทุกครั้งที่ฉันต้องการสร้างการเชื่อมต่อกับอุปกรณ์

คำถาม:ฉันจะพยายามเชื่อมต่อกับอุปกรณ์บลูทู ธ ที่รู้จักและจับคู่จากบรรทัดคำสั่งได้อย่างไร

คำถามเพิ่มเติม: ฉันจะบอกได้อย่างไรว่าการเชื่อมต่อนั้นสำเร็จหรือไม่?


คำตอบ:


10

บลูทู ธ ภูต

ในการติดตั้งเริ่มต้น daemon ( bluetoothd ) จะทำงานในพื้นหลัง (เรียกใช้จากไฟล์/etc/init.d/bluetooth) ภูตนี้จะดูแลเกี่ยวกับการรับรู้และการเชื่อมต่อกับอุปกรณ์บลูทู ธ ที่รู้จักและอาจจะ cofigured กับไฟล์การกำหนดค่า/etc/bluetoothมา สำหรับการถอดชุดหูฟังโดยอัตโนมัติบรรทัดต่อไปนี้audio.confควรไม่ใส่เครื่องหมายข้อคิดเห็น(ลบ#):

AutoConnect=true

sudo /etc/init.d/bluetooth restartเมื่อต้องการเริ่มต้นประเภทภูต

หมายเหตุ:การใช้เครื่องมือบรรทัดคำสั่งsudo hcitool cc <MAC-Adress>ไม่ได้นำไปสู่การเชื่อมต่อที่เสถียรไปยังอุปกรณ์ที่รู้จักในสภาพแวดล้อมการทดสอบที่นี่เมื่อ daemon กำลังทำงาน


DBus

เพื่อเชื่อมต่อชุดหูฟังที่ขาดการเชื่อมต่อ แต่มีอยู่จริงและจับคู่เราสามารถใช้D-Busจากสคริปต์ นี่คือตัวอย่างในภาษาไพ ธ อน:

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

ในกรณีที่เรามีอุปกรณ์บลูทู ธ มากกว่าหนึ่งเราจะต้องปรับให้devicePathเหมาะสมอย่างแน่นอน Headsetตัวอย่างข้างต้นจะเชื่อมต่อ เปลี่ยนอินเตอร์เฟสเป็นโปรโตคอลอื่นสำหรับบริการอื่น ๆ (เช่นAudioSink)


PulseAudio

หากคุณรู้จักที่อยู่ MAC ของอุปกรณ์บลูทู ธ ของคุณคุณสามารถเชื่อมต่ออุปกรณ์นั้นเป็นเอาท์พุทซิงค์สำหรับ pulseaudio โดย:

pacmd set-default-sink bluez_sink.xx_xx_xx_xx_xx_xx

โดยที่ xx_xx_xx_xx_xx_xx เป็นที่อยู่ MAC (แทนที่ ':' โดย '_' เพื่อให้ pulseaudio จดจำได้)

ดูคำตอบนี้สำหรับรายละเอียดเพิ่มเติม


ฉันรู้ที่อยู่และฉันแทนที่ xx ด้วย ฉันได้Sink bluez_sink.xx_xx_xx_xx_xx_xx does not exist.ลองทั้งตัวพิมพ์ใหญ่และตัวพิมพ์เล็กเท่านั้น
Ilari Kajaste

1
ใช่ pulseaudio-module-bluetooth isntalle ไม่มีอะไรที่ตรงกันbtหรือมีชื่ออยู่ในblue pacmd list-sinks(มีรายงานว่ามีเพียง 1 sink เท่านั้น)
Ilari Kajaste

2
ดังนั้นจึงไม่เป็นที่รู้จัก นี่เป็นข้อกำหนดเบื้องต้นเพื่อให้สามารถเชื่อมต่อโดย commandline ลองเริ่มต้น BT อีกครั้งหรือลองเริ่ม pulsaudio ฉันยังไม่พบสาเหตุที่บางครั้งมันไม่ได้ถูกถอดออก
Takkat

ฮะ? ดังนั้นจึงอาจอยู่ในสถานะที่เป็นไปได้ที่จะเชื่อมต่อจาก GUI แต่ไม่ใช่จาก CLI หรือไม่
Ilari Kajaste

1
@ Takkat โอ้ใช่แล้วจุดดี ความผิดฉันเอง! ฉันใช้ชุดหูฟังในการค้นพบมากขึ้นดังนั้นมันจะไม่เชื่อมต่ออัตโนมัติ ฉันแก้ไขคำถามเพื่อสะท้อนสิ่งนี้ ขออภัยที่พาคุณไปสู่เส้นทางที่ผิด
Ilari Kajaste

6

ฉันใช้สคริปต์นี้เพื่อเชื่อมต่ออุปกรณ์เสียงบลูทู ธ ของฉัน หากหูฟังของคุณจะถูกจับคู่แล้วคุณควรจะสามารถเชื่อมต่อชุดหูฟังของคุณในทางเดียวกันโดยใช้org.bluez.Headset.Connect / ยกเลิกการเชื่อมต่อในสถานที่ของorg.bluez.Audiosink.Connect / ยกเลิกการเชื่อมต่อ

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


สิ่งนี้ได้ผลกับฉันเช่นกัน16.04ขอบคุณ! คนอื่น ๆ อย่าลืมที่จะส่งonตัวเลือกให้กับสคริปต์!
MInner

2

ฉันใช้i3เป็นตัวจัดการหน้าต่างดังนั้นฉันจึงไม่มีไอคอนถาดบลูทู ธ ด้วยเหตุผลบางอย่างปุ่มตรวจสอบในการตั้งค่าความสามัคคีไม่อ่อนไหวและดังนั้นฉันจึงต้องการวิธีการทำเช่นนี้เป็นครั้งคราวเมื่อหูฟังของฉันไม่ได้เชื่อมต่อ

ป้อนคำอธิบายรูปภาพที่นี่

มันดูเหมือนว่าจะbluezมีการเปลี่ยนแปลง dbus API คำตอบที่ใช้org.bluez.Managerไม่ปรากฏว่าทำงานได้อีกต่อไป ขอแนะนำให้ใช้ObjectManagerแทน

นี่คือสคริปต์ python ที่อัปเดตซึ่งจะเชื่อมต่อชุดหูฟังบลูทู ธ แรกที่ไม่ได้เชื่อมต่อที่พบ (สันนิษฐานว่ารายการมีอุปกรณ์ที่จับคู่ทั้งหมดหรือไม่):

#!/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แพ็คเกจหลาม บน Ubuntu 16.04 apt-get install python-dbusผมติดตั้งผ่านทางนี้

หากคุณต้องการจับคู่เกณฑ์อื่น ๆเอกสารนี้จะปรากฏขึ้นเพื่อแสดงรายการคุณสมบัติที่สามารถสอบถามได้มากกว่า dbus

ฉันได้บันทึกสคริปต์นี้ไว้~/.local/bin/bt-connect-headsetซึ่งเป็นของฉันPATHดังนั้นฉันจึงสามารถเรียกใช้งานได้จากตัวเรียกใช้งาน i3 ทำให้สามารถเรียกใช้งานได้ ( chmod +x bt-connect-headset) หากคุณวางแผนที่จะใช้เป็นคำสั่ง

สคริปต์นี้ได้รับการทดสอบบน Ubuntu รุ่นล่าสุด 16.04 ณ วันที่ 09/28/2018


1
ใช้สคริปต์ของคุณบน Ubuntu 18.10 ขอบคุณ!
Brombomb

1
Super ใช้งานได้กับ Linux Mint 19 Cinnamon แต่ผมใช้คลาสอุปกรณ์ของแทน2360344 0x240404
dom_watson

1
ทำงานได้ใน Mint Xfce 19.2 ฉันแน่ใจว่าใช้งานได้ใน Xubuntu - แล้วสคริปต์ที่จะตัดการเชื่อมต่อบลูทู ธ ล่ะ?
cipricus

1
@cipricus นั่นถูกต้องและถูกกล่าวถึงแล้วในคำตอบ มีลิงก์ในคำตอบเกี่ยวกับวิธีจับคู่เกณฑ์อื่น ๆ หากคุณต้องการสิ่งที่สูงกว่า (เช่นจับคู่อุปกรณ์ที่มีชื่อเฉพาะ) ลิงค์นั้นยังมีรายการวิธีการที่มีอยู่ในส่วนต่อประสานนี้ หากต้องการยกเลิกการเชื่อมต่อฉันเดาว่าใช้Disconnect()วิธีนี้ ฉันไม่ได้ลอง แต่อาจเป็นทางออกที่ปลอดภัย;)
cheshirekow

ฉันผิดไป. ฉันคิดว่ามันจะไม่ไปไกลกว่าอุปกรณ์ตัวแรกที่จับคู่ แต่ทำได้ ฉันอาจพลาดความจริงที่ว่าคุณพูดว่าfirst unconnected bluetooth headset : มันจะใช้ชุดหูฟัง (หากเปิดเครื่อง) เสมอก่อนอุปกรณ์อื่นเช่นลำโพงบลูทู ธ (ไม่ว่าจะอยู่ในตำแหน่งใดในรายการ) หรือไม่ นั่นคือสิ่งที่เกิดขึ้นในกรณีของฉัน - นอกจากนี้ในการที่จะตัดการเชื่อมต่อฉันไม่สามารถทำได้โดยเพียงแค่เปลี่ยนบรรทัดสุดท้ายเป็นadapter.Disconnect())
cipricus

1

หลังจากลองใช้บางข้อ (สคริปต์ไม่ทำงานสำหรับฉัน) ฉันพบวิธีแก้ไขปัญหาต่อไปนี้

ขั้นแรกให้ค้นหา MAC-Adress ของอุปกรณ์ที่คุณต้องการเชื่อมต่อ

bluetoothctl

สิ่งนี้จะเข้าสู่เชลล์และแสดงรายการอุปกรณ์ที่มีอยู่ทั้งหมดพร้อมที่อยู่ ("ออก" เพื่อออกจากเชลล์ & กลับไปที่พรอมต์)

จากนั้นเชื่อมต่อกับอุปกรณ์บลูทู ธ XX: XX: XX: XX: XX: XX:

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

เพื่อยกเลิกการเชื่อมต่อ

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

การค้นหาสิ่งนี้มาระยะหนึ่งแล้วดูเหมือนจะไม่มีอะไรทำงานเลยรู้สึกโล่งใจเมื่อฉันพบ คิดว่าคนอื่นอาจต้องการทราบเกี่ยวกับมันเช่นกัน :))


คุณสามารถแก้ไขคำตอบเพื่อเพิ่มวิธีรับที่อยู่ของอุปกรณ์ได้อย่างไรคำตอบจึงสมบูรณ์ยิ่งขึ้น
3140225

1
@ user3140225 เพิ่งทำไป
โจเซฟ

~$ bluetoothctl Agent registered [UE BOOM 2]#ฉันได้รับ disconnect "UE BOOM 2" Device UE BOOM 2 not availableแล้วก็
cipricus

@cipricus @ user3140225 คุณสามารถโพสต์ผลลัพธ์ของได้ bluetoothctlหรือไม่ คุณต้องป้อนคำสั่งด้วย MAC-adress ของอุปกรณ์ - ซึ่งเป็นการรวมกันของค่า HEX ในรูปแบบ XX: XX: XX: XX: XX: XX โดยที่ X เป็นตัวอักษรหรือตัวเลข
โจเซฟ

ฉันสามารถดูแม็คกล่าวว่าเป็นที่นี่ จากนั้นecho -e 'connect CC:AF:78:AF:59:03' | bluetoothctlฉันจะลอง:Agent registered [bluetooth]# connect CC:AF:78:AF:59:03 Device CC:AF:78:AF:59:03 not available
cipricus
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.