Skip to content

Instantly share code, notes, and snippets.

@cgomesu
Created December 14, 2022 15:56
Show Gist options
  • Save cgomesu/cc310b74fdf89d0602c02fe3cd6510f9 to your computer and use it in GitHub Desktop.
Save cgomesu/cc310b74fdf89d0602c02fe3cd6510f9 to your computer and use it in GitHub Desktop.
Bash script that checks a laptop battery status via sysfs and performs automatic shutdown if capacity is below a user-specified threshold (30% by default)
#!/usr/bin/env bash
##################
# Battery watchdog
##################
DEFAULT_BAT="BAT0"
DEFAULT_CAPACITY_LOW='30'
capacity_now () {
if [[ $(cat "/sys/class/power_supply/${BAT:-$DEFAULT_BAT}/uevent") =~ POWER_SUPPLY_CAPACITY=([0-9]*) ]]; then
echo "${BASH_REMATCH[1]}"; return 0
else
echo "NA"; return 1
fi
}
check_bat () {
if cat "/sys/class/power_supply/$1/uevent" > /dev/null 2>&1; then return 0; else return 1; fi
}
msg () {
echo "[Battery Watchdog] [$(date +%T)] [$1]: $2"
}
# main logic
if [[ "$(id -u)" -ne 0 ]]; then
msg 'ERROR' 'User is not root. This script needs root permission.'; exit 1
fi
trap "msg 'INFO' 'Received a signal to stop. Bye!'; exit 0" INT HUP TERM
while getopts 'b:c:' OPT; do
case $OPT in
b) BAT="$OPTARG";;
c) CAPACITY_LOW="$OPTARG";;
\?) msg 'ERROR' 'Invalid option. Use -b for BAT dir name and -c lowest capacity before shutting down.'; exit 1;;
esac
done
if ! check_bat "${BAT:-$DEFAULT_BAT}"; then
msg 'ERROR' "The battery ${BAT:-$DEFAULT_BAT} does not exist at '/sys/class/power_supply/'"; exit 1
fi
msg 'INFO' 'Checking battery status...'
if [[ $(cat "/sys/class/power_supply/${BAT:-$DEFAULT_BAT}/uevent" 2> /dev/null) =~ "POWER_SUPPLY_STATUS=Discharging" ]]; then
msg 'INFO' 'Battery is discharging. Checking level...'
if capacity_now > /dev/null 2>&1; then
if [[ $(capacity_now) -lt "${CAPACITY_LOW:-$DEFAULT_CAPACITY_LOW}" ]]; then
msg 'WARNING' "Battery level is below threshold (${CAPACITY_LOW:-$DEFAULT_CAPACITY_LOW}): $(capacity_now)"
msg 'INFO' 'Starting shutdown procedure in 5 minutes. Bye!'; sleep 300
shutdown now
else
msg 'INFO' "Battery level is above threshold (${CAPACITY_LOW:-$DEFAULT_CAPACITY_LOW}): $(capacity_now)."
msg 'INFO' 'Nothing to be done. Bye!'; exit 1
fi
else
msg 'ERROR' 'Unable to retrieve the capacity level.'; exit 1
fi
else
msg 'INFO' 'Battery is not discharging. Bye!'; exit 0
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment