Please do not post a support request without first reading and following the advice in https://retropie.org.uk/forum/topic/3/read-this-first

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 the hdmi_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 using tvservice instead vcgencmd to control the display as there's some reports of vcgencmd 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
    • 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

    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 the exit 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;
    


  • 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!



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.