The new way to turn your connected HDMI monitor on and off on a Raspberry Pi

I recently received an email from a reader telling me that there was a problem.

The long-serving command vcgencmd display_power 1/0 wouldn’t work with the latest Raspberry Pi operating system update.

I have written a post here to explain several ways to automatically turn your Raspberry Pi digital picture frame on and off at fixed times or simply with a Terminal command.

Tested with Raspberry Pi OS Buster and Bookworm on a Raspberry Pi 4 (Oct 2023).

Death by consensus

It turns out that the vcgencmd command had been retired and moved to the graveyard of commands that we used a lot but, for some inexplicable reason, had to die a cruel death because some code maintainers decided it was time.

Even ChatGPT was still suggesting the vcgencmd command. But no more. The otherwise suggested xset dpms force off didn’t work either with my graphic settings.

I found a solution using xrandr which is a bit more complicated than vcgencmd, but it works. With one shortcoming, but more on that later.

A new hope

The xrandr command is a utility in the Raspberry Pi OS that configures and manages display settings, including screen resolution, refresh rate, rotation, and multiple monitor setups. xrandr stands for X Resize, Rotate, and Reflect Extension.

Provided you are running a Raspberry Pi 4 with the OS bullseye or even the very recent bookworm, you can use the following Terminal command to turn your connected HDMI monitor (the left output of the two) off:

DISPLAY=:0.0 xrandr --output HDMI-1 --off

To turn it on, you have to specify the monitor setting like the resolution and the frame rate, something that wasn’t necessary with the old vcgencmd command.

So in the case of an HD display, you would write:

DISPLAY=:0.0 xrandr --output HDMI-1 --mode 1920x1080 --rate 60

If you have a 4K monitor connected, the command would be:

DISPLAY=:0.0 xrandr --output HDMI-1 --mode 3840x2160 --rate 30

Here is what the Python script for turning the monitor off would look like:

#!/usr/bin/python3
# coding: utf8 #

import subprocess  # for command execution

def turn_off_monitor(display=":0.0", output="HDMI-1"):
    try:
        command = f"DISPLAY={display} xrandr --output {output} --off"
        subprocess.call(command, shell=True)
        print(f"Monitor {output} turned off successfully on display {display}.")
    except Exception as e:
        print(f"An error occurred: {e}")

turn_off_monitor()

And for turning it on:

#!/usr/bin/python3
# coding: utf8 #

import subprocess  # for command execution

def turn_on_monitor(display=":0.0", output="HDMI-1", mode="3840x2160 --rate 30"):
    try:
        command = f"DISPLAY={display} xrandr --output {output} --mode {mode}"
        subprocess.call(command, shell=True)
        print(f"Monitor {output} turned on successfully on display {display}.")
    except Exception as e:
        print(f"An error occurred: {e}")

turn_on_monitor()

Adjust the resolution to your specific monitor. In the code example above, a 4k monitor is being used.

Unfortunately, xrandr doesn’t retain the settings of your monitor when turning it off. This is why you must specify the resolution and frame rate every time you turn it on.

If you are unsure what the resolution or frame rate of your connected monitor is, type

DISPLAY=:0.0 xrandr

and you will get an output that should look like this:

Screen 0: minimum 320 x 200, current 1920 x 1080, maximum 7680 x 7680
HDMI-1 connected primary 1920x1080+0+0 (normal left inverted right x axis y axis) 708mm x 398mm
   1920x1080     60.00*+  50.00    59.94    30.00    25.00    24.00    29.97    23.98  
   4096x2160     30.00    29.97  
   3840x2160     30.00    29.97  
   1600x1200     60.00  
   1680x1050     59.95    59.88  
   1400x1050     59.98    59.95  
   1600x900      60.00  
   1280x1024     60.02  
   1440x900      59.89    59.90  
   1280x960      60.00  
   1360x768      60.02  
   1280x800      59.81  
   1280x768      60.35    59.87  
   1280x720      60.00    50.00    30.00    25.00    59.94    29.97    24.00    23.98  
   1024x768      60.00  
   800x600       60.32  
   720x576       50.00  
   720x480       60.00    59.94  
   640x480       60.00    59.94  
HDMI-2 disconnected (normal left inverted right x axis y axis)

The missing display status

The vcgencmd returned a “0” or “1” depending on the monitor being off or on. xrandr does not have a similar option, but there is a workaround which I describe here.

Was this article helpful?


Thank you for your support and motivation.


Scroll to Top