Extending the remote control capabilities of LIRC

If you have installed the LIRC package on your computer so that it can receive signals from an infrared remote control (as we showed how to do in Ubuntu 18.04 in our previous article, Make LIRC work in Ubuntu 18.04, so that you can use your infrared remote in Kodi), you may have thought that you could only utilize it inside programs that have remote control support built-in, such as Kodi.  But did you know that you can also use your remote to execute any command that can be executed from a Linux command prompt, or even run a shell script to execute multiple commands?

In order to do that you need to do at least two things.  First, you need to run the irexec program (which is installed as part of the LIRC package), and second, you need to create a .lircrc file in your user directory.  In addition, you may wish to create shell scripts to do whatever you want.

An example may make things easier to understand.  Let’s take the case of starting or restarting Kodi from the desktop.  Let’s say you have just started up your system and it is sitting at the desktop waiting for you to start a program, and you want to start Kodi.  Sure, you could use your mouse to select Kodi and start it, but it’s more convenient to just be able to push a button on the remote to do it.  Or maybe you have been using Kodi and it has simply frozen up on you – wouldn’t it be nice to be able to push a button, kill the frozen instance of Kodi, and then restart Kodi?

Windows Media Center Edition compatible remote controlMost Windows Media Center Edition compatible remotes have four colored buttons, colored red, green, yellow, and blue, that don’t do anything inside Kodi by default. But, LIRC still recognizes them, and they are perfect for use in such an application.

The first thing you would need is a script to start Kodi.  Here’s a bash script that we use with Kodi 17.  Note that in Kodi 18 (at least in beta versions) some changes will need to be made, and these are noted in comment lines. Also note the comment about changing the value of yourusername in the “export USER=” line:

#!/bin/bash
# For Kodi V18 change AE_SINK=ALSA to KODI_AE_SINK=ALSA and
# all instances of kodi.bin to kodi-x11

# In the line below replace yourusername with your actual
# user name in Ubuntu (this will probably be the same as
# the name of your user directory)
export USER=yourusername

# Now try to kill existing Kodi if it is running
if ps -ef|grep -v grep|grep -i kodi.bin
then
ps aux|grep -i $USER|grep -v grep|grep -i kodi.bin|awk '{print $2}'|xargs kill
sleep 3
fi

# If it's still running, force kill it using kill -9
if ps -ef|grep -v grep|grep -i kodi.bin
then
ps aux|grep -i $USER|grep -v grep|grep -i kodi.bin|awk '{print $2}'|xargs kill -9
sleep 3
fi

# If it's STILL running it won't die, so exit
if ps -ef|grep -v grep|grep -i kodi.bin
then
exit
fi

# Delete old Kodi crashlogs (optional)
/bin/rm -f ~/kodi_crashlog-????????_??????.log

# Start Kodi using ALSA sound system
AE_SINK=ALSA nice -20 kodi --standalone &
exit

We saved this script as startkodi.sh and made it executable:

chmod +x startkodi.sh

Please note that we start Kodi with some specific options that you may or may not wish to use. To break them down:

AE_SINK=ALSA (this will change to KODI_AE_SINK=ALSA in Kodi 18): This usually forces Kodi to use the ALSA sound system rather than PulseAudio, which can give better performance if you are using passthrough audio in a multichannel system (5.1 or 7.1 audio). We say usually because on at least one system it was necessary to take more aggressive steps to kill PulseAudio before this would work (see the section headed “Disabling daemon autospawn” on this wiki page if you have this problem). You will know if it is working because you’ll need to reset your audio output under System Settings | System | Audio to use the ALSA output (and the PulseAudio options will disappear). If you are not using passthrough audio (using the “Allow passthrough” setting, and selecting a Passthrough audio device), then there is probably no reason to use this.

nice -20: This gives Kodi more CPU time than other processes that may be running at the same time, and therefore helps avoid jerkiness and dropped frames during playback.

