|
2 | 2 |
|
3 | 3 | import evdev
|
4 | 4 | import logging
|
5 |
| -import os |
| 5 | +import subprocess |
6 | 6 | import sys
|
| 7 | +import threading |
7 | 8 |
|
8 | 9 | logging.basicConfig(level=logging.INFO)
|
9 | 10 |
|
10 |
| -devices = [evdev.InputDevice(path) for path in evdev.list_devices()] |
11 |
| -device_names = ', '.join([d.name for d in devices]) |
12 |
| -logging.info(f'Found devices: {device_names}') |
| 11 | +def handle_device(device): |
| 12 | + """Handle power key presses for the given input device by invoking poweroff.""" |
13 | 13 |
|
14 |
| -power_off_device = next((d for d in devices if d.name == 'Power Button'), None) |
15 |
| -if power_off_device is None: |
16 |
| - logging.error(f'Power Button device not found') |
17 |
| - sys.exit(1) |
| 14 | + logging.info(f'Listening to Power Button on device {device.path}') |
| 15 | + try: |
| 16 | + for event in device.read_loop(): |
| 17 | + if event.type == evdev.ecodes.EV_KEY and event.code == evdev.ecodes.KEY_POWER and event.value: |
| 18 | + logging.info(f'KEY_POWER detected on {device.path}, shutting down') |
| 19 | + subprocess.run(['systemctl', 'start', 'poweroff.target'], check=True) |
| 20 | + except Exception as e: |
| 21 | + logging.error(f'Error handling {device.path}: {e}') |
| 22 | + |
| 23 | +def get_power_button_devices(): |
| 24 | + """Get all input devices which identify as 'Power Button' and have a power key.""" |
| 25 | + |
| 26 | + devices = [evdev.InputDevice(path) for path in evdev.list_devices()] |
| 27 | + |
| 28 | + power_button_devices = [] |
| 29 | + for device in devices: |
| 30 | + try: |
| 31 | + if device.name == 'Power Button': |
| 32 | + ev_capabilities = device.capabilities().get(evdev.ecodes.EV_KEY, []) |
| 33 | + if evdev.ecodes.KEY_POWER in ev_capabilities: |
| 34 | + power_button_devices.append(device) |
| 35 | + except Exception as e: |
| 36 | + logging.warning(f'Failed to inspect {device.path}: {e}') |
| 37 | + |
| 38 | + return power_button_devices |
| 39 | + |
| 40 | +# Identify Power Button devices |
| 41 | +power_button_devices = get_power_button_devices() |
| 42 | +if not power_button_devices: |
| 43 | + logging.error('No Power Button devices found') |
| 44 | + sys.exit(1) |
| 45 | +logging.info(f'Found {len(power_button_devices)} Power Button device(s)') |
| 46 | + |
| 47 | +# Start a thread with a handler for each identified device |
| 48 | +handler_threads = [] |
| 49 | +for device in power_button_devices: |
| 50 | + thread = threading.Thread(target=handle_device, args=(device,)) |
| 51 | + thread.start() |
| 52 | + handler_threads.append(thread) |
| 53 | + |
| 54 | +# Exit gracefully if a handler executes |
| 55 | +try: |
| 56 | + for thread in handler_threads: |
| 57 | + thread.join() |
| 58 | +except KeyboardInterrupt: |
| 59 | + sys.exit(0) |
18 | 60 |
|
19 |
| -logging.info(f'Listening to Power Button on device {power_off_device.path}') |
20 |
| -for event in power_off_device.read_loop(): |
21 |
| - if event.type == evdev.ecodes.EV_KEY and evdev.ecodes.KEY[event.code] == 'KEY_POWER' and event.value: |
22 |
| - logging.info('KEY_POWER detected on Power Button device, shutting down') |
23 |
| - os.system('systemctl start poweroff.target') |
|
0 commit comments