Reputation: 57
I am attempting to run some code (preferably in a script) whenever I plug in my keyboard to my Raspberry Pi. I currently have Rasbian Jessie installed on it (probably the latest version?). I found through my research that I should use "udev" to trigger events when usb devices get plugged into a Linux machine.
Just to test this out I want it to open up a browser whenever I plugin my keyboard (the command it's trying to run does work in a terminal on the raspberry pi with my monitor plugged in). I've created the following file /etc/udev/rules.d/keyboard.rules
:
ACTION=="add",ATTRS{idVendor}=="413c",RUN+="epiphany --display=:0 http://www.google.com"
I got the idVendor from the lsusb
command: Bus 001 Device 027: ID 413c:2105 Dell Computer Corp. Model L100 Keyboard
But when I unplug & plug back in my keyboard nothing happens.
What else I've tried:
sudo udevadm control --reload-rules
sudo udevadm control --reload
RUN+='/home/pi/test.sh'
(which has been setup to be runnable).udevadm info -a -p $(udevadm info -q path -n /dev/input/event0)
(which gives me all of the ATTRS for the keyboard)udevadm monitor
& udevadm monitor --property
as I'm plugging in the keyboardudevadm test $(udevadm info -q path -n /dev/input/event0)
. This displays the following information:calling: test version 215 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 Network interface NamePolicy= disabled on kernel commandline, ignoring. timestamp of '/etc/systemd/network' changed timestamp of '/lib/systemd/network' changed Parsed configuration file /lib/systemd/network/99-default.link Created link configuration context. timestamp of '/etc/udev/rules.d' changed timestamp of '/lib/udev/rules.d' changed read rules file: /lib/udev/rules.d/10-local-rpi.rules read rules file: /etc/udev/rules.d/40-scratch.rules read rules file: /lib/udev/rules.d/42-usb-hid-pm.rules read rules file: /lib/udev/rules.d/50-bluetooth-hci-auto-poweron.rules read rules file: /lib/udev/rules.d/50-firmware.rules read rules file: /lib/udev/rules.d/50-udev-default.rules read rules file: /lib/udev/rules.d/55-dm.rules read rules file: /lib/udev/rules.d/60-cdrom_id.rules read rules file: /lib/udev/rules.d/60-crda.rules read rules file: /lib/udev/rules.d/60-drm.rules read rules file: /lib/udev/rules.d/60-fuse.rules read rules file: /lib/udev/rules.d/60-gnupg.rules read rules file: /lib/udev/rules.d/60-keyboard.rules read rules file: /lib/udev/rules.d/60-libgphoto2-6.rules read rules file: /lib/udev/rules.d/60-libpisock9.rules read rules file: /lib/udev/rules.d/60-persistent-alsa.rules read rules file: /lib/udev/rules.d/60-persistent-input.rules read rules file: /lib/udev/rules.d/60-persistent-serial.rules read rules file: /lib/udev/rules.d/60-persistent-storage-dm.rules read rules file: /lib/udev/rules.d/60-persistent-storage-tape.rules read rules file: /lib/udev/rules.d/60-persistent-storage.rules read rules file: /lib/udev/rules.d/60-persistent-v4l.rules read rules file: /lib/udev/rules.d/60-triggerhappy.rules read rules file: /lib/udev/rules.d/61-accelerometer.rules read rules file: /lib/udev/rules.d/64-btrfs.rules read rules file: /lib/udev/rules.d/64-xorg-xkb.rules read rules file: /lib/udev/rules.d/69-libmtp.rules read rules file: /lib/udev/rules.d/70-power-switch.rules read rules file: /lib/udev/rules.d/70-uaccess.rules read rules file: /lib/udev/rules.d/71-seat.rules read rules file: /lib/udev/rules.d/73-idrac.rules read rules file: /lib/udev/rules.d/73-seat-late.rules read rules file: /lib/udev/rules.d/75-net-description.rules read rules file: /lib/udev/rules.d/75-persistent-net-generator.rules read rules file: /lib/udev/rules.d/75-probe_mtd.rules read rules file: /lib/udev/rules.d/75-tty-description.rules read rules file: /lib/udev/rules.d/78-sound-card.rules read rules file: /lib/udev/rules.d/80-drivers.rules read rules file: /lib/udev/rules.d/80-net-setup-link.rules read rules file: /lib/udev/rules.d/80-networking.rules read rules file: /lib/udev/rules.d/80-udisks.rules read rules file: /lib/udev/rules.d/80-udisks2.rules read rules file: /lib/udev/rules.d/85-hdparm.rules read rules file: /lib/udev/rules.d/85-hwclock.rules read rules file: /lib/udev/rules.d/85-regulatory.rules read rules file: /lib/udev/rules.d/90-alsa-restore.rules read rules file: /lib/udev/rules.d/95-udev-late.rules read rules file: /lib/udev/rules.d/95-wedo.rules read rules file: /lib/udev/rules.d/97-hid2hci.rules read rules file: /etc/udev/rules.d/99-com.rules read rules file: /lib/udev/rules.d/99-systemd.rules read rules file: /etc/udev/rules.d/keyboard.rules read rules file: /etc/udev/rules.d/test.rules rules contain 393216 bytes tokens (32768 * 12 bytes), 23387 bytes strings 23799 strings (190642 bytes), 21572 de-duplicated (169483 bytes), 2228 trie nodes used IMPORT builtin 'input_id' /lib/udev/rules.d/50-udev-default.rules:10 capabilities/ev raw kernel attribute: 120013 capabilities/abs raw kernel attribute: 0 capabilities/rel raw kernel attribute: 0 capabilities/key raw kernel attribute: 10000 7 ff9f207a c14057ff febeffdf ffefffff ffffffff fffffffe test_key: checking bit block 0 for any keys; found=1 test_key: checking bit block 32 for any keys; found=1 test_key: checking bit block 64 for any keys; found=1 test_key: checking bit block 96 for any keys; found=1 test_key: checking bit block 128 for any keys; found=1 test_key: checking bit block 160 for any keys; found=1 test_key: checking bit block 192 for any keys; found=1 test_key: checking bit block 224 for any keys; found=1 GROUP 101 /lib/udev/rules.d/50-udev-default.rules:29 IMPORT builtin 'hwdb' /lib/udev/rules.d/60-keyboard.rules:12 IMPORT builtin 'hwdb' returned non-zero IMPORT builtin 'hwdb' /lib/udev/rules.d/60-keyboard.rules:20 IMPORT builtin 'hwdb' returned non-zero IMPORT builtin 'usb_id' /lib/udev/rules.d/60-persistent-input.rules:7 /sys/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.2/1-1.2:1.0: if_class 3 protocol 0 LINK 'input/by-id/usb-Dell_Dell_USB_Keyboard-event-kbd' /lib/udev/rules.d/60-persistent-input.rules:24 IMPORT builtin 'path_id' /lib/udev/rules.d/60-persistent-input.rules:31 LINK 'input/by-path/platform-3f980000.usb-usb-0:1.2:1.0-event-kbd' /lib/udev/rules.d/60-persistent-input.rules:33 RUN '/usr/sbin/th-cmd --socket /var/run/thd.socket --passfd --udev' /lib/udev/rules.d/60-triggerhappy.rules:4 GROUP 101 /etc/udev/rules.d/99-com.rules:1 MODE 0660 /etc/udev/rules.d/99-com.rules:1 RUN 'epiphany --display=:0 http://www.google.com' /etc/udev/rules.d/keyboard.rules:1 handling device node '/dev/input/event0', devnum=c13:64, mode=0660, uid=0, gid=101 preserve permissions /dev/input/event0, 020660, uid=0, gid=101 preserve already existing symlink '/dev/char/13:64' to '../input/event0' found 'c13:64' claiming '/run/udev/links/\x2finput\x2fby-id\x2fusb-Dell_Dell_USB_Keyboard-event-kbd' creating link '/dev/input/by-id/usb-Dell_Dell_USB_Keyboard-event-kbd' to '/dev/input/event0' preserve already existing symlink '/dev/input/by-id/usb-Dell_Dell_USB_Keyboard-event-kbd' to '../event0' found 'c13:64' claiming '/run/udev/links/\x2finput\x2fby-path\x2fplatform-3f980000.usb-usb-0:1.2:1.0-event-kbd' creating link '/dev/input/by-path/platform-3f980000.usb-usb-0:1.2:1.0-event-kbd' to '/dev/input/event0' preserve already existing symlink '/dev/input/by-path/platform-3f980000.usb-usb-0:1.2:1.0-event-kbd' to '../event0' unable to create temporary db file '/run/udev/data/c13:64.tmp': Permission denied .INPUT_CLASS=kbd ACTION=add BACKSPACE=guess DEVLINKS=/dev/input/by-id/usb-Dell_Dell_USB_Keyboard-event-kbd /dev/input/by-path/platform-3f980000.usb-usb-0:1.2:1.0-event-kbd DEVNAME=/dev/input/event0 DEVPATH=/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.2/1-1.2:1.0/0003:413C:2105.0014/input/input23/event0 ID_BUS=usb ID_INPUT=1 ID_INPUT_KEY=1 ID_INPUT_KEYBOARD=1 ID_MODEL=Dell_USB_Keyboard ID_MODEL_ENC=Dell\x20USB\x20Keyboard ID_MODEL_ID=2105 ID_PATH=platform-3f980000.usb-usb-0:1.2:1.0 ID_PATH_TAG=platform-3f980000_usb-usb-0_1_2_1_0 ID_REVISION=0352 ID_SERIAL=Dell_Dell_USB_Keyboard ID_TYPE=hid ID_USB_DRIVER=usbhid ID_USB_INTERFACES=:030101: ID_USB_INTERFACE_NUM=00 ID_VENDOR=Dell ID_VENDOR_ENC=Dell ID_VENDOR_ID=413c MAJOR=13 MINOR=64 SUBSYSTEM=input USEC_INITIALIZED=78790607 XKBLAYOUT=us XKBMODEL=pc105 XKBOPTIONS=terminate:ctrl_alt_bksp XKBVARIANT= run: '/usr/sbin/th-cmd --socket /var/run/thd.socket --passfd --udev' run: 'epiphany --display=:0 http://www.google.com' unload module index Unloaded link configuration context.
Which if you scroll down to the bottom you see run: 'epiphany --display=:0 http://www.google.com'
. Which makes me believe that it should work.
But when I unplug & plug my keyboard back in nothing happens....
I haven't been able to get udevadm trigger
to do anything (tried multiple paths and other inputs, but it just returns nothing).
Are there some sort of logs that I can check to see if it's trying to run my command/script? Is there another way to monitor this script? Is there another way to test this script so I can actually see it run without actually plugging in a usb device?
Upvotes: 1
Views: 4565
Reputation: 57
Are there some sort of logs that I can check to see if it's trying to run my command/script? Is there another way to monitor this script?
After finding this thread I found you could see the udev logs in the system log file found in the /var/log/syslog
file. This will show only the errors by default, but if you bump the log level up to "debug" you'll be able to see everything. I first ran udevadm control --log-priority=debug
and updated the /etc/udev/udev.conf
file to "debug".
What I found was that when I plugged in my keyboard the system would throw the following error:
failed to execute '/lib/udev/epiphany --display=:0 http://www.google.com': No such file or directory
.
Ah-Ha it seems like it was trying to run epiphany from the /lib/udev folder. So I updated the code again to run the correct file path to epiphany: /usr/bin/epiphany --display=:0 http://www.google.com
. But I then got the following error:
Feb 19 13:44:10 raspberrypi systemd-udevd[6473]: '/usr/bin/epiphany --display=:0 http://www.google.com'(err) 'No protocol specified'
Feb 19 13:44:10 raspberrypi systemd-udevd[6473]: '/usr/bin/epiphany --display=:0 http://www.google.com'(err) 'Unable to init server: Could not connect: Connection refused'
Feb 19 13:44:10 raspberrypi systemd-udevd[6473]: '/usr/bin/epiphany --display=:0 http://www.google.com'(out) 'Failed to parse arguments: Cannot open display: :0'
Feb 19 13:44:10 raspberrypi systemd-udevd[6473]: '/usr/bin/epiphany --display=:0 http://www.google.com' [6479] exit with return code 1
This code works correctly if I paste it directly into a terminal so it was odd that it couldn't find the display... Eventually I figured out that udev runs everything as "root". Which apparently "root" does not have access to the displays. When I run the command through the terminal it uses the user "pi" which does have access to the displays. So the final edit to the command: /sbin/runuser -l pi -c '/usr/bin/epiphany --display=:0 http://www.google.com'
. AND IT WORKS!
Current small hiccup is it opens 2 browsers, but I think that's just because I'm only checking the "idVendor" and the usb device has quite a few children that share that "idVendor". So when the single keyboard gets plugged in it see multiple usb devices and run the udev rule multiple times.
Is there another way to test this script so I can actually see it run without actually plugging in a usb device?
I mentioned this in the comments above, but I found you could run the following command to trigger the udev command without having to un-plug & plug back in the keyboard: sudo udevadm trigger -v -c add -a idVendor=413c
Upvotes: 1