kodi - -standalone: The recommended way to run Kodi from a shell script. (Please note there is a hidden character between the two – (hyphen) characters in this line, to force WordPress to display it correctly, so if you copy and paste this it won’t work if you don’t remove that hidden character.  Unfortunately, this is the case anyplace you see two adjacent hyphens in this article, except when they are within a code block.)

&: The ampersand at the end allows the script to exit immediately, without shutting down Kodi. It effectively makes Kodi a background task.

So that is the script we use to start Kodi, and of course we could run that from a terminal window (which you may want to do in order to check for errors), but that would not be very convenient. So, we use the .lircrc file (in the user’s home directory) to start the script when a button is pressed. We’ll use the green button in this example. Start by editing the file .lircrc (if it doesn’t already exist, this should create it):

nano ~/.lircrc

And just paste in these lines:

begin
 prog = irexec
 button = KEY_GREEN
 config = ~/startkodi.sh &
 repeat = 0
end

Then you can use Ctrl-X to exit nano (be sure to save the file).

The only other thing you need to do is make sure that the irexec program runs at startup. To do that, from the Ubuntu desktop bring up Startup Applications, and when it comes up click the Add button and enter these values:

Name: irexec
Command: irexec -d
Comment: Whatever you want, we used “Infrared Remote Control”

Add irexec to startup programs
Click the Add button to save it.

Then REBOOT THE SYSTEM.

Once the system has rebooted, you should be able to press the green button and it should run the startkodi.sh script and start Kodi. If it doesn’t, it’s probably because your remote is using different labels for the buttons, and we’ll cover how to determine that in a moment.  In case you are wondering, the -d option used with irexec is what makes it run as a background task.

Now maybe you’d like to be able to push the red button to stop Kodi in case it is hung, but without restarting it.  All you need to do is copy the startkodi.sh script to another script (call it stopkodi.sh), then edit that script to remove the line that starts Kodi, and then edit the .lircrc configuration to add another section:

begin
 prog = irexec
 button = KEY_RED
 config = ~/stopkodi.sh &
 repeat = 0
end

We can also run system commands directly from the .lircrc file. Let’s say we wanted to use the blue button to reboot the system, in case things really get messed up. We could add this to .lircrc:

begin
 prog = irexec
 button = KEY_BLUE
 config = sudo reboot
 repeat = 0
end

You would think this would work, but it won’t because when it tries to run sudo it will prompt for your password, and the script can’t deal with that. In order to avoid that, you’ll need to edit the /etc/sudoers file:

sudo nano /etc/sudoers

Move the cursor to the end of the file and on a new line add this:

yourusername ALL = NOPASSWD: /sbin/reboot

Replace yourusername with your your actual user name in Ubuntu. Use Ctrl-X to exit nano, and save the file. This allows running “sudo reboot” without needing to enter a password.

Remember that you will need to REBOOT THE SYSTEM before any changes take effect!

Now, if you are lucky these .lircrc configurations will work as shown. But if you have a different type of remote, you may need to use different buttons, or maybe the buttons aren’t returning the values that .lircrc is expecting to see. To determine that, from a Linux command prompt run this:

irw

Then while watching the terminal window or ssh session, press the buttons you are trying to use on the remote. As an example, here is what we see when we press the green button:

$ irw
000000037ff07ba3 00 KEY_GREEN mceusb
000000037ff07ba3 01 KEY_GREEN mceusb

Press Ctrl-C to exit irw. The thing you are looking for here is the button name, in this case it is KEY_GREEN as shown in the .lircrc section that starts Kodi above, but if your remote returns something other than that, that’s what you’ll need to use in the .lircrc file.  By the way, it is not unusual for a remote to send a button press two or three times in a row, just in case the infrared receiver misses it the first time.  This is not a cause for concern.

When you use irw as shown above, remember that lirc is still running, so don’t press any buttons that would take any action you don’t want to have happen, such as rebooting the system or launching Kodi or something else.

