Wie komme ich denn per node2 an die Rohdaten?
Der Empfänger wird über das Kernel-Modul serial_ir eingebunden, lircd ist da nicht mehr beteiligt. Du kannst bei gestopptem eventlircd.service und eventlircd.socket mit ir-keytable -t die Tastendrücke ansehen und wenn du die Keytable löschst (ir-keytable -c), bekommst du die rohen dekodierten Scancodes.
Im VDR kannst du über die Fernbedienungseinstellungen (vgl. https://projects.vdr-developer…dr.git/tree/HISTORY#n7587 ff.) festlegen, dass zu schnell gesendete Tastenwiederholungen ignoriert werden sollen.
Wenn das auch mit KODI ein Problem ist, kann man sich mit einem Repeat-Filter behelfen:
- #!/usr/bin/env python3
- import os
- import select
- import socket
- import sys
- import time
- class LircConnection:
- socket_path_in = '/run/lirc/lircd'
- socket_path_out = '/run/lirc/lircd_filter'
- last_keypress = 0
- last_key = None
- last_ts = float('nan')
- clients = []
- def __init__(self, ignore_repeats=1, timeout=400):
- self.ignore_repeats = ignore_repeats
- self.timeout = timeout / 1000.0
- self.buffer = b""
- self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
- self.sock.connect(self.socket_path_in)
- self.last_key = None
- self.last_ts = 0
- self.n_repeats = 0
- # output
- self.cleanup()
- self.output_sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
- self.output_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
- self.output_sock.bind(self.socket_path_out)
- os.chmod(self.socket_path_out, 0o666)
- self.output_sock.listen(5)
- # set up epoll
- self.epoll = select.epoll()
- self.epoll.register(self.sock, select.EPOLLIN)
- self.epoll.register(self.output_sock, select.EPOLLIN)
- def cleanup(self):
- try:
- os.remove(self.socket_path_out)
- except OSError:
- pass
- def line_checker(self, line):
- ts = time.time()
- result = True
- try:
- keycode, count, keyname, devname = line.split()
- except ValueError:
- return False
- if (count == b'0' and self.last_key == keyname and
- ts - self.last_ts < self.timeout):
- if self.n_repeats < self.ignore_repeats:
- self.n_repeats += 1
- result = False
- else:
- self.n_repeats = 0
- self.last_ts = ts
- self.last_key = keyname
- return result
- def output(self, line):
- for client in self.clients:
- try:
- client.send(line + b"\n")
- except Exception: # garbage collection for lost clients
- print((f"cannot write to connection {client},"
- "removing client connection"), file=sys.stderr)
- client.close()
- self.clients.remove(client)
- def lircd_handler(self):
- while True:
- events = self.epoll.poll()
- for fileno, event in events:
- if event & select.EPOLLIN:
- if fileno == self.sock.fileno():
- self.buffer += self.sock.recv(1024)
- line, sep, rest = b' ', b' ', b' '
- while sep and rest:
- line, sep, rest = self.buffer.partition(b'\n')
- self.buffer = rest
- if self.line_checker(line):
- self.output(line)
- else:
- conn, address = self.output_sock.accept()
- self.clients.append(conn)
- if __name__ == '__main__':
- try:
- lirc = LircConnection(ignore_repeats=1, timeout=400)
- lirc.lircd_handler()
- except KeyboardInterrupt:
- lirc.output_sock.close()
- lirc.cleanup()
Und dann noch mit systemctl enable repeat-filter.socket anschalten. Dann sollte der Dienst automatisch starten, wenn jemand auf /run/lirc/lircd_filter zugreift.