Определение файлового дескриптора в python3 - для работы с pyudev / evdev - PullRequest
0 голосов
/ 05 мая 2018

В настоящее время я пытаюсь обнаружить соединение кнопки Bluetooth на Raspberry Pi 3 (эта часть работает) и после подключения определить, когда кнопка нажата (эта часть не работает).

Я начал с кода, предоставленного evdev, и попытался настроить его для моего использования (см. Ниже), но мне не удается создать правильный дескриптор файла для использования с select (если я правильно понял, что происходит).

import functools
import pyudev
import evdev
from select import select

context = pyudev.Context()
monitor = pyudev.Monitor.from_netlink(context)
monitor.filter_by(subsystem='bluetooth')
monitor.start()

fds = {monitor.fileno(): monitor}
finalizers = []

while True:
    r, w, x = select(fds, [], [])

    if monitor.fileno() in r:
        r.remove(monitor.fileno())
        for udev in iter(functools.partial(monitor.poll, 0), None):
            devices = [evdev.InputDevice(fn) for fn in evdev.list_devices()]
            for device in devices:
                if device.name.strip() == 'AB Shutter3':
                    if udev.action == u'add':
                        print('Device added: %s' % udev)
                        fds[dev.fd] = device #This here breaks. dev.fd undefined.
                        break
                    if udev.action == u'remove':
                        print('Device removed: %s' % udev)
                        def helper():
                            global fds
                            fds = {monitor.fileno(): monitor}
                        finalizers.append(helper)
                        break

    for fd in r:
        dev = fds[fd]
        for event in dev.read():
            print(event)


    for i in range(len(finalizers)):
        finalizers.pop()()

Проблема в том, что при попытке добавить устройство dev.fd не определяется. Я пытался определить это, но я понятия не имею, как определить дескриптор файла. Что мне делать?

Device added: Device('/sys/devices/platform/soc/3f201000.serial/tty/ttyAMA0/hci0/hci0:64')
Traceback (most recent call last):
  File "dev_status.py", line 27, in <module>
    fds = {dev.fd:device} #This here breaks. dev.fd undefined.
NameError: name 'dev' is not defined

Другая информация: Raspberry Pi 3 с Raspbian Strech & Python 3.5.3

Кроме того, это мой первый вопрос о переполнении стека, поэтому, если что-то отсутствует или может быть более подробным, не стесняйтесь упомянуть об этом.

Спасибо

Pom '

1 Ответ

0 голосов
/ 05 мая 2018

ОК, мне удалось найти решение. Вот оно, если это может кому-нибудь помочь.

#!/usr/bin/env python3

import functools
import pyudev
import evdev
from select import select

context = pyudev.Context()
monitor = pyudev.Monitor.from_netlink(context)
monitor.filter_by(subsystem='bluetooth')
monitor.start()


fds = {monitor.fileno(): monitor}
time = 0.0

udevices = context.list_devices(subsystem='bluetooth')
link_up = False
for udevice in udevices :
    if udevice.device_type == 'link' and udevice.is_initialized :
        link_up = True
        print('yiha')

evdevices = [evdev.InputDevice(fn) for fn in evdev.list_devices()]

if len(evdevices) > 0:
    for evdevice in evdevices:
        if evdevice.name.strip() == 'AB Shutter3' and link_up:
            print('Device existing: %s' % udevice)
            fds[evdevice.fileno()] = evdevice

while True:
    r, w, x = select(fds, [], [])

    if monitor.fileno() in r:
        for udevice in iter(functools.partial(monitor.poll, 0), None):
            evdevices = [evdev.InputDevice(fn) for fn in evdev.list_devices()]
            for evdevice in evdevices:
                if evdevice.name.strip() == 'AB Shutter3':
                    if udevice.action == u'add':
                        print('Device added: %s' % udevice)
                        fds[evdevice.fileno()] = evdevice
                        break
                    if udevice.action == u'remove':
                        print('Device removed: %s' % udevice)
                        fds.pop(evdevice.fileno(),None) 
                        break

    if evdevice.fileno() in r:
        dev = fds[evdevice.fileno()]
        for event in dev.read():
            if event.type == evdev.ecodes.EV_KEY:
                data = evdev.categorize(event)
                if data.keystate == 1 and data.event.timestamp() - time > 0.05 :
                    if data.scancode == 115:
                        print("Big button")
                    elif data.scancode == 28:
                        print("Small button")
                time = data.event.timestamp()

Я почти уверен, что через несколько месяцев посмотрю на это с ужасом, но на данный момент, это делает свою работу.

...