【问题标题】:List nearby/discoverable bluetooth devices, including already paired, in Python, on Linux在 Linux 上用 Python 列出附近/可发现的蓝牙设备,包括已经配对的设备
【发布时间】:2012-12-25 02:23:34
【问题描述】:

我正在尝试列出所有附近/可发现的蓝牙设备,包括那些已经配对的,在 Linux 上使用 Python。

我知道如何使用设备的地址列出服务,并且可以成功连接:

services = bluetooth.find_service(address='...')

阅读 PyBluez 文档,如果我不指定任何条件,我希望附近的任何设备都会出现:

“如果未指定条件,则返回检测到的所有附近服务的列表。”

我现在需要的“唯一”事情是能够列出已经配对的设备,无论它们是打开、关闭还是附近。就像我在 Ubuntu/Unity 中的所有设置 --> 蓝牙中得到的列表一样。

顺便说一句,以下没有列出我机器上已经配对的设备,即使它们在/附近。可能是因为它们一旦配对就无法被发现:

import bluetooth
for d in bluetooth.discover_devices(flush_cache=True):
    print d

有什么想法吗...?

编辑:我找到并安装了“bluez-tools”。

bt-device --list

... 为我提供所需的信息,即添加设备的地址。

我检查了 C 源代码,发现这可能不像我想象的那么容易。

仍然不知道如何在 Python 中做到这一点......

编辑:我认为 DBUS 可能是我应该阅读的内容。似乎够复杂。如果有人有一些代码可以分享,我会非常高兴。 :)

【问题讨论】:

  • 您可以通过搜索 Blueman Project 的source code 找到您正在寻找的答案。
  • @Richard,我也想过,也开始做,不过真的是绕dbus...

标签: python linux bluetooth


【解决方案1】:

我自己设法解决了这个问题。以下 sn-p 列出了我默认蓝牙适配器上所有配对设备的地址:

import dbus

bus = dbus.SystemBus()

manager = dbus.Interface(bus.get_object('org.bluez', '/'), 'org.bluez.Manager')

adapterPath = manager.DefaultAdapter()

adapter = dbus.Interface(bus.get_object('org.bluez', adapterPath), 'org.bluez.Adapter')

for devicePath in adapter.ListDevices():
    device = dbus.Interface(bus.get_object('org.bluez', devicePath),'org.bluez.Device')
    deviceProperties = device.GetProperties()
    print deviceProperties["Address"]

【讨论】:

  • org.freedesktop.DBus.Error.UnknownMethod:接口“org.bluez.Manager”上带有签名“”的方法“DefaultAdapter”不存在
  • @WolfgangFahl 自从采用 bluez 5 API 后,对蓝牙设备的自定义查询的支持就被取消了。您必须恢复到 bluez 4 或使用我发布的替代版本
【解决方案2】:

自从采用蓝牙 API 版本 5 以来,@Micke 解决方案中使用的大部分功能都被删除了,交互 与总线通过 ObjectManager.GetManagedObjects [1]

import dbus


def proxyobj(bus, path, interface):
    """ commodity to apply an interface to a proxy object """
    obj = bus.get_object('org.bluez', path)
    return dbus.Interface(obj, interface)


def filter_by_interface(objects, interface_name):
    """ filters the objects based on their support
        for the specified interface """
    result = []
    for path in objects.keys():
        interfaces = objects[path]
        for interface in interfaces.keys():
            if interface == interface_name:
                result.append(path)
    return result


bus = dbus.SystemBus()

# we need a dbus object manager
manager = proxyobj(bus, "/", "org.freedesktop.DBus.ObjectManager")
objects = manager.GetManagedObjects()

# once we get the objects we have to pick the bluetooth devices.
# They support the org.bluez.Device1 interface
devices = filter_by_interface(objects, "org.bluez.Device1")

# now we are ready to get the informations we need
bt_devices = []
for device in devices:
    obj = proxyobj(bus, device, 'org.freedesktop.DBus.Properties')
    bt_devices.append({
        "name": str(obj.Get("org.bluez.Device1", "Name")),
        "addr": str(obj.Get("org.bluez.Device1", "Address"))
    })  

bt_device 列表中有包含所需数据的字典: 即

例如

[{
    'name': 'BBC micro:bit [zigiz]', 
    'addr': 'E0:7C:62:5A:B1:8C'
 }, {
    'name': 'BBC micro:bit [putup]',
    'addr': 'FC:CC:69:48:5B:32'
}]

参考: [1]http://www.bluez.org/bluez-5-api-introduction-and-porting-guide/

【讨论】:

    【解决方案3】:

    您总是可以将其作为 shell 命令执行并读取它返回的内容:

    import subprocess as sp
    p = sp.Popen(["bt-device", "--list"], stdin=sp.PIPE, stdout=sp.PIPE, close_fds=True)
    (stdout, stdin) = (p.stdout, p.stdin)
    data = stdout.readlines()
    

    现在data 将包含所有输出行的列表,您可以根据需要对其进行格式化和播放。

    【讨论】:

    • 谢谢!如果我没有设法在 Python 中完成所有事情,那将是我的后备解决方案。
    【解决方案4】:

    有点长,但一行就可以了

    bt-device -l | egrep '\(.*\)' | grep -oP '(?<=\()[^\)]+' | xargs -n1 bt-device -i 
    

    【讨论】:

    • 对于像我这样的任何人,如果尚未执行,则需要先sudo apt install bluez-tools bluez
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-29
    • 1970-01-01
    相关资源
    最近更新 更多