ADDING ADDITIONAL BUTTONS FROM THE SAME OR A DIFFERENT REMOTE

When you use irw, there’s a slight chance you might notice that your remote has one or more buttons that don’t generate any output at all, and maybe you’d like to make them recognized. Or, maybe you’d like to use a second remote (perhaps one that came with a device that you no longer use) to control some additional functions. These things are possible (usually) but the procedure is slightly complicated. One thing to keep in mind is that infrared receivers are only responsive to a certain part of the spectrum of infrared light, and some remotes may generate light pulses outside that range, in which case a particular remote may not work with a particular infrared receiver. But it’s worth a try.

Here’s the basic procedure for getting LIRC to recognize additional buttons:

Open the file /etc/lirc/lircd.conf in a text editor, or just do cat /etc/lirc/lircd.conf from a Linux command prompt, and note the contents – more than likely it will contain an “include” statement such as

include "/usr/share/lirc/remotes/mceusb/lircd.conf.mceusb"

Open THAT file in a text editor and note how it is constructed. You will probably see definitions for one or more remotes, in sections between “begin remote” and “end remote” tags. In each such section you will see a list of codes, in sections between “begin codes” and “end codes”, and in such sections you will see two columns. The first is a list of names that have already been used for existing remote buttons, and that you therefore should not use when adding new buttons.

However, you cannot just go using any button names you like for your new buttons. You can only use the button names that are shown when you run this command from a Linux command prompt:

irrecord - -list-namespace

(Please note there is a hidden character between the two – (hyphen) characters in the above line, to force WordPress to display the line correctly, so if you copy and paste the above it won’t work if you don’t remove that hidden character.)

So to try to make this clear, when naming a new button you can only use names that appear in the list you get when you run irrecord - -list-namespace but you should NOT use names that appear in the /etc/lirc/lircd.conf file, or in any file that is mentioned in an include statement within that file, because you run the risk of specifying the same button name for two different buttons.

You may have to read that a couple of times for it to sink in, but it’s important. You will probably want to find a way to keep both lists visible during the next steps. You could open them in two different Text Editor windows, or two different terminal windows, or two different ssh sessions from another computer – it really doesn’t matter as long as you can refer to both lists, and know which is which.

Now you are ready to try to map new buttons. During this process, lircd cannot be running, so do this:

sudo killall lircd

Next, run this command:

sudo irrecord -d /dev/lirc0 ~/newremote.txt

The character at the end of lirc0 is a zero, not a letter O. You can use any filename you want rather than “newremote.txt”, just make sure it’s a filename you aren’t already using. When using irrecord, don’t try to add buttons from more than one remote in a single run, and if you make a mistake just Ctrl-C out, delete the “newremote.txt” file, and start over. Also, note the above line assumes that /dev/lirc0 is the correct path for LIRC’s connection to your infrared receiver, which is almost always the case.

The irrecord program will walk you through the entire procedure for adding new buttons — just follow the instructions it gives precisely. It will first have you perform some tasks so it can determine basic timing information about your remote.  If irrecord can’t seem to detect your remote, it may be that the remote isn’t compatible with your infrared receiver, or it may be that the batteries are dead in the remote! Don’t give up on a remote without at least trying new batteries.

After the preliminary tasks are completed, irrecord will ask you to enter the name of a button. This is when you will refer to the two lists — remember, you want to use a name that DOES appear in the irrecord - -list-namespace list, but that does NOT currently appear in /etc/lirc/lircd.conf or in any file referenced by an include statement therein (such as /usr/share/lirc/remotes/mceusb/lircd.conf.mceusb in our example above).  Just to be clear, there is no requirement that the names you use in this procedure be in any way related to the names of the buttons on the remote, since you will be defining what the button press actually does in the .lircrc file.  It may be convenient to use a related name (if it’s not already used in another remote’s codes list) to help you remember which button is associated with which name, but if you can’t find an unused name that comes close to the name of the button on your remote,  it’s perfectly okay to pick any unused name from the irrecord - -list-namespace list and use that, though in that case you may want to make notes about which names are associated with which buttons.

