As I’ve mentioned in a previous blog article, I have started using a brilliant Raspberry Pi-based music player called RuneAudio (which uses Music Player Daemon – MPD – at its heart). I have this connected to a home cinema system, and I wanted to be able to use its remote control to control the music player (play/pause, next track, previous track, etc). This article describes how to set this up.
RuneAudio can be found at https://www.runeaudio.com/ . At the time of writing the latest version of RuneAudio is RuneAudio+R e4 which can be found at https://www.runeaudio.com/forum/runeaudio-r-e4-t7084.html, but it is worth checking this thread in case a later version has been released. (Frustratingly this seems to be only a semi-official version of RuneAudio, so it can’t be found at the RuneAudio download page https://www.runeaudio.com/download/.)
Previously LIRC (Linux Infrared Remote Control) would have been an essential component of this setup, but now support for infrared remote controls has been built into the Linux kernel.
The latest releases of RuneAudio use Archlinux, and I have tested this approach on RuneAudio+R e3 and RuneAudio+R e4, but the same principles may work with other flavours of Linux or with other music players.
I should add that many of the ideas in this article are derived from other web articles which I have listed in the Further Reading section below. Grateful thanks to those authors who have taken the trouble to document their work.
Note that the operating system used by RuneAudio is Archlinux, and the user logs in as
root. This approach may work with systems, but with other types of Linux the user may log in with a non-root account so some of the commands with will have to be prefaced with
- You need an infrared receiver: there are many articles on the Internet about how to build or buy a receiver, so I haven’t duplicated that information here. For convenience I used an Energenie ENER314-IR Infrared Controller board which I got from an Internet supplier for about £9.00 (US$12). This worked well and the receiver was very sensitive; it includes both an infrared receiver and infrared transmitter. (The only potential disadvantages with it that I could think of were (a) if you’re using the Official Raspberry Pi Case then you need to drill a hole in it to expose the receiver, and (b) both the receiver and the transmitter point in the same direction and can’t be moved.)
- You need to know which GPIO pin is used by the infrared receiver: with the Energenie ENER314-IR the IR signal in is on GPIO pin 18.
- Log in as
- Add the following to
(Change the GPIO pin number as necessary to match the hardware that you are using.)
- Re-boot the Raspberry Pi:
- Confirm that the gpio module has been loaded:
lsmod | grep gpio
The output should look similar to the following:
root@runeaudio+R e4:~ # lsmod | grep gpio
gpio_ir_recv 16384 0
rc_core 40960 4 ir_rc6_decoder,rc_rc6_mce,gpio_ir_recv
root@runeaudio+R e4:~ #
Show the corresponding input device:
The output should look similar to the following:
root@runeaudio+R e4:~ # cat /proc/bus/input/devices
I: Bus=0019 Vendor=0001 Product=0001 Version=0100
H: Handlers=kbd event0
B: KEY=fff 0 0 4200 108fc32e 2376051 0 0 0 7 158000 4192 4001 8e9680 0 0 10000000
root@runeaudio+R e4:~ #
- Ensure that ir-keytable is installed:
The output should look similar to the following:
root@runeaudio+R e4:~ # ir-keytable
Found /sys/class/rc/rc0/ with:
Default keymap: rc-rc6-mce
Input device: /dev/input/event0
LIRC device: /dev/lirc0
Supported kernel protocols: lirc rc-5 rc-5-sz jvc sony nec sanyo mce_kbd rc-6 sharp xmp imon rc-mm
Enabled kernel protocols: lirc rc-6
bus: 25, vendor/product: 0001:0001, version: 0x0100
Repeat delay = 500 ms, repeat period = 125 ms
root@runeaudio+R e4:~ #
- Enable all the kernel protocols:
ir-keytable -p all
The output should look similar to the following:
root@runeaudio+R e4:~ # ir-keytable -p all
Protocols changed to unknown other lirc rc-5 rc-5-sz jvc sony nec sanyo mce_kbd rc-6 sharp xmp cec imon rc-mm
Can't find xbox-dvd bpf protocol in /etc/rc_keymaps/protocols or /usr/lib/udev/rc_keymaps/protocols
root@runeaudio+R e4:~ #
- Test the infrared remote control with ir-keytable
ir-keytable -t -s rc0
Point the infrared remote control at the receiver, press some buttons on the controller, and observe the output. The output may look similar to the following:
root@runeaudio+R e4:~ # ir-keytable -t -s rc0 Testing events. Please, press CTRL-C to abort. 216.380035: lirc protocol(sony20): scancode = 0x101000 216.380059: event type EV_MSC(0x04): scancode = 0x101000 216.380059: event type EV_SYN(0x00). ... 248.820027: lirc protocol(sony12): scancode = 0x10025 248.820050: event type EV_MSC(0x04): scancode = 0x10025 248.820050: event type EV_SYN(0x00). ... 353.510019: lirc protocol(rc5_sz): scancode = 0x2fff toggle=1 353.510051: event type EV_MSC(0x04): scancode = 0x2fff 353.510051: event type EV_SYN(0x00). 353.510082: event type EV_MSC(0x04): scancode = 0xd00002 353.510082: event type EV_SYN(0x00). 353.510079: lirc protocol(sony15): scancode = 0xd00002
In this case the controller is using various sony protocols: 20 bit protocol for some keys, 15 bit protocol for some other keys, and 12 bit protocol for the remaining keys.
- Look in
/lib/udev/rc_keymapsto see whether a keymap
.tomlfile exists for the controller being used – if so copy the keymap file to
- If the keymap file for the controller being used doesn’t exist in
/lib/udev/rc_keymapsthen it’s possible that one exists somewhere on the Internet.
- In my case the wasn’t an existing keymap for the controller that I was using (a Sony RM-ADP090), so I therefore created my own keymap by doing the following steps.
As I knew from the above that my controller was using Sony protocol I ran this command to select only the Sony protocols:
ir-keytable -p sony
The output looked like this:
root@runeaudio+R e4:~ # ir-keytable -p sony
Protocols changed to sony
root@runeaudio+R e4:~ #
I then ran:
ir-keytable -v -t
and noted the scancodes that were shown for each button.
I then constructed a keymap file (
Sony_RM-ADP090.tomlin my case) which I placed in
The definition of the format of the keymap file can be found at https://manpages.debian.org/testing/ir-keytable/rc_keymap.5.en.html
My resulting keymap file was as follows:
[[protocols]] name = "sony_RM-ADP090" protocol = "sony" variant = "sony20" [protocols.scancodes] # brand: Sony # model: RM-ADP090 # devices: Sony BDV-E2100 Home Cinema System # # Vaughan Harper, July 2020 # # remote layout: # +-------------------------------------------------+ # | (EJECTCD) (TV_SPEAKER) (TV_POWER) (POWER) | # | (SLEEP) (1) (2) (3) | # | (BLUETOOTH) (4) (5) (6) | # | (FUNCTION) (7) (8) (9) | # | (FOOTBALL) (AUDIO) (0) (SUBTITLE) | # | (RED) (GREEN) (YELLOW) (BLUE) | # | (TOP MENU) (UP) (POP UP/MENU) | # | (LEFT) (OK) (RIGHT) | # | (RETURN) (DOWN) (OPTIONS) | # | (SOUND_MODE_DOWN) (HOME) (SOUND_MODE_UP) | # | (MUSIC_EQ) (PREVIOUS) (NEXT) (SEN) | # | (REWIND) (PLAY) (FASTFORWARD) | # | (DISPLAY) (PAUSE) (STOP) | # | (VOLUMEUP) (TV_VOL_UP) | # | (MUTE) (TV_SOURCE) | # | (VOLUMEDOWN) (TV_VOL_DOWN) | # +-------------------------------------------------+ 0x10103c = "KEY_EJECTCD" 0x103045 = "KEY_TV_SPEAKER" 0x101000 = "KEY_1" 0x101001 = "KEY_2" 0x101002 = "KEY_3" 0x103071 = "KEY_BLUETOOTH" 0x101003 = "KEY_4" 0x101004 = "KEY_5" 0x101005 = "KEY_6" 0x101006 = "KEY_7" 0x101007 = "KEY_8" 0x101008 = "KEY_9" 0x107017 = "KEY_FOOTBALL" 0x101012 = "KEY_AUDIO" 0x101009 = "KEY_0" 0x101011 = "KEY_SUBTITLE" 0x103005 = "KEY_RED" 0x103006 = "KEY_GREEN" 0x103007 = "KEY_YELLOW" 0x103004 = "KEY_BLUE" 0x101019 = "KEY_MEDIA_TOP_MENU" # labelled 'TOP MENU' 0x101078 = "KEY_UP" 0x10101a = "KEY_MENU" # labelled 'POP UP/MENU 0x10107a = "KEY_LEFT" 0x10107c = "KEY_OK" 0x10107b = "KEY_RIGHT" 0x10107d = "KEY_RETURN" 0x101079 = "KEY_DOWN" 0x101073 = "KEY_OPTION" # labelled 'OPTIONS' 0x101030 = "KEY_PREVIOUS" 0x101031 = "KEY_NEXT" 0x107050 = "KEY_SEN" 0x101033 = "KEY_REWIND" 0x101034 = "KEY_FASTFORWARD" 0x101018 = "KEY_DISPLAY" [[protocols]] name = "sony_RM-ADP090_2" protocol = "sony" variant = "sony15" [protocols.scancodes] 0x500015 = "KEY_POWER" 0x500060 = "KEY_SLEEP" 0xd00002 = "KEY_PLAY" 0xd00069 = "KEY_FUNCTION" 0xd0006f = "KEY_SOUND_MODE_DOWN" 0xd00007 = "KEY_HOME" 0xd0006e = "KEY_SOUND_MODE_UP" 0xd00049 = "KEY_MUSIC_EQ" 0xd00001 = "KEY_PAUSE" 0xd00000 = "KEY_STOP" 0x500012 = "KEY_VOLUMEUP" 0x500014 = "KEY_MUTE" 0x500013 = "KEY_VOLUMEDOWN" [[protocols]] name = "sony_RM-ADP090_3" protocol = "sony" variant = "sony12" [protocols.scancodes] 0x10015 = "KEY_POWER2" # TV power button 0x10012 = "KEY_TV_VOL_UP" 0x10013 = "KEY_TV_VOL_DOWN" 0x10025 = "KEY_TV_SOURCE"
(In my case, because the controller used three separate variants of the Sony protocol there needed to be three separate sections within the keymap file.)
- Delete the existing table and load the the new table from the keymap file by running a command similar to the following:
ir-keytable -c -p sony -w /etc/rc_keymaps/Sony_RM-ADP090.toml
-cclears the existing table
-p sonysets the protocol to sony
-w /etc/rc_keymaps/Sony_RM-ADP090.tomlwrite (add) the keymapping from the file specified
Review the resulting output – mine was as follows:
root@runeaudio+R e4:~ # ir-keytable -c -p sony -w /etc/rc_keymaps/Sony_RM-ADP090.toml Read sony_RM-ADP090 table /etc/rc_keymaps/Sony_RM-ADP090.toml: keycode `KEY_TV_SPEAKER' not recognised, no mapping for scancode 0x04103045 /etc/rc_keymaps/Sony_RM-ADP090.toml: keycode `KEY_RETURN' not recognised, no mapping for scancode 0x0410107d /etc/rc_keymaps/Sony_RM-ADP090.toml: keycode `KEY_SEN' not recognised, no mapping for scancode 0x04107050 /etc/rc_keymaps/Sony_RM-ADP090.toml: keycode `KEY_DISPLAY' not recognised, no mapping for scancode 0x04101018 /etc/rc_keymaps/Sony_RM-ADP090.toml: keycode `KEY_TV_VOL_UP' not recognised, no mapping for scancode 0x0410012 /etc/rc_keymaps/Sony_RM-ADP090.toml: keycode `KEY_TV_VOL_DOWN' not recognised, no mapping for scancode 0x0410013 /etc/rc_keymaps/Sony_RM-ADP090.toml: keycode `KEY_TV_SOURCE' not recognised, no mapping for scancode 0x0410025 /etc/rc_keymaps/Sony_RM-ADP090.toml: keycode `KEY_FUNCTION' not recognised, no mapping for scancode 0x04d00069 /etc/rc_keymaps/Sony_RM-ADP090.toml: keycode `KEY_SOUND_MODE_DOWN' not recognised, no mapping for scancode 0x04d0006f /etc/rc_keymaps/Sony_RM-ADP090.toml: keycode `KEY_SOUND_MODE_UP' not recognised, no mapping for scancode 0x04d0006e /etc/rc_keymaps/Sony_RM-ADP090.toml: keycode `KEY_MUSIC_EQ' not recognised, no mapping for scancode 0x04d00049 Old keytable cleared Wrote 41 keycode(s) to driver Protocols changed to sony root@runeaudio+R e4:~ #
You can see from the output that 41 keycodes were written, but there were also a number of errors listed: the keycodes specified need to match the keycodes already defined within the system. I never found where the list of allowable keycodes is defined or whether it can be added to, but you can find a list of keycodes (as comments) in
/usr/include/linux/input-event-codes.h. Of course it doesn’t matter if you get some errors – you only need to recognise the keycodes from the buttons on the controller that you want to use to control RuneAudio. So if, for example, you wanted to use the button labelled ‘FOOTBALL’ on the remote control then you would need to map its scancode to one of the allowable keycodes.
- Check the contents of the keytable. If you run
it will list the keycodes that are now in the keytable together with their corresponding scancodes:
root@runeaudio+R e4:~ # ir-keytable -r scancode 0x10015 = KEY_POWER2 (0x164) scancode 0x101000 = KEY_1 (0x02) scancode 0x101001 = KEY_2 (0x03) scancode 0x101002 = KEY_3 (0x04) scancode 0x101003 = KEY_4 (0x05) scancode 0x101004 = KEY_5 (0x06) scancode 0x101005 = KEY_6 (0x07) scancode 0x101006 = KEY_7 (0x08) scancode 0x101007 = KEY_8 (0x09) scancode 0x101008 = KEY_9 (0x0a) scancode 0x101009 = KEY_0 (0x0b) scancode 0x101011 = KEY_SUBTITLE (0x172) scancode 0x101012 = KEY_AUDIO (0x188) scancode 0x101019 = KEY_MEDIA_TOP_MENU (0x26b) scancode 0x10101a = KEY_MENU (0x8b) scancode 0x101030 = KEY_PREVIOUS (0x19c) scancode 0x101031 = KEY_NEXT (0x197) scancode 0x101033 = KEY_REWIND (0xa8) scancode 0x101034 = KEY_FASTFORWARD (0xd0) scancode 0x10103c = KEY_EJECTCD (0xa1) scancode 0x101073 = KEY_OPTION (0x165) scancode 0x101078 = KEY_UP (0x67) scancode 0x101079 = KEY_DOWN (0x6c) scancode 0x10107a = KEY_LEFT (0x69) scancode 0x10107b = KEY_RIGHT (0x6a) scancode 0x10107c = KEY_OK (0x160) scancode 0x103004 = KEY_BLUE (0x191) scancode 0x103005 = KEY_RED (0x18e) scancode 0x103006 = KEY_GREEN (0x18f) scancode 0x103007 = KEY_YELLOW (0x190) scancode 0x103071 = KEY_BLUETOOTH (0xed) scancode 0x107017 = BTN_TRIGGER_HAPPY10 (0x2c9) scancode 0x500012 = KEY_VOLUMEUP (0x73) scancode 0x500013 = KEY_VOLUMEDOWN (0x72) scancode 0x500014 = KEY_MUTE (0x71) scancode 0x500015 = KEY_POWER (0x74) scancode 0x500060 = KEY_SLEEP (0x8e) scancode 0xd00000 = KEY_STOP (0x80) scancode 0xd00001 = KEY_PAUSE (0x77) scancode 0xd00002 = KEY_PLAY (0xcf) scancode 0xd00007 = KEY_HOME (0x66) Enabled kernel protocols: lirc sony root@runeaudio+R e4:~ #
Crucially you need to ensure that the remote control keys that you want to use to control RuneAudio are listed here, and if not you’ll need to update the keymap file.
- Test the operation of the keytable – run this command:
and press some buttons on the remote control. You should get some output similar to the following:
root@runeaudio+R e4:~ # ir-keytable -t Testing events. Please, press CTRL-C to abort. 673.780023: lirc protocol(sony20): scancode = 0x10103c 673.780068: event type EV_MSC(0x04): scancode = 0x10103c 673.780068: event type EV_KEY(0x01) key_down: KEY_EJECTCD(0x00a1) 673.780068: event type EV_SYN(0x00). 673.820050: lirc protocol(sony20): scancode = 0x10103c 673.820079: event type EV_MSC(0x04): scancode = 0x10103c 673.820079: event type EV_SYN(0x00). 673.870025: lirc protocol(sony20): scancode = 0x10103c 673.870046: event type EV_MSC(0x04): scancode = 0x10103c 673.870046: event type EV_SYN(0x00). 673.910033: lirc protocol(sony20): scancode = 0x10103c 673.910049: event type EV_MSC(0x04): scancode = 0x10103c 673.910049: event type EV_SYN(0x00). 674.030025: event type EV_KEY(0x01) key_up: KEY_EJECTCD(0x00a1) 674.030025: event type EV_SYN(0x00). 679.450023: lirc protocol(sony20): scancode = 0x101000 679.450058: event type EV_MSC(0x04): scancode = 0x101000 679.450058: event type EV_KEY(0x01) key_down: KEY_1(0x0002) 679.450058: event type EV_SYN(0x00). 679.490024: lirc protocol(sony20): scancode = 0x101000 679.490049: event type EV_MSC(0x04): scancode = 0x101000 679.490049: event type EV_SYN(0x00). 679.540022: lirc protocol(sony20): scancode = 0x101000 679.540037: event type EV_MSC(0x04): scancode = 0x101000 679.540037: event type EV_SYN(0x00). 679.660021: event type EV_KEY(0x01) key_up: KEY_1(0x0002) 679.660021: event type EV_SYN(0x00). 685.550027: lirc protocol(sony15): scancode = 0x500012 685.550055: event type EV_MSC(0x04): scancode = 0x500012 685.550055: event type EV_KEY(0x01) key_down: KEY_VOLUMEUP(0x0073) 685.550055: event type EV_SYN(0x00). 685.600028: lirc protocol(sony15): scancode = 0x500012 685.600054: event type EV_MSC(0x04): scancode = 0x500012 685.600054: event type EV_SYN(0x00). 685.640024: lirc protocol(sony15): scancode = 0x500012 685.640039: event type EV_MSC(0x04): scancode = 0x500012 685.640039: event type EV_SYN(0x00). 685.760026: event type EV_KEY(0x01) key_up: KEY_VOLUMEUP(0x0073) 685.760026: event type EV_SYN(0x00). 696.170030: lirc protocol(sony15): scancode = 0xd00002 696.170073: event type EV_MSC(0x04): scancode = 0xd00002 696.170073: event type EV_KEY(0x01) key_down: KEY_PLAY(0x00cf) 696.170073: event type EV_SYN(0x00). 696.220087: lirc protocol(sony15): scancode = 0xd00002 696.220138: event type EV_MSC(0x04): scancode = 0xd00002 696.220138: event type EV_SYN(0x00). 696.260117: lirc protocol(sony15): scancode = 0xd00002 696.260154: event type EV_MSC(0x04): scancode = 0xd00002 696.260154: event type EV_SYN(0x00). 696.380076: event type EV_KEY(0x01) key_up: KEY_PLAY(0x00cf) 696.380076: event type EV_SYN(0x00).
Crucially you want to see messages like
key_down: KEY_EJECTCD and
key_down: KEY_PLAY which shows that the scancodes from the controller are being mapped to keycodes within Archlinux.
Optionally you can get debug messages by specifying the verbose option:
ir-keytable -t -v
- Edit the file
/etc/rc_maps.cfgto ensure that this keymapping is loaded automatically on bootup. There are a lot of comments in the file, and a lot of options selected by default, but I just commented out all the entries and added this line to the file:
* * /etc/rc_keymaps/Sony_RM-ADP090.toml
(This keymapping seems to take effect 30-60 seconds after the system boots up.)
- Test that the keytable is automatically loaded correctly by running this command:
and then pressing some buttons on the remote control. Again you want to see messages like
- Certain keycodes control Archlinux/MPD behaviour by default: for example,
KEY_PLAYautomatically causes MPD to toggle play/pause (equivalent of
mpc toggle), and
KEY_POWERcauses the system to power off. The automatic key bindings that I have found are as follows:
KEY_LEFT– previous track
KEY_UP– increase mpc volume
KEY_RIGHT– next track
KEY_DOWN– decrease mpc volume
KEY_POWER– powers down the system
KEY_PLAY– toggle play/pause
KEY_MUTE– mute the output
KEY_VOLUMEUP– increase mpc volume
KEY_VOLUMEDOWN– decrease mpc volume
This means that supposing you want the red button on your control to power off the pi and the scancode generated by the red button on the remote control is
0x103005, then you can cause this to happen by putting the following entry in the keymap file:
0x103005 = "KEY_POWER" # code for red button
Conversely if, for example, you want to ensure that no button on the remote control will cause the pi to power down then don’t map any scancode to the
It is possible to map more than one scancode to a particular keycode. For example when I decided that I wanted to the following operations to be performed:
– Left arrow and up arrow: previous track
– OK button: toggle play/pause
– Right arrow and down arrow: next track
my keymap file just needed to contain the following:
name = "sony_RM-ADP090"
protocol = "sony"
variant = "sony20"
0x101078 = "KEY_LEFT" # KEY_UP button -> Previous track
0x10107a = "KEY_LEFT" # KEY_LEFT button -> Previous track
0x10107c = "KEY_PLAY" # KEY_OK button -> Play/pause
0x10107b = "KEY_RIGHT" # KEY_RIGHT button -> Next track
0x101079 = "KEY_RIGHT" # KEY_DOWN button -> Next track
If you can meet your requirements by using the automatic key bindings to mpc commands then this is all you need to do!
- If you want to perform some of the MPD operations not covered by the default key bindings listed above (for example, you wanted a button on the remote control to cause an
mpc stopor an
mpc repeat oncommand) then you can do this by installing Triggerhappy. This is described at https://github.com/wertarbyte/triggerhappy as ‘a hotkey daemon developed with small and embedded systems in mind, e.g. linux based routers. It attaches to the input device files and interprets the event data received and executes scripts configured in its configuration.’
(One idea I had is to use Triggerhappy to trigger a script that would power down the pi if, for example, a certain set of buttons were pressed within a short period of time, as it would be useful to be able to use the remote control to shut down the pi, but I’d like to to avoid powering it down accidentally. However I haven’t gone any further with that idea.)
The Archlinux repository does not appear to have a version of Triggerhappy which works on armv7h architecture, so I found the most reliable method was to fire up a Raspbian/Raspberry Pi OS system, install Triggerhappy, save the relevant files and copy them across to the RuneAudio system. (If you’re interested I have written more about the other options that I tried at the foot of this article.)
On a Raspbian system, install Triggerhappy by running the following commands:
sudo apt-get updateThen copy the files listed below onto a local PC, or a memory stick/thumbdrive/USB flash drive.
sudo apt-get install triggerhappy
|Filename||Permissions/ownership||Directory on Raspbian||Directory on RuneAudio|
On the RuneAudio system create a directory, say,
/tmp/triggerhappyTempSave, and copy the saved Triggerhappy files to that directory.
Then run the following commands:
Set the permissions:
chmod 644 /tmp/triggerhappyTempSave/*
chmod 755 /tmp/triggerhappyTempSave/thd
Create the required directory:
mkdir -p /etc/triggerhappy/triggers.d/
Move the files to their correct directories:
mv /tmp/triggerhappyTempSave/triggerhappy.service /usr/lib/systemd/system/
mv /tmp/triggerhappyTempSave/triggerhappy.socket /usr/lib/systemd/system/
mv /tmp/triggerhappyTempSave/triggerhappy.conf.examples /etc/triggerhappy/triggers.d/
mv /tmp/triggerhappyTempSave/thd /usr/bin
- Run Triggerhappy interactively by running the following command:
thd -d /dev/input/event*
Then press some keys on the remote control. You should see some output similar to the following:
EV_KEY KEY_1 1 /dev/input/event0 # KEY_1 1 command EV_KEY KEY_1 0 /dev/input/event0 # KEY_1 0 command EV_KEY KEY_2 1 /dev/input/event0 # KEY_2 1 command EV_KEY KEY_2 0 /dev/input/event0 # KEY_2 0 command EV_KEY KEY_3 1 /dev/input/event0 # KEY_3 1 command EV_KEY KEY_3 0 /dev/input/event0 # KEY_3 0 command EV_KEY KEY_RED 1 /dev/input/event0 # KEY_RED 1 command EV_KEY KEY_RED 0 /dev/input/event0 # KEY_RED 0 command EV_KEY KEY_GREEN 1 /dev/input/event0 # KEY_GREEN 1 command EV_KEY KEY_GREEN 0 /dev/input/event0 # KEY_GREEN 0 command EV_KEY KEY_YELLOW 1 /dev/input/event0 # KEY_YELLOW 1 command EV_KEY KEY_YELLOW 0 /dev/input/event0 # KEY_YELLOW 0 command EV_KEY KEY_BLUE 1 /dev/input/event0 # KEY_BLUE 1 command EV_KEY KEY_BLUE 0 /dev/input/event0 # KEY_BLUE 0 command
- Create a trigger definitions file, such as
This specifies what actions should be performed when a given key is pressed.
The file can have any name, but it needs to be in
You will find examples in
More information about the syntax of the configuration file can be found at http://manpages.ubuntu.com/manpages/bionic/man1/thd.1.html
Here is an example of the contents:
KEY_RED 1 /usr/bin/mpc stop
KEY_GREEN 1 /usr/bin/mpc repeat on
Run this interactively and display the output:
thd --dump --triggers /etc/triggerhappy/triggers.d /dev/input/event*
(This will look for trigger definitions in any file in the
Then press the red key – you should see something similar to the following:
EV_KEY KEY_RED 1 /dev/input/event0
KEY_RED 1 command
Executing trigger action: /usr/bin/mpc stop
volume:100% repeat: off random: off single: off consume: off
EV_KEY KEY_RED 0 /dev/input/event0
KEY_RED 0 command
- You can list all the key events that Triggerhappy will react to by running this command:
Note that this also includes additional events of the form
BTN_TRIGGER_HAPPYnnso if, for example, you wanted to perform an action when the button labelled ‘FOOTBALL’ on the remote control is pressed you could add something similar to the following to the keymap file in
0x107017 = "BTN_TRIGGER_HAPPY10" # Button labelled 'FOOTBALL'
and then add an entry for
- Enable the triggerhappy service and start it:
systemctl enable triggerhappy
systemctl start triggerhappy
systemctl status triggerhappy
This should look similar to the following:
root@runeaudio+R e4:~ # systemctl enable triggerhappy root@runeaudio+R e4:~ # systemctl start triggerhappy root@runeaudio+R e4:~ # systemctl status triggerhappy * triggerhappy.service - triggerhappy global hotkey daemon Loaded: loaded (/usr/lib/systemd/system/triggerhappy.service; enabled; vendor preset: disabled) Active: active (running) since Fri 2020-08-07 15:59:15 BST; 6s ago Main PID: 2247 (thd) Tasks: 1 (limit: 2140) CGroup: /system.slice/triggerhappy.service `-2247 /usr/sbin/thd --triggers /etc/triggerhappy/triggers.d/ --socket /run/thd.socket --user nobody --deviceg> Aug 07 15:59:15 runeaudio systemd: Starting triggerhappy global hotkey daemon... Aug 07 15:59:15 runeaudio systemd: Started triggerhappy global hotkey daemon. lines 1-10/10 (END)...skipping... * triggerhappy.service - triggerhappy global hotkey daemon Loaded: loaded (/usr/lib/systemd/system/triggerhappy.service; enabled; vendor preset: disabled) Active: active (running) since Fri 2020-08-07 15:59:15 BST; 6s ago Main PID: 2247 (thd) Tasks: 1 (limit: 2140) CGroup: /system.slice/triggerhappy.service `-2247 /usr/sbin/thd --triggers /etc/triggerhappy/triggers.d/ --socket /run/thd.socket --user nobody --deviceg> Aug 07 15:59:15 runeaudio systemd: Starting triggerhappy global hotkey daemon... Aug 07 15:59:15 runeaudio systemd: Started triggerhappy global hotkey daemon.
And that’s it all done!
Here are some articles that I found useful when setting up my system:
- This article discusses IR hardware options for the infrared receiver and also many of the principles described above: https://blog.gordonturner.com/2020/05/31/raspberry-pi-ir-receiver/
- This article provides additional information about testing ir-keytable: https://mauricius.dev/configure-an-infrared-remote-control-with-linux/
- This page defines the format of rc_keymap: https://manpages.debian.org/testing/ir-keytable/rc_keymap.5.en.html
- This page provides information about the configuration of the Triggerhappy configuration file: http://manpages.ubuntu.com/manpages/bionic/man1/thd.1.html
- This very interesting article discusses the coding used by Sony IR remote controls: http://www.righto.com/2010/03/understanding-sony-ir-remote-codes-lirc.html
Further notes on installing Triggerhappy on RuneAudio
If you run:
pacman -S Triggerhappy
then you get:
error: target not found: Triggerhappy
Although Triggerhappy exists in the Archlinux repository, when I tried running
makepkg on it I got an error indicating that armv7h architecture isn’t supported.
Nishil Kohli has described how to compile Triggerhappy for Archlinux at https://nishil.in/blog/Turn-on-off-appliances-using-a-TV-remote-and-Raspbery-Pi/ . (In fact he is using RuneAudio.) I followed a process similar what he described to compile Triggerhappy, but I needed to use a different approach to set it up to run as a service. This is the process that I tried:
cd ~ mkdir triggerhappywork cd triggerhappywork pacman -Sy # update the repos pacman -S guile make gcc git # install dependencies and build tools git clone https://github.com/wertarbyte/triggerhappy cd triggerhappy make make install copy /root/triggerhappywork/triggerhappy/systemd/triggerhappy.s* /usr/lib/systemd/system/
This all worked fine with RuneAudio+R e3, and it would work interactively with RuneAudio+R e4, but when I tried to start the service on e4 it did nothing until it eventually timed out and failed – so that’s why I adopted the process that I described above.