In order to prevent my laptop to die abruptly when battery is critically low and corrupting my main filesystem, I put up a tiny little simple solution: a script, run by cron, that checks if battery is low and cleanly shutdown the system when it is critically low.
So, first, the script, largely inspired by this answer.
#!/bin/sh
# touch $HOME/.dbus/Xdbus
# chmod 600 $HOME/.dbus/Xdbus
# env | grep DBUS_SESSION_BUS_ADDRESS > $HOME/.dbus/Xdbus
# echo 'export DBUS_SESSION_BUS_ADDRESS' >> $HOME/.dbus/Xdbus
# exit 0
#
if [ -r ~/.dbus/Xdbus ]; then
. ~/.dbus/Xdbus
fi
low_threshold=6
critical_threshold=4
timeout=50
shutdown_cmd='sudo /sbin/shutdown -h now'
level=$(cat /sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:08/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/capacity)
state=$(cat /sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:08/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/status)
if [ x"$state" != x'Discharging' ]; then
exit 0
fi
do_shutdown() {
sleep $timeout && kill $zenity_pid 2>/dev/null
if [ x"$state" != x'Discharging' ]; then
exit 0
else
$shutdown_cmd
fi
}
if [ "$level" -gt $critical_threshold ] && [ "$level" -lt $low_threshold ]; then
notify-send -u critical -t 6000 "Battery level is low: $level%"
fi
if [ "$level" -lt $critical_threshold ]; then
notify-send -u critical -t 20000 "Battery level is low: $level%" \
"The system is going to shut down in $timeout seconds."
DISPLAY=:0 zenity --question --ok-label 'OK' --cancel-label 'Cancel' \
--text "Battery level is low: $level%.\n\n The system is going to shut down in $timeout seconds." &
zenity_pid=$!
do_shutdown &
shutdown_pid=$!
trap 'kill $shutdown_pid' 1
if ! wait $zenity_pid; then
kill $shutdown_pid 2>/dev/null
fi
fi
You have to adapt to the place where the battery state is on your system.
You may have to check that the battery state is really "Discharging".
You also have to add a cron job to run this script on a sufficiently regular basis. To do so :
$ crontab -e
and add this line :
*/1 * * * * /home/me/usr/bin/auto-shutdown
This will cause the script to be run every second.
For the script to work, you'll need:
- To be able to shutdown your system from the command line using sudo.
- Have zenity and notify-send installed.
username ALL=(ALL) NOPASSWD: /sbin/shutdown
In debian, notify-send is in the libnotify-bin package.
Hope it helps.