Detect Idle State - Power Off Screen
-
I needed a solution to power off (not just blank) the display if the system is idle for a while.
Spent some time searching for an existing solution but the closes I got was thehdmi_blanking=1
option but I couldn't get it to work properly.I wrote this script to monitor joystick activity and shutdown the monitor if it's idle.
It's hacky but it works well and has minimal overhead, might need to revisit usingtvservice
insteadvcgencmd
to control the display as there's some reports ofvcgencmd
not working with some displays.Please let me know if you've tried it and have any issues, suggestions, feedback, etc...
The script was thoroughly commented to make it easier to review and hack at :|
I'll be posting it to my github at some point, should make it easier to track.Script Functionality
- HDMI On
- Monitor joystick device for activity
- Check for input in a 5 second window
- Check every 30 seconds
- If idle for longer than idle timeout, power off HDMI
- Monitor joystick device for activity
- HDMI Off
- Joystick exists
- Wait for input (blocking) - power on HDMI when detected
- Joystick doesn't exist (ex. XBOX 360 Wireless controller timeout)
- Sleep 1s and keep checking
- Joystick exists
Installation Instructions
- Copy script to user home ex.
/home/pi/idle-screenoff.sh
- Make it executable
chmod +x /home/pi/idle-screenoff.sh
- Edit the script variables to suit your timeouts and device
# inputDevice = Device to monitor for activity # - Tested with XBOX 360 Controller (first joystick js0) inputDevice=/dev/input/js0 # inputWindow = Time window (s) to monitor the device for input # - Check for input in a 5 second window inputWindow=5 # inputCount = How many inputs constitute activity + 1 # - Add 1 to desired, might be XBOX 360 unique behavior inputCount=2 # inputInterval = Time interval (s) between input checks # - Wait 30 seconds between idle input checks inputInterval=30 # inactivityTimeout = Idle time before powering off screen idleTimeoutM=10
- Reference the script in
/etc/rc.local
before theexit 0
command#!/bin/sh -e # # rc.local # # Power off screen when idle /home/pi/idle-screenoff.sh & exit 0
Script:
idle-screenoff.sh
#!/bin/bash #============================================================= # Title : idle-screenoff.sh # # Description : Power off the display when idle # - Detects idle by monitoring joystick input # # Author : QuixoticDev # # Version : v1.0 - 05/23/2018 # #============================================================= #-------------------- # User Variables #-------------------- # inputDevice = Device to monitor for activity # - Tested with XBOX 360 Controller (first joystick js0) inputDevice=/dev/input/js0 # inputWindow = Time window (s) to monitor the device for input # - Check for input in a 5 second window inputWindow=5 # inputCount = How many inputs constitute activity + 1 # - Add 1 to desired, might be XBOX 360 unique behavior inputCount=2 # inputInterval = Time interval (s) between input checks # - Wait 30 seconds between idle input checks inputInterval=30 # inactivityTimeout = Idle time before powering off screen idleTimeoutM=10 #-------------------- # Script Variables #-------------------- # Dont change idleTimeoutS=$(( ${idleTimeoutM} * 60 )) idleFlag=0 #-------------------- # Loop Forever #-------------------- while true; do # Check if HDMI is ON # 1 = ON # 0 = OFF tvStatus=$(vcgencmd display_power | awk -F'=' '{print $2}' ) if [ ${tvStatus} -eq 1 ]; then #------------------------------------------------------------------------- # HDMI Status = ON #------------------------------------------------------------------------- # - Query joystick for input with a timeout (inputWindow) # - Check if idle # - idle (first time) = start counter and set idle flag # - idle (subsequent) = Do nothing, keep looping # - Active = Reset idle flag # - Sleep between checks (inputInterval) # - Check if idle flag has been active for longer than the idleTimeoutM # - Longer = Shutdown Display # - Shorter = Keep looping #------------------------------------------------------------------------- # Check if joystick active # 0 = Joystick input detected, user active # 1 = Joystick device not available # 124 = No input received during inputWindow inputAcive=$(timeout ${inputWindow} dd if=${inputDevice} of=/dev/null count=${inputCount} >/dev/null 2>&1; echo $?) if [ ${inputAcive} -eq 0 ]; then # Active - Clear idle flag idleFlag=0 else # Not Active # Skip if already inactive if [ ${idleFlag} -eq 0 ]; then # Start timer SECONDS=0 # Set to state to inactive idleFlag=1 fi fi # Sleep sleep ${inputInterval} # Poweroff display if longer than timeout and idle if [ ${SECONDS} -ge ${idleTimeoutS} ] && [ ${idleFlag} -eq 1 ]; then vcgencmd display_power 0 fi else #------------------------------------------------------------------------- # HDMI Status = OFF #------------------------------------------------------------------------- # - Query joystick for input # - Block script until input is received # - If device is not valid return and keep checking # - If Activity is detected # - Yes = Power on display # - No = Sleep for a second and repeat #------------------------------------------------------------------------- # Check if joystick active # 0 = Joystick input detected, user active # 1 = Joystick device not available # 124 = No input received during inputWindow inputAcive=$(dd if=${inputDevice} of=/dev/null count=${inputCount} >/dev/null 2>&1; echo $?) if [ ${inputAcive} -eq 0 ]; then vcgencmd display_power 1 else sleep 1 fi fi done;
- HDMI On
-
is there a way to make it so any controller not just a specific one work?
-
I was able to get this working without the script!
Like you mentioned, add a new line with "hdmi_blanking=1" to /boot/config.txt.
You must also add "consoleblank=600" to the existing line (not a new line!) in /boot/cmdline.txt.Reboot and your screen should turn off after 600 seconds (10 minutes) of idle time.
This goes against the recommendation in the RetroPie manual install instructions (here), though I'm not sure why they recommend using consoleblank=0 in the first place.
Hope this helps!
-
Thanks for your solution, it's doing most of the job for me, but neither of my joysticks seem to wake the device back up. A keyboard stroke does wake the device though.
They are cheapo $40 amazon joystick kits, registering as js0/js1. Pi 3b+.
I tried OP's script, but it appears to not stay off for more than a couple seconds.
Were you able to find a workaround perhaps?
Contributions to the project are always appreciated, so if you would like to support us with a donation you can do so here.
Hosting provided by Mythic-Beasts. See the Hosting Information page for more information.