Reputation: 287
I'd like to automate keyboard backlight on my Thinkpad X1, like I was used in my old XPS13. At any key press the backlight should switch on, and after a certain idle time (here 30 s) backlight should switch off.
I've written this basic bash script, which works fine although it polls every second through xprintidle
, and it may drain some battery:
#!/bin/bash
function switch {
echo $1 > /sys/devices/platform/thinkpad_acpi/leds/tpacpi\:\:kbd_backlight/brightness
}
while (true); do
sleep 1
last=`xprintidle`
status=`cat /sys/devices/platform/thinkpad_acpi/leds/tpacpi\:\:kbd_backlight/brightness`
[ $last -lt 20000 -a $status -lt 2 ] && switch 2 && continue
[ $last -ge 20000 -a $status -eq 2 ] && switch 1 && continue
[ $last -ge 30000 -a $status -ge 1 ] && switch 0 && continue
done
I was wondering if some non-polling way could be done, such as through systemd or dbus.
Upvotes: 1
Views: 1378
Reputation: 389
xprintidle
is not an option when using Wayland
, here is an other solution:
sudo apt install swayidle
Create the script /usr/local/bin/keyboard_backlit_timeout
and make sure it is executable
#!/bin/bash
# sudo apt install swayidle
idle_after=10 # in seconds
low_state=0
high_state=1
export WAYLAND_DISPLAY="wayland-0"
export XDG_RUNTIME_DIR="/run/user/1001"
swayidle \
timeout $idle_after "echo $low_state | tee /sys/class/leds/asus::kbd_backlight/brightness" \
resume "echo $high_state | tee /sys/class/leds/asus::kbd_backlight/brightness"
Create a systemd
service that will auto restart until a display is available:
echo "[Unit]
Description=Keyboard backlight auto on/off
[Service]
Restart=on-failure
RestartSec=5s
ExecStart=/usr/local/bin/keyboard_backlit_timeout
[Install]
WantedBy=multi-user.target" | sudo tee /etc/systemd/system/keyboard_backlit_timeout.service
Enable, start and check status of the service:
sudo systemctl enable keyboard_backlit_timeout.service
sudo systemctl start keyboard_backlit_timeout.service
sudo systemctl status keyboard_backlit_timeout.service
This script does not remember the "current" keyboard lit value so the keyboard lit can't be turned off unless you stop the service. Improvements are welcome in the comments!
Upvotes: 0
Reputation: 287
I have managed to optimize the script so that it polls much less often when the light in on. I have also included dbus way to detect status and switch backlight. In order to use qdbus the script must be run as user, and thus writing permission for /sys/devices/../kbd_backlight/brightness
is required.
#!/bin/bash
idletime=30000 # in milliseconds
prepath=/sys/class/leds/tpacpi\:\:kbd_backlight
sudo chmod a+w $prepath/brightness
function switch {
echo $1 > $prepath/brightness
# ALTERNATIVE WITH QDBUS: WORKS BUT SHOWS NOISY OVERLAY ICON
#qdbus local.org_kde_powerdevil /org/kde/Solid/PowerManagement/Actions/KeyboardBrightnessControl setKeyboardBrightness $1
}
while (true); do
# BOTH THE FOLLOWING WORK FINE, BUT THE SECOND DONT WORK AS ROOT
#last=`xprintidle`
last=`qdbus org.kde.screensaver /ScreenSaver GetSessionIdleTime`
# BOTH THE FOLLOWING WORK FINE, BUT THE SECOND DONT WORK AS ROOT
status=`< $prepath/brightness`
#status=`qdbus org.kde.Solid.PowerManagement /org/kde/Solid/PowerManagement/Actions/KeyboardBrightnessControl keyboardBrightness`
val=`< $prepath/brightness_hw_changed`
[ $last -lt $idletime -a $status -lt $val ] && switch $val && sleep ${idletime}e-3 && continue #SWITCH ON
[ $last -ge $idletime -a $status -ge $val ] && switch 0 #SWITCH OFF
sleep 1
done
edit: now the script keeps trace to the brightness chosen by the user with fn key
Upvotes: 1