2018-10-28, 10:10
Like many others here I had problems with my remote control on Ubuntu since 18.04. Most of the keys of my IR remote control would just stop working after the upgrade. Since I was tinkering with it off and on for more than half a year and finally found a solution, I thought I should share it with everyone. Recently I actually found a possible workaround on this forum that suggested installing an old version of lirc. But since I had so much trouble with lirc in the past, I wanted to repair my installation of inputlirc.
We start off with neither lirc nor inputlirc installed. The linux kernel actually contains drivers for many IR interfaces and maps these to devices at "/dev/input/event*". You can check if the kernel detects the remote and all keys correctly, by using ir-keytable. If this is not the case, you may need to fix the keytables (see the first few steps of this) or find another solution. In my case all keys were correctly detected, but kodi did not use them right (sorry for the german output...).
The inputlirc package is an alternative to lirc, that does not come with any drivers, but instead takes events from an input device and maps these to lirc events. But, as it turns out, the inputlirc package seems "broken" since Ubuntu 18.04. So we have to go ahead and fix it.
To correctly identify the input device, we are going to create a udev rule to map this to a known name. You might get away with using “/dev/input/event*” (note the wildcard) as a name, but I had some problems, so I'm using following udev rule, that is saved at “/etc/udev/rules.d/10-persistent-ir.rules”. Adjust the name to the one reported by “ir-keytable”.
After reloading the udev rules (or a reboot), there should now be a file at "/dev/input/htpc_remote". Now we are ready to install the inputlirc package and setup the correct event source in the config file “/etc/default/inputlirc” (the option "-g" is probably necessary, but I guess that the other ones depend on the remote control).
Up until Ubuntu 18.04, this was my usual way of getting my remote to work and inputlircd would just start automatically. But if we try to start inputlircd by hand now, we see, that we're gettting the following error.
As it turns out, there is no directory “/run/lirc”, so inputlircd can't create a socket there (By the way: “/run” and “/var/run” are symlinked on Ubuntu). To test this out, we can create the necessary directory and try it again.
That looks good. If we looked at the events in ir-keytable now, we should notice, that most of the events are now captured by inputlircd.
And if we enable debug logging in Kodi, we should now be able to see all key events.
Since the created directory in “/run” gets removed on every start, this is not a permanent solution. Instead we are going to alter the inputlircd systemd service file, to create the directory for us ("RuntimeDirectory=", see this for more info). There is also a problem with the dependencies ("After=") in the service file. Originally it depends on lirc and udev. I have no idea why lirc would be necessary, as this should be a replacement, so we remove it. But udev is necessary to create the newly created input device. But somehow it can't be found. I just removed it, and it works. But I'm, pretty sure that this is not right, since the input device may not be there when the service gets started. Anyways, here is the fixed service file, that we save at “/etc/systemd/user/inputlirc.service”, based on the file that is distributed by inputlircd and can be found at “/lib/systemd/system/inputlirc.service”.
Now we need to replace the broken service with our fixed one.
After restarting the service (or a reboot), inputlircd should now run and kodi can get all input events as lirc events. From here on we can configure the keys just like with lirc using the Lircmap.xml in the kodi userdata directory. The device needs to be the one we created earlier and the key codes can be obtained through “ir-keytable -t”.
And that's it! The kernel input events are collected by inputlircd, translated via Lircmap.xml and can be used by kodi. I'm incredibly happy to use my full remote control again and hope that somebody else finds this useful.
TL;DR:
* Check ir-keytable if all keys are recognized by kernel
* Create udev input device
* Install and configure inputlircd
* Fix the systemd service by adding “RuntimeDirectory=lirc” and removing “After=udev lirc”
* Edit Lircmap.xml to let kodi map the lirc keys to the correct kodi keys
We start off with neither lirc nor inputlirc installed. The linux kernel actually contains drivers for many IR interfaces and maps these to devices at "/dev/input/event*". You can check if the kernel detects the remote and all keys correctly, by using ir-keytable. If this is not the case, you may need to fix the keytables (see the first few steps of this) or find another solution. In my case all keys were correctly detected, but kodi did not use them right (sorry for the german output...).
Code:
$ sudo ir-keytable
/sys/class/rc/rc0/ gefunden (/dev/input/event5) mit:
Name: iMON Remote (15c2:0036)
Treiber: imon, Tabelle: rc-imon-pad
Lirc Gerät: /dev/lirc0
unterstützte Protokolle: other rc-6
Aktivierte Protokolle: other
bus: 3, Anbieter/Produkt: 15c2:0036, Version: 0x0003
$ sudo ir-keytable -t
3092.206194: Lirc Protokoll(23): scancode = 0x2000028
3092.206224: Ereignistyp EV_MSC(0x04): Scancode = 0x2000028
3092.206224: Ereignistyp EV_KEY(0x01) key_runter: KEY_ENTER(0x001c)
3092.206224: Ereignistyp EV_SYN(0x00).
3092.350174: Ereignistyp EV_KEY(0x01) key_hoch: KEY_ENTER(0x001c)
3092.350174: Ereignistyp EV_SYN(0x00).
3093.886258: Lirc Protokoll(23): scancode = 0x200002a
3093.886289: Ereignistyp EV_MSC(0x04): Scancode = 0x200002a
3093.886289: Ereignistyp EV_KEY(0x01) key_runter: KEY_BACKSPACE(0x000e)
3093.886289: Ereignistyp EV_SYN(0x00).
3093.982229: Ereignistyp EV_KEY(0x01) key_hoch: KEY_BACKSPACE(0x000e)
3093.982229: Ereignistyp EV_SYN(0x00).
The inputlirc package is an alternative to lirc, that does not come with any drivers, but instead takes events from an input device and maps these to lirc events. But, as it turns out, the inputlirc package seems "broken" since Ubuntu 18.04. So we have to go ahead and fix it.
To correctly identify the input device, we are going to create a udev rule to map this to a known name. You might get away with using “/dev/input/event*” (note the wildcard) as a name, but I had some problems, so I'm using following udev rule, that is saved at “/etc/udev/rules.d/10-persistent-ir.rules”. Adjust the name to the one reported by “ir-keytable”.
Code:
KERNEL=="event*",ATTRS{name}=="iMON Remote (15c2:0036)",SYMLINK="input/htpc_remote"
After reloading the udev rules (or a reboot), there should now be a file at "/dev/input/htpc_remote". Now we are ready to install the inputlirc package and setup the correct event source in the config file “/etc/default/inputlirc” (the option "-g" is probably necessary, but I guess that the other ones depend on the remote control).
Code:
EVENTS="/dev/input/htpc_remote"
OPTIONS="-g -m 0 -c"
Up until Ubuntu 18.04, this was my usual way of getting my remote to work and inputlircd would just start automatically. But if we try to start inputlircd by hand now, we see, that we're gettting the following error.
Code:
$ sudo inputlircd -g -m 0 -c /dev/input/htpc_remote
/dev/input/htpc_remote 100013
Unable to bind AF_UNIX socket to /run/lirc/lircd: No such file or directory
As it turns out, there is no directory “/run/lirc”, so inputlircd can't create a socket there (By the way: “/run” and “/var/run” are symlinked on Ubuntu). To test this out, we can create the necessary directory and try it again.
Code:
$ sudo mkdir /run/lirc
$ sudo inputlircd -g -m 0 -c /dev/input/htpc_remote
/dev/input/htpc_remote 100013
That looks good. If we looked at the events in ir-keytable now, we should notice, that most of the events are now captured by inputlircd.
Code:
$ sudo ir-keytable -t
4849.732368: Lirc Protokoll(23): scancode = 0x200002a
4851.676534: Lirc Protokoll(23): scancode = 0x289515b7
4854.836371: Lirc Protokoll(23): scancode = 0x2aa515b7
4855.188329: Lirc Protokoll(23): scancode = 0x2aa515b7
4855.900373: Lirc Protokoll(23): scancode = 0x2ba515b7
And if we enable debug logging in Kodi, we should now be able to see all key events.
Code:
08:01:04.201 T:140671866692032 DEBUG: LIRC: Update - NEW at 44771:6c 0 KEY_DOWN /dev/input/htpc_remote (KEY_DOWN)
08:01:04.201 T:140671866692032 DEBUG: OnKey: 167 (0xa7, obc88) pressed, action is Down
08:01:04.902 T:140671866692032 DEBUG: LIRC: Update - NEW at 45471:67 0 KEY_UP /dev/input/htpc_remote (KEY_UP)
08:01:04.903 T:140671866692032 DEBUG: OnKey: 166 (0xa6, obc89) pressed, action is Up
Since the created directory in “/run” gets removed on every start, this is not a permanent solution. Instead we are going to alter the inputlircd systemd service file, to create the directory for us ("RuntimeDirectory=", see this for more info). There is also a problem with the dependencies ("After=") in the service file. Originally it depends on lirc and udev. I have no idea why lirc would be necessary, as this should be a replacement, so we remove it. But udev is necessary to create the newly created input device. But somehow it can't be found. I just removed it, and it works. But I'm, pretty sure that this is not right, since the input device may not be there when the service gets started. Anyways, here is the fixed service file, that we save at “/etc/systemd/user/inputlirc.service”, based on the file that is distributed by inputlircd and can be found at “/lib/systemd/system/inputlirc.service”.
Code:
Documentation=man:inputlircd(8)
Description=Zeroconf LIRC daemon using input event devices
After=
[Service]
Type=simple
EnvironmentFile=/etc/default/inputlirc
RuntimeDirectory=lirc
ExecStart=/usr/sbin/inputlircd -f $OPTIONS $EVENTS
[Install]
WantedBy=multi-user.target
Now we need to replace the broken service with our fixed one.
Code:
$ sudo systemctl disable inputlirc.service
$ sudo systemctl enable /etc/systemd/user/inputlirc.service
After restarting the service (or a reboot), inputlircd should now run and kodi can get all input events as lirc events. From here on we can configure the keys just like with lirc using the Lircmap.xml in the kodi userdata directory. The device needs to be the one we created earlier and the key codes can be obtained through “ir-keytable -t”.
Code:
<?xml version="1.0" encoding="UTF-8"?>
<lircmap>
<remote device="/dev/input/htpc_remote">
<obc1>KEY_EXIT</obc1>
<power>KEY_POWER</power>
....
<language>KEY_LANGUAGE</language>
</remote>
</lircmap>
And that's it! The kernel input events are collected by inputlircd, translated via Lircmap.xml and can be used by kodi. I'm incredibly happy to use my full remote control again and hope that somebody else finds this useful.
TL;DR:
* Check ir-keytable if all keys are recognized by kernel
* Create udev input device
* Install and configure inputlircd
* Fix the systemd service by adding “RuntimeDirectory=lirc” and removing “After=udev lirc”
* Edit Lircmap.xml to let kodi map the lirc keys to the correct kodi keys