Block > LIRC oder: System bedienen fuer Faule

Ich hab seit meinem ersten eigenen Rechner (ein Medion Titanium MD 8080 XL aus dem Aldi :D) eine Infrarot-Fernbedienung herumliegen.
[Oh je, das ist auch schon wieder ueber 11 Jahre her … Krass.]

Meine alte Infrarot-Fernbedienung mit Empfaenger

Nun ist sie mir wieder in die Haende gefallen und ich hab ein bisschen damit herumgespielt. Das hatte ich auch schonmal gemacht, aber frueher hat das irgendwie nicht so geklappt mit Linux und ich war wahrscheinlich auch nicht so dahinter ;)
Nun klappt das mit LIRC (Linux Infrared Remote Control) ganz hervorragend, d.h. ich kann nun noch fauler sein und vom Bett aus z.B. Filme starten ;)

Ich beschreibe hier mal, wie ich das alles zum Laufen gebracht habe und wie ein paar Programme damit gesteuert werden koennen.
Tipp: Mit dwm zusammen ist das Steuern einfach nur awesome :D

Uebersicht

Das Wiki von Arch Linux beschreibt hier ganz gut, wie LIRC (Linux Infrared Remote Control) funktioniert und welche Konfigurationsdateien wo und wie benoetigt werden.
Dem habe ich nichts hinzuzufuegen ;)

Installation

Dazu reicht ein einfaches:

# pacman -S lirc lirc-utils

Konfiguration

Wie hier beschrieben wird, bringt mir die normale Konfiguration von LIRC leider recht wenig, da die vorhandenen Konfigurationsdateien nicht fuer dieses Geraet geeignet sind und eine eigene Konfigurationsdatei zu aufwendig zu erstellen ist. Also folgen wir einfach der Anleitung Setup a HID device with LIRC ;)

Erstmal mussen wir das passende Event unterhalb von /dev/input herausfinden. Dazu folgen wir diesem Link (und dann jeweils den anderen Links):

$ ls -l /sys/class/rc/rc0
lrwxrwxrwx 1 root root 0 Jun 29 11:53 /sys/class/rc/rc0 -> ../../devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.5/1-1.5.4/1-1.5.4:1.0/rc/rc0/

$ ls -l /sys/devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.5/1-1.5.4/1-1.5.4:1.0/rc/rc0
[..]
drwxr-xr-x 6 root root    0 Jun 29 11:53 input67/
[..]

$ ls -l /sys/devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.5/1-1.5.4/1-1.5.4:1.0/rc/rc0/input67
[..]
drwxr-xr-x 3 root root    0 Jun 29 11:53 event19/
[..]

Also ist in diesem Fall das Event event19, womit wir mit dem folgenden Befehl die ID von dem USB-Geraet herausfinden koennen:

$ ls -l /dev/input/by-id
[..]
lrwxrwxrwx 1 root root 10 Jun 29 11:53 usb-X10_Wireless_Technology_Inc_USB_Receiver-event-if00 -> ../event19
[..]

In diesem Fall ist nun die richtige ID usb-X10_Wireless_Technology_Inc_USB_Receiver-event-if00.
Die tragen wir nun als LIRC_DEVICE in die /etc/conf.d/lircd.conf ein:

LIRC_DEVICE="/dev/input/by-id/usb-X10_Wireless_Technology_Inc_USB_Receiver-event-if00"
LIRC_DRIVER="devinput"
LIRC_EXTRAOPS=""
LIRC_CONFIGFILE="/etc/lirc/lircd.conf"

Die Konfigurationsdatei /etc/lirc/lircd.conf muessen bzw. koennen wir zum Glueck nicht selbst erstellen, also laden wir uns einfach diese hier aus dem Netz herunter:

# mv /etc/lirc/lirc.conf /etc/lirc/lirc.conf.orig
# wget http://sourceforge.net/p/lirc/git/ci/master/tree/remotes/devinput/lircd.conf.devinput?format=raw -O /etc/lirc/lircd.conf

