Using evdev in the background/in crontab
This issue may or may not be related to evdev itself, if not please excuse my ignorance. I guess it could also be related to permissions.
I am attempting to use evdev to read button input on a NVIDIA Jetson TX2. When I run the script directly the terminal I get the desired output. When running in the background or in crontab the device.read_loop() causes the script to hang indefinetely or at least not print anything or even crash.
The script is given below:
import evdev
from evdev import ecodes
import sh
import time
DOWN = 1
print("Waiting 10 seconds for correct start up")
time.sleep(10)
print("Wait complete")
device = evdev.InputDevice("/dev/input/event3")
print(device)
# become the sole recipient of all incoming input events
device.grab()
for event in device.read_loop():
print(evdev.categorize(event))
if event.code == ecodes.KEY_POWER:
print "KEY_POWER", str(event.value)
if event.value == DOWN:
print "Sleeping before shutdown"
time.sleep(5)
#sh.shutdown("now")
elif event.code == ecodes.KEY_VOLUMEUP:
print "KEY_VOLUMEUP", str(event.value)
#device.ungrab()
The nvidia user has been added to the input group for permission to read events without root.
I run from crontab with: @reboot python /home/nvidia/testButton.py &> /home/nvidia/testButton.log
I run in the backgrorund with: python /home/nvidia/testButton.py &> /home/nvidia/testButton.log
I run normally as: python /home/nvidia/testButton.py
I'm coming across the same problem. Did you ever solve it?
Sorry about the latency. We had to solve it very fast and implemented a workaround solely to solve our use case of detecting a push and release using the read_one method. I have extracted our "solution" and attached it below.
We determine the InputDevice programmatically since we had some difficulties when specifying it statically.
import evdev
import time
import os
## Find the device ##
path = "/proc/bus/input/devices"
# Open the file and get
# the file descriptor associated
# with it using os.open() method
fd = os.open(path, os.O_RDONLY)
# Number of bytes to be read
n = 5000
# Read at most n bytes
# from file descriptor fd
# using os.read() method
readBytes = os.read(fd, n)
gpin = readBytes.find('gpio')
gpEV = readBytes.find('EV=',gpin)
gpevent = readBytes[gpEV+3]
# close the file descriptor
os.close(fd)
## Check the button ##
device = evdev.InputDevice(device+gpevent)
key = evdev.ecodes.KEY_VOLUMEUP
def check_button(value):
event = device.read_one()
retval = False
if event:
if event.code == key and event.value == value:
retval = True
return retval
def button_down():
return check_button(value=evdev.KeyEvent.key_down)
def button_up():
return check_button(value=evdev.KeyEvent.key_up)
delay = 0.01
while True:
if button_down():
print("Button down")
break
time.sleep(delay)
while True:
if button_up():
print("Button up")
break
time.sleep(delay)