2
votes

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:

  • Restarting the Raspberry Pi
  • Running the command sudo udevadm control --reload-rules
  • Running the command sudo udevadm control --reload
  • Having the keyboard.rules try and run a script RUN+='/home/pi/test.sh' (which has been setup to be runnable).
  • Checking the different "desktops" (hitting Crl+Alt+F1 - F12) (though only F1 (console) and F7 (gui desktop) are active).
  • Verifying the idVendor by running udevadm info -a -p $(udevadm info -q path -n /dev/input/event0) (which gives me all of the ATTRS for the keyboard)
  • Verifying that udev is seeing the "add" even come in by running udevadm monitor & udevadm monitor --property as I'm plugging in the keyboard
  • Testing it with udevadm 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?

1
I've created a script controller_retropi.sh that has the following:Grayson Malinowski
I've created a script controller_retropi.sh that has the following: #!/bin/sh epiphany --display=:0 http://www.google.com (chowning it to 777 so that it can run) I've updated my keyboard.rules to now be: ACTION=="add",ATTRS{idVendor}=="413c",RUN+="/bin/bash /home/pi/scripts/controller_retropi.sh &" I've re-ran the sudo udevadm control --reload-rules to refresh the rules and double checked they were loaded with udevadmin test $(udevadm info -q path -n /dev/input/event0). Still no luck.Grayson Malinowski
I've also figured out how to use trigger with sudo udevadm trigger -v -c add -a idVendor=413c. And i see the device pop up, and see it when I monitor it. But the RUN command still is not being triggered.....Grayson Malinowski

1 Answers

1
votes

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