Wenn noch nicht geschehen, sollte noch das Kernelmodul evdev geladen werden:

# modprobe evdev

Unter systemd muessen wir nun die lirc.service-Datei anpassen (Quelle):

# cd /usr/lib/systemd/system
# mv lirc.service lirc.service.bak

Nun eine neue Datei lirc.service erstellen, mit folgendem Inhalt:

[Unit]
Description=LIRC Daemon
After=network.target

[Service]
Type=forking
EnvironmentFile=/etc/conf.d/lircd.conf
PIDFile=/run/lirc/lircd.pid
ExecStartPre=/bin/mkdir -p /run/lirc
ExecStartPre=/bin/rm -f /dev/lircd
ExecStartPre=/bin/rm -f /run/lirc/lircd
ExecStartPre=/bin/ln -s /run/lirc/lircd /dev/lircd

ExecStart=/usr/sbin/lircd -d $LIRC_DEVICE -P /run/lirc/lircd.pid -H $LIRC_DRIVER $LIRC_CONFIGFILE
ExecStopPost=/bin/rm -f /dev/lircd
ExecStopPost=/bin/rm -fR /run/lirc
ExecStartPost=/usr/bin/ir-keytable --protocol=LIRC

[Install]
WantedBy=multi-user.target

Die Datei sollte nun in /etc/systemd/system/multi-user.target.wants richtig verlinkt sein:

# ls -l /etc/systemd/system/multi-user.target.wants
[..]
lrwxrwxrwx 1 root root 36 2014-06-21 16:26:21 lirc.service -> /usr/lib/systemd/system/lirc.service
[..]

Nun testen wir noch, ob die Fernbedienung auch erkannt wurde:

# ir-keytable -v
Found device /sys/class/rc/rc0/
Input sysfs node is /sys/class/rc/rc0/input67/
Event sysfs node is /sys/class/rc/rc0/input67/event19/
Parsing uevent /sys/class/rc/rc0/input67/event19/uevent
/sys/class/rc/rc0/input67/event19/uevent uevent MAJOR=13
/sys/class/rc/rc0/input67/event19/uevent uevent MINOR=83
/sys/class/rc/rc0/input67/event19/uevent uevent DEVNAME=input/event19
Parsing uevent /sys/class/rc/rc0/uevent
/sys/class/rc/rc0/uevent uevent NAME=rc-medion-x10
/sys/class/rc/rc0/uevent uevent DRV_NAME=ati_remote
input device is /dev/input/event19
/sys/class/rc/rc0/protocols protocol other (disabled)
Found /sys/class/rc/rc0/ (/dev/input/event19) with:
        Driver ati_remote, table rc-medion-x10
        Supported protocols: other 
        Enabled protocols: 
        Extra capabilities: <access denied>

Ja, passt :)
Und noch ein Test, ob die Tasten auch funktionieren, wenn auch LIRC noch nicht laeuft:

# ir-keytable -t
Testing events. Please, press CTRL-C to abort.
1404045071.911565: event type EV_MSC(0x04): scancode = 0x33
1404045071.911565: event type EV_KEY(0x01) key_down: KEY_GREEN(0x0001)
1404045071.911565: event type EV_SYN(0x00).
1404045071.911589: event type EV_KEY(0x01) key_up: KEY_GREEN(0x0001)
1404045071.911589: event type EV_SYN(0x00).

Ok, super, auch das klappt :)
Nun koennen wir LIRC starten:

# systemctl enable lirc.service
# systemctl start lirc.service

Und testen nun nur noch, ob der Service auch richtig laeuft:

