nix-files/hosts/common/programs/conky/battery_estimate

185 lines
4.9 KiB
Bash
Executable File
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/sh
#!/usr/bin/env nix-shell
#!nix-shell -i bash
usage() {
echo "usage: battery_estimate [options...]"
echo
echo "pretty-prints a battery estimate (icon to indicate state, and a duration estimate)"
echo
echo "options:"
echo " --debug: output additional information, to stderr"
echo " --minute-suffix <string>: use the provided string as a minutes suffix"
echo " --hour-suffix <string>: use the provided string as an hours suffix"
echo " --icon-suffix <string>: use the provided string as an icon suffix"
echo " --percent-suffix <string>: use the provided string when displaying percents"
}
# these icons come from sxmo; they only render in nerdfonts
icon_bat_chg=("󰢟" "󱊤" "󱊥" "󰂅")
icon_bat_dis=("󰂎" "󱊡" "󱊢" "󱊣")
suffix_icon="" # thin space
suffix_percent="%"
# suffix_icon=" "
# render time like: 2ʰ08ᵐ
# unicode sub/super-scripts: <https://en.wikipedia.org/wiki/Unicode_subscripts_and_superscripts>
# symbol_hr="ʰ"
# symbol_min="ᵐ"
# render time like: 2ₕ08ₘ
# symbol_hr="ₕ"
# symbol_min="ₘ"
# render time like: 2h08m
# symbol_hr="h"
# symbol_min="m"
# render time like: 2:08
# symbol_hr=":"
# symbol_min=
# render time like: 208⧗
symbol_hr=""
symbol_min="⧗"
# variants:
# symbol_hr=":"
# symbol_min="⧖"
# symbol_min="⌛"
# render time like: 2'08"
# symbol_hr="'"
# symbol_min='"'
log() {
if [ "$BATTERY_ESTIMATE_DEBUG" = "1" ]; then
printf "$@" >&2
echo >&2
fi
}
render_icon() {
# args:
# 1: "chg" or "dis"
# 2: current battery percentage
level=$(($2 / 25))
level=$(($level > 3 ? 3 : $level))
level=$(($level < 0 ? 0 : $level))
log "icon: %s %d" "$1" "$level"
if [ "$1" = "dis" ]; then
printf "%s" "${icon_bat_dis[$level]}"
elif [ "$1" = "chg" ]; then
printf "%s" "${icon_bat_chg[$level]}"
fi
}
try_path() {
# assigns output variables:
# - perc, perc_from_full (0-100)
# - full, rate (pos means charging)
if [ -f "$1/capacity" ]; then
log "perc, perc_from_full from %s" "$1/capacity"
perc=$(cat "$1/capacity")
perc_from_full=$((100 - $perc))
fi
if [ -f "$1/charge_full_design" ] && [ -f "$1/current_now" ]; then
log "full, rate from %s and %s" "$1/charge_full_design" "$1/current_now"
# current is positive when charging
full=$(cat "$1/charge_full_design")
rate=$(cat "$1/current_now")
elif [ -f "$1/energy_full" ] && [ -f "$1/power_now" ]; then
log "full, rate from %s and %s" "$1/energy_full" "$1/power_now"
# power_now is positive when discharging
full=$(cat "$1/energy_full")
rate=-$(cat "$1/power_now")
elif [ -f "$1/energy_full" ] && [ -f "$1/energy_now" ]; then
log "full, rate from %s and %s" "$1/energy_full" "$1/energy_now"
log " this is a compatibility path for legacy Thinkpad batteries which do not populate the 'power_now' field, and incorrectly populate 'energy_now' with power info"
# energy_now is positive when discharging
full=$(cat "$1/energy_full")
rate=-$(cat "$1/energy_now")
fi
}
try_all_paths() {
try_path "/sys/class/power_supply/axp20x-battery" # Pinephone
try_path "/sys/class/power_supply/BAT0" # Thinkpad
log "perc: %d, perc_from_full: %d" "$perc" "$perc_from_full"
log "full: %f, rate: %f" "$full" "$rate"
log " rate > 0 means charging, else discharging"
}
fmt_minutes() {
# args:
# 1: icon to render
# 2: string to show if charge/discharge time is indefinite
# 3: minutes to stable state (i.e. to full charge or full discharge)
# - we work in minutes instead of hours for precision: bash math is integer-only
log "charge/discharge time: %f min" "$3"
# args: <battery symbol> <text if ludicrous estimate> <estimated minutes to full/empty>
if [ -n "$3" ] && [ "$3" -lt 1440 ]; then
hr=$(($3 / 60))
hr_in_min=$(($hr * 60))
min=$(($3 - $hr_in_min))
printf "%s%s%d%s%02d%s" "$1" "$suffix_icon" "$hr" "$symbol_hr" "$min" "$symbol_min"
else
log "charge/discharge duration > 1d"
printf "%s%s%s" "$1" "$suffix_icon" "$2" # more than 1d
fi
}
pretty_output() {
if [ -n "$perc" ]; then
duration=""
if [ "$rate" -gt 0 ]; then
log "charging"
icon="$(render_icon chg $perc)"
duration="$(($full * 60 * $perc_from_full / (100 * $rate)))"
else
log "discharging"
icon="$(render_icon dis $perc)"
if [ "$rate" -lt 0 ]; then
duration="$(($full * 60 * $perc / (-100 * $rate)))"
fi
fi
fmt_minutes "$icon" "$perc$suffix_percent" "$duration"
fi
}
while [ "$#" -gt 0 ]; do
case "$1" in
"--debug")
shift
BATTERY_ESTIMATE_DEBUG=1
;;
"--icon-suffix")
shift
suffix_icon="$1"
shift
;;
"--hour-suffix")
shift
symbol_hr="$1"
shift
;;
"--minute-suffix")
shift
symbol_min="$1"
shift
;;
"--percent-suffix")
shift
suffix_percent="$1"
shift
;;
*)
usage
exit 1
;;
esac
done
try_all_paths
pretty_output