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:
[Socket]
ListenStream=/run/lirc/lircd_filter
[Install]
WantedBy=sockets.target
Also=repeat-filter.service
[Unit]
Description="read eventlircd output, write to own socket"
[Service]
Type=simple
ExecStart=/usr/local/bin/repeat-filter
Restart=on-failure
RestartSec=1s
KillMode=process
KillSignal=SIGINT
TimeoutStopSec=1s
[Install]
WantedBy=multi-user.target
Alles anzeigen
[Service]
Environment=LIRC_SOCKET_PATH=/run/lirc/lircd_filter
#!/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()
Alles anzeigen
Und dann noch mit systemctl enable repeat-filter.socket anschalten. Dann sollte der Dienst automatisch starten, wenn jemand auf /run/lirc/lircd_filter zugreift.