yaVDR und [irmp]lircd Fernbedienungen – eine grundsätzliche Frage

  • Kurz zusammengefasst geht es um die Tücken des Weges irmplircd bzw lircd → lircd2uinput → /dev/input/eventX → eventlircd → Anwendung.


    Bislang gab es bei mir nur den direkten Weg irmplircd → Anwendung, und das funktioniert wie es soll. Für OpenELEC habe ich mich mit dem yaVDR-„Umweg“, der ja von vielen übernommen wurde, auseinandergesetzt.


    /dev/input/eventX arbeitet mit KeyDown und KeyUp. Bei den Fernbedienungen gibt es aber keine KeyUp-Entsprechung (auch das toggle-bit kommt ja erst beim nächsten Knopfdruck). Da eventX solange bis das KeyUp kommt Signale abfeuert, wird in lircd2uinput (yaVDR) bzw. lircd-uinput (OpenELEC) nach einem timeout ein KeyUp automatisch erzeugt.

    Das führt zu einem Problem. Nehmen wir an, dass die Fernbedienung bei gedrückt gehaltener Taste alle repeat_period Millisekunden feuert.

    Fall A: Falls timeout > repeat_period gibt es einen Nachlauf, und in eventX werden eventuell ein oder mehrere Knopfdrücke zu viel erzeugt.

    In einem Menu läuft der Cursor dann weiter, obwohl der Finger schon vom Knopf ist.

    Fall B: Falls timeout < repeat_period läuft weniger bis nichts nach, aber es wird jedes Mal ein neuer Knopfdruck erzeugt, obwohl es noch derselbe ist. Kodi verhält sich aber teilweise bei neuem Knopfdruck anders als bei wiederholtem Knopfdruck.

    Den Fall timeout = repeat_period gibt es nicht, da die Signale, die von der Fernbedienung kommen, nie ganz regelmäßig kommen, und die Intervalle mal etwas kürzer und mal etwas länger sind.


    Gibt es eine Lösung für dieses Problem?


    Bei meinem ersten OpenELEC Versuch habe ich das Problem dadurch umgangen, dass ich Kodi direkt an irmplircd gehängt habe, und das könnte man auf yaVDR auch so tun. Hat das ungünstige Nebenwirkungen?


    Spräche etwas dagegen, dass wenn ein irmplircd-Paket installiert wird, automatisch eventlircd gestoppt wird und statt dessen irmplircd auf /var/run/lirc/lircd ausgibt (also da, wo vorher eventlircd ausgegeben hat)?

    Würde das gehen, solange IRMP der einzige IR-Empfänger ist?


    Im Prinzip wäre es auch möglich, durch geschickt gewählte Werte von delay und repeat in eventX den Nachlauf klein zu halten. Das hängt aber von der Fernbedienung ab und müßte individuell eingestellt werden.

  • eventlircd produziert eigentlich nur auf Key-Down bzw. Key-Repeat Events hin Tastendrücke auf seinem Sockel, eine automatische Tastenwiederholung gibt es nicht. Wenn eine Taste von lircd2uinput länger als nötig gedrückt gehalten (also nach einem Tastendruck nicht Zeitnah ein Key-Up gesendet) wird, sollte das keine zusätzlichen Tastendrücke verursachen.


    Ich habe lircd2uinput für kommende yaVDR-Versionen mal so überarbeitet, dass es sich da möglichst transparent verhält, statt wie bisher zu versuchen überflüssige Wiederholungen herauszufiltern: https://github.com/seahawk1986/lircd2uinput (der letzte Stand ist noch nicht in den PPAs für xenial und bionic - Launchpad baut seit heute Morgen angeblich wieder Pakete, aber es wird vermutlich noch Stunden oder Tage dauern, bis alle aufgelaufenen Aufträge abgearbeitet sind). Damit sollte abgesehen von einer kleinen zusätzlichen Latzenz von ca. 2 ms durch den Umweg über lircd2uinput und eventlircd (gemessen mit einem modifizierten irw (irw.zip), das einen Timestamp für jeden Tastendruck mit ausgibt) kein spürbarer Unterschied mehr zu einem nativen lircd-kompatiblen Daemon bestehen.


    Vielleicht kannst du mal ausprobieren, ob das für deinen Geschmack gut genug funktioniert (das Paket sollte sich auch für trusty bauen lassen).


    Das Nachlaufen wird nach meinen Beobachtungen auch noch durch zusätzliche Faktoren beeinflusst:

    • einen großen Einfluss hat die Frame-Wiederholung der Fernbedienungen (bei RC-5 und RC-6 senden Harmony-Fernbedienungen z.B. in der Voreinstellung 2 Wiederholungen - der Wert ist über verschiedene Fernbedienungen hinweg leider nicht wirklich konsistent, ich habe hier zwei Hauppauge A415, von denen eine 1 einen und die andere 2 wiederholte Frames sendet). Je nachdem ob man vor oder nach dem Beginn des nächsten Wiederholungszyklus loslässt, bekommt man bis zu 2 zusätzliche Tastendrücke. Wenn man die Frame-Wiederholung über die Konfigurationssoftware für die Harmony abschaltet, verschwindet der Effekt praktisch.
    • Die Ausgabe am TV ist je nach Bildmodus ein paar Frames verzögert, dadurch lässt man die Taste tendenziell zu spät los.
    • Das Zeichnen des OSD dauert mit aufwendigen Skins zu lange, auch hier sieht man das gewünschte Ergebnis zu spät und hält die Taste dadurch zu lange gedrückt

    Der irmp-Empfänger, den mir ranseyer damals zugeschickt hatte, ist leider sehr zickig beim Aushandeln der USB-Verbindung und funktioniert nur an einem alten Athlon64, aber nicht an meinem normalen Testsystem. Außerdem scheint er zumindest bei RC-5 die ersten paar Tastenwiederholungen zu verschlucken.

    Spräche etwas dagegen, dass wenn ein irmplircd-Paket installiert wird,automatisch eventlircd gestoppt wird und statt dessen irmplircd auf /var/run/lirc/lircd ausgibt (also da, wo vorher eventlircd ausgegeben hat)?

    Würdedas gehen, solange IRMP der einzige IR-Empfänger ist

    Kann irmplircd mittlerweile dynamisch einen später erkannten Empfänger einbinden? Der Charme bei der Lösung mit eventlircd ist in meinen Augen, dass es egal ist, wann die IR-Empfänger verfügbar sind. Mit Systemd muss man so nicht mal Abhängigkeiten definieren, sondern kann den Dienst bequem per Socket-Activation starten und VDR und KODI sind zufrieden, weil es sofort einen nutzbaren lirc-Sockel gibt. Außerdem hat man einen einheitlichen Namespace, was z.B. für die Lircmap.xml von KODI praktisch ist - dadurch heißen alle Fernbedienungen "devinput", sonst müsste man für jede lircd.conf und die ganzen anderen Daemons zusätzliche <altname> Tags setzen.


    Ansonsten kann man das System natürlich auch so konfigurieren, dass irmplircd statt eventlircd genutzt wird, nur sollte das IMHO eine explizit vom Nutzer gewünschte Konfiguration sein, keine Automatik.

    yaVDR-Dokumentation (Ceterum censeo enchiridia esse lectitanda.)

  • Erstmal danke, dass du dich der Sache annimmst :) .


    eventlircd produziert eigentlich nur auf Key-Down bzw. Key-Repeat Events hin Tastendrücke auf seinem Sockel, eine automatische Tastenwiederholung gibt es nicht. Wenn eine Taste von lircd2uinput länger als nötig gedrückt gehalten (also nach einem Tastendruck nicht Zeitnah ein Key-Up gesendet) wird, sollte das keine zusätzlichen Tastendrücke verursachen.

    Meine Tests waren auf OpenELEC, aber das ist ja auch nur ein Ubuntu und sollte keinen Unterschied machen.

    Wenn ich mit evtest an /dev/input/eventX gehe, werden nach einem Key-Down solange erster Tastendruck und dann Repeats gesendet, bis ein Key-Up kommt. eventlircd gibt die dann weiter.


    einen großen Einfluss hat die Frame-Wiederholung der Fernbedienungen

    Meine OFA URC-7541 hält sich an die RC-5 Specs und sendet bei gedrückt gehaltener Taste alle 114 ms ein Frame. Da mein Finger aber etwas träge ist, werden auf einen Druck hin meistens 2, manchmal auch 3 Frames gesendet.


    Die Ausgabe am TV ist je nach Bildmodus ein paar Frames verzögert, dadurch lässt man die Taste tendenziell zu spät los.
    Das Zeichnen des OSD dauert mit aufwendigen Skins zu lange, auch hier sieht man das gewünschte Ergebnis zu spät und hält die Taste dadurch zu lange gedrückt

    Im Prinzip Ja. Ich habe aber einen einfachen Skin und wenn die Fernbedienung wirklich knackig reagiert, ist der Effekt praktisch vernachlässigbar. Wenn tatsächlich ein Nachlaufen deutlich spürbar ist, stimmt etwas nicht.


    Der irmp-Empfänger, den mir ranseyer damals zugeschickt hatte, ist leider sehr zickig beim Aushandeln der USB-Verbindung und funktioniert nur an einem alten Athlon64, aber nicht an meinem normalen Testsystem.

    Interessant :) . Das kenne ich nur, wenn der USBDP Pullup nicht den vorgeschriebenen Wert hat. Bei China-Ware gibt es das manchmal. Hast du einen Blauen? Dann messe ich mal.


    Außerdem scheint er zumindest bei RC-5 die ersten paar Tastenwiederholungen zu verschlucken.

    Das habe ich noch nie beobachtet. Jedenfalls nicht seit ich damals die Firmware als für den produktiven Einsatz bereit erklärt habe. Die LEDs toggelten aber langsamer und reagierten nicht auf die erste Wiederholung.


    Kann irmplircd mittlerweile dynamisch einen später erkannten Empfänger einbinden?

    Mit der udev Regel aus meinem git schon immer.


    Der Charme bei der Lösung mit eventlircd ist

    Meine Lösung steht dem nicht nach. Es wird halt z.B. eine Lircmap.xml mit remote device="IRMP" installiert.

    Den Vorteil der Lösung mit eventlircd sehe ich eher darin, dass es für alle Fernbedienungen passt. Aber wenn man nur eine hat, ist das auch wieder egal.


    Ansonsten kann man das System natürlich auch so konfigurieren, dass irmplircd statt eventlircd genutzt wird, nur sollte das IMHO eine explizit vom Nutzer gewünschte Konfiguration sein, keine Automatik.

    Ja, so ist es gemeint.

    Ich wollte wissen, ob das irgendeine unerwünschte Nebenwirkung haben könnte.


    Ich würde es ja auch gerne mal auf einem yaVDR testen, vielleicht ist ja doch irgendwas anders als auf OpenELEC, nur scheint es zur Zeit etwas kompliziert zu sein, einen neu zu installieren.


    Der Hauptknackpunkt ist für mich als Erstes die Frage, wieso ich mit evtest an /dev/input/eventX nach einem Key-Down fortlaufend Wiederholungen sehe, bis ein Key-Up kommt (so wie bei Keyboard Tastendrücken), während du keine zusätzlichen Tastendrücke hast.

  • Das kenne ich nur, wenn der USBDP Pullup nicht den vorgeschriebenen Wert hat. Bei China-Ware gibt es das manchmal. Hast du einen Blauen? Dann messe ich mal.

    Ja, das ist ein blaues USBASP V2.0 - welche Werte für die Widerstände sollte ich da messen können? Die SMD-Bauteile scheinen z.T. etwas wenig Lötzinn abbekommen zu haben (eventuell ist es ein Wackelkontakt, an dem Athlon64 fliegt der Empfänger bei längerem Betrieb immer mal wieder kurzzeitig raus und wird danach wieder neu erkannt):



    Der Hauptknackpunkt ist für mich als Erstes die Frage, wieso ich mit evtest an /dev/input/eventX nach einem Key-Down fortlaufend Wiederholungen sehe, bis ein Key-Up kommt (so wie bei Keyboard Tastendrücken), während du keine zusätzlichen Tastendrücke hast.

    Um was für einem Gerät geht es da genau? lircd2uinput sollte eigentlich nur Tastendrücke weiterreichen, die es von einem Lirc-kompatiblen Sockel liest (Ausnahme ist der Key-Release, der bei der Version, die aktuell in yavdr-utils steckt, auch über einen Timeout ausgelöst werden kann, sonst passiert das z.B. wenn man auf eine andere Taste wechselt). Bei anderen Varianten um die Tasten-Events zu generieren (wie z.B. lircd-uinput) kann das natürlich abweichen. Die lircd2uinput-Version im weiter oben verlinkten Git-Repository ist noch mal deutlich besser darin eventlircd dazu zu bringen möglichst 1:1 das auf dem Eventlircd-Sockel auszugeben, was auf dem lirc-kompatiblen Sockel ankommt - der IRMP-Empfänger hat wohl die Besonderheit, dass er die ersten gesendeten Tastenwiederholungen ignoriert und mit früheren Versionen läuft lircd2uinput deswegen leicht mal in den Timeout und liefert deswegen erst einen einzelnen Tastendruck und erst danach Tastenwiederholungen für eine gedrückt gehaltene Taste.

    Mit der udev Regel aus meinem git schon immer.

    Wenn ich das richtig sehe, sorgt diese Udev-Regel im Zusammen spielt mit der implircd.service nur dafür, dass irmplircd bei erkannter Hardware gestartet wird. Und erst dann wird der lirc-kompatible Sockel bereitgestellt. Damit fängt man sich eine implizite Abhängigkeit von KODI zu irmplircd ein, denn wenn der Sockel noch nicht verfügbar ist, wenn KODI gestartet wird, reagiert es nicht auf die Fernbedienung (im Gegensatz zum VDR macht KODI keine endlosen Verbindungsversuche). Eventlircd hat keinerlei Abhängigkeiten zu vorhandener Hardware und bindet alles dynamisch ein, was ein passendes udev-Attribut trägt.

    yaVDR-Dokumentation (Ceterum censeo enchiridia esse lectitanda.)

  • das ist ein blaues USBASP V2.0

    Sorry, bei IRMP dachte ich gleich an „meinen“ IRMP, aber du hast ja den USBASP und nicht den STM32. Mit dem USBASP kenne ich mich nicht wirklich aus, weil ich nie einen hatte. IRMP != IRMP ;)


    Um was für einem Gerät geht es da genau?

    Das von lircd-uinput erzeugte.


    Bei anderen Varianten um die Tasten-Events zu generieren (wie z.B. lircd-uinput) kann das natürlich abweichen.

    Ich konnte bisher nur mit lircd-uinput testen, aber ich werde Tests mit lircd2uinput nachholen.


    Wenn ich das richtig sehe, sorgt diese Udev-Regel im Zusammen spielt mit der implircd.service nur dafür, dass irmplircd bei erkannter Hardware gestartet wird. Und erst dann wird der lirc-kompatible Sockel bereitgestellt.

    OK, ich hatte die Frage falsch verstanden. Ist aber ein guter Hinweis, darüber mache ich mir mal Gedanken.


    Der Knackpunkt scheint zu sein wie das uinput Device konfiguriert wird.

    Hiermit wird in der libsuinput der Autorepeat aktiviert, aber anscheinend nicht in deinem lircd2uinput, oder?

    Bei lircd-uinput in Zeile 565 && ioctl(fd, UI_SET_EVBIT, EV_REP) == 0 wird der Autorepeat aber aktiviert, ohne dass man das wegkonfigurieren könnte.

    Und das ist vermutlich der Grund für mein Problem mit dem Standard-Weg in OpenELEC.

  • ich werde Tests mit lircd2uinput nachholen.

    Funktioniert einwandfrei :) !


    Also ist lircd-uinput das Problem.

    Warum benutzt OpenELEC so einen Mist?!


    Die lircd2uinput-Version im weiter oben verlinkten Git-Repository ist noch mal deutlich besser darin eventlircd dazu zu bringen möglichst 1:1 das auf dem Eventlircd-Sockel auszugeben, was auf dem lirc-kompatiblen Sockel ankommt

    Vielen Dank für deine Hilfe und für lircd2uinput!

  • Darum gibt es heut zu Tage ja auch LibreElec :)

  • Für lircd2uinput braucht man etliche Python Pakete oder man baut mit pyinstaller ein Binary, dass aber lächerlich groß wird. Das ist für ein Minimal-System wie LibreELEC nicht so schön.


    Daher habe ich lircd-uinput so gepatcht, dass es mit irmplircd genauso knackig läuft wie lircd2uinput. Da das C ist, ist das ein kleines Binary. Muss aber noch aufgeräumt und auf Sonderfälle untersucht werden. Dann gebe ich es heraus.


    Noch ein kleiner Patch für irw mit timestamps, die Zeile muss für führende Nullen so lauten:

    printf("%ld.%06ld: %s", currentTime.tv_sec, currentTime.tv_usec, buf);

    Beim Testen ist das sehr praktisch, in einem Fenster läuft irw mit timestamps am irmplircd-Sockel, in einem Zweiten läuft lircd-uinput mit Debug-Ausgaben und im Dritten evtest oder ir-keytable. Dann sieht man genau was passiert.

  • Fürlircd2uinput braucht man etliche Python Pakete oder man baut mitpyinstaller ein Binary, dass aber lächerlich groß wird. Das ist fürein Minimal-System wie LibreELEC nicht so schön.

    Schön, wenn du dir die Zeit nimmst da etwas schlankes in C zu bauen - vielleicht könnte man das dann auch dem neuen Lirc-Maintainer vorschlagen (nur wäre da ein funktionierender Key-Release notwendig, denn es muss ja nicht zwingend eventlircd dran hängen).


    lircd2uinput kann ja noch ein paar Sachen mehr als nur Tastendrücke von einem einzigen Lircd-Sockel weiterzuleiten, daher ist das für yaVDR schon ok - zumal bis auf python3-uinput alle Abhängigkeiten auch von anderen Sachen wie dem Frontend-Skript genutzt werden.

    yaVDR-Dokumentation (Ceterum censeo enchiridia esse lectitanda.)

  • nur wäre da ein funktionierender Key-Release notwendig

    Ja, genau der ist noch auf meiner TODO Liste.


    vielleicht könnte man das dann auch dem neuen Lirc-Maintainer vorschlagen

    Das ist der Plan, wenn es dann erst mal fertig ist.


    lircd2uinput kann ja noch ein paar Sachen mehr

    Was denn?

  • Was denn?

    Es bietet über DBus die Möglichkeit im laufenden Betrieb lirc-kompatible Sockel hinzuzufügen bzw. zu entfernen (und man kann auch Tastendrücke auslösen).


    Die Grundidee ist, dass man ein beliebiges Systemd-Skript leicht für lircd2uinput fit machen kann - z.B. gibt es dann zusätzlich zu einer lircd.service, die aus dem originalen Paket stammt, ein kleines Drop-In, das den Sockel bei lircd2uinput an- bzw. abmeldet:

    Code
    1. # /etc/systemd/system/lircd.service.d/lircd2uinput.conf
    2. [Service]
    3. ExecStartPost=/usr/bin/lircd2uinput-add /var/run/lirc/lircd0
    4. ExecStopPost=/usr/bin/lircd2uinput-remove /var/run/lirc/lircd0

    yaVDR-Dokumentation (Ceterum censeo enchiridia esse lectitanda.)

  • Geschafft :) .


    In die lirc_options.conf muss so ein Abschnitt rein:

    [lircd-uinput]

    release-timeout = 0


    Anbei diff und Binary zum bequemen testen.

    Dateien

  • Vermutlich liest irw nicht schnell genug vom lirc-Sockel, evtest holt sich den Timestamp direkt aus den Events statt ihn selbst zu ermitteln: https://cgit.freedesktop.org/evtest/tree/evtest.c#n1111

    yaVDR-Dokumentation (Ceterum censeo enchiridia esse lectitanda.)

  • Ich hab es mal ausprobiert - leider feuert lircd-uinput aus der Version 0.10.0 auch mit deinem Patch endlos Wiederholungsevents, sobald man eine Taste gedrückt hat.

    Dein binary scheint auch nicht zur Lirc-Version 0.10.0 zu passen (LibreElec scheint noch die Version 0.9.4d zu nutzen), denn es verabschiedet sich mit einem Crash, sobald man eine Taste drückt:

    Code
    1. $ sudo ./lircd-uinput
    2. lircd-0.10.0[2356]: Info: lircd-uinput: Opening log, level: Info
    3. lircd-0.10.0[2356]: Info: Reading data from /var/run/lirc/lircd0, writing to /dev/uinput
    4. ./lircd-uinput: symbol lookup error: ./lircd-uinput: undefined symbol: _ZN10LineBuffer13get_next_lineEv

    yaVDR-Dokumentation (Ceterum censeo enchiridia esse lectitanda.)

  • Fehlt mir da noch etwas in der lirc_options.conf?

    yaVDR-Dokumentation (Ceterum censeo enchiridia esse lectitanda.)

  • Bin unterwegs und kann erst Dienstag gucken, aus welchem git ich das geladen hatte.


    Hab vergessen zu erwähnen, dass mit -a gestartet werden muss, damit der release-timeout aktiviert wird: lircd-uinput -a

  • Ok, wenn ich lircd2uinput -a nutze, ist sind die endlosen Tastenwiederholungen weg, allerdings kommt das Programm bei der Reihenfolge der Tasten-Events durcheinander, wenn release-timeout=0 gesetzt ist (und dann ignoriert eventlircd die Wiederholungs-Events):

    Code: irw /run/lirc/lircd0
    1. 1516014427.509139: 00000000000002c5 00 KEY_DOWN harmony_kls_vdr_1.6
    2. 1516014427.621137: 00000000000002c5 01 KEY_DOWN harmony_kls_vdr_1.6
    3. 1516014427.733153: 00000000000002c5 02 KEY_DOWN harmony_kls_vdr_1.6
    4. 1516014427.845125: 00000000000002c5 03 KEY_DOWN harmony_kls_vdr_1.6
    5. 1516014427.965126: 00000000000002c5 04 KEY_DOWN harmony_kls_vdr_1.6
    6. 1516014428.077128: 00000000000002c5 05 KEY_DOWN harmony_kls_vdr_1.6
    7. 1516014428.237263: 00000000000002c5 06 KEY_DOWN harmony_kls_vdr_1.6


    Wenn man den release-timeout erhöht (z.B. 150 ms), sendet er einen Key-Repeat am Ende zu viel:

    Code
    1. 1516014216.702177: 00000000000002c5 00 KEY_DOWN harmony_kls_vdr_1.6
    2. 1516014216.814162: 00000000000002c5 01 KEY_DOWN harmony_kls_vdr_1.6
    3. 1516014216.974323: 00000000000002c5 02 KEY_DOWN harmony_kls_vdr_1.6

    Code
    1. Event: time 1516014216.702225, type 1 (EV_KEY), code 108 (KEY_DOWN), value 1
    2. Event: time 1516014216.702225, -------------- SYN_REPORT ------------
    3. Event: time 1516014216.814216, type 1 (EV_KEY), code 108 (KEY_DOWN), value 2
    4. Event: time 1516014216.814216, -------------- SYN_REPORT ------------
    5. Event: time 1516014216.958897, type 1 (EV_KEY), code 108 (KEY_DOWN), value 2
    6. Event: time 1516014216.958897, -------------- SYN_REPORT ------------
    7. Event: time 1516014216.964420, type 1 (EV_KEY), code 108 (KEY_DOWN), value 0
    8. Event: time 1516014216.964420, -------------- SYN_REPORT ------------
    9. Event: time 1516014216.974373, type 1 (EV_KEY), code 108 (KEY_DOWN), value 2
    10. Event: time 1516014216.974373, -------------- SYN_REPORT ------------

    yaVDR-Dokumentation (Ceterum censeo enchiridia esse lectitanda.)