- Architecture & Tools
LinHES 7 introduced a number of changes to the way remotes and associated devices are handled. This is largely being picked up from changes in the Linux base. The way remotes are now handled is significantly different and also requires a different tool set to build and diagnose an implementation. In general this new implementation is a significant improvement in what was previously a rather adhoc structure.
This guide will attempt to introduce you to the new architecture and tool sets relevant to LinHES.
The following picture is a logical representation of how various blocks in LinHES are connected.
As of LinHES 7, the remote drivers are included in the kernel whereas previously they were part of the lirc subsystem. If Lircd is not running then by default the Remote Driver will issue keyboard and/or mouse events. These events will be seen by higher level applications such as X and MythTV as if normal keyboard and mouse events occurred. Thus if you do not require certain lirc functions such as irexec and irxevent then you can quite happily not use lirc at all. Note, some remotes actually do issue mouse events such as certain imon remotes.
Each Remote Receiver will be identified by a unique device ID which will be associated by a driver that recognizes that ID. In most cases this should automatically make the needed associations. In some rare cases more than one driver may try to associate with the device which can cause conflicts. In these exceptional cases, this device can be blacklisted from the driver or the driver itself can be blacklisted.
The device ID can normally be found using tools such "lsusb" where you may see an entry similar to:
Bus 003 Device 002: ID 15c2:0043 SoundGraph Inc.
The driver does not actually know about the remote, it only sees the IR codes received by and translated by the Remote Receiver. The Remote Receiver may use any number of protocols (e.g. RC6, imon, etc) and its associated driver will normally understand all of the protocol variants that the Remote Receiver supports.
The Remote Driver will interact with the Remote Receiver in order to maintain the device and of course receive information from the remote itself. Depending on the Remote Receiver and associated Remote, the driver may separate the events as keyboard and mouse events. In this case you may see entries in "/dev/input/by-id" with entries such as "usb-15c2_0043-event-if00" and "usb-15c2_0043-event-mouse". Note in customization it is generally safer to specify a driver using its "/dev/input/by-id" path rather than the "/dev/input" path as the "/dev/input" path can change.
ir-keytable interacts with the driver and normalizes its output. It utilizes a keymap file normally found in "/etc/rc_keymaps" and the default association with the driver will be defined by "/etc/rc_maps.cfg"There are a number of things that you can do with ir-keytable including:
- Identify the driver and its protocols (eg. ir-keytable)
- Monitor the driver output of received events from the Remote Receiver (eg. ir-keytable -t)
- configure the driver for items such as protocols (eg. ir-keytable -p RC6, LIRC, etc)
- Load a specific or custom keymap for a driver (eg. ir-keytable -w /etc/rc_keymaps/imon_mce)
For example, in one of my systems ir-keytable returns:
# ir-keytable Found /sys/class/rc/rc0/ (/dev/input/event7) with: Driver imon, table rc-imon-pad Supported protocols: RC-6 other Enabled protocols: RC-6 Repeat delay = 500 ms, repeat period = 33 ms
I also force my imon receiver (to generate the above) to use the RC6 protocol and the imon_mce keytable instead of the default imon protocol and imon keymap using:
/usr/bin/ir-keytable -c -p RC6 -w /etc/rc_keymaps/imon_mce
I test the output of my driver using "ir-keytable -t" which yields output such as:
# ir-keytable -t Testing events. Please, press CTRL-C to abort. 1330396066.132941: event MSC: scancode = 800ff418 1330396066.132950: event key down: KEY_PAUSE (0x0077) 1330396066.132951: event sync
NOTE: for "ir-keytable -t" to work, lirc must not be running. Disable lirc using "sv stop lircd".
If your keymap file does not match the input protocol from the driver then you will only see output similar to:
# ir-keytable -t Testing events. Please, press CTRL-C to abort. 1330396066.132941: event MSC: scancode = 800ff418 1330396066.132951: event sync
It is important to note that if you use lirc then the code numbers (such as (0x0077)) are used by lircd.conf.
Remote Driver Event interface¶
The Remote Driver will output events to only one of the standard keyboard/mouse interface, /dev/lircd?, or devinput. If you do not enable lirc then the driver will default to the standard keyboard/mouse event interface. In most cases this will be fine for mythtv and will be the simplest way to implement your system.
If however, you want to use some of lirc's higher functions such as irexec (I use this to have my remote shutdown the system) then you will want to use one of the other interfaces. By default there is nothing to do to create devinput but to use /dev/lircd? you will need to specifically tell ir-keytable to use the lirc protocol in addition to any other protocols if it does not do so already. Use "ir-keytable" to see which protocols are enabled and see of LIRC is one of them. If not you can try "ir-keytable -p lirc" plus any other protocol such rc-6 to add it in.
If the lirc protocol is enabled and the driver supports it, you will see a file such as /dev/lircd0 or /dev/lircd1 etc. From here you can have lirc set up the way you always have in the past with your standard lircd.conf file. If the driver does not create /dev/lircd? then chances are it only uses devinput. If you have to use devinput then you will likely not be able to use your normal lircd.conf file but instead you will need to use the standard devinput version of lircd.conf which is in "/usr/share/lirc/remotes/devinput/lircd.conf.devinput".
Normally all of the current driver to lirc associations are handled in /etc/sv/lircd/run with a default to using /dev/lircd?
If the run file does not already do this then to hook lirc into the devinput interface you will need to create a file called /etc/runit/lirc.sh which contains a line similar to:
/usr/sbin/lircd -r -n --driver devinput -d /dev/input/by-id/usb-15c2_0043-event-if00 --output /var/run/lirc/lircd
In LinHES, LIRC is normally running and is initiated and configured by /etc/sv/lircd/run. To customize the lirc config files please refer to the Remotes wiki entry.
Note if you are using devinput you will need to use the devinput version of lircd.conf. Depending on the driver this may still require some minor modification. The lircd.conf entries must match the number output (e.g. 0x0077) that you saw using "ir-keytable -t". If it does not then you will not see any output from lirc.
To test the output of lirc, you should use irw. If you have everything configured properly then you will see output similar to:
# irw 0000000080010077 00 KEY_PAUSE devinput 0000000080010077 00 KEY_PAUSE_UP devinput
More detailed information on LIRC, though somewhat outdated, can be found at: http://lirc.org/html/index.html
Finally you need to map the key code maps from lircd.conf to specific execution. Lircrc takes these commands and applies specific rules such as what keyboard command to send based on the application calling it (eg. mythtv, irexec, mplayer, xine, etc). It also allows you to add rules such as absorb excessive key presses (eg. repeat=3) or insert delay (e.g. delay=1). Of course each lircrc entry must match the label output from lircd.conf. Using the examples above an entry might look like:
# Pause begin prog = mythtv button = KEY_PAUSE config = P end
If this is configured properly then mythtv (and irexec, etc) will behave as you expect.
For more information on lircrc see also: http://lirc.org/html/configure.html#lircrc_format
MythTV Key Bindings¶
In most cases people do not modify the MythTV key bindings and thus the output of lircrc will normally map fine and in a consistent fashion. If for some reason you are convinced that the mapping up to lircrc is correct yet certain keys are not doing what you expect then you can verify the values assigned to the key bindings in the MythTV setup menu.
See Service Menu -> MythTV Configuration -> Edit Keys
In this menu you will see a list of "Contexts" in the left pane and the various key "Actions" in the right pane. Assigned keys are in the boxes at the bottom. Note you can add more than one key to the action you want and the defaults do that in some cases.
Using the earlier example of KEY_PAUSE mapping to P, you can verify that Context of TV Playback -> PAUSE has a value of P.
For more information on MythTV keybindings see also: http://www.mythtv.org/wiki/Keybindings
With the changes to the architecture in LinHES 7 (and linux in general) usage of tools related to remotes has changed to some degree. For example, mode2 which used to test the output of the Remote Driver is now replaced by ir-keytable -t. Below is a list of the common tools used to trace your message flow:
Lists USB devices including Remote Receivers attached via USB. You can use this to find the device type which the Remote Driver will find and map to.
NOTE: for "ir-keytable -t" to work, lirc must not be running. Stop lirc using "sv stop lircd". After testing you can start lirc using "sv start lircd".Shows the output of the Remote Driver before it enters lirc.
- If you get no output then it could be any of the following:
- the driver is not set to a protocol that is actually being used by the Remote Receiver (e.g. RC-6, imon);
- the driver and Remote Receiver device are not connected;
- the wrong driver is mapped to the device;
- If you get only raw translated codes then your keymap file does not match the Remote Receiver and Remote.
- If you get translated output (e.g. KEY_PAUSE (0x0077)) then the driver and keymap is working.
Shows the output from lirc after being mapped through lircd.conf.If you get no output from irw but ir-keytable worked then it may be any of the following:
- lirc is not connected through the correct event interface from the driver
- the output codes from ir-keytable do not match the entries in lircd.conf