# systemctl status lirc.service
● lirc.service - LIRC Daemon
   Loaded: loaded (/usr/lib/systemd/system/lirc.service; enabled)
   Active: active (running) since Sun 2014-06-29 14:32:24 CEST; 44s ago
  Process: 19703 ExecStartPost=/usr/bin/ir-keytable --protocol=LIRC (code=exited, status=0/SUCCESS)
  Process: 19701 ExecStart=/usr/sbin/lircd -d $LIRC_DEVICE -P /run/lirc/lircd.pid -H $LIRC_DRIVER $LIRC_CONFIGFILE (code=exited, status=0/SUCCESS)
  Process: 19698 ExecStartPre=/bin/ln -s /run/lirc/lircd /dev/lircd (code=exited, status=0/SUCCESS)
  Process: 19695 ExecStartPre=/bin/rm -f /run/lirc/lircd (code=exited, status=0/SUCCESS)
  Process: 19692 ExecStartPre=/bin/rm -f /dev/lircd (code=exited, status=0/SUCCESS)
  Process: 19689 ExecStartPre=/bin/mkdir -p /run/lirc (code=exited, status=0/SUCCESS)
 Main PID: 19702 (lircd)
   CGroup: /system.slice/lirc.service
           └─19702 /usr/sbin/lircd -d /dev/input/by-id/usb-X10_Wireless_Technology_Inc_USB_Receiver-event-if00 -P /run/lirc/lircd.pid -H devinput /etc/lirc/...

Jun 29 14:32:23 yavanna ir-keytable[19703]: Protocols changed to LIRC
Jun 29 14:32:24 yavanna systemd[1]: Started LIRC Daemon.

Ok, auch der Dienst laeuft :)
Ab jetzt koennen wir als normale*r Nutzer*in weitermachen (sprich: ohne root).
Dazu testen wir noch einmal, ob auch die Tasten ohne root und diesmal mit LIRC funktionieren:

$ irw
000000008001018f 00 KEY_GREEN devinput

Ok, das klappt :)

Sollte das nicht geklappt haben, liegt noch irgendwo ein Fehler vor, der vorher behoben sein sollte.

Wenn alles laeuft, geht es mit der Einrichtung weiter.

Einrichtung

Um mal eben schnell zu zeigen, dass LIRC auch wirklich funktioniert, erstellen wir uns eine Beispieldatei. Dazu muss ein Ordner .lirc im $HOME erstellt werden, der dann die einzelnen Konfigurationsdateien fuer verschiedene Ordner enthaelt und eine Datei .lircrc im $HOME, die diese Konfigurationsdateien inkludiert.

$ mkdir ~/.lirc
$ touch ~/.lircrc
$ touch ~/.lirc/test

In der Datei test fuegen wir nun einfach mal folgendes ein:

begin
    prog = irexec
    config = echo "yeah"
    button = KEY_1
end

Um das nun aktiv werden zu lassen, muss das Programm laufen, was bei prog steht, in diesem Fall also irexec (wir starten irexec direkt mit der test-Datei, da der Pfad ja noch nicht in der ~/.lircrc definiert wurde).

$ irexec ~/.lirc/test

Druecken wir nun auf die Taste 1 auf der Fernbedienung, sollte in der Konsole yeah ausgegeben werden :)

Eine Konfiguration fuer vlc und mpv sowie fuer Funktionen von dwm und sogar eine Maussteuerung liefere ich gleich, allerdings hier noch einige Kommentare:

Ok, damit nun hier ein paar Beispieldateien.

Erstmal die ~/.lircrc, in der die anderen Dateien genannt werden:

begin vlc
        include "~/.lirc/vlc"
end vlc

begin mpv
        include "~/.lirc/mpv"
end mpv

begin irexec
        include "~/.lirc/maus"
        include "~/.lirc/dwm"
end irexec

Die Konfiguration von VLC (stark hier abgeguckt, wobei einige Belegungen anders heissen):

begin
    prog = vlc
    button = KEY_PLAY
    config = key-play
end

begin
    prog = vlc
    button = KEY_PAUSE
    config = key-play-pause
end

begin
    prog = vlc
    button = KEY_STOP
    config = key-stop
end

