gvalkov / python-evdev Goto Github PK
View Code? Open in Web Editor NEWPython bindings for the Linux input subsystem
Home Page: https://python-evdev.rtfd.org/
License: BSD 3-Clause "New" or "Revised" License
Python bindings for the Linux input subsystem
Home Page: https://python-evdev.rtfd.org/
License: BSD 3-Clause "New" or "Revised" License
Hi,
I have a question about your code sample from this issue:
link
This is source code:
dev = InputDevice(...)
dev.grab()
for ev in dev.read_loop():
if ev.code not in (KEY_LEFTCTRL, KEY_RIGHTCTRL, KEY_Q):
ui.write_event(ev)
continue
# lots of messy checks for when Q is pressed/depressed while a
# Ctrl key is pressed (ev.value == 1)
The LED indicators don't work when device is grabbed and events are resended by ui.write_event
function. Is it possible to fix the LEDs work?
Hi,
I'm trying to read out the axis of a "Logitech Cordless RumblePad 2", not without trouble however...
I am able to read out the events coming from the device with .read_loop() (events_get in the sample code) and from read_one. But I am unable to to read from the read() buffer (get_axis_pos in example).
I'm using Ubuntu 14.04.2 LTS
Dumbed down the code I am using looks like this:
import evdev
import logging
controller_name = "Logitech Logitech Cordless RumblePad 2"
logging.basicConfig(level=logging.DEBUG, format="[%(asctime)s] %(threadName)s %(message)s", datefmt="%H:%M:%S")
logging.info("Controller output script started")
def main():
controller = ControllerInput(controller_name)
while True:
controller.get_axis_pos()
class ControllerInput():
def __init__(self, controller_name):
devices = [evdev.InputDevice(fn) for fn in evdev.list_devices()]
logging.debug("Found devices: " + str(len(devices)))
dev_location = None
for dev in devices:
if dev.name == controller_name:
dev_location = dev.fn
logging.debug("Found desired device: " + dev.name + " at: " + dev.fn)
break
if dev_location is None:
raise "Device not found!"
self.dev_obj = evdev.InputDevice(dev_location)
self.axispos = [128, 128, 128, 128] #left x,y |right x,y
def events_get(self):
for event in self.dev_obj.read_loop():
if event.type != 0:
print(event)
def get_axis_pos(self):
event_gen = self.dev_obj.read()
if event_gen is not None:
for event in event_gen:
if event.type == 3:
if event.code == 0: #0: left x axis |1: left y axis
self.axispos[0] = event.value
elif event.code == 1:
self.axispos[1] = event.value
elif event.code == 2: #2: right x axis |5: right y axis
self.axispos[2] = event.value
elif event.code == 5:
self.axispos[3] = event.value
logging.debug("Controller axis: " + str(self.axispos[0]))
if __name__ == "__main__":
main()
The error I get when running this code is:
[16:34:26] MainThread Controller output script started
[16:34:26] MainThread Found devices: 1
[16:34:26] MainThread Found desired device: Logitech Logitech Cordless RumblePad 2 at: /dev/input/event13
Traceback (most recent call last):
File "/media/philip/2.3.1-18-amd64/Projects/pycharm/quadcopter/controller.py", line 139, in <module>
main()
File "/media/philip/2.3.1-18-amd64/Projects/pycharm/quadcopter/controller.py", line 48, in main
controller.get_axis_pos()
File "/media/philip/2.3.1-18-amd64/Projects/pycharm/quadcopter/controller.py", line 125, in get_axis_pos
for event in event_gen:
File "/usr/lib/python3/dist-packages/evdev/device.py", line 246, in read
events = _input.device_read_many(self.fd)
BlockingIOError: [Errno 11] Resource temporarily unavailable
Regards Avraamu
Using updated Raspbian Jessie with all the dependencies installed, now when I try to install with pip (or pip3)
sudo pip install evdev
Then when building 'evdev._ecodes' extension I get the following error:
In file included from /usr/include/python2.7/Python.h:126:0, from evdev/ecodes.c:2: evdev/ecodes.c: In function ‘moduleinit’: evdev/ecodes.c:69:29: error: ‘BUS_RMI’ undeclared (first use in this function) PyModule_AddIntMacro(m, BUS_RMI);
Thanks in advance!
im using InputDevice in a loop to poll for a device to get online.
im not keeping the reference to the InputDevice, so it should be subject to the garbage collection. But still, the open file descriptors are increasing until i hit the max open file limit.
i have to call the .close() function of the InputDevice manually for proper closing.
this can be observed in the first example:
>>> from evdev import InputDevice, list_devices
>>> devices = map(InputDevice, list_devices())
>>> for dev in devices:
print( '%-20s %-32s %s' % (dev.fn, dev.name, dev.phys) )
if you then ls -la /proc/PID/fd you can see all the handles still open, even if the for dev in devices loop were in a already finished function and no references are left.
if this is not a bug and cannot be done better, the .close() should be at least added the the samples.
When using UInput.from_device()
to merge the capabilities of several devices, the resulting capabilities of the uinput device are not the full list of those in the source devices.
Since for each ev_type in dev.capabilities()
we have a list of ev_codes, if two devices have same ev_type but differente ev_codes, the update method on uinput.py
replaces the previous list with the last ones:
all_capabilities = {}
for dev in device_instances:
all_capabilities.update(dev.capabilities())
To correctly merge capabilities of several devices we should do something like this to extend the lists instead of replacing them:
all_capabilities = defaultdict(list)
for dev in device_instances:
dev_caps = dev.capabilities()
for ev_type, ev_codes in dev_caps.iteritems():
all_capabilities[ev_type].extend(ev_codes)
all_capabilities[ev_type] = list(set(all_capabilities[ev_type])) # removes duplicate ev_codes
The last line could be avoided if instead of lists we had sets for device capabilities, which would automatically avoid duplicate ev_codes, but that might be a bigger API change, I think.
I could do a pull request if you find it appropriate
Hi,
For a linux embed project, we need to detect long press on a keys. Is it possible from scratch in evedv?
If not, how would you manage it?
Kind regards
import evdev
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "evdev/__init__.py", line 7, in <module>
from evdev.device import DeviceInfo, InputDevice, AbsInfo
File "evdev/device.py", line 8, in <module>
from evdev import _input, _uinput, ecodes, util
File "evdev/ecodes.py", line 42, in <module>
from evdev import _ecodes
ImportError: cannot import name _ecodes
append to man notify about correct global enviroment variable PYTHON_PATH="/usr/local/lib/python2.7/"
I'm wondering how to break wait for event loop if some time is gonna pass by. Dont know how to do this in evdev
Hi:
I am trying to install python-evdev on my arduino yun using "./setup.py install". I get the following error: Any suggestion will be appreciated (bear in mind that I am a newbie).
./setup.py install
running install
running bdist_egg
writing ecodes.c (using /usr/include/linux/input.h)
running egg_info
writing evdev.egg-info/PKG-INFO
writing top-level names to evdev.egg-info/top_level.txt
writing dependency_links to evdev.egg-info/dependency_links.txt
reading manifest file 'evdev.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
writing manifest file 'evdev.egg-info/SOURCES.txt'
installing library code to build/bdist.linux-mips/egg
running install_lib
running build_py
running build_ext
building 'evdev._input' extension
mips-openwrt-linux-uclibc-gcc -fno-strict-aliasing -Os -pipe -mips32r2
-mtune=mips32r2 -fno-caller-saves -fhonour-copts -Wno-error=unused-but-set-variable -msoft-float -DNDEBUG -Os -pipe -mips32r2 -mtune=mips32r2 -fno-caller-saves -fhonour-copts -Wno-error=unused-but-set-variable -msoft-float -fPIC -I/usr/include/python2.7 -c evdev/input.c -o build/temp.linux-mips-2.7/evdev/input.o -std=c99 -Wno-error=declaration-after-statement
cc1: error: unrecognized command line option '-fhonour-copts'
cc1: error: unrecognized command line option '-fhonour-copts'
error: command 'mips-openwrt-linux-uclibc-gcc' failed with exit status 1
root@Arduino:/mnt/sda1/python-evdev-0.4.7# cc1: error: unrecognized command
line option '-fhonour-copts'
-ash: cc1:: not found
root@Arduino:/mnt/sda1/python-evdev-0.4.7# cc1: error: unrecognized command line option '-fhonour-copts'
-ash: cc1:: not found
It seems the code has changed to rename AbsData -> AbsInfo, but the documentation does not reflect that change.
When deallocating InputDevice objects the memory is not restored.
This problem was spotted because a problematic USB bus resets randomly. The code needed to workaround this fact, creates a new InputDevice on demand. The memory is allways increasing. Try this to watch:
for i in xrange(10000):
a = InputDevice(path)
a.close()
I looked at the C code and it seems that the ref count calls see this article are missing and thus the memory is not released. This is just a guess - no experience with python C extensions...
Hello @gvalkov, recently there was a new board called Linkit smart 7688, which is a cheap IoT board. I was trying to use this board to build an bluetooth keyboard adapter, and just like Arduino Yun, it uses openwrt as the OS.
As I was trying to use this awesome plugin, the installation was failed due to missing linux kernel header files. Then I found there is another evdev for Arduino Yun, I downloaded and run opkg install to install that package, it popped error messages, saying that "incompatible with the architectures configured".
Can you give some me advise? Thank you!
spec of Linkit smart 7688:
MIPS CPU
When i trying inject event as described in tutorial, i receiving following error:
from evdev import UInput, ecodes as e
ui = UInput()
ui.write(e.EV_KEY, e.KEY_A, 1)
ui.write(e.EV_KEY, e.KEY_A, 0)
ui.syn()
# for this point everything works ok, i can see "a" symbol input in console
ui.close()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "evdev/uinput.py", line 115, in close
self.device.close()
AttributeError: 'NoneType' object has no attribute 'close'
It would be nice to have PEP-484 typehints for all functions and methods to make it easier to write correct code using python-evdev.
Using Gentoo's gentoo-sources-4.4.0, python-evdev generates from a input.h which causes it to fail on input:
Python 2.7.11 (default, Jan 21 2016, 21:00:40)
[GCC 5.3.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
from evdev import UInput, UInputError, ecodes
Traceback (most recent call last):
File "", line 1, in
File "/usr/lib64/python2.7/site-packages/evdev/init.py", line 5, in
from evdev.device import DeviceInfo, InputDevice, AbsInfo
File "/usr/lib64/python2.7/site-packages/evdev/device.py", line 7, in
from evdev import _input, _uinput, ecodes, util
File "/usr/lib64/python2.7/site-packages/evdev/ecodes.py", line 75, in
keys.update(BTN)
NameError: name 'BTN' is not defined
This affects at least python-evdev 0.4.5 and 0.5.0 and can be fixed by downgrading both the kernel and sys-kernel/linux-headers to version 4.3, then rebuilding python-evdev.
Hello,
I've started working on a project that reads from a remote control and sends the input to another child process. I could try to find out the key mapping by trial and error, but I hoped I could find something ready to do this.
Unfortunately evdev doesn't seem to help much with it, only shows keycodes e.g. KEY_UP = 103, that can only be redirected system wide (using UInput.write()), but does not map to convert the keycode to the corresponding ascii character sequence ("\027[A") or allow to redirect the input to a user process
Do you know a way to see this mapping?
Regards, Mauro
Currently InputDevice wants to open the device os.RDWR
(code) but there's good reason to be able to open a device os.RDONLY
, either if there's no intention to modify anything or there's not sufficient permissions.
Making a custom derived class with changed __init__
seems to work but I think it could very well be included in the library:
from evdev import InputDevice, _input, DeviceInfo
import os
class ReadInputDevice(InputDevice):
def __init__(self, dev):
'''
:param dev: path to input device
'''
#: Path to input device.
self.fn = dev
#: A non-blocking file descriptor to the device file.
self.fd = os.open(dev, os.O_RDONLY | os.O_NONBLOCK)
# Returns (bustype, vendor, product, version, name, phys, capabilities).
info_res = _input.ioctl_devinfo(self.fd)
#: A :class:`DeviceInfo <evdev.device.DeviceInfo>` instance.
self.info = DeviceInfo(*info_res[:4])
#: The name of the event device.
self.name = info_res[4]
#: The physical topology of the device.
self.phys = info_res[5]
#: The evdev protocol version.
self.version = _input.ioctl_EVIOCGVERSION(self.fd)
#: The raw dictionary of device capabilities - see `:func:capabilities()`.
self._rawcapabilities = _input.ioctl_capabilities(self.fd)
#: The number of force feedback effects the device can keep in its memory.
self.ff_effects_count = _input.ioctl_EVIOCGEFFECTS(self.fd)
Hi,
How would I determine what key codes to fire off to generate a specific character?
(For instance to generate a '~' there is ecodes.KEY_GRAVE, but I don't see something like ecodes.COLON (for ':').)
So on my desktop I use a combination of KEY_LEFTSHIFT + KEY_SEMICOLON to generate a colon (:).
How would I determine the correct sequence of events on a particular platform/keyboard layout?
Oh also this is using UInput.
There's a typo on the documentation of util.resolve_ecodes:
https://github.com/gvalkov/python-evdev/blob/master/evdev/util.py#L70
resoLve_ecodes
Possibly linked to the change for issue #5 the msg string defined in the str method of DeviceInfo (currently line 71 of device.py) needs to swap the vendor and product names.
from lsusb -v:
Bus 001 Device 004: ID 08ff:0009 AuthenTec, Inc.
idVendor 0x08ff AuthenTec, Inc.
idProduct 0x0009
from print str(dev.info):
bus: 0003, product 08ff, vendor 0009, version 0110
I'm using UInput to connect a device with leds and a buzzer (EV_LED and EV_SND)
Python-evdev should support a read()
operation that lets me set those.
I get a KeyError when using evtest.py and a PS4 controller. The same error occurs in both Python2 and 3.
File "/usr/local/lib/python3.5/dist-packages/evdev/evtest.py", line 183, in <module>
ret = main()
File "/usr/local/lib/python3.5/dist-packages/evdev/evtest.py", line 79, in main
print_event(event)
File "/usr/local/lib/python3.5/dist-packages/evdev/evtest.py", line 164, in print_event
codename = ecodes.bytype[e.type][e.code]
KeyError: 45
The way I had to worked around it is by checking that e.code is in ecodes.bytype[e.type]
Bob
I will look more into it but here is what I have figured out so far:
I am not sure if this a problem with this package or with evdev, but X uses the same API right? Anyway I will try to figure it out but please let me know If you have any ideas about what is happening.
If the build host kernel/linux-headers package provides the same headers as the embedded toolchain/sysroot, then all is fine. As soon as they diverge, it blows up. Since both setup.py and genecodes.py have the full path hardcoded, I made this patch for openembedded/yocto:
In the above patch, STAGING_INCDIR is specific to the bitbake build environment, and I didn't want to try mind-reading (since that never works anyway) so what ideas might you have for a generic fix? Something like adding a (normally empty) SYSROOT var in front of the header path (sort of like DESTDIR) might be enough.
Basically a way to configure the header path with a local prefix.
Unable to create a UInput device from an xbox 360 controller due to the EV_FF capability.
Similar to #60 but the EV_FF capability needs to be filtered out as well as EV_SYN
I'm working on a project that needs to do certain things on specific keypresses.
To do this I'm using a loop to check the value of the pressed key and do something accordingly. The problem I'm having is that the while loop is interrupted whenever I'm using the getKey() function, so the rest of the loop only runs once after each keypress.
I'm probably doing something very basic horribly wrong as I've just started out with python recently. A push in the right direction would be of great help!
from evdev import InputDevice, list_devices, categorize, ecodes
dev = InputDevice('/dev/input/event0')
def getKey():
for event in dev.read_loop():
if event.type == ecodes.EV_KEY:
keybrd = categorize(event)
if keybrd.keystate == keybrd.key_down:
c = keybrd.keycode
return c
c = ''
while 42:
c = getKey()
print 'expected to be looping'
if c == 'KEY_Z':
print 'dosomething'
if c == 'KEY_Q':
print 'dosomethingelse'
runSomeOtherFunctionThatNeedsToBeLooped()
Hi!
I'm try send vibration to Xbox 360 controller with python. Do you have example of sending vibroeffect with evdev?
I am trying to do a mouse button click when I receive some input from serial in Raspberry Pi. When done in a shell with just evdev, it works, but when done inside a loop that monitors the serial, it does not work. It gives no error or any message in the shell. The same code works in a laptop though.
Is is an issue with the Raspberry Pi (ArchLinuxARM) or some issue inside python-evdev?
Hello!
I just bought a "retro" gamepad, with 8 buttons and a directional pad (d-pad).
Buttons are detected and can be separated (though ecodes are a bit strange — but this isn't an issue).
D-pad on the contrary seems to be a bit harder to understand…
Here's a print of caught events:
# UP
event at 1380042926.679244, code 01, type 03, val 00
event at 1380042926.679262, code 00, type 00, val 00
event at 1380042926.767252, code 01, type 03, val 127
event at 1380042926.767270, code 00, type 00, val 00
# RIGHT
event at 1380042927.919373, code 00, type 03, val 255
event at 1380042927.919392, code 00, type 00, val 00
event at 1380042927.983368, code 00, type 03, val 127
event at 1380042927.983387, code 00, type 00, val 00
# BOTTOM
event at 1380042929.063476, code 01, type 03, val 255
event at 1380042929.063495, code 00, type 00, val 00
event at 1380042929.111483, code 01, type 03, val 127
event at 1380042929.111500, code 00, type 00, val 00
# LEFT
event at 1380042930.175583, code 00, type 03, val 00
event at 1380042930.175603, code 00, type 00, val 00
event at 1380042930.263594, code 00, type 03, val 127
event at 1380042930.263612, code 00, type 00, val 00
Any advice on how to use those values ? Each press-release seems to do four events, as you can see -.-'.
Thank you for your time!
Cheers,
C.
I am using evdev to catch keyboard events like LCtrl + C + C. I want to grab the device as LCtrl is pressed (event.code = 29, event.value = 1) and ungrab it when Ctrl is released (event.code = 29, event.value = 0) to guarantee that the regular shortcut is not triggered.
The problem is, after the keyboard is ungrabbed on LCtrl release, the system behaves as if LCtrl were still held down, so if I hit C (after LCtrl is released and the device is ungrabbed), it is interpreted as LCtrl + C.
Example code:
from evdev import InputDevice, ecodes
dev = InputDevice('/dev/input/event0') # Or whatever the keyboard device is
for event in dev.read_loop():
if (event.type == ecodes.EV_KEY):
if ((event.code, event.value) == (29, 1)):
dev.grab()
print ('Grab')
elif ((event.code, event.value) == (29, 0)):
dev.ungrab()
print('Ungrab')
Just run it in terminal (I assume you're on Linux), press and release LCtrl, then press C, and see that the script is interrupted, as if you pressed Ctrl+C.
If the documentation etc doesn't say which version of what it depends on eg python etc it would be nice if it did. BTW I haven't looked through everything yet to check. I'd also say I tried the pip install from the web site documentation and discovered that you have to be root to make it work, maybe obvious but why not indicate it; hardly difficult to put a '#' in front of each command.
I am trying to move the mouse visually on screen for an automation tool that I am working on, it seems the mouse pointer does not move with ecodes.EV_REL. I am working on Ubuntu and I tried on both X11 and Mir display server. python-uinput seems to be working fine though, but our project heavily uses python-evdev so we need to keep using it. Below is the code that reproduces the issue.
from time import sleep
from evdev import UInput, ecodes
ui = UInput()
for i in range(20):
ui.write(ecodes.EV_REL, ecodes.REL_X, 5)
ui.write(ecodes.EV_REL, ecodes.REL_Y, 5)
ui.syn()
sleep(0.01)
That codes does run without errors but it does not do anything, OTH, mouse click events do work.
Hello,
In setup.py and gencodes.py, locations of input.h
and input-event-codes.h
are hardcoded. It seems problematic for cross-compiling.
Example: I use buildroot and try to integrate python-evdev in my local buildroot repo. During the cross-compilation of python-evdev, gencodes.py
parses theses two headers files in order to generate a encode.c
. Then the compiler try to compile with the target header files which are located in the buildroot path.
I temporarily changed theses hardocded values to point on my buildroot local repository, but it's ugly and couldn't be automatized.
First of all, thanks for your great work! :-)
Using the code provided in "Specifying uinput device options" raises an error (using Python2.7, python-evdev 0.4.5, Ubuntu 14.04) :
cap = { ecodes.EV_KEY : [ecodes.KEY_A, ecodes.KEY_B], ecodes.EV_ABS : [ (ecodes.ABS_X, AbsInfo(min=0, max=255, fuzz=0, flat=0)), (ecodes.ABS_Y, AbsInfo(0, 255, 0, 0)), (ecodes.ABS_MT_POSITION_X, (0, 255, 128, 0)) ] }
TypeError: __new__() takes exactly 7 arguments (5 given)
Probably because the constructor of AbsInfo changed somehow? I can see how a new parameter called "resolution" has been added, but I don't understand what is the 7th argument. Correcting the AbsInfo instances with:
AbsInfo(min=0, max=255, fuzz=0, flat=0, resolution=0)
raises the same error
TypeError: __new__() takes exactly 7 arguments (6 given)
Changing the line to:
AbsInfo(0, 255, 0, 0, 0, 0)
executes without errors, but (and this might be a separate issue) the virtual mouse does not move, albeit the EV_KEY events work.
a minor thing
regarding https://github.com/gvalkov/python-evdev/blob/master/doc/index.rst
is print(categorize(e))
should be print(categorize(event))
Some uses of uinput are not currently supported (for example, rumblers: #23, ff branch). Which, doesn't seem to be documented.
Adding to the documentation, a brief description of what is and isn't working, might help potential users anticipate whether python-evdev is appropriate for their intended use.
Here is a strawman draft:
All keyboard and mice events should work. Rumblers #23 currently do not work. Joysticks, touchpads, tablets, cameras, force feedback, and less common devices probably work / probably don't work / sometimes work / partially work / haven't been tested / are not supported.
Some characters, such as :
(colon), cannot easily be generated from scratch #7. Translating them into UInput events would require knowing the kernel keyboard translation table, and there is no python equivalent of dumpkeys
. Consider using PyUserInput instead.
Related projects include: python-uinput; uinput-mapper; PyUserInput; pygame.
Is it possible to ignore/disregard events?
I'm trying to re-map certain keypresses. For example, ctrl-q would become crtl-c.
Your documentation shows how I can easily watch for the keypress and then fire a new keypress event (this is very clear, thanks). However, I don't know how to ignore the first keypress event.
Thanks very much for this library.
line 14 on util.py reads:
fns = glob.glob('{}/event*'.format(input_device_dir))
to work (on python 2.6) it has to read:
fns = glob.glob('{0}/event*'.format(input_device_dir))
If you run the first tutorial example with the current util.py line 14 you get:
>>> devices = map(InputDevice, list_devices())
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python2.6/dist-packages/evdev/util.py", line 14, in list_devices
fns = glob.glob('{}/event*'.format(input_device_dir))
ValueError: zero length field name in format
If you run the modified line 14 you get:
>>> fns = glob.glob('{0}/event*'.format('/dev/input'))
>>> print fns
['/dev/input/event6', '/dev/input/event5', '/dev/input/event4', '/dev/input/event3', '/dev/input/event2', '/dev/input/event1', '/dev/input/event0']
Hope that helps
The docstring of the InputDevice.read()
method says:
Raises
BlockingIOError
if there are no available events at the moment.
BlockingIOError
has become a built-in exception in Python 3. What does it raise in Python 2? IOError
? io.BlockingIOError
(available since Python 2.6)?
That information should be part of the docstring, too.
I'm trying to mirror a gamepad with code below.
from evdev import InputDevice, UInput, AbsInfo, ecodes as e
cap = {
e.EV_MSC : [e.MSC_SCAN],
e.EV_KEY : [e.BTN_A, e.BTN_B, e.BTN_C, e.BTN_X, e.BTN_Y, e.BTN_Z, e.BTN_TL, e.BTN_TR, e.BTN_TL2],
e.EV_ABS : [(e.ABS_X, AbsInfo(value=128, min=0, max=255, fuzz=0, flat=15, resolution=0)), (e.ABS_Y, AbsInfo(value=128, min=0, max=255, fuzz=0, flat=15, resolution=0))]
}
dev_real = InputDevice('/dev/input/event20')
dev_virt = UInput(cap, name='Cypress Virtual')
for event in dev_real.read_loop():
dev_virt.write_event(event)
Above code keeps getting the error below.
Traceback (most recent call last):
File "pytest.py", line 10, in <module>
dev_virt = UInput(cap, name='Cypress Virtual')
File "/usr/lib/python3.5/site-packages/evdev/uinput.py", line 83, in __init__
_uinput.create(self.fd, name, vendor, product, version, bustype, absinfo)
OSError: [Errno 22] Invalid argument
But when I change the value=128 to value=0 for both AbsInfo()'s. it runs without an error.
Printing the uinput device capabilities with evtest.py reveals this:
Type EV_ABS 3:
Code ABS_X 0:
val 139, min 0, max 0, fuzz 255, flat 0, res 0
Code ABS_Y 1:
val 101, min 0, max 0, fuzz 255, flat 0, res 0
Any help would be appreciated.
Thanks
Howdy,
I currently write a screenreader deamon for linux.
for this i need to "consume" the shortcuts for the screenreader because there should no other programm react to it. so i need to grab the InputDevices -> Check ist the keypress for me? No -> write it back to the "normal" input line for other programms.
so i try to generate a UInput class per InputDevice and i like to have the same capabilities (because later i just forewart the input)
If i define the UInput variable with (see example):
uDevices[fd] = UInput( dev.capabilities())
i get the following error:
Traceback (most recent call last): File "<stdin>", line 7, in <module> File "/usr/lib/python3.5/site-packages/evdev/uinput.py", line 104, in __init__ _uinput.enable(self.fd, etype, code) OSError: [Errno 22] Invalid argument
if i try something more simple it works:
from evdev import UInput, AbsInfo, ecodes as e t = UInput({ e.EV_KEY : [e.KEY_A, e.KEY_B]})
so somehow it seems that it is not able to parse.
Did i something wrong? can I got this working somehow? is this maybe a bug?
the following example code gives me the error:
import evdev
from evdev import InputDevice, UInput
from select import select
import time
iDevices = map(evdev.InputDevice, (evdev.list_devices()))
iDevices = {dev.fd: dev for dev in iDevices if dev.fn in ['/dev/input/event14']} # event14 is in my example a keyboard
uDevices = {}
for fd in iDevices:
dev = iDevices[fd]
print(dev.capabilities(verbose=True))
print('-----------')
print(dev.capabilities(verbose=False))
print('-----------')
uDevices[fd] = UInput( dev.capabilities())
the prints give me the following:
{('EV_MSC', 4): [('MSC_SCAN', 4)], ('EV_SYN', 0): [('SYN_REPORT', 0), ('SYN_CONFIG', 1), ('?', 4), ('?', 17), ('?', 20)], ('EV_KEY', 1): [('KEY_ESC', 1), ('KEY_1', 2), ('KEY_2', 3), ('KEY_3', 4), ('KEY_4', 5), ('KEY_5', 6), ('KEY_6', 7), ('KEY_7', 8), ('KEY_8', 9), ('KEY_9', 10), ('KEY_0', 11), ('KEY_MINUS', 12), ('KEY_EQUAL', 13), ('KEY_BACKSPACE', 14), ('KEY_TAB', 15), ('KEY_Q', 16), ('KEY_W', 17), ('KEY_E', 18), ('KEY_R', 19), ('KEY_T', 20), ('KEY_Y', 21), ('KEY_U', 22), ('KEY_I', 23), ('KEY_O', 24), ('KEY_P', 25), ('KEY_LEFTBRACE', 26), ('KEY_RIGHTBRACE', 27), ('KEY_ENTER', 28), ('KEY_LEFTCTRL', 29), ('KEY_A', 30), ('KEY_S', 31), ('KEY_D', 32), ('KEY_F', 33), ('KEY_G', 34), ('KEY_H', 35), ('KEY_J', 36), ('KEY_K', 37), ('KEY_L', 38), ('KEY_SEMICOLON', 39), ('KEY_APOSTROPHE', 40), ('KEY_GRAVE', 41), ('KEY_LEFTSHIFT', 42), ('KEY_BACKSLASH', 43), ('KEY_Z', 44), ('KEY_X', 45), ('KEY_C', 46), ('KEY_V', 47), ('KEY_B', 48), ('KEY_N', 49), ('KEY_M', 50), ('KEY_COMMA', 51), ('KEY_DOT', 52), ('KEY_SLASH', 53), ('KEY_RIGHTSHIFT', 54), ('KEY_KPASTERISK', 55), ('KEY_LEFTALT', 56), ('KEY_SPACE', 57), ('KEY_CAPSLOCK', 58), ('KEY_F1', 59), ('KEY_F2', 60), ('KEY_F3', 61), ('KEY_F4', 62), ('KEY_F5', 63), ('KEY_F6', 64), ('KEY_F7', 65), ('KEY_F8', 66), ('KEY_F9', 67), ('KEY_F10', 68), ('KEY_NUMLOCK', 69), ('KEY_SCROLLLOCK', 70), ('KEY_KP7', 71), ('KEY_KP8', 72), ('KEY_KP9', 73), ('KEY_KPMINUS', 74), ('KEY_KP4', 75), ('KEY_KP5', 76), ('KEY_KP6', 77), ('KEY_KPPLUS', 78), ('KEY_KP1', 79), ('KEY_KP2', 80), ('KEY_KP3', 81), ('KEY_KP0', 82), ('KEY_KPDOT', 83), ('KEY_ZENKAKUHANKAKU', 85), ('KEY_102ND', 86), ('KEY_F11', 87), ('KEY_F12', 88), ('KEY_RO', 89), ('KEY_KATAKANA', 90), ('KEY_HIRAGANA', 91), ('KEY_HENKAN', 92), ('KEY_KATAKANAHIRAGANA', 93), ('KEY_MUHENKAN', 94), ('KEY_KPJPCOMMA', 95), ('KEY_KPENTER', 96), ('KEY_RIGHTCTRL', 97), ('KEY_KPSLASH', 98), ('KEY_SYSRQ', 99), ('KEY_RIGHTALT', 100), ('KEY_HOME', 102), ('KEY_UP', 103), ('KEY_PAGEUP', 104), ('KEY_LEFT', 105), ('KEY_RIGHT', 106), ('KEY_END', 107), ('KEY_DOWN', 108), ('KEY_PAGEDOWN', 109), ('KEY_INSERT', 110), ('KEY_DELETE', 111), (['KEY_MIN_INTERESTING', 'KEY_MUTE'], 113), ('KEY_VOLUMEDOWN', 114), ('KEY_VOLUMEUP', 115), ('KEY_POWER', 116), ('KEY_KPEQUAL', 117), ('KEY_PAUSE', 119), ('KEY_KPCOMMA', 121), (['KEY_HANGEUL', 'KEY_HANGUEL'], 122), ('KEY_HANJA', 123), ('KEY_YEN', 124), ('KEY_LEFTMETA', 125), ('KEY_RIGHTMETA', 126), ('KEY_COMPOSE', 127), ('KEY_STOP', 128), ('KEY_AGAIN', 129), ('KEY_PROPS', 130), ('KEY_UNDO', 131), ('KEY_FRONT', 132), ('KEY_COPY', 133), ('KEY_OPEN', 134), ('KEY_PASTE', 135), ('KEY_FIND', 136), ('KEY_CUT', 137), ('KEY_HELP', 138), ('KEY_F13', 183), ('KEY_F14', 184), ('KEY_F15', 185), ('KEY_F16', 186), ('KEY_F17', 187), ('KEY_F18', 188), ('KEY_F19', 189), ('KEY_F20', 190), ('KEY_F21', 191), ('KEY_F22', 192), ('KEY_F23', 193), ('KEY_F24', 194), ('KEY_UNKNOWN', 240)], ('EV_LED', 17): [('LED_NUML', 0), ('LED_CAPSL', 1), ('LED_SCROLLL', 2), ('LED_COMPOSE', 3), ('LED_KANA', 4)]}
-----------
{0: [0, 1, 4, 17, 20], 1: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 113, 114, 115, 116, 117, 119, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 240], 4: [4], 17: [0, 1, 2, 3, 4]}
-----------
Line 217 should be (under python 2.6):
return '{0!r}'.format(msg)
Not:
return '{}({!r})'.format(msg)
Is this valid syntax anyway, use of (), since {0}({!r}) doesn't work!
Having made my changes tutorial 1 now works under python 2.6
Hi gvalkov,
I am using python-evdev on a project (spacemouse-py) to get rid of calls to a c library and so far I am really pleased with python-evdev.
With that out of the way; I am using python-evdev 0.4.2 on python 3.3.3 and 2.7.6 and am getting this error writing to ipython/the terminal:
On python2:
Exception OSError: (19, 'No such device') in <bound method InputDevice.__del__ of InputDevice(u'/dev/input/event3')> ignored
And on python3:
Exception OSError: OSError(9, 'Bad file descriptor') in <bound method InputDevice.__del__ of InputDevice('/dev/input/event3')> ignored
anytime an InputDevice is deleted or completely unreferenced.
The problem according to the python documentation:
Warning : Due to the precarious circumstances under which del() methods are invoked, exceptions that occur during their execution are ignored, and a warning is printed to sys.stderr instead. Also, when del() is invoked in response to a module being deleted (e.g., when execution of the program is done), other globals referenced by the del() method may already have been deleted or in the process of being torn down (e.g. the import machinery shutting down). For this reason, del() methods should do the absolute minimum needed to maintain external invariants. Starting with version 1.5, Python guarantees that globals whose name begins with a single underscore are deleted from their module before other globals are deleted; if no other references to such globals exist, this may help in assuring that imported modules are still available at the time when the del() method is called.
Which means any exceptions raised in a del method will not be propagated but instead will be printed as a message to stderr.
My use case is that a device is disconnected while I still have an open connection to it. The device node will be removed and calling close on the still open file descriptor will generate this error.
The solution would be to just ignore this specific error by using an try: except: block in the del method.
Any thoughts on the matter would be appreciated.
Serialization might be a good topic for the tutorial, or for a simple examples/uinput-serialize.py.
For inspiration, there is https://github.com/MerlijnWajer/uinput-mapper , which can send pickled device capabilities and events between machines. input-read /dev/input/event1 | ssh somewhere input-create
>>> import evdev
>>> e = evdev.InputDevice(evdev.list_devices()[0])
>>> e2 = evdev.InputDevice(evdev.list_devices()[0])
>>> e == e2
True
>>> e != e2
True
File "setup.py", line 85, in create_ecodes
print('writing ecodes.c (using {})'.format(header))
cwd='{}/evdev'.format(here),
ValueError: zero length field name in format
for corrent this issue:
diff --git a/setup.py b/setup.py
index d5dc724..58db7e7 100755
--- a/setup.py
+++ b/setup.py
@@ -82,9 +82,9 @@ def create_ecodes():
from subprocess import check_call
cwd='{}/evdev'.format(here),
cwd='{0}/evdev'.format(here),
shell=True)
Hi,
I have a USB device which sometimes disappears unexpectedly for a few ms and I'm trying to handle this cleanly in application-level code -- similar to issue #64, I get an OSError back from a read call, and need to respond by closing and waiting to reopen the device.
I'm using async_read_one()
. Unfortunately when the underlying (synchronous) read_one()
call raises an exception, the exception leaks out of the future into the event loop. The fix that worked for me is to catch it and attach it to the future:
def async_read_one(self):
future = asyncio.Future()
def read_next():
try:
future.set_result(self.read_one())
except Exception as ex:
future.set_exception(ex)
self._do_when_readable(read_next)
return future
Hi there. I'm trying to implement a little script which watches for a certain bluetooth button device to appear, then read events from it, and handle gracefully if it disappears.
I actually found your post on https://stackoverflow.com/questions/15944987/python-evdev-detect-device-unplugged/16500472#16500472 and I'm using that as an example.
However, the interesting thing is that when my bluetooth device goes to sleep, it appears that select() returns with descriptor in the read array. When I go and call read() or read_one() on the corresponding InputDevice I get:
Traceback (most recent call last):
File "key_controller.py", line 67, in <module>
event = dev.read_one()
File "/usr/local/lib/python2.7/dist-packages/evdev/eventio.py", line 54, in read_one
event = _input.device_read(self.fd)
IOError: [Errno 19] No such device
So interestingly, it seems that it takes a while for udev to actually tell me that the device is gone (so that I can tear down the fd in the selected set. I dealt with this by just doing an os.path.exists() on the devices' .fn field, which seems to work.
Not sure if this should be considered a bug or expected behavior, but given these devices can appear and disappear, it might be nice for the python evdev api to be able to handle that more gracefully somehow. I expected read_one() to return None in this case, and for there to maybe be some kind of other flag I could check to see if this InputDevice instance was still "valid".
On this page:
http://pythonhosted.org/evdev/apidoc.html#module-evdev.ecodes
evdev.ecodes.EV[evdev.EV_KEY]
'EV_KEY'
Should probably be:
evdev.ecodes.EV[evdev.ecodes.EV_KEY]
'EV_KEY'
(Hmm, I not sure how to escape the above triple greater-than characters.)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.