Created
September 3, 2021 12:21
-
-
Save cassc/e801363286a40ceb1531ce45d0e88f9a to your computer and use it in GitHub Desktop.
Search HID devices by name and listen keyboard events
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Get event id and names for connected HID devices: | |
# cat /proc/bus/input/devices | grep -P '^[NH]: ' | paste - - | |
# | |
# To allow current user to run this script without root: | |
# sudo usermod -a -G input $USER | |
import evdev | |
from evdev import InputDevice, categorize # import * is evil :) | |
import time | |
import traceback | |
import sys | |
# Provided as an example taken from my own keyboard attached to a Centos 6 box: | |
scancodes = { | |
# Scancode: ASCIICode | |
0: None, 1: u'ESC', 2: u'1', 3: u'2', 4: u'3', 5: u'4', 6: u'5', 7: u'6', 8: u'7', 9: u'8', | |
10: u'9', 11: u'0', 12: u'-', 13: u'=', 14: u'BKSP', 15: u'TAB', 16: u'Q', 17: u'W', 18: u'E', 19: u'R', | |
20: u'T', 21: u'Y', 22: u'U', 23: u'I', 24: u'O', 25: u'P', 26: u'[', 27: u']', 28: u'CRLF', 29: u'LCTRL', | |
30: u'A', 31: u'S', 32: u'D', 33: u'F', 34: u'G', 35: u'H', 36: u'J', 37: u'K', 38: u'L', 39: u';', | |
40: u'"', 41: u'`', 42: u'LSHFT', 43: u'\\', 44: u'Z', 45: u'X', 46: u'C', 47: u'V', 48: u'B', 49: u'N', | |
50: u'M', 51: u',', 52: u'.', 53: u'/', 54: u'RSHFT', 56: u'LALT', 100: u'RALT' | |
} | |
class KeyboardReader(): | |
def __init__(self, keyword, handler=None): | |
self.keyword = keyword | |
self.devices = self.search_devices() | |
# device /dev/input/event21, name "Logitech K400 Plus", phys "usb-0000:00:14.0-2/input2:1" | |
self.handler=handler | |
def handle_line(self, dev, line): | |
print(f'Received line: {line} from {dev.phys}') | |
if self.handler is not None: | |
self.handler(dev, line) | |
def search_devices(self): | |
devs = [] | |
while len(devs) < 1: | |
for p in evdev.list_devices(): | |
dev = InputDevice(p) | |
if self.keyword in dev.name: | |
devs.append(dev) | |
if len(devs) < 1: | |
print(f'Searching for devices {self.keyword}') | |
time.sleep(1) | |
print(f'Found devices: {devs}') | |
return devs | |
def listen_device_loop(self, dev): | |
keyseq = [] | |
for event in dev.read_loop(): | |
if event.type == evdev.ecodes.EV_KEY: | |
data = evdev.categorize(event) # Save the event temporarily to introspect it | |
if data.keystate == 1: # Down events only | |
key = scancodes.get(data.scancode) | |
if key: | |
if key == u'CRLF': | |
self.handle_line(dev, ''.join(keyseq)) | |
keyseq = [] | |
else: | |
keyseq.append(key) | |
def start(self): | |
'''Blocking start handling events | |
''' | |
for dev in self.devices: | |
try: | |
self.listen_device_loop(dev) | |
# todo read from multiple devices | |
except OSError as e: | |
traceback.print_exc(file=sys.stdout) | |
self.devices = self.search_devices() | |
if __name__ == '__main__': | |
reader = KeyboardReader('Logitech') | |
reader.start() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment