This guide tries to describe the basic configuration steps for commonly used hardware. It's focused on the basic usage scenario to get the remote up and running, the more advanced features are not covered. This includes irexec, lircmd, ir blasting and the TCP/IP-based remote features.
Recent Linux kernels have built-in support for IR remotes. Using that, pressing an up-arrow on the remote works the same way as pressing the up-arrow on a keyboard. This is a modern "just works" solution. On the other hand, LIRC is an old style linux application which can be tweaked to do almost anything, but is tricky to setup. So, why would you use LIRC?
So, while the kernel built-in handling works out of the box in many cases, there are still scenarios when LIRC is the right tool.
---------- --------------------- ---------- | | | | | | | |---->----| Linux input layer |------->-------| Appli- | | | | | /dev/input | cation | | | --------------------- | | --->---| kernel | | | ---------- remote | | devinput v | | | | ^ uinput | | | | ---------- | | --------------------- | Appli- | | |---->----| lirc |------->-------| cation |-- | | | | /var/run/lirc | | | ---------- --------------------- ---------- |-- | | | ---------- | | | ----------
LIRC can be run together with the kernel in different ways. You need to decide on a general approach first.
Depending on whether lirc is used or not application will get data either from the input layer (/dev/input) or from LIRC (/var/run/lirc). Using the LIRC data requires application support. Support for LIRC is common in typical linux htpc applications like mythtv, xbmc and vlc.
The /var/run/lirc interfaces allows several applications to receive input events. On the other hand, the /dev/input interfaces only allows one application to receive the events.
If you need to use lirc, there is two cases depending on if your remote is supported by the kernel or not.
Last option is to connect the LIRC driver to the linux input layer using LIRC's --uinput option. This means that application sees the input as coming from the kernel, and LIRC's other capabilities are not available. This is not described here.
------------ | remote | ------------ (air gap) ------------ ! capture ! ! device ! ------------ | v | ------------ ! kernel & ! ! driver ! ------------ | v | ------------ Often needs a device e. g., | lirc | /dev/input/eventXX | driver | ------------ | v IR pulse data Use mode2(1) to debug. | ---------------- | lirc pass 1 | lircd.conf config file. ---------------- | v Key symbols Use irw(1) to debug. | ---------------- | lirc pass 2 | lircrc config file. ---------------- | v Application strings Use ircat(1) to debug. | ApplicationsThe overall lirc blues:
To determine the driver to use you might need to know the name of your capture device, what module the kernel has loaded for it and the kernel device it's connected to.
If our remote is bundled with a capture device such as a usb dongle, your first stop is the remote database. If you can find your device here, look in lircd.conf file's header for the following comment:
this config file was automatically generated # using lirc-0.8.5-CVS(awlibusb) on Thu Oct 30 11:03:30 2008Here you can learn that this file was recorded using the awlibusb driver. Take a note to the final decision.
Next thing to do is to invoke ir-keytable:
$ ir-keytable Found /sys/class/rc/rc0/ (/dev/input/event11) with: Driver em28xx, table rc-pinnacle-pctv-hd Supported protocols: NEC RC-5 RC-6 Enabled protocols: RC-5 Extra capabilities:If you get this kind of output you know the event device (/dev/input/event11) and the kernel module loaded (em28xx). Furthermore, since ir-keytable finds the device you know that the driver is part of the rc subsystem. Not all devices are recognized by ir-keytable, though.
Next step is to inspect dmesg, possibly after reconnecting your device. If you have a standard IR remote which is recognized by the kernel you can find how it's registered as rc0:
usb 3-2: Product: eHome Infrared Transceiver Registered IR keymap rc-rc6-mce input: Media Center Ed. eHome Infrared Remote Transceiver (0609:031d) as /devices/pci0000:00/0000:00:14.0/usb3/3-2/3-2:1.0/rc/rc0/input16 rc0: Media Center Ed. eHome Infrared Remote Transceiver (0609:031d) as /devices/pci0000:00/0000:00:14.0/usb3/3-2/3-2:1.0/rc/rc0 input: MCE IR Keyboard/Mouse (mceusb) as /devices/virtual/input/input17 rc rc0: lirc_dev: driver ir-lirc-codec (mceusb) registered at minor = 0If you just find something like this you have a device which isn't an ir device (in this case an RF remote):
usb 2-2: Product: RF receiver usb 2-2: Manufacturer: X10 WTIEven if you have an ir device, you might see something like this if the kernel sees it as a keyboard rather than a remote. Here, an usb keyboard from JITTEL:
Product: JTTEL Composite Devices hid-generic 0003:20E8:5820.0001: input,hidraw0: USB HID v10.01 Keyboard [JTTEL Inc. JTTEL Composite Devices] on usb-0000:00:1d.1-1/input0
For devices like these which not are registered as rc devices (and thus not recognized by ir-keytable) you need to find out the corresponding event device as described in Appendix 2 .
Knowing the capture device name, the kernel module loaded (if any) and perhaps also a /dev/input device you have to select a driver:
--driver devinput --device /dev/input/event11
--driver default --device /dev/lirc0
----------------- | kernel | ----------------- | v | ----------------- | input layer | ----------------- | v /dev/input/eventX Use ir-keytable to manage and debug | ---------------- | lirc | Use devinput driver | | Use lircd.conf.devinput ---------------- | v key symbols Use irw to debug |
If you're lucky, your remote is already supported by the kernel. In order to find out, the first task is to locate the event device, something like /dev/input/event12 which is connected to your IR device. This is described in appendix 2.
With the device known use ir-keytable to test if your remote works:
# ir-keytable -t -d /dev/input/event13Press buttons on the remote. If it starts to print out scan codes and key symbols everything is fine. Otherwise, try to change the protocol (see the ir-keytable manpage). If this doesn't work, it might be the end of the road and you might need to use the lirc driver option instead.
Check that all buttons generate output when testing. If there are buttons which are not mapped (no key symbol) you might not be able to fix this unless you go for the lirc driver option (to change the key symbol is perfectly possible, but probably not what you want here).
Then, grab the devinput/lircd.conf.devinput file (remotes) and copy it to /etc/lirc/lircd.conf. Start the lircd daemon and use irw to check:
$ lircd --device /dev/input/event13 --driver devinput $ irwPress remote buttons. You should see the key symbols being printed. When so you are done and can proceed to Convert key symbols to application strings
Depending on your box, it might be that the event device found this way changes after a reboot. If this becomes o problem, look into appendix 6
--------------------------------- | kernel devices | --------------------------------- | | kernel rc driver | Needs configuration | -- ----------------- | | v v raw pulse data | | --------------- | | LIRC driver |---------- --------------- | v pulses Use mode2 to debug. | --------------- | LIRC pass 1 | lircd.conf --------------- | v keysyms Use irw to debug
You have already determined the driver and perhaps device to use. Make sure the lirc driver can read the remote, and produce pulses:
lirc pass 1: Using lircd.conf, convert pulses to key symbols like KEY_UP:
The lircd.conf is the file which lircd uses to read data from the driver and then convert (or decode) it to key symbols. It's the single most important lirc configuration file. There are some ways to install such a file:
$ lircd --driver default --device /dev/lirc0Verify the results using irw(1). Check all buttons!
| v keysyms Use irw to debug. | --------------- | LIRC pass 2 | ~/.config/lircrc --------------- | | /var/run/lirc/lircX v config strings | Use ircat to debug. | --------------- | Application | ---------------
By now you should know the driver and device used when running lircd. Update the configuration file /etc/lirc/lirc_options.conf with the driver and device you have determined. You should then be able to start, stop and inspect the service status using:
# systemctl start lircd.socket # systemctl stop lircd.socket # systemctl status lircd.socket lircd.service # journalctl -b 0 /usr/sbin/lircd
Using ~/.config/lircrc, convert the key symbols to application-specific strings:
Test the application, and investigate further steps:
When using an LIRC ir driver, the kernel ir driver must be configured to send the data only to the /dev/lirc device and not to the general input layer. If not, each button event will delivered twice to the application, both through /var/run/lirc and /dev/input.
As of 0.9.1+ this is configured automatically by lircd, and neither the echo 'lirc' >/sys/class/rc/... nor the udev rule should normally be required.
Also, some lirc drivers conflicts with the kernel drivers. A common example is the lirc atilibusb driver which conflicts with the kernel ati_remote driver. Another example is lirc serial drivers which conflicts with the kernel default tty driver. Such conflicts shows up as dmesg output about not being able to open the involved device, plus various other symptoms.
If required, the kernel driver configuration can be done using the interfaces under /sys/class/rc or using a udev rule. Conflicting kernel drivers must be blacklisted. Conflicts on serial ports can be handled by disabling the kernel serial driver for that port.
The builtin ir driver subsystem is aware of LIRC, and is capable to send all data through /dev/lirc0. If lircd fails to configure this automatically it can be done manually:
# echo -- 'lirc' > /sys/class/rc/rc0/protocolsHere, 'rc0' is OK if you have only one infrared device. Note that this is not persistent, you need to do this after each boot.
Using '-lirc' instead restores the normal kernel operation when stopping LIRC. >
Likewise, if lircd fails to configure the kernel automatically you can create a file /etc/udev/rules.d/99-remote-control-lirc like:
SUBSYSTEM=="rc", ATTR{protocols}="lirc"This is persistent and makes all ir devices send data only through /dev/lirc where it can be retrieved by the 'default' driver.
When using remotes which are not infrared, the corresponding driver is not affected by the methods above. One example is an RF remote I have which uses the atilibusb LIRC driver. This conflicts with the ati_remote kernel module, which thus needs to be disabled. Do this by creating the file /etc/modprobe.d/blacklist-atiremote.conf like:
# Conflicts with LIRC. blacklist ati_remoteFinding out what module to blacklist is not always easy. dmesg(1) sometimes gives a hint about conflicts on a device. Another method is to boot the system without the usb device connected, and do a lsmod. After that, connect the device and make a new lsmod. Comparing the different outputs might give a clue.
Usually the default kernel serial port driver grabs all ports it auto-detects as soon as it is loaded and the LIRC modules won't be able to use any of them.
There are two solutions for this problem. Either you load the LIRC module before the kernel serial port driver is loaded or you call setserial /dev/ttySx uart none to release the according port. setserial usually is already called during boot-up in some init script whose location depends on the distribution you use. You should check your setserial configuration to only configure available ports. Debian users should adjust their /etc/serial.conf.
For many tasks it's necessary to find out the event device, something like /dev/input/event12, which is connected to your IR input.
The first try is to invoke ir-keytable without any options:
$ ir-keytable Found /sys/class/rc/rc0/ (/dev/input/event11) with: Driver em28xx, table rc-pinnacle-pctv-hd Supported protocols: NEC RC-5 RC-6 Enabled protocols: RC-5 Extra capabilities:
If the reported device matches your expectations you're done - here we have /dev/input/event11.
If this doesn't work next try is to look in in /dev/input/by-id. If you find a device here which looks like your device, check where it's linked:
$ ls /dev/input/by-id usb-Plus_More_Enterprise_LTD._USB-compliant_keyboard-event-kbd usb-_Home_Infrared_Transceiver_TS0013Yn-event-if00 $ ls -l /dev/input/by-id/usb-eHome_Infrared_Transceiver_TS0013Yn-event-if00 lrwxrwxrwx [cut] /dev/input/by-id/usb-eHome_Infrared_Transceiver_TS0013Yn-event-if00 -> ../event13So, here your interface is /dev/input/event13, and your're done.
If this does not work, cat the input devices under /sys.
$ cat /proc/bus/input/devices > fooLook in foo to find this snippet about your device:
I: Bus=0003 Vendor=2013 Product=024f Version=0001 N: Name="em28xx IR (em28174 #0)" P: Phys=usb-0000:00:1d.7-1/input0 S: Sysfs=/devices/pci0000:00/0000:00:1d.7/usb1/1-1/rc/rc0/input14Here, the device is /dev/input/event14.
The driver list gives some hints on the usage for each driver. The important columns are "Hardware", "Required LIRC kernel module", "lircd driver" and "Default lircd and lircmd config files".
The "Hardware" column should be obvious. Note that it in many cases it refers to the receiver unit (e. g., the name reported by dmesg), not the name of the remote. So, before looking for a suitable driver use dmesg to find out the name as described in Appendix 2
The "lircd driver" refers to the argument you should give to lircd i. e., --driver=... You might need to check that the driver is available using irrecord -H help. If it's not listed here you need to rebuild lirc which is outside the scope of this document.
The "Required LIRC kernel modules" refers to modules that are part of the linux kernel. Some of these are regular modules and should be available in any reasonably updated linux system. However, some of these modules are part of the staging drivers and might not be available on your system.
To look for a particular module just search for it in /lib/modules e. g.,
$ find /lib/modules/$(uname -r) -name lirc_imon\* /lib/modules/3.12.7-300.fc20.i686/kernel/drivers/staging/media/lirc/lirc_imon.koIf it's listed, kernel should load it automatically on-demand. If it's not you have to build the staging drivers, also outside the scope of this document.
The Supported Remotes column reflects what kind of lircd.conf files which are supported. Common values are 'Any' meaning that any file from the website could be used or 'bundled' meaning that the driver requires a specific config file. In some cases any file can be used if it conforms to some limitation.
Unfortunately, the driver list does not provide information on the device which should be used for a particular driver. The only way to be sure is actually inspecting he sources. You might try to search the web before walking this path, though.
Several of the pre-defined remotes uses non-standard key symbols. This is a Bad Thing, which makes it harder to create the ~/.config/lircrc file in next step. It's also a prblem when using the uinput option, or when converting to use the build-in decoding.
You should replace all non-standard definitions with standard key symbols where it's possible. Some buttons might not be possible to map to standard symbols is a sane way, and could be left as-is. But the vast majority of buttons should use standard symbols. The standard symbols a. k. a. the namespace, is listed by irrecord -l.
The script lirc-config-tool is helpful here. List all non-standard symbols in lircd.conf:
$ lirc-config-tool -s -c /etc/lirc/lircd.confUpdate the lircd.conf file with standard key symbols as applicable:
$ sudo lirc-config-tool -u -c /etc/lirc/lircd.conf
The .lircrc file basically combines the remote buttons with application capabilities. To actually write a .lircrc file from scratch is not that hard, but it's a lot of work. lirc-config-tool can save some of this work by creating a starting point. For this to work , the lircd.conf file must be in place.
The first step is to check if your application is supported by the script:
$ ./lirc-config-tool -lif you find your application here, you can make an .lircrc for that app:
$ ./lirc-config-tool -o . vlcIf you're using the devinput lircd.conf, create a new version of that file which only contains the key symbols you are actually using. Use this instead in the -c option to let lirc-config-tool make it's work. The generated file will look like (excerpt!)
# Created by /home/al/bin/lirc-config-tool at tis dec 3 23:26:18 CET 2013 # See http://wiki.videolan.org/How_to_Use_Lirc begin prog = vlc button = KEY_REWIND config = key-rewind end begin prog = vlc button = KEY_FASTFORWARD config = key-faster end begin prog = vlc button = KEY_NEXT config = key-next end # Unused buttons: # # KEY_HOME # KEY_GREEN # KEY_RED # KEY_YELLOW # # Unused capabilities: # # # begin # prog = vlc # button = KEY_EXIT # config = key-quit # end # # begin # prog = vlc # button = KEY_PLAY_PAUSE. # config = key-play-pause # end # # begin # prog = vlc # button = KEY_PLAY # config = key-play # end #
The comments are about buttons which havn't found a use, and capabilities in the program (vlc) which are not bound to a button. Obviously, this saves some work.
The lirc-config-tool has a -h and a manpage option for more info.
BEWARE: The configuration file generated this way is a starting point. It needs to be inspected and tweaked before it actually does it's job.
When using the devinput driver, input devices like /dev/input/event12 might come up as another device after a reboot. If this becomes a problem, you should address the device using it's name or it's physical bus address.
The first step is to inspect dmesg after connecting the device. There you should find something like:
rc0: Media Center Ed. eHome Infrared Remote Transceiver (1784:0001) as /devices/pci0000:00/0000:00:12.0/usb4/4-4/4-4:1.0/rc/rc0Here you can see the device's name: "Media center Ed. eHome..." and it's address: ...usb4/4-4/4-4:1.0/rc/rc0.
As long as you have only one remote of each kind you can use simple name matching like in
--device=name='*eHome*'If you have several devices with the same name you need to use the address instead. Since this depends on how the device is connected, you lose if you disconnect the device and reconnect it to another socket. With this limitation you can use phys=*usb4/4-4/4-4:1.0* in the same way as name.
After having configured lirc, you might want to run irexec(1). Using this, you can bind remote buttons to any command you can run. It's typically used to shut down system, system volume controls etc.
There is two ways to run irexec, both with their pros and cons.
The first way is to run irexec as a system daemon. This can be done in many ways e. g., from a rc.local script or as a systemd service. Any way you will have security problems since running arbitrary commands and scripts as root is generally a bad idea. There is also the problem that irexec runs outside your session which means it's problematic to access the display, sound system and other resources typically bound to the session. On the other hand, this is flexible and since irexec runs as root it can in the end do anything
The second way to run irexec is to run is as a part of the session. A standard way to do this is to drop a irexec.desktop file in the config autostart directory, normally ~/.config/autostart. Doing so you can use your desktop tools to control the service. Also, since the service runs as part of your session, it can access the display, sound system etc.
The drawback is that since it runs as a regular user, it might run into permission problems e. g., when trying to shut down the computer. This can be handled using sudo, giving the user running irexec right to run specific commands otherwise requiring root permission. E. g., the following entry in /etc/sudoers allows the htpc user to restart gdm, effectively making a soft reboot:
## Allows members of the htpc group to restart session service %htpc ALL=NOPASSWD: /usr/bin/systemctl restart gdm.serviceAll in all, to configure irexec:
include
directive. Using this,
you can include files without changing them e. g., using a file like
include "/usr/share/lirc-remotes/ei/tv90" include "MKJ61842704"A relative path like MKJ61842704 is supposed to live in the same dir as the main lircd.conf file, usually
/etc/lirc
.
All-in-all, this is good method which preserves the original files
.conf
is
automagically included. One way to use this is to symlink remotes
from e. g., /usr/share/lirc-remotes to this directory. manual_sort
to 1 in any of the configs. Doing
so disables the automatic sorting.
In manual sort mode the remotes are used in the order they appear in the
config file. Files in lircd.conf.d are used in order defined by the
filenames. The recommended way to use this is to name the links to
00-my_first_remote.conf
, 01-next-remote.conf
etc.
To add the manual_sort attribute to an existing remote is actually a bad idea since it creates cross-depencies between configurations. A cleaner way is to add a dummy remote like this in lircd.conf.d (the name does not matter):
begin remote name manual_sort manual_sort 1 begin codes end codes end remote