battery-monitor.sh 2.86 KB
Newer Older
1 2 3 4 5
#!/bin/sh

# This script monitors the battery. It shows warnings and adjust power-saving
# parameters when the battery becomes low, and suspend/hibernate the computer
# when the battery becomes critically low.
6 7 8 9
#
# Note: This script is compatible with TLP (Linux Advanced Power Management) and
# complements it, since TLP does not affect screen brightness, nor suspending.
#     https://linrunner.de/en/tlp/docs/tlp-faq.html#conflict
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26

# Battery thresholds, in percents.
THRESHOLD_LOW=20
THRESHOLD_VERY_LOW=10
THRESHOLD_CRITICAL=3

# Brightness at various stages of depletion, in percents.
BRIGHTNESS_NORMAL=20    # unused
BRIGHTNESS_SAVING=0.02

# Frequency at which to check the status of the battery.
FREQUENCY=30s

# This script depends on the program “acpi”.
command -V acpi >/dev/null || return 1

# How to ring the bell.
27 28
# FIXME: This does not work (probably because not outputing to a terminal).
#   Use paplay and some sounds from /usr/share/sounds/ instead.
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
bell() {
  duration="$1"
  # Save the bell settings.
  settings=( $(xset -q | grep bell | grep -o '[0-9]*') )
  # Set up the bell.
  xset b 100 800 "$duration"
  # Ring the bell.
  echo -ne '\a'
  # Restore the bell settings.
  xset b "${settings[@]}"
}

state=3
normal_brightness="$BRIGHTNESS_NORMAL"

while true ; do

  sleep "$FREQUENCY"

  output=( $(acpi) )
  status="${output[2]%,}"
50 51
  percentage="${output[3]%,}"
  percentage="${percentage%\%}"
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69

  # Battery becomes charging, or charged enough.
  if [ "$state" -lt 3 -a \( "$status" != 'Discharging' -o "$percentage" -gt "$THRESHOLD_LOW" \) ] ; then
    state=3
    xbacklight -set "$normal_brightness"

  # Battery becomes low.
  elif [ "$state" -gt 2 -a "$status" = 'Discharging' -a "$percentage" -le "$THRESHOLD_LOW" ] ; then
    state=2
    bell 100
    notify-send -u critical -i battery-good-symbolic \
      "Batterie à $percentage %" 'Je suis fatigué…'
    normal_brightness="$(xbacklight)"
    xbacklight -set "$BRIGHTNESS_SAVING"

  # Battery becomes very low.
  elif [ "$state" -gt 1 -a "$status" = 'Discharging' -a "$percentage" -le "$THRESHOLD_VERY_LOW" ] ; then
    state=1
70
    bell 250
71 72 73 74 75 76 77 78 79
    # Note: notify-send is buggy, it picks the incorrect icon “battery-low”
    # from /usr/share/notify-osd/icons/ instead of “battery-low-symbolic”
    # from /usr/share/icons/.
    notify-send -u critical -i battery-low-symbolic \
      "Batterie à $percentage %" 'Mes paupières sont si lourdes…'

  # Battery becomes critically low.
  elif [ "$state" -gt 0 -a "$status" = 'Discharging' -a "$percentage" -le "$THRESHOLD_CRITICAL" ] ; then
    state=0
80
    bell 500
81 82 83 84 85 86 87 88 89 90
    notify-send -u critical -i battery-caution-symbolic \
      "Batterie à $percentage %" 'Je vais dormir.'
    logger 'Battery critically low, going to sleep'
    # FIXME: Set up the computer so that hibernation works.
    # FIXME: Make sure this bypasses all existing inhibiters.
    systemctl suspend

  fi

done