pyudev:如何使设备的友好"名称?

时间:2017-04-25 01:06:42

标签: python linux udev pyudev

我想提供一个/dev/DEVICE路径作为输入,并获得设备"人性化"名称为输出。

我成功从ID_MODEL_ENC获取名称,就像在此片段中一样:

def dev_name(dev_path):
    from pyudev import Context
    for device in Context().list_devices(DEVNAME=dev_path):
        print device.get('ID_MODEL_ENC').decode('string_escape')

但它不能与蓝牙设备配合使用。似乎ID_MODEL_ENC没有被广泛使用。

在我的应用程序中,我只将其用于操纵杆,然后设备路径始终为/dev/input/js*

示例1:USB操纵杆是js0

$ dev_name.py /dev/input/js0
Twin USB Joystick

示例2:蓝牙操纵杆是js2

$ dev_name.py /dev/input/js2
Traceback (most recent call last):
  File "pyudev_get_js_name.py", line 9, in <module>
    dev_name(sys.argv[1])
  File "pyudev_get_js_name.py", line 7, in dev_name
    print '"'+ device.get('ID_MODEL_ENC').decode('string_escape') +'"'
AttributeError: 'NoneType' object has no attribute 'decode'

很明显,因为该设备没有ID_MODEL_ENC属性。

为了确保系统知道设备的名称,我们可以直接在shell提示符中执行此操作:

$ sys_dev_path="$(udevadm info --name=/dev/input/js2 | grep DEVPATH | cut -d= -f2)"
$ cat "/sys$(dirname $sys_dev_path)/name"
8Bitdo NES30 GamePad

我知道我可以用python做类似的东西并检查/sys/devices/.../name文件的内容,但它看起来像一个临时搭建。 有没有办法让pyudev给我操纵杆名称?

注意:我知道使用pygame获取操纵杆名称非常简单,但这不是一个选项。

提前致谢。

2 个答案:

答案 0 :(得分:0)

我用我的控制器检查了pyudev创建的设备对象,该对象的所有成员都没有描述性名称。据我所知,它也没有在文档中提到它。无论如何,这就是我实现名称功能的方式。就像你说的那样,我只是从名字文件中提取。

def get_devices():
    context = Context()
    ##devices = []
    #equivalent to "ls /dev/input | grep js"
    js_list = [d for d in os.listdir("/dev/input") if d.startswith("js")]
    for js in js_list:
        js_file = os.path.join("/dev/input", js)
        #different syntax to only get one item from Context()
        #.sys_path gives only the full system path
        js_path = Devices.from_device_file(context, js_file).sys_path
        #the name file should exist at this combined path
        name_path = os.path.join(js_path, "device", "name")
        #read the name from that file
        with open(name_path, "r") as buf:
            js_name = buf.read().strip()
        print("File: {}".format(js_path))
        print("Name: {}".format(js_name))
        ##devices.append(...)
    ##return devices

答案 1 :(得分:0)

如果pyudev未能满足您的要求,请尝试使用evdev

>>> from evdev import InputDevice,list_devices
>>> devices = [InputDevice(fn) for fn in list_devices()]
>>> for dev in devices:
...  print (dev.fn, dev.name)
... 
/dev/input/event12 HDA Intel PCH HDMI/DP,pcm=3
/dev/input/event11 HDA Intel PCH Front Headphone
/dev/input/event10 HDA Intel PCH Line Out
/dev/input/event9 HDA Intel PCH Rear Mic
/dev/input/event8 HDA Intel PCH Front Mic
/dev/input/event7 RDing FootSwitch3F1.
/dev/input/event6  USB OPTICAL MOUSE
/dev/input/event5 BTC USB Multimedia Keyboard
/dev/input/event4 BTC USB Multimedia Keyboard
/dev/input/event3 Video Bus
/dev/input/event2 Power Button
/dev/input/event1 Sleep Button
/dev/input/event0 Power Button

http://python-evdev.readthedocs.io/en/latest/

仅仅回答你关于操纵杆的评论,简单的答案并不是直接的,但是如果你能找到所有操纵杆都具有但没有别的东西的能力,那么可以用来过滤掉所有非操纵杆设备。 我有类似的要求,因为我只需要识别脚踏板装置。为此,我创建了一个文件,其中包含所有已知脚踏板的USB供应商和Procuct Id的列表。有了这个,我只需检查每个设备的dev.info.vendordev.info.product项,看看我是否有匹配。 为了允许拥有未知设备的人,如果我找不到匹配项,我会展示所有设备并要求他们识别他们的脚踏板(操纵杆),我只需将其附加到列表中并附加到/ lib / udev / rules。 d / 51-footswitch.rules文件。 这是检查代码:

devices = [InputDevice(fn) for fn in list_devices()]
for dev in devices:
    vendor = "%x" % dev.info.vendor
    vendor = vendor.zfill(4)
    product = "%x" % dev.info.product
    product = product.zfill(4)
    check_pedal_string = vendor+":"+product
    event_id = dev.fn
    if check_pedal_string in known_devices:
        found_hid = event_id
        break