import evdev import json import sys import select import os class KeyboardLedMonitor: def __init__(self): self.last_state = {"caps": "0", "num": "0"} self.kbd_devices = [] # ищем все устройства, которые умеют в CapsLock devices = [evdev.InputDevice(path) for path in evdev.list_devices()] for dev in devices: capabilities = dev.capabilities().get(evdev.ecodes.EV_KEY, []) if evdev.ecodes.KEY_CAPSLOCK in capabilities: self.kbd_devices.append(dev) if not self.kbd_devices: sys.exit(1) # выводим начальное состояние self.push_update(self.kbd_devices[0]) def get_led_state(self, dev): # проверяем коды leds = dev.leds() return { "caps": "1" if 1 in leds else "0", "num": "1" if 0 in leds else "0" } def push_update(self, dev): # отдаем json в stdout при изменении current_state = self.get_led_state(dev) if current_state != self.last_state: sys.stdout.write(json.dumps(current_state) + "\n") sys.stdout.flush() self.last_state = current_state def run(self): # создаем мапу файловых дескрипторов для селектора devices_dict = {d.fd: d for d in self.kbd_devices} try: while True: # ждем событий от любого из устройств r, _, _ = select.select(devices_dict, [], []) for fd in r: dev = devices_dict[fd] for event in dev.read(): # если прилетело событие изменения светодиода if event.type == evdev.ecodes.EV_LED: self.push_update(dev) except (PermissionError, KeyboardInterrupt): sys.exit(0) if __name__ == "__main__": KeyboardLedMonitor().run()