begin
    prog = vlc
    button = KEY_MUTE
    config = key-vol-mute
end

begin
    prog = vlc
    button = KEY_VOLUMEDOWN
    config = key-vol-down
    repeat = 2
    delay = 10
end

begin
    prog = vlc
    button = KEY_VOLUMEUP
    config = key-vol-up
    repeat = 2
    delay = 10
end

begin
    prog = vlc
    button = KEY_NEXT
    config = key-next
end

begin
    prog = vlc
    button = KEY_PREVIOUS
    config = key-prev
end

begin
    prog = vlc
    button = KEY_SWITCHVIDEOMODE
    config = key-toggle-fullscreen
end

begin
    prog = vlc
    button = KEY_REWIND
    config = key-slower
end

begin
    prog = vlc
    button = KEY_FORWARD
    config = key-faster
end

# Navigation im DVD-Menue
begin
    prog = vlc
    button = KEY_LEFT
    config = key-nav-left
end

begin
    prog = vlc
    button = KEY_DOWN
    config = key-nav-down
end

begin
    prog = vlc
    button = KEY_UP
    config = key-nav-up
end

begin
    prog = vlc
    button = KEY_RIGHT
    config = key-nav-right
end

begin
    prog = vlc
    button = KEY_OK
    config = key-nav-activate
end

begin
    prog = vlc
    button = KEY_MENU
    config = key-disc-menu
end

begin
    prog = vlc
    button = KEY_POWER
    config = key-quit
end

Die Konfiguration von MPV, die Befehle habe ich mit man 1 mpv herausgefunden:

begin
    prog = mpv
    button = KEY_PLAY
    config = cycle pause
end

begin
    prog = mpv
    button = KEY_PAUSE
    config = cycle pause
end

begin
    prog = mpv
    button = KEY_STOP
    config = quit
end

begin
    prog = mpv
    button = KEY_MUTE
    config = cycle mute
end

begin
    prog = mpv
    button = KEY_VOLUMEDOWN
    config = add volume -10
    repeat = 2
    delay = 10
end

begin
    prog = mpv
    button = KEY_VOLUMEUP
    config = add volume 10
    repeat = 2
    delay = 10
end

begin
    prog = mpv
    button = KEY_NEXT
    config = playlist_next
end

begin
    prog = mpv
    button = KEY_PREVIOUS
    config = playlist_prev
end

begin
    prog = mpv
    button = KEY_SWITCHVIDEOMODE
    config = cycle fullscreen
end

begin
    prog = mpv
    button = KEY_REWIND
    config = seek -60
end

begin
    prog = mpv
    button = KEY_FORWARD
    config = seek 60
end

begin
    prog = mpv
    button = KEY_POWER
    config = quit
end

Die Konfiguration von dwm (0xffeb entspricht Super_L und wurde mit xev herausgefunden; das Paket fuer xte heisst xautomation):

# desktops
begin
    prog = irexec
    config = xte 'keydown 0xffeb' 'keydown 1' 'keyup 0xffeb' 'keyup 1'
    button = KEY_KEYBOARD
    button = KEY_1
end

begin
    prog = irexec
    config = xte 'keydown 0xffeb' 'keydown 2' 'keyup 0xffeb' 'keyup 2'
    button = KEY_KEYBOARD
    button = KEY_2
end

begin
    prog = irexec
    config = xte 'keydown 0xffeb' 'keydown 3' 'keyup 0xffeb' 'keyup 3'
    button = KEY_KEYBOARD
    button = KEY_3
end

begin
    prog = irexec
    config = xte 'keydown 0xffeb' 'keydown 4' 'keyup 0xffeb' 'keyup 4'
    button = KEY_KEYBOARD
    button = KEY_4
end

begin
    prog = irexec
    config = xte 'keydown 0xffeb' 'keydown 5' 'keyup 0xffeb' 'keyup 5'
    button = KEY_KEYBOARD
    button = KEY_5
end

