led_monitor -> led-monitor
This commit is contained in:
@@ -18,7 +18,7 @@ Singleton {
|
|||||||
id: capslockMonitorProcess
|
id: capslockMonitorProcess
|
||||||
|
|
||||||
running: true
|
running: true
|
||||||
command: ["led_monitor", "-l", "capslock"]
|
command: ["led-monitor", "-l", "capslock"]
|
||||||
|
|
||||||
stdout: SplitParser {
|
stdout: SplitParser {
|
||||||
splitMarker: "\n"
|
splitMarker: "\n"
|
||||||
|
|||||||
+22
-16
@@ -4,21 +4,17 @@ import glob
|
|||||||
import argparse
|
import argparse
|
||||||
import select
|
import select
|
||||||
import os
|
import os
|
||||||
import fcntl
|
|
||||||
import struct
|
import struct
|
||||||
|
|
||||||
# struct input_event: struct timeval (typically 2 longs), type (uint16), code (uint16), value (int32)
|
# struct input_event: struct timeval (typically 2 longs), type (uint16), code (uint16), value (int32)
|
||||||
# '@' ensures native byte order, size, and alignment.
|
# '@' ensures native byte order, size, and alignment.
|
||||||
EVENT_FORMAT = '@llHHi'
|
EVENT_FORMAT = "@llHHi"
|
||||||
EVENT_SIZE = struct.calcsize(EVENT_FORMAT)
|
EVENT_SIZE = struct.calcsize(EVENT_FORMAT)
|
||||||
|
|
||||||
EV_LED = 0x11
|
EV_LED = 0x11
|
||||||
|
|
||||||
LED_CODES = {
|
LED_CODES = {"numlock": 0x00, "capslock": 0x01, "scrolllock": 0x02}
|
||||||
'numlock': 0x00,
|
|
||||||
'capslock': 0x01,
|
|
||||||
'scrolllock': 0x02
|
|
||||||
}
|
|
||||||
|
|
||||||
def get_led_state(led_type: str) -> int:
|
def get_led_state(led_type: str) -> int:
|
||||||
pattern = f"/sys/class/leds/*::{led_type}/brightness"
|
pattern = f"/sys/class/leds/*::{led_type}/brightness"
|
||||||
@@ -27,24 +23,26 @@ def get_led_state(led_type: str) -> int:
|
|||||||
return 0
|
return 0
|
||||||
for path in paths:
|
for path in paths:
|
||||||
try:
|
try:
|
||||||
with open(path, 'r') as f:
|
with open(path, "r") as f:
|
||||||
if int(f.read().strip()) > 0:
|
if int(f.read().strip()) > 0:
|
||||||
return 1
|
return 1
|
||||||
except (IOError, ValueError, OSError):
|
except (IOError, ValueError, OSError):
|
||||||
continue
|
continue
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
def has_led_capability(event_path: str) -> bool:
|
def has_led_capability(event_path: str) -> bool:
|
||||||
try:
|
try:
|
||||||
basename = os.path.basename(event_path)
|
basename = os.path.basename(event_path)
|
||||||
cap_path = f"/sys/class/input/{basename}/device/capabilities/led"
|
cap_path = f"/sys/class/input/{basename}/device/capabilities/led"
|
||||||
if os.path.exists(cap_path):
|
if os.path.exists(cap_path):
|
||||||
with open(cap_path, 'r') as f:
|
with open(cap_path, "r") as f:
|
||||||
return f.read().strip() != "0"
|
return f.read().strip() != "0"
|
||||||
except OSError:
|
except OSError:
|
||||||
pass
|
pass
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
class DeviceMonitor:
|
class DeviceMonitor:
|
||||||
def __init__(self, target_led: str):
|
def __init__(self, target_led: str):
|
||||||
self.target_led = target_led
|
self.target_led = target_led
|
||||||
@@ -62,7 +60,7 @@ class DeviceMonitor:
|
|||||||
|
|
||||||
def scan_devices(self) -> None:
|
def scan_devices(self) -> None:
|
||||||
current_fds = set(self.active_fds.keys())
|
current_fds = set(self.active_fds.keys())
|
||||||
paths = glob.glob('/dev/input/event*')
|
paths = glob.glob("/dev/input/event*")
|
||||||
found_fds = set()
|
found_fds = set()
|
||||||
|
|
||||||
for path in paths:
|
for path in paths:
|
||||||
@@ -134,9 +132,14 @@ class DeviceMonitor:
|
|||||||
events_count = len(data) // EVENT_SIZE
|
events_count = len(data) // EVENT_SIZE
|
||||||
for i in range(events_count):
|
for i in range(events_count):
|
||||||
chunk = data[i * EVENT_SIZE : (i + 1) * EVENT_SIZE]
|
chunk = data[i * EVENT_SIZE : (i + 1) * EVENT_SIZE]
|
||||||
_, _, ev_type, ev_code, _ = struct.unpack(EVENT_FORMAT, chunk)
|
_, _, ev_type, ev_code, _ = struct.unpack(
|
||||||
|
EVENT_FORMAT, chunk
|
||||||
|
)
|
||||||
|
|
||||||
if ev_type == EV_LED and ev_code == self.target_led_code:
|
if (
|
||||||
|
ev_type == EV_LED
|
||||||
|
and ev_code == self.target_led_code
|
||||||
|
):
|
||||||
# Instead of acting immediately on the value, we just flag it.
|
# Instead of acting immediately on the value, we just flag it.
|
||||||
# This prevents state bouncing between multiple kernel devices.
|
# This prevents state bouncing between multiple kernel devices.
|
||||||
led_event_triggered = True
|
led_event_triggered = True
|
||||||
@@ -166,19 +169,22 @@ class DeviceMonitor:
|
|||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
parser = argparse.ArgumentParser(description="Keyboard LED monitor.")
|
parser = argparse.ArgumentParser(description="Keyboard LED monitor.")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-l', '--led',
|
"-l",
|
||||||
|
"--led",
|
||||||
type=str,
|
type=str,
|
||||||
default='capslock',
|
default="capslock",
|
||||||
choices=['capslock', 'numlock', 'scrolllock'],
|
choices=["capslock", "numlock", "scrolllock"],
|
||||||
help="Target LED to monitor"
|
help="Target LED to monitor",
|
||||||
)
|
)
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
monitor = DeviceMonitor(args.led)
|
monitor = DeviceMonitor(args.led)
|
||||||
monitor.run()
|
monitor.run()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
Reference in New Issue
Block a user