Fix power button shutdown by consolidating input handling in screen monitor
Both the evtest-based power monitor and the Python screen monitor were reading /dev/input/event0 simultaneously, causing missed events on the device's Linux 4.9 kernel. Moved long-press shutdown into the screen monitor (which already reads event0 directly) and removed the evtest dependency entirely. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,23 +1,27 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Screen idle timeout and power button toggle for RG35XX Plus.
|
||||
Screen idle timeout, power button toggle, and long-press shutdown for RG35XX Plus.
|
||||
|
||||
Monitors /dev/input/event{0,1,2} for activity. Turns off the screen
|
||||
(via Allwinner /dev/disp SET_BRIGHTNESS ioctl) after 15s of no input.
|
||||
Any button press wakes the screen. A short power button press (<2s)
|
||||
toggles the screen on/off.
|
||||
toggles the screen on/off. A long press (3s+) triggers clean shutdown.
|
||||
|
||||
Launched by rg35xx-wrapper.sh alongside sdlamp2. Killed on cleanup.
|
||||
|
||||
Usage: rg35xx-screen-monitor.py <sdlamp2_pid>
|
||||
"""
|
||||
import fcntl
|
||||
import os
|
||||
import select
|
||||
import signal
|
||||
import struct
|
||||
import sys
|
||||
import time
|
||||
|
||||
IDLE_TIMEOUT = 15 # seconds
|
||||
POWER_HOLD_THRESHOLD = 2.0 # seconds — short press if released before this
|
||||
POWER_SHORT_THRESHOLD = 2.0 # seconds — short press if released before this
|
||||
POWER_LONG_THRESHOLD = 3.0 # seconds — shutdown if held this long
|
||||
|
||||
# Allwinner /dev/disp ioctl commands
|
||||
DISP_GET_BRIGHTNESS = 0x103
|
||||
@@ -50,6 +54,12 @@ def set_brightness(disp_fd, value):
|
||||
|
||||
|
||||
def main():
|
||||
if len(sys.argv) < 2:
|
||||
print("Usage: rg35xx-screen-monitor.py <sdlamp2_pid>", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
sdlamp2_pid = int(sys.argv[1])
|
||||
|
||||
disp_fd = os.open("/dev/disp", os.O_RDWR)
|
||||
original_brightness = get_brightness(disp_fd)
|
||||
if original_brightness == 0:
|
||||
@@ -82,14 +92,29 @@ def main():
|
||||
os.close(disp_fd)
|
||||
sys.exit(1)
|
||||
|
||||
import select
|
||||
|
||||
while True:
|
||||
readable, _, _ = select.select(event_fds, [], [], IDLE_TIMEOUT)
|
||||
# Dynamic timeout: if power button is held, shorten timeout to detect 3s mark
|
||||
timeout = IDLE_TIMEOUT
|
||||
if power_press_time is not None:
|
||||
remaining = POWER_LONG_THRESHOLD - (time.monotonic() - power_press_time)
|
||||
if remaining <= 0:
|
||||
# Already past threshold — trigger shutdown now
|
||||
touch_and_shutdown(disp_fd, original_brightness, screen_on, sdlamp2_pid)
|
||||
return
|
||||
timeout = min(timeout, remaining)
|
||||
|
||||
readable, _, _ = select.select(event_fds, [], [], timeout)
|
||||
|
||||
# Check long-press threshold (whether select returned due to timeout or input)
|
||||
if power_press_time is not None:
|
||||
held = time.monotonic() - power_press_time
|
||||
if held >= POWER_LONG_THRESHOLD:
|
||||
touch_and_shutdown(disp_fd, original_brightness, screen_on, sdlamp2_pid)
|
||||
return
|
||||
|
||||
if not readable:
|
||||
# Timeout — no input for IDLE_TIMEOUT seconds
|
||||
if screen_on:
|
||||
# Timeout with no input — turn off screen if idle
|
||||
if screen_on and power_press_time is None:
|
||||
set_brightness(disp_fd, 0)
|
||||
screen_on = False
|
||||
continue
|
||||
@@ -118,7 +143,7 @@ def main():
|
||||
elif ev_value == 0 and power_press_time is not None: # release
|
||||
hold_duration = time.monotonic() - power_press_time
|
||||
power_press_time = None
|
||||
if hold_duration < POWER_HOLD_THRESHOLD:
|
||||
if hold_duration < POWER_SHORT_THRESHOLD:
|
||||
# Short press — toggle screen
|
||||
if screen_on:
|
||||
set_brightness(disp_fd, 0)
|
||||
@@ -126,6 +151,7 @@ def main():
|
||||
else:
|
||||
set_brightness(disp_fd, original_brightness)
|
||||
screen_on = True
|
||||
# Between SHORT and LONG threshold: ignore (release before 3s)
|
||||
continue
|
||||
|
||||
# Any other key press — wake screen if off
|
||||
@@ -134,5 +160,20 @@ def main():
|
||||
screen_on = True
|
||||
|
||||
|
||||
def touch_and_shutdown(disp_fd, original_brightness, screen_on, sdlamp2_pid):
|
||||
"""Signal sdlamp2 to exit and flag for shutdown."""
|
||||
if not screen_on:
|
||||
set_brightness(disp_fd, original_brightness)
|
||||
os.close(disp_fd)
|
||||
try:
|
||||
open("/tmp/.sdlamp2_shutdown", "w").close()
|
||||
except OSError:
|
||||
pass
|
||||
try:
|
||||
os.kill(sdlamp2_pid, signal.SIGTERM)
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
Reference in New Issue
Block a user