如何将基于 L2CAP 的蓝牙相机快门(AB 快门 3)连接到 Linux 并在 Python 中获取关键事件?

Posted

技术标签:

【中文标题】如何将基于 L2CAP 的蓝牙相机快门(AB 快门 3)连接到 Linux 并在 Python 中获取关键事件?【英文标题】:How do I connect a L2CAP-based Bluetooth Camera Shutter (AB Shutter 3) to Linux and get the key event in Python? 【发布时间】:2021-05-28 11:12:48 【问题描述】:

目标

我有一个HITSLAM Camera Shutter Bluetooth button(这是一个 AB Shutter 3 设备,一个常见的蓝牙相机遥控器),我想使用蓝牙连接到我的 NVIDIA Jetson Nano,这样我就可以使用按钮的输入来完成某些任务。

我做了什么

我正在使用 PyBluez 库进行连接。我使用以下内容找出 AB Shutter 3 使用的端口和协议(其中target_device_address 是 AB Shutter 3 的设备地址):

service_matches = bt.find_service(name=None,uuid=None,address=target_device_address)
first_match = service_matches[0]
print("Port , Name , Host , Protocol ".format(first_match['port'], first_match['name'], first_match['host'], first_match['protocol']))

这就是我获取要连接的端口 (17) 及其使用的协议 (L2CAP) 的方式。

现在,我尝试使用以下方式连接到它:

client_sock = bt.BluetoothSocket(bt.L2CAP)
client_sock.connect((target_device_address,port))

我还使用了 Python 的原生 socket 库(产生了相同的结果):

client_sock = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_SEQPACKET, socket.BTPROTO_L2CAP)
client_sock.connect((target_device_address,port))

根据hcitool连接成功,然后等待用户输入:

if target_device_address in (subprocess.getoutput("hcitool con")).split():
    print('connected')
    while True:
        data = client_sock.recv(1024)
        print(str(data))

问题

该设备实际上并未在/dev/input/ 中显示为输入。当我通过 GUI 手动连接它时,它显示为 /dev/input/event5。 连接后,我的脚本没有捕获任何输入。

我的问题

它如何根据hcitool con 进行连接但尚未注册为输入设备(并注册任何输入)? 您建议做什么?我到处寻找,似乎没有得到适当的解决方案。有一个workaround with implementing a bash script that uses bluetoothctl 可以连接到蓝牙遥控器,但我不明白为什么 Python 无法建立此连接并检索信息。

【问题讨论】:

【参考方案1】:

我的建议是不要使用 hcitool,因为它在 2017 年是 deprecated。

我更喜欢直接使用 BlueZ D-Bus API,该 API 记录在:https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc/device-api.txt

这可以在 Python 中使用 pydbus 库访问

我假设您的蓝牙适配器在 Jetson 上的 hci0 上,但您可以通过以下方式进行检查:

$ busctl tree org.bluez
└─/org
  └─/org/bluez
    └─/org/bluez/hci0

这将使代码类似于:

import pydbus

DEVICE_ADDR = '11:22:22:E7:CE:BE'

# DBus object paths
BLUEZ_SERVICE = 'org.bluez'
ADAPTER_PATH = '/org/bluez/hci0'
device_path = f"ADAPTER_PATH/dev_DEVICE_ADDR.upper().replace(':', '_')"

# setup dbus
bus = pydbus.SystemBus()
mngr = bus.get(BLUEZ_SERVICE, '/')
adapter = bus.get(BLUEZ_SERVICE, ADAPTER_PATH) 
device = bus.get(BLUEZ_SERVICE, device_path)

device.Connect()

这应该在/dev/input/ 创建事件,我将使用python 库evdev 来获取输入,就像在以下问题中所做的那样: https://***.com/a/54765300/7721752

【讨论】:

非常感谢!这正是我所需要的——这很有意义,因为我正在尝试实际连接到设备,而不是创建用于交换数据的套接字。需要注意的一件有趣的事情是,当我尝试使用之前拥有的设备地址连接到设备时,它实际上发生了变化。所以继续前进,我会使用PyBluez 搜索快门并获取设备地址,然后使用pydbus 连接到它。

以上是关于如何将基于 L2CAP 的蓝牙相机快门(AB 快门 3)连接到 Linux 并在 Python 中获取关键事件?的主要内容,如果未能解决你的问题,请参考以下文章

想要获得像在 iphone 中打开相机快门一样的动画

V6版如何关闭相机快门声音和截图声音

如何在安卓手机上静音相机快门声音

如何减少 Android 相机快门延迟的可变性?

需要访问 iPhone 使用的默认相机快门声音

android静音相机快门声音?