Simple desktop monitor brightness toggle for unwilling monitors

Using my desktop-computer I have the brightness of my monitor turned up full (it is a reasonably sunny room and a reasonably old monitor)
In the evening i turn the brightness down to almost minimum.

Since the values of my monitor settings are set through a menu with 'up' and 'down' entries i thought that setting it could be accomplished in a less 'labour intensive' way.

The goal is to toggle between bright and dim by clicking on an icon on the panel
and in MATE it is easy to make a launcher for a script so let's make that script.

Now the trouble is that my monitor is a bit old and the firmware is therefor either not fully compliant to the standard control protocols or the firmware is just plain buggy.

     Mfg id:               SAM - Samsung Electric Company
     Model:                SA300/SA350
     Product code:         1941  (0x0795)
     Manufacture year:     2011,  Week: 37

Anyway, I want to use ddcutil to do the switching but since my monitor not always seem to understand the commands and sometimes replies a bit confused (1 out of 3 on average) I decided to go bruteforce and keep on repeating the command until the monitor does what it is told to do.

Since it is a toggle, I have to do the same for retreiving the current value from the monitor.

Anyway, this is the script. The only thing you have to do yourself is saving it, making it executable and creating a launcher for it.

#!/bin/bash

# simple brightness toggle (bright/dim) for unwilling monitors and buggy ddcutil
# it keeps on trying until it thinks it succeeds
# no guarantee it will work for you, just try and see
#
# depends on ddcutil (sudo apt get install ddcutil)

#### PRESET VALUES, change it to your hearts desire, 0 is reserved (so don't use that)
max_value=100
min_value=10

#### INIT, comment the 'exec' command when debugging
exec &>/dev/null
declare -i old_value=0

#### GET BRIGHTNESS
while [ $old_value -eq 0 ]
do old_value="$( ddcutil getvcp '10' |tr ":," "\n\n" |grep 'current' |cut -d= -f2 )"
done

#### TOGGLE BRIGHTNESS VALUE
[ $old_value -eq $min_value ] && new_value=$max_value || new_value=$min_value

#### SET NEW BRIGHTNESS
while ! ddcutil setvcp '10' "$new_value" --sleep-multiplier 2.0 --disable-dynamic-sleep
do sleep 0.1
done

Keep in mind though that this script won't work if your monitor returns the wrong values (like off-by-one due to rounding and the like ).

5 Likes

If your monitor doesn't seem to reply properly

In this case we have to remember the brightness setting ourselves between script invocations, for instance in a file in RAM: $XDG_RUNTIME_DIR/brightness

Let's give it a try:

#!/bin/bash

# simple brightness toggle (bright/dim) for unwilling monitors and buggy ddcutil
# it keeps on trying until it thinks it succeeds
# no guarantee it will work for you, just try and see
#
# this version will skip the brightness query and remembers the setting itself
#
# depends on ddcutil (sudo apt get install ddcutil)


#### PRESET VALUES
max_value=100
min_value=10

#### INIT, comment the 'exec' command when debugging
exec &>/dev/null
declare -i old_value=50

#### GET BRIGHTNESS
read -r old_value <"$XDG_RUNTIME_DIR/brightness"

#### TOGGLE BRIGHTNESS VALUE
[ $old_value -eq $max_value ] && new_value=$min_value || new_value=$max_value

#### SAVE NEW BRIGHTNESS
echo $new_value >"$XDG_RUNTIME_DIR/brightness"

#### SET NEW BRIGHTNESS
while ! ddcutil setvcp '10' "$new_value" --sleep-multiplier 2.0 --disable-dynamic-sleep
do sleep 0.1
done
4 Likes

If you want more than just a toggle

Here we'll use a slider to set the brightness. Remember that it will apply the setting after you click OK. This because old monitors usually react pretty slow to commands.

#!/bin/bash

# Force brightness change onto an unwilling monitor

# 1) keep querying the monitor until it gives its stored value without error
# 2) use this value as initial value as for setting the actuator
# 3) while actuated value is unequal to the stored value:
# 	a) keep writing the actuated value to the monitor until it complies without error
# 	b) keep querying the monitor until it gives the written value back without error

#### comment out to debug
exec 2>/dev/null

#### kill all other still running instances of this script if there are any
kill -SIGKILL $( pgrep "${0##*/}" | grep -v "$$" )

declare -i get_value set_value

GetValueByForce()
{
	while ! ddcutil getvcp '10'
	do sleep 0.1
	done |tr ":," "\n\n" |grep 'current' |cut -d= -f2
}
NewValue()
{
	zenity --scale --value="$1" --text='Brightness' || kill -SIGTERM "$$"
}
SetValueByForce()
{
	while ! ddcutil setvcp '10' "$1" --sleep-multiplier 2.0 --disable-dynamic-sleep
	do sleep 0.1
	done
}
get_value=$( GetValueByForce )
set_value=$( NewValue "$get_value" )
while [ "$get_value" -ne "$set_value" ]
do
	SetValueByForce "$set_value" >/dev/null
	get_value=$( GetValueByForce )
done

Keep in mind that adjusting the brightness with any of these scripts could potentially take up to several seconds due to buggy monitor firmware

EDIT: improved code.

4 Likes