begin
    prog = irexec
    config = xte 'keydown 0xffeb' 'keydown 6' 'keyup 0xffeb' 'keyup 6'
    button = KEY_KEYBOARD
    button = KEY_6
end

begin
    prog = irexec
    config = xte 'keydown 0xffeb' 'keydown 7' 'keyup 0xffeb' 'keyup 7'
    button = KEY_KEYBOARD
    button = KEY_7
end

begin
    prog = irexec
    config = xte 'keydown 0xffeb' 'keydown 8' 'keyup 0xffeb' 'keyup 8'
    button = KEY_KEYBOARD
    button = KEY_8
end

begin
    prog = irexec
    config = xte 'keydown 0xffeb' 'keydown 9' 'keyup 0xffeb' 'keyup 9'
    button = KEY_KEYBOARD
    button = KEY_9
end

begin
    prog = irexec
    config = xte 'keydown 0xffeb' 'keydown 0' 'keyup 0xffeb' 'keyup 0'
    button = KEY_KEYBOARD
    button = KEY_0
end

begin
    prog = irexec
    config = xte 'keydown 0xffeb' 'keydown Tab' 'keyup 0xffeb' 'keyup Tab'
    button = KEY_KEYBOARD
    button = KEY_DELETE
end

# music
# siehe dazu meine dwm-config:
# https://github.com/tohn/dwm/blob/master/config.h
# und die entsprechende Datei dwm_music.sh hier:
# https://github.com/tohn/bin/blob/master/dwm_music.sh
begin
    prog = irexec
    config = /home/benjo/repos/bin/dwm_music.sh -n
    button = KEY_KEYBOARD
    button = KEY_NEXT
end

begin
    prog = irexec
    config = /home/benjo/repos/bin/dwm_music.sh -v
    button = KEY_KEYBOARD
    button = KEY_PREVIOUS
end

begin
    prog = irexec
    config = /home/benjo/repos/bin/dwm_music.sh -p
    button = KEY_KEYBOARD
    button = KEY_PLAY
end

begin
    prog = irexec
    config = /home/benjo/repos/bin/dwm_music.sh -p
    button = KEY_KEYBOARD
    button = KEY_PAUSE
end

# volume
begin
    prog = irexec
    config = amixer set Master toggle
    button = KEY_MUTE
end

begin
    prog = irexec
    config = amixer -c 0 set Master 10%+
    button = KEY_VOLUMEUP
end

begin
    prog = irexec
    config = amixer -c 0 set Master 10%-
    button = KEY_VOLUMEDOWN
end

Und zuletzt die Konfiguration zur Steuerung der Maus (Quelle):

# Maussteuerung per xte
begin
    prog = irexec
    button = KEY_2
    config = xte  'mousermove 0 -15'
    repeat = 1
end

begin
    prog = irexec
    button = KEY_3
    config = xte  'mousermove 15 -15'
    repeat = 1
end

begin
    prog = irexec
    button = KEY_1
    config = xte  'mousermove -15 -15'
    repeat = 1
end

begin
    prog = irexec
    button = KEY_8
    config = xte  'mousermove 0 15'
    repeat = 1
end

begin
    prog = irexec
    button = KEY_7
    config = xte  'mousermove -15 15'
    repeat = 1
end

begin
    prog = irexec
    button = KEY_9
    config = xte  'mousermove 15 15'
    repeat = 1
end

begin
    prog = irexec
    button = KEY_4
    config = xte  'mousermove -15 0'
    repeat = 1
end

begin
    prog = irexec
    button = KEY_6
    config = xte  'mousermove 15 0'
    repeat = 1
end

begin
    prog = irexec
    button = KEY_5
    config = xte  'mouseclick 1'
end

begin
    prog = irexec
    button = KEY_0
    config = xte  'mouseclick 2'
end

Moegliche TODOs:

Quellen

Geschrieben: 2014-06-29, 18:28 - Tags: linux, lirc