RF remote in Linux HTPC

If you are setting up a Linux based media center PC, sooner or later you would stumble upon a remote which is not completely supported out-of-the-box. More so, if you have an RF remote like me. I spent couple of days scanning through multiple posts to figure it out. This post outlines the steps to get your remote working as you'd like.

Most remotes are Infra-red (IR) devices. However, radio-frequency (RF) remotes allow you flexibility and better control as line of sight is not mandatory. I have an RF remote that came with ATI TV Wonder HD 250.
ATI Theater remote (source: http://tv.manualsonline.com/manuals/mfg/amd/ati_theater.html?p=11)
Good news is that most of the buttons work out-of-the-box, i.e. the Linux kernel recognizes the device. However, it was annoying that some single key functions like TV or radio were not working. There are total nine buttons that don't work. The first step is to figure out the scancodes of these keys. Run evtest as root and press the desired key. You'll see information about the pressed key on the screen
Testing ... (interrupt to exit)
Event: time 1452774793.296768, type 4 (EV_MSC), code 4 (MSC_SCAN), value c0500
Event: time 1452774793.296768, type 1 (EV_KEY), code 102 (KEY_HOME), value 1
Event: time 1452774793.296768, -------------- SYN_REPORT ------------
Event: time 1452774793.296768, type 1 (EV_KEY), code 102 (KEY_HOME), value 0
Event: time 1452774793.296768, -------------- SYN_REPORT ------------

In this case, the key's scancode is c0500 and the key is recognized as KEY_HOME.

Now we need to make them available in user space. This is done via udev. We need to create a udev rule mapping the hardware scancodes to linux keycodes. Create a file /etc/udev/hwdb.d/ati.hwdb with following content:
#/etc/udev/hwdb.d/ati.hwdb

keyboard:usb:v0471p2001* # A USB keyboard with VID=0471 and PID=2001
 KEYBOARD_KEY_0c0500=home # Bind scancode c0500 to keycode home
 KEYBOARD_KEY_0c050d=f1
 KEYBOARD_KEY_0c0512=f2
 KEYBOARD_KEY_0c0507=f3
 KEYBOARD_KEY_0c0514=f4
 KEYBOARD_KEY_0c0515=f5
 KEYBOARD_KEY_0c0521=f6
 KEYBOARD_KEY_0c0093=f7 #radio
 KEYBOARD_KEY_0c0209=f8 #info
Run the following command as root to refresh the OS keymap.
udevadm hwdb --update && udevadm trigger
Next, we need to let Kodi know what action to perform when these keys are pressed. Create a file ~/.kodi/userdata/keymaps/ati.xml with following content:
<keymap>
<global>
<keyboard>
<!-- Remap because it is a prominent button on the remote but the default mapping just makes XBMC
select the first item on the currently displayed screen.  A bit useless. -->
<home>XBMC.ActivateWindow(Home)</home>  <!-- MCE Home -->
<f1>Back</f1>
<!--f1>PreviousMenu</f1-->
<f2>ActivateWindow(Teletext)</f2>
<!--f2>NextSubtitle</f2-->
<!--f2>ContextMenu</f2-->
<f3>PlayDVD</f3>
<f4>ActivateWindow(TVChannels)</f4>
<f5>ActivateWindow(TVRecordings)</f5>
<f6>ActivateWindow(PVROSDGuide)</f6>
<!--f6>ActivateWindow(TVSearch)</f6-->
<f7>ActivateWindow(RadioChannels)</f7>
<f8>Info</f8>

</keyboard>
</global>
</keymap>
Restart Kodi and you should now be able to use the buttons for new mapped functionality.

Explanation

Before you start, confirm what type of remote you have. An IR remote is supported via lircd in Linux. I assumed (wrongly) that RF remote would be supported the same way and IR or RF won't make any difference. Turns out - it's NOT!! Good news is - it's simpler as you saw previously.

Kodi is an open-source cross-platform media player. Since it needs to run on multiple platforms, it uses SDL API. SDL recognizes only limited number of common keycodes (256) which are available on all the supported platforms. That means Linux recognizing a key won't make it available to Kodi!!

For a new remote button to be recognized by Kodi, it must use one of the available SDL keycode. Also, you MUST NOT use a keycode which collides with another button on the remote or else you'll notice Kodi behaving strangely when the key is pressed. 

My AHA moment came when I realized a keyboard has twelve function keys (F1-F12) which are not present on a remote!! Consequently, any unrecognized key can be bound to these and then made available to Kodi.

EDIT (18/01/16): I tested this on OSMC (RPi1 model B) and aptosid 4.3.0-3.slh.2-aptosid-amd64

Useful links

  • Map scancodes to keycodes using udev https://wiki.archlinux.org/index.php/Map_scancodes_to_keycodes
  • ATI Theater video remote http://tv.manualsonline.com/manuals/mfg/amd/ati_theater.html?p=11
  • Creating Kodi Keymap http://kodi.wiki/view/keymap
  • http://forum.kodi.tv/showthread.php?tid=160193
  • http://forum.kodi.tv/showthread.php?tid=69948
  • List of keys recognized by Kodi in CButtonTranslator::TranslateRemoteString
  • Kodi's default keymap file



Comments

Popular posts from this blog

GNU Emacs as a Comic Book Reader

Tinylisp and Multi-threaded Emacs

Data Visualization with GNU Emacs