Add cec-remote scripts
parent
69b511af2d
commit
535e8c5a72
@ -1,14 +0,0 @@
|
|||||||
[Unit]
|
|
||||||
Description=CEC Receiver Service
|
|
||||||
After=network.target
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
ExecStart=/usr/bin/python3 /home/kuba/cec-remote/cec_receiver.py
|
|
||||||
WorkingDirectory=/home/kuba/cec-remote
|
|
||||||
Restart=on-failure
|
|
||||||
RestartSec=5
|
|
||||||
User=kuba
|
|
||||||
Environment=PYTHONUNBUFFERED=1
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
@ -0,0 +1,127 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import socket
|
||||||
|
import json
|
||||||
|
from evdev import UInput, ecodes as e
|
||||||
|
|
||||||
|
# Capabilities for both gamepad and keyboard
|
||||||
|
capabilities = {
|
||||||
|
e.EV_KEY: [
|
||||||
|
e.BTN_A, e.BTN_B, e.BTN_START,
|
||||||
|
e.BTN_DPAD_UP, e.BTN_DPAD_DOWN, e.BTN_DPAD_LEFT, e.BTN_DPAD_RIGHT,
|
||||||
|
e.KEY_LEFTCTRL, e.KEY_1
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
# Mapping CEC keys to gamepad buttons or keyboard keys
|
||||||
|
key_map = {
|
||||||
|
'SELECT': e.BTN_A,
|
||||||
|
'EXIT': e.BTN_B,
|
||||||
|
'PLAY': e.BTN_START,
|
||||||
|
'PAUSE': e.BTN_START,
|
||||||
|
'UP': e.BTN_DPAD_UP,
|
||||||
|
'DOWN': e.BTN_DPAD_DOWN,
|
||||||
|
'LEFT': e.BTN_DPAD_LEFT,
|
||||||
|
'RIGHT': e.BTN_DPAD_RIGHT
|
||||||
|
# 'CLEAR' handled separately
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
import time
|
||||||
|
from evdev import InputDevice, ecodes, list_devices, UInput
|
||||||
|
|
||||||
|
# Define key codes for Ctrl and 1
|
||||||
|
SHIFT = ecodes.KEY_LEFTSHIFT
|
||||||
|
TAB = ecodes.KEY_TAB
|
||||||
|
|
||||||
|
# Define virtual keyboard capabilities (DO NOT include EV_SYN)
|
||||||
|
keyboard_events = {
|
||||||
|
ecodes.EV_KEY: [SHIFT,TAB],
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create the virtual input device
|
||||||
|
keyboard_ui = UInput(events=keyboard_events, name="Virtual Ctrl+1 Injector", bustype=ecodes.BUS_USB)
|
||||||
|
|
||||||
|
|
||||||
|
def home():
|
||||||
|
print("Sending shift+home")
|
||||||
|
keyboard_ui.write(ecodes.EV_KEY, SHIFT, 1) # Press Ctrl
|
||||||
|
keyboard_ui.write(ecodes.EV_KEY, TAB, 1) # Press 1
|
||||||
|
keyboard_ui.syn()
|
||||||
|
time.sleep(0.1)
|
||||||
|
keyboard_ui.write(ecodes.EV_KEY, SHIFT, 0) # Release 1
|
||||||
|
keyboard_ui.write(ecodes.EV_KEY, TAB, 0) # Release Ctrl
|
||||||
|
keyboard_ui.syn()
|
||||||
|
|
||||||
|
|
||||||
|
last_pressed = None # Track last key to release
|
||||||
|
|
||||||
|
def create_virtual_device():
|
||||||
|
return UInput(capabilities, name='CEC Virtual Input', bustype=e.BUS_USB)
|
||||||
|
|
||||||
|
def handle_press(ui, key):
|
||||||
|
global last_pressed
|
||||||
|
|
||||||
|
if key == 'CLEAR':
|
||||||
|
home()
|
||||||
|
return
|
||||||
|
|
||||||
|
code = key_map.get(key)
|
||||||
|
if not code:
|
||||||
|
print(f"Unknown key: {key}")
|
||||||
|
return
|
||||||
|
|
||||||
|
if code == last_pressed:
|
||||||
|
return
|
||||||
|
|
||||||
|
handle_release(ui)
|
||||||
|
ui.write(e.EV_KEY, code, 1)
|
||||||
|
ui.syn()
|
||||||
|
last_pressed = code
|
||||||
|
print(f"Pressed {key} ({code})")
|
||||||
|
|
||||||
|
def handle_release(ui):
|
||||||
|
global last_pressed
|
||||||
|
if last_pressed is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
if isinstance(last_pressed, tuple):
|
||||||
|
# Release both Ctrl and 1
|
||||||
|
for code in last_pressed:
|
||||||
|
ui.write(e.EV_KEY, code, 0)
|
||||||
|
print("Released Ctrl+1")
|
||||||
|
else:
|
||||||
|
ui.write(e.EV_KEY, last_pressed, 0)
|
||||||
|
print(f"Released {last_pressed}")
|
||||||
|
|
||||||
|
ui.syn()
|
||||||
|
last_pressed = None
|
||||||
|
|
||||||
|
def start_udp_listener():
|
||||||
|
ui = create_virtual_device()
|
||||||
|
print("Virtual input device ready")
|
||||||
|
|
||||||
|
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||||
|
sock.bind(('0.0.0.0', 41234))
|
||||||
|
print("Listening for UDP input...")
|
||||||
|
|
||||||
|
while True:
|
||||||
|
data, _ = sock.recvfrom(1024)
|
||||||
|
try:
|
||||||
|
print("new payload")
|
||||||
|
payload = json.loads(data.decode())
|
||||||
|
if payload['type'] == 'key':
|
||||||
|
event_type = payload.get('event')
|
||||||
|
key_name = payload.get('key', '').upper()
|
||||||
|
|
||||||
|
if event_type == 'press':
|
||||||
|
handle_press(ui, key_name)
|
||||||
|
elif event_type == 'release':
|
||||||
|
handle_release(ui)
|
||||||
|
except Exception as ex:
|
||||||
|
print(f"Error: {ex}")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
try:
|
||||||
|
start_udp_listener()
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print("Shutting down...")
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
import libevdev
|
||||||
|
import sys
|
||||||
|
|
||||||
|
device_path = sys.argv[1]
|
||||||
|
|
||||||
|
with open(device_path, 'rb') as f:
|
||||||
|
d = libevdev.Device(f)
|
||||||
|
print(f"Device: {d.name}")
|
||||||
|
print("Capabilities:")
|
||||||
|
for event_type, codes in d.capabilities().items():
|
||||||
|
print(f" {event_type}:")
|
||||||
|
for code in codes:
|
||||||
|
print(f" {code}")
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
import time
|
||||||
|
from evdev import InputDevice, ecodes, list_devices, UInput
|
||||||
|
|
||||||
|
# Define key codes for Ctrl and 1
|
||||||
|
CTRL = ecodes.KEY_LEFTCTRL
|
||||||
|
KEY_1 = ecodes.KEY_1
|
||||||
|
|
||||||
|
# Define virtual keyboard capabilities (DO NOT include EV_SYN)
|
||||||
|
keyboard_events = {
|
||||||
|
ecodes.EV_KEY: [CTRL, KEY_1],
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create the virtual input device
|
||||||
|
ui = UInput(events=keyboard_events, name="Virtual Ctrl+1 Injector", bustype=ecodes.BUS_USB)
|
||||||
|
|
||||||
|
try:
|
||||||
|
while True:
|
||||||
|
print("Sending Ctrl + 1")
|
||||||
|
ui.write(ecodes.EV_KEY, CTRL, 1) # Press Ctrl
|
||||||
|
ui.write(ecodes.EV_KEY, KEY_1, 1) # Press 1
|
||||||
|
ui.syn()
|
||||||
|
|
||||||
|
time.sleep(0.1)
|
||||||
|
|
||||||
|
ui.write(ecodes.EV_KEY, KEY_1, 0) # Release 1
|
||||||
|
ui.write(ecodes.EV_KEY, CTRL, 0) # Release Ctrl
|
||||||
|
ui.syn()
|
||||||
|
|
||||||
|
time.sleep(2)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print("Exiting...")
|
||||||
|
ui.close()
|
||||||
Loading…
Reference in New Issue