【问题标题】:pyudev: how to get the device's "friendly" name?pyudev:如何获得设备的“友好”名称?
【发布时间】:2017-04-25 01:06:41
【问题描述】:

我想提供一个/dev/DEVICE 路径作为输入,并将设备“人类友好”名称作为输出。

我成功地从ID_MODEL_ENC 获得了这个名字,就像在这个 sn-p 中一样:

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 获取游戏杆名称非常简单,但这里没有选择。

提前致谢。

【问题讨论】:

    标签: python linux udev pyudev


    【解决方案1】:

    我用我的控制器检查了由 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
    

    【讨论】:

    • 是的,我目前正在使用一种非常相似的方法。但仍在寻找一种pythonic方式谢谢! :-)
    • 对了,我目前使用的方式可以看这里:github.com/meleu/share/blob/master/…
    【解决方案2】:

    如果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 供应商和产品 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
    

    【讨论】:

    • 是的,输出非常好,正是我想要的。但在我的应用程序中,我使用 /dev/input/jsX 之类的名称作为操纵杆,而不是 /dev/input/eventXY。我会查看 evdev 文档,看看它是否接受我想要提供的输入。谢谢大佬!
    • 有没有办法让list_devices() 只列出操纵杆?
    • @meleu 我已经更新了我的答案以包括过滤设备的“a”方法
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-24
    • 1970-01-01
    • 2012-05-10
    • 2023-03-16
    • 2010-10-09
    相关资源
    最近更新 更多