Как подключить затвор камеры Bluetooth (AB Shutter 3) на основе L2CAP к Linux и получить ключевое событие в Python?

Цель

У меня есть кнопка Bluetooth для затвора камеры HITSLAM (которая является устройством AB Shutter 3, обычным пультом дистанционного управления камерой Bluetooth), которое я хочу подключить к моему NVIDIA Jetson Nano с помощью Bluetooth, чтобы я мог использовать ввод кнопки для некоторых задач.

Что я сделал

Я использую для подключения библиотеку 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/. Когда я подключаю его вручную через графический интерфейс, он отображается как /dev/input/event5.
  • После подключения мой скрипт не вводит никаких данных.

Мои вопросы

  • Как он подключается в соответствии с hcitool con, но не регистрируется как устройство ввода (и регистрирует любые входы)?
  • Что вы предлагаете делать? Я искал везде и, похоже, не нашел правильного решения. Существует обходной путь с реализацией bash. скрипт, который использует bluetoothctl для подключения к пульту дистанционного управления Bluetooth, но для меня просто не имеет смысла, почему Python не может установить это соединение и получить информацию.

person codeabiswas    schedule 26.02.2021    source источник


Ответы (1)


Я бы рекомендовал не использовать hcitool, поскольку это было еще в 2017 году.

Я предпочитаю напрямую использовать BlueZ D-Bus API, который задокументирован по адресу: https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc/device-api.txt.

Доступ к нему можно получить в Python с помощью библиотеки pydbus.

Я предполагаю, что ваш адаптер Bluetooth включен hci0 на Jetson, но вы можете проверить это с помощью:

$ 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://stackoverflow.com/a/54765300/7721752

person ukBaz    schedule 26.02.2021
comment
Большое спасибо! Это именно то, что мне было нужно - это имеет смысл, потому что я пытаюсь подключиться к устройству, а не создавать сокет для обмена данными. Следует отметить одну интересную вещь: когда я пытался подключиться к устройству, используя адрес устройства, который у меня был ранее, он фактически изменился. Поэтому, двигаясь вперед, я бы использовал PyBluez для поиска затвора и получения адреса устройства, а затем использовал бы pydbus для подключения к нему. - person codeabiswas; 26.02.2021