From 07c95598d18e7eacf128b3276bd4d2c8ec87b966 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Mon, 29 Aug 2016 22:18:04 +0100 Subject: [PATCH] Fix #289 Tweak the second keyboard robot recipe so it detects keyboards and doesn't throw exceptions on unknown keys. Also add a note to the recipe that it won't work over remote connections like SSH. --- docs/examples/robot_keyboard_2.py | 19 +++++++++++++++++-- docs/recipes.rst | 9 +++++++-- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/docs/examples/robot_keyboard_2.py b/docs/examples/robot_keyboard_2.py index e956338..2150f86 100644 --- a/docs/examples/robot_keyboard_2.py +++ b/docs/examples/robot_keyboard_2.py @@ -3,8 +3,23 @@ from evdev import InputDevice, list_devices, ecodes robot = Robot(left=(4, 14), right=(17, 18)) +# Get the list of available input devices devices = [InputDevice(device) for device in list_devices()] -keyboard = devices[0] # this may vary +# Filter out everything that's not a keyboard. Keyboards are defined as any +# device which has keys, and which specifically has keys 1..31 (roughly Esc, +# the numeric keys, the first row of QWERTY plus a few more) and which does +# *not* have key 0 (reserved) +must_have = {i for i in range(1, 32)} +must_not_have = {0} +devices = [ + device + for device in devices + for keys in (set(device.capabilities().get(ecodes.EV_KEY, [])),) + if must_have.issubset(keys) + and must_not_have.isdisjoint(keys) +] +# Pick the first keyboard +keyboard = devices[0] keypress_actions = { ecodes.KEY_UP: robot.forward, @@ -14,7 +29,7 @@ keypress_actions = { } for event in keyboard.read_loop(): - if event.type == ecodes.EV_KEY: + if event.type == ecodes.EV_KEY and event.code in keypress_actions: if event.value == 1: # key down keypress_actions[event.code]() if event.value == 0: # key up diff --git a/docs/recipes.rst b/docs/recipes.rst index 1f0e071..ccc7e51 100644 --- a/docs/recipes.rst +++ b/docs/recipes.rst @@ -345,11 +345,16 @@ Use up/down/left/right keys to control a robot: recipe will *not* work in environments like IDLE. If you prefer a version that works under IDLE, the following recipe should -suffice, but will require that you install the evdev library with ``sudo pip3 -install evdev`` first: +suffice: .. literalinclude:: examples/robot_keyboard_2.py +.. note:: + + This recipe uses the third-party ``evdev`` module. Install this library + with ``sudo pip3 install evdev`` first. Be aware that ``evdev`` will only + work with local input devices; this recipe will *not* work over SSH. + Motion sensor robot ===================