229 lines
5.9 KiB
Bash
Executable File
229 lines
5.9 KiB
Bash
Executable File
#!/bin/sh
|
|
#
|
|
# * Battery Watchdog (see help text below).
|
|
#
|
|
# This is free and unencumbered software released into the public domain.
|
|
#
|
|
# Anyone is free to copy, modify, publish, use, compile, sell, or
|
|
# distribute this software, either in source code form or as a compiled
|
|
# binary, for any purpose, commercial or non-commercial, and by any
|
|
# means.
|
|
#
|
|
# In jurisdictions that recognize copyright laws, the author or authors
|
|
# of this software dedicate any and all copyright interest in the
|
|
# software to the public domain. We make this dedication for the benefit
|
|
# of the public at large and to the detriment of our heirs and
|
|
# successors. We intend this dedication to be an overt act of
|
|
# relinquishment in perpetuity of all present and future rights to this
|
|
# software under copyright law.
|
|
#
|
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
|
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
|
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
# OTHER DEALINGS IN THE SOFTWARE.
|
|
#
|
|
# For more information, please refer to <http://unlicense.org/>
|
|
# ---
|
|
# Dependencies:
|
|
# acpi <https://sourceforge.net/projects/acpiclient/>
|
|
# libnotify <https://salsa.debian.org/gnome-team/libnotify>
|
|
#
|
|
# Installation:
|
|
# # on Arch Linux:
|
|
# pacman -S acpi # (commynity repo)
|
|
# pacman -S libnotyfy # (extra repo)
|
|
# # on Debian/Ubuntu:
|
|
# apt-get install acpi
|
|
# apt-get install libnotify
|
|
|
|
print_help() {
|
|
printf \
|
|
"btw - battery watchdog. Send notification when critical battery level reached.
|
|
|
|
Usage:
|
|
btw [-c|--crit \033[4mvalue\033[0m] [-p|--preriod \033[4mseconds\033[0m] \
|
|
[-l|--log \033[4mfile\033[0m]
|
|
[-j|--syslog] [-s|--summary t\033[4mext\033[0m] \
|
|
[-b|--body t\033[4mext\033[0m] [-w|--watch]
|
|
btw --help
|
|
btw --version
|
|
|
|
Options:
|
|
-v, --version
|
|
Print version and exit.
|
|
|
|
-h, --help
|
|
Print this help message and exit.
|
|
|
|
-c, --crit \033[4mvalue\033[0m
|
|
Battery critical value in percents [default: 10]
|
|
|
|
-p, --preriod \033[4mseconds\033[0m
|
|
Battery check out period in seconds [default: 30]
|
|
|
|
-l, --log \033[4mfile\033[0m
|
|
Log file [default: ~/.cache/btw.log]
|
|
|
|
-j, --syslog
|
|
Use logger instead of log file.
|
|
|
|
-s, --summary \033[4mtext\033[0m
|
|
Custom notification title text.
|
|
|
|
-b, --body \033[4mtext\033[0m
|
|
Custom notification body text.
|
|
|
|
-w, --watch
|
|
Follow to the log file (tail -f).
|
|
|
|
See \033[1mbtw\033[0m(1) for full help.
|
|
"
|
|
}
|
|
|
|
send_notify() {
|
|
notify-send --urgency=critical --icon=battery-empty --category=System \
|
|
"$(eval echo "$1")" "$(eval echo "$2")"
|
|
}
|
|
|
|
is_int() {
|
|
if [ -n "$1" ] && [ "$1" -eq "$1" ] 2>/dev/null; then
|
|
return 0
|
|
else
|
|
echo 'Value is not integer' >&2; exit 1
|
|
fi
|
|
}
|
|
|
|
# Transform long options to short ones
|
|
for ARG in "$@"; do
|
|
shift
|
|
case "$ARG" in
|
|
--crit)
|
|
set -- "$@" "-c"
|
|
;;
|
|
--period)
|
|
set -- "$@" "-p"
|
|
;;
|
|
--log)
|
|
set -- "$@" "-l"
|
|
;;
|
|
--syslog)
|
|
set -- "$@" "-j"
|
|
;;
|
|
--summary)
|
|
set -- "$@" "-s"
|
|
;;
|
|
--body)
|
|
set -- "$@" "-b"
|
|
;;
|
|
--watch)
|
|
set -- "$@" "-w"
|
|
;;
|
|
--help)
|
|
set -- "$@" "-h"
|
|
;;
|
|
--version)
|
|
set -- "$@" "-v"
|
|
;;
|
|
*)
|
|
set -- "$@" "$ARG"
|
|
esac
|
|
done
|
|
|
|
# Parse short opts
|
|
while getopts c:p:l:js:b:whv OPT; do
|
|
case "$OPT" in
|
|
c)
|
|
is_int "$OPTARG"
|
|
critical="$OPTARG"
|
|
;;
|
|
p)
|
|
is_int "$OPTARG"
|
|
period="$OPTARG"
|
|
;;
|
|
l)
|
|
log="$OPTARG"
|
|
;;
|
|
j)
|
|
syslog=1
|
|
;;
|
|
s)
|
|
summary="$OPTARG"
|
|
;;
|
|
b)
|
|
body="$OPTARG"
|
|
;;
|
|
w)
|
|
watch=1
|
|
;;
|
|
h)
|
|
print_help
|
|
exit 0
|
|
;;
|
|
v)
|
|
echo 1.0
|
|
exit 0
|
|
;;
|
|
*)
|
|
echo Unknown option: "$OPT" >&2
|
|
exit 1
|
|
esac
|
|
done
|
|
|
|
# Default values
|
|
period="${period:-30}" # check battery every `period` seconds
|
|
critical="${critical:-10}" # battery limit (in %)
|
|
clevel="${clevel:-100}" # current battery value (in %, temporary variable)
|
|
summary="${summary:-Extremely low battery: \$level%}"
|
|
body="${body:-Check the charger, battery currently is \$state}"
|
|
lock=/tmp/btw.lock # lock file
|
|
log="${log:-"$HOME"/.cache/btw.log}"
|
|
|
|
mkdir -p "$HOME"/.cache
|
|
|
|
if [ -n "$watch" ]; then
|
|
if [ -n "$syslog" ]; then
|
|
journalctl -t btw -f
|
|
else
|
|
tail -f "$log"
|
|
fi
|
|
exit "$?"
|
|
fi
|
|
|
|
printf 'crit: %s%%; period: %ss; log: %s\n' "$critical" "$period" "$log" >&2
|
|
|
|
while true; do
|
|
battery="$(acpi -b | awk '{print $3 " " $4}' |
|
|
sed -E 's/,|%//g;' | tr '[:upper:]' '[:lower:]')"
|
|
level="${battery##* }" # e.g. "49" (in percents)
|
|
state="${battery%% *}" # e.g. "charging"
|
|
|
|
if [ "$level" -le "$critical" ]; then
|
|
if [ ! -f "$lock" ]; then
|
|
send_notify "$summary" "$body"
|
|
touch "$lock"
|
|
fi
|
|
# Warn in every percent less
|
|
if [ "$level" -le "$clevel" ]; then
|
|
send_notify "$summary" "$body"
|
|
touch "$lock"
|
|
clevel="$level"
|
|
fi
|
|
else
|
|
[ -f "$lock" ] && rm "$lock"
|
|
fi
|
|
|
|
log_message="$(printf '%s %s %s%%' \
|
|
"$(date +'%Y-%m-%d %H:%M:%S')" "$state" "$level")"
|
|
if [ -n "$syslog" ]; then
|
|
echo "$log_message"
|
|
logger -i "$$" -t btw -- "$log_message"
|
|
else
|
|
echo "$log_message" | tee -a "$log"
|
|
fi
|
|
|
|
sleep "$period"
|
|
done
|