简体   繁体   English

在Linux上列出附近/可发现的蓝牙设备,包括已经配对的Python

[英]List nearby/discoverable bluetooth devices, including already paired, in Python, on Linux

I'm trying to list all nearby/discoverable bluetooth devices, including those already paired , using Python on Linux. 我正在尝试在Linux上使用Python列出所有附近/可发现的蓝牙设备, 包括那些已配对的蓝牙设备。

I know how to list services for a device using its address, and can connect successfully: 我知道如何使用其地址列出设备的服务,并且可以成功连接:

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

Reading the PyBluez docs I would expect any nearby device to show up if I don't specify any criteria: 阅读PyBluez文档如果我没有指定任何标准,我希望附近的任何设备都能显示出来:

"If no criteria are specified, then returns a list of all nearby services detected." “如果未指定任何条件,则返回检测到的所有附近服务的列表。”

The "only" thing I need right now is to be able to list already paired devices, whether they are on, off, nearby or not. 我现在需要的“唯一”事情就是能够列出已经配对的设备,无论它们是开,关,还是没有。 Much like the list I'm getting in All Settings --> Bluetooth in Ubuntu/Unity. 就像我在Ubuntu / Unity中的All Settings - > Bluetooth中获得的列表一样。

Btw, the following does not list already paired devices on my machine, even if they are on/nearby. 顺便说一句,以下内容列出我的机器上已配对的设备,即使它们在/附近。 Probably because they are not discoverable once paired: 可能是因为配对后它们不可发现:

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

Any ideas ...? 有任何想法吗 ...?

Edit: I found and installed "bluez-tools". 编辑:我找到并安装了“bluez-tools”。

bt-device --list

... gives me the information I need, ie addresses of added devices. ...给我提供我需要的信息,即添加设备的地址。

I've checked the C source, found out that this might not be as easy as I thought it would be. 我检查了C源,发现这可能不像我想象的那么容易。

Still don't know how to do this in Python ... 仍然不知道如何在Python中这样做...

Edit: I think DBUS might be what I should be reading up on. 编辑:我认为DBUS可能是我应该阅读的内容。 Seems complicated enough. 看起来很复杂。 If anyone has got some code to share I would be really happy. 如果有人有一些代码要分享,我会非常高兴。 :) :)

I managed to solve the problem myself. 我设法自己解决了这个问题。 The following snippet lists addresses for all paired devices, on my default bluetooth adapter: 以下代码段列出了我的默认蓝牙适配器上所有配对设备的地址:

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"]

You could always execute it as a shell command and read what it returns: 您始终可以将其作为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()

Now data will include a list of all output lines which you can format and play with as you like. 现在, data将包含所有输出行的列表,您可以根据需要进行格式化和播放。

Since the adoption of the version 5 of the Bluetooth API most of the functions used in the @Micke solutions were dropped and the interaction with the bus take place throught the ObjectManager.GetManagedObjects [1] 自从采用蓝牙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"))
    })  

In the bt_device list there are dictionaries with the desired data: ie bt_device列表中有包含所需数据的字典:即

for example 例如

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

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

有点长,但在一行中诀窍

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM