Grumpy middle-aged software developer who found a home in Sofia, Bulgaria.
Tech notes, hand-drawn arts and city photos.

How to change the brightness of your monitor in Linux with a shell script / command line

What I wanted is to use Meta + sound level wheel to regulate the brightness of my monitor. It's a quicker and more convenient way than using of the monitor's controls. That's how I did it with a simple shell script.

Jump to the script to change brightness

Investigation story

ddcutil is the helper here.

ddcutil --help or man ddcutil returns a list of commands. The most interesting at the moment is probably detect. Let's try it.

$ sudo ddcutil detect
Display 1
I2C bus:  /dev/i2c-4
EDID synopsis:
Mfg id:               SAM
Model:                LC49G95T
Product code:         28754
Serial number:        H4ZT902372
Binary serial number: 1129859672 (0x43584a58)
Model year:           2245
VCP version:         2.1

Good, it can find the monitor. What can I do with the thing? Using the model name, I can question the available features.

$ sudo ddcutil capabilities -l LC49G95T
...
Feature: 10 (Brightness)
...

Sound like what I need. Let's investigate more.

$ sudo ddcutil -l LC49G95T getvcp 10
VCP code 0x10 (Brightness                    ): current value =    15, max value =   100

I can get the brightness, can I set it?

$ sudo ddcutil -l LC49G95T setvcp 10 50

Yep, the monitor is definitely much brighter now... Let's switch it back till my eyes are still OK, and write the script.

The script to change brightness

#!/usr/bin/env bash

if [ -f /tmp/.brightness_sh ]; then
	last_run=$(( $(date +%s) - $(stat -c %Y /tmp/.brightness_sh) ))
	if [[ $last_run -lt 2 ]]; then
		echo "Need time to finish the previous call"
		exit 4
	fi
fi

touch /tmp/.brightness_sh

models=(LC49G95T)
feature=10
action=$1
current_value=$(sudo ddcutil getvcp -l ${models[0]} $feature | sed -r "s/^.*current value = \s+([0-9]+).*$/\1/g")

if [[ -z $current_value ]]; then
	echo "Can't get current brightness level from ddcutil"
	rm /tmp/.brightness_sh
	exit 1
fi

echo "Current brightness is $current_value"

case $action in
	"up")
		if [[ $current_value == 100 ]]; then
			notify-send "Already max brightness level"
			rm /tmp/.brightness_sh
			exit 2
		fi
		value=$(($current_value+10))
		if [[ $value -gt 100 ]]; then value=100; fi
		;;
	"down")
		if [[ $current_value == 0 ]]; then
			notify-send "Already min brightness level"
			rm /tmp/.brightness_sh
			exit 2
		fi
		value=$(($current_value-10))
		if [[ $value -lt 0 ]]; then value=0; fi
		;;
	*)
		echo "Unknown action \"$1\", expected \"up\" or \"down\""
		rm /tmp/.brightness_sh
		exit 3
		;;
esac

notify-send "Setting brightness to $value"

for model in ${models[@]}; do
	sudo ddcutil setvcp -l $model $feature $value
done

rm /tmp/.brightness_sh

#tech #linux #shellscript #shellscripting #ddcutil #monitor #monitors