Table of Contents

Lenovo thinkpad W530 custom brightness

Running Linux on my W530 is awesome, but some issues exists. For example I can’t figure out how to change the display brightness hardware-wise. While it’s okay that the display brightness is stuck at 100%, sometimes it becomes a bit annoying so I decided to make my own implementation using xrandr No, this soution is not the best but does the job decent enough for me to continue using it.

Using Python I’ve created a script that watches /sys/class/backlight/acpi_video0/actual_brightness so I can use the brightness adjustment keys on my keyboard (FN+F8 & FN+F9). This Python script is executed when I, the user, logs in using a systemd service.

Source

~/Documents/python/display_brightness/main.py

Place this Python script in a logical place that is not prune for user error (eg. deletion).

#!/usr/bin/python3

import os
import time

sys_brightness_min = 0
sys_brightness_max = 15
actual_brightness_min = 0.1
actual_brightness_max = 1

last_actual_brightness = -1

def main():
    global last_actual_brightness

    while True:
        sys_brightness = 15
        with open("/sys/class/backlight/acpi_video0/actual_brightness", "r") as file:
            sys_brightness = int(file.read())

        actual_brightness = _map(sys_brightness, sys_brightness_min, sys_brightness_max, actual_brightness_min, actual_brightness_max)

        if actual_brightness is not last_actual_brightness:
            last_actual_brightness = actual_brightness
            os.system("xrandr -display :1 --output LVDS-0 --brightness " + str(actual_brightness))

        time.sleep(.25)

def _map(x, in_min, in_max, out_min, out_max):
    return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min

def follow(thefile):
    thefile.seek(0, 2)
    while True:
        line = thefile.readline()
        if not line:
            time.sleep(0.1)
            continue
        yield line

if __name__ == "__main__":
    main()

/etc/systemd/system/brightness.service

The ExecStart requires to be modified with the actual location of the Python script.

[Unit]
# After=network.service
Description=Display Brightness

[Service]
Type=simple
WorkingDirectory=/home/[USER]
ExecStart=/home/[USER]/Documents/python/display_brightness/main.py
User=[USER]

[Install]
WantedBy=multi-user.target

And finally make it all effective

# systemctl daemon-reload
# systemctl enable brightness.service
# systemctl start brightness.service

End notes

While far from ideal because this is just artificially chaning the brightness using software, it works and it becomes easier on the eyes later in the night (which was the main purpose for me).

It is important to note that my solution is not a general solution for all laptops and should not be used when hardware brightness control works, but it works for me for my ThinkPad W530.

And the nice thing is that it remembers the brightness since it reads from the hardware event, when restarting the previous brightness is automatically applied after logging in.