Skip to content

Instantly share code, notes, and snippets.

@brycepg
Last active May 15, 2023 19:07
Show Gist options
  • Save brycepg/fbfce92a57de9674f9f67f20eb148219 to your computer and use it in GitHub Desktop.
Save brycepg/fbfce92a57de9674f9f67f20eb148219 to your computer and use it in GitHub Desktop.
#!/bin/bash
# file: /usr/local/share/batt.sh
# Checks to see if the battery is below
# the low battery threshold,
# if so, then put the computer to sleep
SECONDS_BETWEEN_CHECK=60
LOW_BATTERY_THRESHOLD=6
WARNING_THRESHOLD=10
HYSTERESIS_BETWEEN_SLEEP=$(($SECONDS_BETWEEN_CHECK*5))
UPOWER_BATTRY_FILEPATH="/org/freedesktop/UPower/devices/battery_BAT0"
battery_percentage_as_digits() {
# Get the battery percentage as a whole number from 0-100
upower_text="$1"
echo "$upower_text" | grep -oe 'percentage: *[0-9]\+' | awk '{ print $2}'
}
get_upower_text() {
# Long text, use quotes to preserve newlines for grep
upower -i $UPOWER_BATTRY_FILEPATH
}
get_battery_state() {
# Battery state in human readable format
# charging, pending-charge, fully-charged, discharging
upower_text="$1"
echo "$upower_text" | grep state | awk '{print $2}'
}
check_if_discharging() {
# echo 1 if discharging
# echo 0 is charged or indeterminate state
upower_text="$1"
battery_state=$(get_battery_state "$upower_text")
if [[ "$battery_state" == @(charging|pending-charge|fully-charged) ]];
then
echo 0
else
echo 1
fi
}
check_if_needs_to_suspend() {
battery_level="$1"
is_discharging="$2"
is_below_threshold=$(( $battery_level < $LOW_BATTERY_THRESHOLD ))
echo $(( $is_below_threshold && $is_discharging ))
}
main() {
while true; do
upower_text=$(get_upower_text)
battery_level=$(battery_percentage_as_digits "$upower_text")
is_discharging=$(check_if_discharging "$upower_text")
needs_to_suspend=$(check_if_needs_to_suspend $battery_level $is_discharging)
if (( $needs_to_suspend )); then
echo needs to suspend at $(date)
systemctl suspend
sleep $HYSTERESIS_BETWEEN_SLEEP
elif (( $battery_level < $WARNING_THRESHOLD && $is_discharging )); then
echo warning at $(date)
notify-send -u critical "Battery is at ${battery_level}%; Will suspend soon if not put on charge"
fi
sleep $SECONDS_BETWEEN_CHECK
done
}
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
trap "notify-send 'Low battery Script Failure'; sleep 1; exit" SIGINT SIGHUP SIGKILL
echo Starting
main
fi
Place files at corresponding locations (or copy by hand)
Make batt.sh executable:
chmod +x /usr/local/share/batt.sh
Allow service to be discoverable:
systemctl --user daemon-reload
start with:
systemctl --user start lowsleep.service
status with:
systemctl --user status lowsleep.service
test by running direclty with bash
[Unit]
Description=Sleep on low battery
After=display-manager.service
# filename: /etc/xdg/systemd/user/lowsleep.service
[Service]
ExecStart=/usr/local/share/batt.sh
Restart=always
[Install]
WantedBy=default.target
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment