You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

树莓派4限时扫描蓝牙设备脚本无回调输出问题排查

问题排查与修复方案

你的脚本存在几个关键问题,导致interfaces_added回调函数无输出:

1. 错误选择DBus总线类型

BlueZ蓝牙服务运行在**系统总线(SystemBus)**上,但你的代码使用了dbus.SessionBus(),这会导致无法接收BlueZ发出的设备发现信号。

2. 冗余的类继承与错误路径

你的GetNewDevices类不需要继承dbus.service.Object——你只是接收信号,并非对外提供DBus服务。即使要继承,也不应该注册到/org/freedesktop/DBus这个系统预留路径。

3. 超时处理器返回值不规范

GLib.timeout_add的回调函数若返回True会重复触发,你的handler函数未显式返回值,虽不影响退出,但显式返回False更符合规范。


修复后的完整代码

#!/usr/bin/python

import dbus
import dbus.mainloop.glib
from gi.repository import GLib
import bluezutils

BLUEZ_SERVICE_NAME = "org.bluez"
DBUS_OM_IFACE = 'org.freedesktop.DBus.ObjectManager'
DEVICE_INTERFACE = BLUEZ_SERVICE_NAME + ".Device1"

TIMEOUT = 10 * 1000
            
class GetNewDevices:
    def __init__(self, loop):
        self.loop = loop
        # 切换为系统总线
        bus = dbus.SystemBus()
        self.setup_timeout(TIMEOUT)
        self.listen_for_signal(bus)

    def setup_timeout(self, timeout):
        GLib.timeout_add(timeout, self.handler)

    def listen_for_signal(self, bus):
        bus.add_signal_receiver(
            self.interfaces_added,
            bus_name=BLUEZ_SERVICE_NAME,
            dbus_interface=DBUS_OM_IFACE,
            signal_name="InterfacesAdded",
        )

    def handler(self):
        self.loop.quit()
        # 显式返回False,避免超时重复触发
        return False

    def interfaces_added(self, path, interfaces):
        # 仅处理蓝牙设备接口的添加事件
        if DEVICE_INTERFACE in interfaces:
            props = interfaces[DEVICE_INTERFACE]
            print(f"发现蓝牙设备:")
            print(f"  设备路径: {path}")
            print(f"  设备名称: {props.get('Name', '未知名称')}")
            print(f"  MAC地址: {props.get('Address', '未知地址')}")
            print("------------------------")


if __name__ == "__main__":
    # 获取蓝牙适配器并启动扫描
    adapter = bluezutils.find_adapter()
    try:
        adapter.StartDiscovery()
        print(f"开始扫描蓝牙设备,将持续{TIMEOUT//1000}秒...")
    except dbus.exceptions.DBusException as e:
        print(f"启动扫描失败: {e}")
        exit(1)

    # 初始化DBus主循环
    dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
    loop = GLib.MainLoop()
    a = GetNewDevices(loop)
    
    try:
        loop.run()
    finally:
        # 确保扫描结束后停止设备发现
        adapter.StopDiscovery()
        print("扫描结束,已停止设备发现")

print("程序退出")

额外注意事项

  • 必须以root权限运行脚本(蓝牙扫描需要系统权限),执行命令:sudo python3 your_script.py
  • 确认树莓派蓝牙模块已启用,可通过bluetoothctl命令检查状态
  • 若缺失bluezutils模块,可从BlueZ示例目录获取(通常位于/usr/share/doc/bluez/examples/)

内容的提问来源于stack exchange,提问作者Eduardo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 04:00:03