After you enter the name, it will ask you to hold down the button on the remote. After a few moments it should ask you to enter the name for your next button – that is your confirmation that the button was accepted by your infrared receiver. You can keep on adding new buttons from the same remote, or exit by pressing only the Enter key when asked for the name of the next button.

Once you have exited irrecord, you must open the file it created (~/newremote.txt, or whatever name you used) in a text editor, and change the value on the name line (right below the line that reads “begin remote”) to something that is all lowercase letters with NO SPACES – underscore characters are okay, though.  So, something like

 name new_remote

would be fine.  The name must not duplicate the name in any of your existing remote definitions.  Also, we always remove all the commented-out lines produced by irrecord (lines that begin with a # character), since they are not needed.

After you have made those changes, copy the section starting with “begin remote” and ending with “end remote” to the clipboard, and then open the file containing your other remote definitions and carefully paste your new remote definitions to the end of that file (leave at least one blank line after the existing contents of the file before pasting).  By “the file containing your other remote definitions” we mean either /etc/lirc/lircd.conf or the file that is mentioned in an include statement within /etc/lirc/lircd.conf, such as /usr/share/lirc/remotes/mceusb/lircd.conf.mceusb in our above example (we used the latter).  The basic idea is you want to put your new remote definitions and codes at the end of the same file that contains all the other remote definitions and codes. BE CAREFUL when doing this because if you somehow screw up this file, your remote may not work at all!  It probably isn’t the worst idea to make a backup of the file prior to making any changes.

If you don’t want to mess with your existing remote definitions file, you could probably add a new include line within /etc/lirc/lircd.conf and point that to a new file that you have created that contains your new remote definitions.  That is supposed to work, according to the LIRC documentation, but we haven’t actually tested doing it that way (please note that the LIRC documentation link takes you to the documentation for the latest version of LIRC, and therefore some parts may not be applicable if you are using an older LIRC version).

Note that if you were trying to add buttons from your main remote that LIRC has not previously recognized for some reason, you will probably want to add just those new codes directly to the existing codes list for that remote, rather than copying the entire new block of remote definitions.

You will probably want to save a backup of your new remote definitions someplace, so you don’t have to go through this process again the next time you upgrade the system!  This comment comes from experience — during our most recent Ubuntu upgrade, we backed up the entire home directory and some specific configurations from the /etc directory, but we totally forgot about the remote definitions that we had put into the /usr/share/lirc/remotes/mceusb/lircd.conf.mceusb file, so we had to do redo this process.

Once you have added your new remote definitions and codes to the file containing your existing remote definitions and codes and saved it, you should REBOOT THE SYSTEM so that lircd will restart and read in the new codes.  After the system is rebooted, you can once again run irw and now when you press one of the buttons you added, it should show the name that you assigned to the button.  And if that works, you can then use that button name in the .lircrc file to launch shell scripts or system commands, or do just about anything you could do from a Linux command prompt.

Addendum:  Mind the Gap!  No, we haven’t been riding the London underground, but we have discovered that on some systems, but not others for some weird reason, if you add remote definitions that contain a “gap” value in the headers — which almost all added definitions will — it may cause LIRC to stop working altogether if for whatever reason irexec doesn’t like the gap value.  So if you have a gap value that is a bit on the high side (near or above 100000) you may need to reduce the gap value to get things working again.  For example in one case the gap value should have been 108382, but we wound up having to reduce it to 80000 on just one system for it to work, even though the higher value works fine on several other systems, and even though some of the other remote definitions had higher gap values.  The real issue is that if you get bitten by this, your remote won’t work at all until you change the gap value to something that irexec approves of — it will just silently fail to recognize your remote! This may even be a problem when you are copying remote definitions from one system to another — the gap value that works just fine on one system will cause the failure of your remote control to work at all on a different system.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.