Get keystrokes from / dev / input (python evdev)

Introduction

Get input from a keyboard connected to the Raspberry Pi Zero W via USB or bluetooth in preparation for making a key converter

What I used

/dev/input

Find out which input devices are connected with / proc / bus / input / devices When Thinkpad Tracpoint Keyboard is connected, it corresponds to the one with "sysrq kbd leds" in the handler.

pi@raspberrypi:~ $ cat /proc/bus/input/devices 
I: Bus=0003 Vendor=17ef Product=6047 Version=0100
N: Name="Lenovo ThinkPad Compact USB Keyboard with TrackPoint"
P: Phys=usb-20980000.usb-1/input0
S: Sysfs=/devices/platform/soc/20980000.usb/usb1/1-1/1-1:1.0/0003:17EF:6047.0005/input/input14
U: Uniq=
H: Handlers=sysrq kbd leds event0 
B: PROP=0
B: EV=120013
B: KEY=10000 7 ff800000 7ff febeffdf ffefffff ffffffff fffffffe
B: MSC=10
B: LED=1f

It is possible to just display the value with hexdump (I don't know what it is)

pi@raspberrypi:~ $ hexdump /dev/input/event0
0000000 a065 5eae 5f51 0009 0004 0004 0009 0007
0000010 a065 5eae 5f51 0009 0001 0021 0001 0000

Value meaning

/usr/include/input.Excerpt from h


/*
 * The event structure itself
 * Note that __USE_TIME_BITS64 is defined by libc based on
 * application's request to use 64 bit time_t.
 */

struct input_event {
#if (__BITS_PER_LONG != 32 || !defined(__USE_TIME_BITS64)) && !defined(__KERNEL)
	struct timeval time;
#define input_event_sec time.tv_sec
#define input_event_usec time.tv_usec
#else
	__kernel_ulong_t __sec;
	__kernel_ulong_t __usec;
#define input_event_sec  __sec
#define input_event_usec __usec
#endif
	__u16 type;
	__u16 code;
	__s32 value;
};

Try to read using Python

Preparation

$ pip install evdev

Monitor keystrokes

$ python
>>> from evdev import InputDevice, categorize, ecodes
>>> dev = InputDevice('/dev/input/event0')
>>> print(dev)
device /dev/input/event0, name "Lenovo ThinkPad Compact USB Keyboard with TrackPoint", phys "usb-20980000.usb-1/input0"
>>> dev.capabilities(verbose=True)
{('EV_LED', 17L): [('LED_NUML', 0L), ('LED_CAPSL', 1L), ('LED_SCROLLL', 2L), ('LED_COMPOSE', 3L), ('LED_KANA', 4L)], ('EV_MSC', 4L): [('MSC_SCAN', 4L)], ('EV_KEY', 1L): [('KEY_ESC', 1L), ('KEY_1', 2L), ('KEY_2', 3L), ('KEY_3', 4L), ('KEY_4', 5L), ('KEY_5', 6L), ('KEY_6', 7L), ('KEY_7', 8L), ('KEY_8', 9L), ('KEY_9', 10L), ('KEY_0', 11L), ('KEY_MINUS', 12L), ('KEY_EQUAL', 13L), ('KEY_BACKSPACE', 14L), ('KEY_TAB', 15L), ('KEY_Q', 16L), ('KEY_W', 17L), ('KEY_E', 18L), ('KEY_R', 19L), ('KEY_T', 20L), ('KEY_Y', 21L), ('KEY_U', 22L), ('KEY_I', 23L), ('KEY_O', 24L), ('KEY_P', 25L), ('KEY_LEFTBRACE', 26L), ('KEY_RIGHTBRACE', 27L), ('KEY_ENTER', 28L), ('KEY_LEFTCTRL', 29L), ('KEY_A', 30L), ('KEY_S', 31L), ('KEY_D', 32L), ('KEY_F', 33L), ('KEY_G', 34L), ('KEY_H', 35L), ('KEY_J', 36L), ('KEY_K', 37L), ('KEY_L', 38L), ('KEY_SEMICOLON', 39L), ('KEY_APOSTROPHE', 40L), ('KEY_GRAVE', 41L), ('KEY_LEFTSHIFT', 42L), ('KEY_BACKSLASH', 43L), ('KEY_Z', 44L), ('KEY_X', 45L), ('KEY_C', 46L), ('KEY_V', 47L), ('KEY_B', 48L), ('KEY_N', 49L), ('KEY_M', 50L), ('KEY_COMMA', 51L), ('KEY_DOT', 52L), ('KEY_SLASH', 53L), ('KEY_RIGHTSHIFT', 54L), ('KEY_KPASTERISK', 55L), ('KEY_LEFTALT', 56L), ('KEY_SPACE', 57L), ('KEY_CAPSLOCK', 58L), ('KEY_F1', 59L), ('KEY_F2', 60L), ('KEY_F3', 61L), ('KEY_F4', 62L), ('KEY_F5', 63L), ('KEY_F6', 64L), ('KEY_F7', 65L), ('KEY_F8', 66L), ('KEY_F9', 67L), ('KEY_F10', 68L), ('KEY_NUMLOCK', 69L), ('KEY_SCROLLLOCK', 70L), ('KEY_KP7', 71L), ('KEY_KP8', 72L), ('KEY_KP9', 73L), ('KEY_KPMINUS', 74L), ('KEY_KP4', 75L), ('KEY_KP5', 76L), ('KEY_KP6', 77L), ('KEY_KPPLUS', 78L), ('KEY_KP1', 79L), ('KEY_KP2', 80L), ('KEY_KP3', 81L), ('KEY_KP0', 82L), ('KEY_KPDOT', 83L), ('KEY_ZENKAKUHANKAKU', 85L), ('KEY_102ND', 86L), ('KEY_F11', 87L), ('KEY_F12', 88L), ('KEY_RO', 89L), ('KEY_KATAKANA', 90L), ('KEY_HIRAGANA', 91L), ('KEY_HENKAN', 92L), ('KEY_KATAKANAHIRAGANA', 93L), ('KEY_MUHENKAN', 94L), ('KEY_KPJPCOMMA', 95L), ('KEY_KPENTER', 96L), ('KEY_RIGHTCTRL', 97L), ('KEY_KPSLASH', 98L), ('KEY_SYSRQ', 99L), ('KEY_RIGHTALT', 100L), ('KEY_HOME', 102L), ('KEY_UP', 103L), ('KEY_PAGEUP', 104L), ('KEY_LEFT', 105L), ('KEY_RIGHT', 106L), ('KEY_END', 107L), ('KEY_DOWN', 108L), ('KEY_PAGEDOWN', 109L), ('KEY_INSERT', 110L), ('KEY_DELETE', 111L), (['KEY_MIN_INTERESTING', 'KEY_MUTE'], 113L), ('KEY_VOLUMEDOWN', 114L), ('KEY_VOLUMEUP', 115L), ('KEY_POWER', 116L), ('KEY_KPEQUAL', 117L), ('KEY_PAUSE', 119L), ('KEY_KPCOMMA', 121L), (['KEY_HANGEUL', 'KEY_HANGUEL'], 122L), ('KEY_HANJA', 123L), ('KEY_YEN', 124L), ('KEY_LEFTMETA', 125L), ('KEY_RIGHTMETA', 126L), ('KEY_COMPOSE', 127L), ('KEY_STOP', 128L), ('KEY_AGAIN', 129L), ('KEY_PROPS', 130L), ('KEY_UNDO', 131L), ('KEY_FRONT', 132L), ('KEY_COPY', 133L), ('KEY_OPEN', 134L), ('KEY_PASTE', 135L), ('KEY_FIND', 136L), ('KEY_CUT', 137L), ('KEY_HELP', 138L), ('KEY_F13', 183L), ('KEY_F14', 184L), ('KEY_F15', 185L), ('KEY_F16', 186L), ('KEY_F17', 187L), ('KEY_F18', 188L), ('KEY_F19', 189L), ('KEY_F20', 190L), ('KEY_F21', 191L), ('KEY_F22', 192L), ('KEY_F23', 193L), ('KEY_F24', 194L), ('KEY_UNKNOWN', 240L)], ('EV_SYN', 0L): [('SYN_REPORT', 0L), ('SYN_CONFIG', 1L), ('?', 4L), ('?', 17L), ('?', 20L)]}
>>> for event in dev.read_loop():
...     if event.type == ecodes.EV_KEY:
...             print(categorize(event))
... 
(Try pressing the key)
key event at 1588676502.615220, 30 (KEY_A), down
key event at 1588676502.743221, 30 (KEY_A), up
key event at 1588676507.023183, 57 (KEY_SPACE), down
key event at 1588676507.167180, 57 (KEY_SPACE), up
key event at 1588676511.455180, 94 (KEY_MUHENKAN), down
key event at 1588676511.551190, 94 (KEY_MUHENKAN), up
key event at 1588676519.855091, 28 (KEY_ENTER), down
key event at 1588676519.951096, 28 (KEY_ENTER), up

>>> for event in dev.read_loop():
...     if event.type == ecodes.EV_KEY:
...             print(event)
... 
event at 1588676839.036923, code 30, type 01, val 01
event at 1588676839.156917, code 30, type 01, val 00
event at 1588676850.044849, code 57, type 01, val 01
event at 1588676850.140902, code 57, type 01, val 00
event at 1588676872.860695, code 30, type 01, val 01
event at 1588676873.114706, code 30, type 01, val 02
event at 1588676873.164685, code 30, type 01, val 02
(val: 00 up, 01 down,02 hold)

Monitor mouse buttons

>>> from evdev import InputDevice, categorize, ecodes
>>> dev = InputDevice('/dev/input/event1')
>>> print(dev)
device /dev/input/event1, name "Lenovo ThinkPad Compact USB Keyboard with TrackPoint Mouse", phys "usb-20980000.usb-1/input1"
>>> dev.capabilities(verbose=True)
{('EV_MSC', 4L): [('MSC_SCAN', 4L)], ('EV_KEY', 1L): [(['BTN_LEFT', 'BTN_MOUSE'], 272L), ('BTN_RIGHT', 273L), ('BTN_MIDDLE', 274L), ('BTN_SIDE', 275L), ('BTN_EXTRA', 276L)], ('EV_REL', 2L): [('REL_X', 0L), ('REL_Y', 1L), ('REL_HWHEEL', 6L), ('REL_WHEEL', 8L)], ('EV_SYN', 0L): [('SYN_REPORT', 0L), ('SYN_CONFIG', 1L), ('SYN_MT_REPORT', 2L), ('?', 4L)]}
>>> for event in dev.read_loop():
...     if event.type == ecodes.EV_KEY:
...             print(categorize(event))
... 
key event at 1588677297.069200, 272 (['BTN_LEFT', 'BTN_MOUSE']), down
key event at 1588677297.181200, 272 (['BTN_LEFT', 'BTN_MOUSE']), up
key event at 1588677304.573205, 273 (BTN_RIGHT), down
key event at 1588677304.717200, 273 (BTN_RIGHT), up
key event at 1588677307.053195, 274 (BTN_MIDDLE), down
key event at 1588677307.325200, 274 (BTN_MIDDLE), up
key event at 1588677313.549196, 274 (BTN_MIDDLE), down
key event at 1588677313.757202, 274 (BTN_MIDDLE), up
key event at 1588677317.453202, 274 (BTN_MIDDLE), down
key event at 1588677317.949163, 274 (BTN_MIDDLE), up
...     if event.type == ecodes.EV_KEY:
...             print(event)
... 
event at 1588677538.444881, code 272, type 01, val 01
event at 1588677538.540875, code 272, type 01, val 00
event at 1588677542.492876, code 273, type 01, val 01
event at 1588677542.684843, code 273, type 01, val 00
event at 1588677545.580863, code 274, type 01, val 01
event at 1588677545.676858, code 274, type 01, val 00

Monitor Tracpoint

mouse.py


from evdev import InputDevice, categorize, ecodes

dev = InputDevice('/dev/input/event1')
for event in dev.read_loop():
	if event.type == ecodes.EV_REL:
		if event.code == ecodes.REL_X:
			print('REL_X:{}'. format(event.value))
		elif event.code == ecodes.REL_Y:
			print('REL_Y:{}'.format(event.value))
		if event.code == ecodes.REL_WHEEL:
			print('REL_WHEEL:{}'.format(event.value))
$ python mouse.py 
REL_X:1
REL_X:1
REL_Y:-1
REL_Y:-1
REL_Y:-3
REL_X:-1
REL_Y:-4
REL_X:-1
REL_WHEEL:-1
REL_WHEEL:-1

c.f. Customize Linux input devices (https://qiita.com/propella/items/a73fc333c95d14d06835) python tutorial

--Monitor Tranpoint

mouse2.py


from evdev import InputDevice, categorize, ecodes

dev = InputDevice('/dev/input/event1')
for event in dev.read_loop():
	if event.type == ecodes.EV_REL:
		if event.code == ecodes.REL_X:
			print('REL_X:{}'. format(event.value))
		elif event.code == ecodes.REL_Y:
			print('REL_Y:{}'.format(event.value))
		if event.code == ecodes.REL_WHEEL:
			print('REL_WHEEL:{}'.format(event.value))
	elif event.type == ecodes.EV_KEY:
		if event.code == ecodes.BTN_LEFT:
			print('BTN_LEFT:{}'.format(event.value))
		elif event.code == ecodes.BTN_RIGHT:
			print('BTN_RIGHT:{}'.format(event.value))
		if event.code == ecodes.BTN_MIDDLE:
			print('BTN_MIDDLE:{}'.format(event.value))

Run the program when connecting to the keyboard using udev

USB

Get device information

pi@raspberrypi:~/hid_test $ udevadm info -a --path=$(udevadm info -q path -n /dev/input/event0)

Udevadm info starts with the device specified by the devpath and then
walks up the chain of parent devices. It prints for every device
found, all possible attributes in the udev rules key format.
A rule to match, can be composed by the attributes of the device
and the attributes from one single parent device.

  looking at device '//devices/platform/soc/20980000.usb/usb1/1-1/1-1:1.0/0003:17EF:6047.0001/input/input0/event0':
    KERNEL=="event0"
    SUBSYSTEM=="input"
    DRIVER==""

  looking at parent device '//devices/platform/soc/20980000.usb/usb1/1-1/1-1:1.0/0003:17EF:6047.0001/input/input0':
    KERNELS=="input0"
    SUBSYSTEMS=="input"
    DRIVERS==""
    ATTRS{properties}=="0"
    ATTRS{uniq}==""
    ATTRS{name}=="Lenovo ThinkPad Compact USB Keyboard with TrackPoint"
    ATTRS{phys}=="usb-20980000.usb-1/input0"

  looking at parent device '//devices/platform/soc/20980000.usb/usb1/1-1/1-1:1.0/0003:17EF:6047.0001':
    KERNELS=="0003:17EF:6047.0001"
    SUBSYSTEMS=="hid"
    DRIVERS=="hid-generic"
    ATTRS{country}=="00"

  looking at parent device '//devices/platform/soc/20980000.usb/usb1/1-1/1-1:1.0':
    KERNELS=="1-1:1.0"
    SUBSYSTEMS=="usb"
    DRIVERS=="usbhid"
    ATTRS{bNumEndpoints}=="01"
    ATTRS{bInterfaceProtocol}=="01"
    ATTRS{bAlternateSetting}==" 0"
    ATTRS{bInterfaceSubClass}=="01"
    ATTRS{bInterfaceClass}=="03"
    ATTRS{bInterfaceNumber}=="00"
    ATTRS{supports_autosuspend}=="1"
    ATTRS{authorized}=="1"

  looking at parent device '//devices/platform/soc/20980000.usb/usb1/1-1':
    KERNELS=="1-1"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb"
    ATTRS{bNumConfigurations}=="1"
    ATTRS{manufacturer}=="Lenovo"
    ATTRS{avoid_reset_quirk}=="0"
    ATTRS{speed}=="12"
    ATTRS{tx_lanes}=="1"
    ATTRS{busnum}=="1"
    ATTRS{devpath}=="1"
    ATTRS{bmAttributes}=="a0"
    ATTRS{bConfigurationValue}=="1"
    ATTRS{version}==" 2.00"
    ATTRS{removable}=="unknown"
    ATTRS{quirks}=="0x0"
    ATTRS{bDeviceProtocol}=="00"
    ATTRS{bDeviceSubClass}=="00"
    ATTRS{devnum}=="2"
    ATTRS{product}=="ThinkPad Compact USB Keyboard with TrackPoint"
    ATTRS{maxchild}=="0"
    ATTRS{bcdDevice}=="0330"
    ATTRS{devspec}=="  (null)"
    ATTRS{ltm_capable}=="no"
    ATTRS{rx_lanes}=="1"
    ATTRS{urbnum}=="19"
    ATTRS{idVendor}=="17ef"
    ATTRS{bDeviceClass}=="00"
    ATTRS{bMaxPower}=="100mA"
    ATTRS{idProduct}=="6047"
    ATTRS{authorized}=="1"
    ATTRS{configuration}==""
    ATTRS{bNumInterfaces}==" 2"
    ATTRS{bMaxPacketSize0}=="8"

  looking at parent device '//devices/platform/soc/20980000.usb/usb1':
    KERNELS=="usb1"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb"
    ATTRS{bMaxPower}=="0mA"
    ATTRS{bConfigurationValue}=="1"
    ATTRS{bMaxPacketSize0}=="64"
    ATTRS{idVendor}=="1d6b"
    ATTRS{maxchild}=="1"
    ATTRS{urbnum}=="27"
    ATTRS{bDeviceProtocol}=="01"
    ATTRS{bNumInterfaces}==" 1"
    ATTRS{bmAttributes}=="e0"
    ATTRS{removable}=="unknown"
    ATTRS{ltm_capable}=="no"
    ATTRS{bDeviceSubClass}=="00"
    ATTRS{bNumConfigurations}=="1"
    ATTRS{configuration}==""
    ATTRS{version}==" 2.00"
    ATTRS{devpath}=="0"
    ATTRS{bDeviceClass}=="09"
    ATTRS{authorized}=="1"
    ATTRS{manufacturer}=="Linux 4.19.97+ dwc2_hsotg"
    ATTRS{idProduct}=="0002"
    ATTRS{authorized_default}=="1"
    ATTRS{rx_lanes}=="1"
    ATTRS{devnum}=="1"
    ATTRS{tx_lanes}=="1"
    ATTRS{serial}=="20980000.usb"
    ATTRS{avoid_reset_quirk}=="0"
    ATTRS{busnum}=="1"
    ATTRS{product}=="DWC OTG Controller"
    ATTRS{bcdDevice}=="0419"
    ATTRS{speed}=="480"
    ATTRS{interface_authorized_default}=="1"
    ATTRS{quirks}=="0x0"

  looking at parent device '//devices/platform/soc/20980000.usb':
    KERNELS=="20980000.usb"
    SUBSYSTEMS=="platform"
    DRIVERS=="dwc2"
    ATTRS{driver_override}=="(null)"

  looking at parent device '//devices/platform/soc':
    KERNELS=="soc"
    SUBSYSTEMS=="platform"
    DRIVERS==""
    ATTRS{driver_override}=="(null)"

  looking at parent device '//devices/platform':
    KERNELS=="platform"
    SUBSYSTEMS==""
    DRIVERS==""

Use ATTR idVendor = 17ef, idProduct = 6047

/etc/udev/rules.d/99-tracpoint-keyboard.rules


ACTION=="add" ATTRS{idVendor}=="17ef", ATTRS{idProduct}=="6047", RUN+="/home/pi/hid_test/logger.sh"

logger.sh


logger "test message"

Rule testing

pi@raspberrypi:/etc/udev/rules.d $ udevadm test --action=add /devices/platform/soc/20980000.usb/usb1/1-1/1-1:1.0/0003:17EF:6047.0001/input/input0/event0
This program is for debugging only, it does not run any program
specified by a RUN key. It may show incorrect results, because
some values may be different, or not available at a simulation run.

Load module index
Skipping empty file: /etc/systemd/network/99-default.link
Created link configuration context.
Reading rules file: /lib/udev/rules.d/10-local-rpi.rules
(Omitted)
Reading rules file: /etc/udev/rules.d/99-tracpoint-keyboard.rules
Rules contain 393216 bytes tokens (32768 * 12 bytes), 26214 bytes strings
20241 strings (160784 bytes), 17669 de-duplicated (137143 bytes), 2573 trie nodes used
Invalid inotify descriptor.
Starting 'libinput-device-group /sys/devices/platform/soc/20980000.usb/usb1/1-1/1-1:1.0/0003:17EF:6047.0001/input/input0/event0'
'libinput-device-group /sys/devices/platform/soc/20980000.usb/usb1/1-1/1-1:1.0/0003:17EF:6047.0001/input/input0/event0'(out) '3/17ef/6047:usb-20980000.usb-1'
Process 'libinput-device-group /sys/devices/platform/soc/20980000.usb/usb1/1-1/1-1:1.0/0003:17EF:6047.0001/input/input0/event0' succeeded.
DEVPATH=/devices/platform/soc/20980000.usb/usb1/1-1/1-1:1.0/0003:17EF:6047.0001/input/input0/event0
DEVNAME=/dev/input/event0
MAJOR=13
MINOR=64
ACTION=add
SUBSYSTEM=input
ID_INPUT=1
ID_INPUT_KEY=1
ID_INPUT_KEYBOARD=1
ID_VENDOR=Lenovo
ID_VENDOR_ENC=Lenovo
ID_VENDOR_ID=17ef
ID_MODEL=ThinkPad_Compact_USB_Keyboard_with_TrackPoint
ID_MODEL_ENC=ThinkPad\x20Compact\x20USB\x20Keyboard\x20with\x20TrackPoint
ID_MODEL_ID=6047
ID_REVISION=0330
ID_SERIAL=Lenovo_ThinkPad_Compact_USB_Keyboard_with_TrackPoint
ID_TYPE=hid
ID_BUS=usb
ID_USB_INTERFACES=:030101:030102:
ID_USB_INTERFACE_NUM=00
ID_USB_DRIVER=usbhid
.INPUT_CLASS=kbd
DEVLINKS=/dev/input/by-id/usb-Lenovo_ThinkPad_Compact_USB_Keyboard_with_TrackPoint-event-kbd /dev/input/by-path/platform-20980000.usb-usb-0:1:1.0-event-kbd
ID_PATH=platform-20980000.usb-usb-0:1:1.0
ID_PATH_TAG=platform-20980000_usb-usb-0_1_1_0
XKBMODEL=pc105
XKBLAYOUT=jp
BACKSPACE=guess
TAGS=:power-switch:
LIBINPUT_DEVICE_GROUP=3/17ef/6047:usb-20980000.usb-1
USEC_INITIALIZED=693923915
run: '/usr/sbin/th-cmd --socket /var/run/thd.socket --passfd --udev'
run: '/home/pi/hid_test/logger.sh'
Unload module index
Unloaded link configuration context.

Checking the operation of the script

pi@raspberrypi:/etc/udev/rules.d $ tail -n5  /var/log/messages
May  6 21:43:09 raspberrypi mtp-probe: checking bus 1, device 2: "/sys/devices/platform/soc/20980000.usb/usb1/1-1"
May  6 21:43:09 raspberrypi mtp-probe: bus: 1, device: 2 was not an MTP device
May  6 21:43:10 raspberrypi mtp-probe: checking bus 1, device 2: "/sys/devices/platform/soc/20980000.usb/usb1/1-1"
May  6 21:43:10 raspberrypi mtp-probe: bus: 1, device: 2 was not an MTP device
May  6 21:55:32 raspberrypi pi: test message

--Reference http://yukirinmk2.hatenablog.com/entry/2013/10/23/210559

Bluetooth

Keyboard connection

Reference: https://qiita.com/da1fujimoto/items/c0d652049e8455894fd9

pi@raspberrypi:~ $ sudo hciconfig hci0 down
pi@raspberrypi:~ $ sudo hciconfig hci0 up
pi@raspberrypi:~ $ bluetoothctl 
Agent registered
[bluetooth]# scan on
Discovery started
...
[NEW] Device 90:7F:61:55:CA:1A 90-7F-61-55-CA-1A #Turned on
[CHG] Device 90:7F:61:55:CA:1A LegacyPairing: no
[CHG] Device 90:7F:61:55:CA:1A Name: ThinkPad Compact Bluetooth Keyboard with TrackPoint
[CHG] Device 90:7F:61:55:CA:1A Alias: ThinkPad Compact Bluetooth Keyboard with TrackPoint
...
[bluetooth]# scan off
 ...
[CHG] Device 90:7F:61:xx:xx:xx RSSI is nil
...
Discovery stopped
[bluetooth]# pair 90:7f:61:xx:xx:xx:
Attempting to pair with 90:7F:61:xx:xx:xx
[CHG] Device 90:7F:61:55:CA:1A Connected: yes
[agent] Passkey: 762917 #Enter this number on your keyboard and Enter
[CHG] Device 90:7F:61:xx:xx:xx Modalias: usb:v17EFp6048d0312
[CHG] Device 90:7F:61:xx:xx:xx UUIDs: 00001000-0000-1000-8000-00805f9b34fb
[CHG] Device 90:7F:61:xx:xx:xx UUIDs: 00001124-0000-1000-8000-00805f9b34fb
[CHG] Device 90:7F:61:xx:xx:xx UUIDs: 00001200-0000-1000-8000-00805f9b34fb
[CHG] Device 90:7F:61:xx:xx:xx ServicesResolved: yes
[CHG] Device 90:7F:61:xx:xx:xx Paired: yes
Pairing successful
[CHG] Device 90:7F:61:xx:xx:xx ServicesResolved: no
[CHG] Device 90:7F:61:xx:xx:xx Connected: no
[bluetooth]# connect 90:7f:61:xx:xx:xx
Attempting to connect to 90:7f:61:xx:xx:xx
[CHG] Device 90:7F:61:xx:xx:xx Connected: yes
Connection successful
[CHG] Device 90:7F:61:xx:xx:xx ServicesResolved: yes
[ThinkPad Compact Bluetooth Keyboard with TrackPoint]# trust 90:7f:61:55:ca:1a
[CHG] Device 90:7F:61:55:CA:1A Trusted: yes
Changing 90:7F:61:55:CA:1A trust succeeded
[ThinkPad Compact Bluetooth Keyboard with TrackPoint]# quit

Now you can pair

Check device information

pi@raspberrypi:~ $ udevadm info -a --path=$(udevadm info -q path -n /dev/input/event0)

Udevadm info starts with the device specified by the devpath and then
walks up the chain of parent devices. It prints for every device
found, all possible attributes in the udev rules key format.
A rule to match, can be composed by the attributes of the device
and the attributes from one single parent device.

  looking at device '//devices/platform/soc/20201000.serial/tty/ttyAMA0/hci0/hci0:12/0005:17EF:6048.0001/input/input0/event0':
    KERNEL=="event0"
    SUBSYSTEM=="input"
    DRIVER==""

  looking at parent device '//devices/platform/soc/20201000.serial/tty/ttyAMA0/hci0/hci0:12/0005:17EF:6048.0001/input/input0':
    KERNELS=="input0"
    SUBSYSTEMS=="input"
    DRIVERS==""
    ATTRS{uniq}=="90:7f:61:55:ca:1a"
    ATTRS{name}=="ThinkPad Compact Bluetooth Keyboard with TrackPoint Keyboard"
    ATTRS{phys}=="b8:27:eb:ba:4f:00"
    ATTRS{properties}=="0"

  looking at parent device '//devices/platform/soc/20201000.serial/tty/ttyAMA0/hci0/hci0:12/0005:17EF:6048.0001':
    KERNELS=="0005:17EF:6048.0001"
    SUBSYSTEMS=="hid"
    DRIVERS=="hid-generic"
    ATTRS{country}=="21"

  looking at parent device '//devices/platform/soc/20201000.serial/tty/ttyAMA0/hci0/hci0:12':
    KERNELS=="hci0:12"
    SUBSYSTEMS=="bluetooth"
    DRIVERS==""

  looking at parent device '//devices/platform/soc/20201000.serial/tty/ttyAMA0/hci0':
    KERNELS=="hci0"
    SUBSYSTEMS=="bluetooth"
    DRIVERS==""

  looking at parent device '//devices/platform/soc/20201000.serial/tty/ttyAMA0':
    KERNELS=="ttyAMA0"
    SUBSYSTEMS=="tty"
    DRIVERS==""

  looking at parent device '//devices/platform/soc/20201000.serial':
    KERNELS=="20201000.serial"
    SUBSYSTEMS=="amba"
    DRIVERS=="uart-pl011"
    ATTRS{id}=="00241011"
    ATTRS{irq0}=="81"
    ATTRS{driver_override}=="(null)"

  looking at parent device '//devices/platform/soc':
    KERNELS=="soc"
    SUBSYSTEMS=="platform"
    DRIVERS==""
    ATTRS{driver_override}=="(null)"

  looking at parent device '//devices/platform':
    KERNELS=="platform"
    SUBSYSTEMS==""
    DRIVERS==""

update udev rules

/etc/udev/rules.d/99-tracpoint-keyboard.rules


ACTION=="add" ATTRS{idVendor}=="17ef", ATTRS{idProduct}=="6047", RUN+="/home/pi/hid_test/logger.sh", SYMLINK+="input/ThinkPaaTracPointKeyboard"
ACTION=="add" ATTRS{name}=="ThinkPad Compact Bluetooth Keyboard with TrackPoint Keyboard", RUN+="/home/pi/hid_test/keyboardFoundMessage.sh", SYMLINK+="input/ThinkPadTracPointKeyboard"
ACTION=="add" ATTRS{name}=="ThinkPad Compact Bluetooth Keyboard with TrackPoint Mouse", RUN+="/home/pi/hid_test/mouseFoundMessage.sh", SYMLINK+="input/ThinkPadTracPointKeyboardMouse"

This will distinguish the input device

Get handler for input device

If the device is decided, I thought that it would be better to use by-id for the number of event, You can specify it with SYMLINK in udev's rule.

pi@raspberrypi:/etc/udev/rules.d $ ls -la /dev/input/by-id
Total 0
drwxr-xr-x 2 root root 120 May 6 21:43 .
drwxr-xr-x 4 root root 240 May 6 21:43 ..
lrwxrwxrwx 1 root root 9 May 6 21:43 usb-Lenovo_ThinkPad_Compact_USB_Keyboard_with_TrackPoint-event-if01 -> ../event3
lrwxrwxrwx 1 root root 9 May 6 22:11 usb-Lenovo_ThinkPad_Compact_USB_Keyboard_with_TrackPoint-event-kbd -> ../event0
lrwxrwxrwx 1 root root 9 May 6 21:43 usb-Lenovo_ThinkPad_Compact_USB_Keyboard_with_TrackPoint-if01-event-mouse -> ../event1
lrwxrwxrwx 1 root root 9 May 6 21:43 usb-Lenovo_ThinkPad_Compact_USB_Keyboard_with_TrackPoint-if01-mouse -> ../mouse0

Recommended Posts

Get keystrokes from / dev / input (python evdev)
Get data from Quandl in Python
Get upcoming weather from python weather api
Get html from element with Python selenium
Get exchange rates from open exchange rates in Python
Get battery level from SwitchBot in Python
Get Precipitation Probability from XML in Python
[Python] Get the main color from the screenshot
Get metric history from MLflow in Python
Get the contents of git diff from python
[Python] Standard input
Get keystrokes during background execution in Python (windows)
[Bash] Use here-documents to get python power from bash
sql from python
MeCab from Python
Get BTC / JPY board information from Python --bitflyer
[Python] Get one year's message history from Slack
Get only articles from web pages in Python
Python: Use zipfile to unzip from standard input
[Python] Get the text of the law from the e-GOV Law API
Have python parse the json entered from the standard input
Get schedule from Garoon SOAP API with Python + Zeep
Get data from GPS module at 10Hz in Python
Get the return code of the Python script from bat
[Python] Change standard input from keyboard to text file
Get mail from Gmail and label it with Python3
Get files from Linux using paramiko and scp [Python]
Python hand play (get column names from CSV file)
Get data from database via ODBC with Python (Access)
Use thingsspeak from python
[Python] Get environment variables
Touch MySQL from Python 3
Key input in Python
Operate Filemaker from Python
Use fluentd from python
Access bitcoind from python
Changes from Python 3.0 to Python 3.5
Changes from Python 2 to Python 3.0
[Python] Get Qiita trends
Python from or import
Use MySQL from Python
Run python from excel
Install python from source
Execute command from Python
[ev3dev × Python] Touch sensor
Operate neutron from Python!
python input and output
Python audio input / output
[ev3dev × Python] Gyro sensor
Use MySQL from Python
Operate LXC from Python
[Python3] Get date diff
Get date in Python
Memorize Python commentary 4 --Input
Manipulate riak from python
Force Python from Fortran
Get date with python
Use BigQuery from python.
[ev3dev × Python] Color sensor
Key input in Python
Execute command from python