Skip to content

Instantly share code, notes, and snippets.

@BlackthornYugen
Created December 15, 2023 17:18
Show Gist options
  • Save BlackthornYugen/c1684f6f68dd0ae96a99d72ecf662af6 to your computer and use it in GitHub Desktop.
Save BlackthornYugen/c1684f6f68dd0ae96a99d72ecf662af6 to your computer and use it in GitHub Desktop.
Run caffeinate when battery is above a given value, preventing MacOS from sleeping.
#!/bin/bash
# Default values
verbose=0
min_battery=20
log() {
if [[ "$verbose" -gt 0 ]]; then
echo "$@"
fi
}
# Function to display the battery bar with ANSI colors
display_battery_bar() {
local current_percentage bar_length time_progress
current_percentage="$(grep -Eo "\d+%" <<< "$1" | cut -d% -f1)"
bar_length=20
time_progress=-1
if grep ' charging' <<< "$1" > /dev/null ; then
time_progress=$((SECONDS % bar_length))
elif grep ' discharging' <<< "$1" > /dev/null ; then
time_progress=$((bar_length - SECONDS % bar_length - 1))
fi
# Determine the length of each color section
local red_length=$((bar_length / 3))
local yellow_length=$((bar_length / 3))
local green_length=$((bar_length - red_length - yellow_length))
# Calculate filled and empty lengths
local filled_length=$((current_percentage * bar_length / 100))
# Construct the bar with colors
local bar=""
for (( i = 0; i < bar_length; i++ )); do
if [[ $i -lt $filled_length ]]; then
# Active part of the bar
if [[ $i -eq $time_progress ]]; then
# Show progression of time
bar+="#"
else
bar+="="
fi
else
# Empty part of the bar
if [[ $i -eq $time_progress ]]; then
# Show progression of time
bar+="+"
else
bar+="-"
fi
fi
done
# Add colors
local red_bar=${bar:0:red_length}
local yellow_bar=${bar:red_length:yellow_length}
local green_bar=${bar:red_length+yellow_length:green_length}
echo -ne " Current Battery [$(tput setaf 1)$red_bar$(tput setaf 3)$yellow_bar$(tput setaf 2)$green_bar$(tput sgr0)] ${current_percentage}% \r"
}
# Parse arguments
while [[ "$#" -gt 0 ]]; do
case $1 in
-v|--verbose) ((verbose++)) ;;
-m|--min-battery) min_battery="$2"; shift ;;
-*) echo "Unknown option $1"; exit 1 ;;
*) if [[ -z "$min_battery_arg" ]]; then min_battery_arg=$1; fi ;;
esac
shift
done
if [[ ! -z "$min_battery_arg" ]]; then
min_battery=$min_battery_arg
fi
# Check if the input is a valid number
if ! [[ "$min_battery" =~ ^[0-9]+$ ]]; then
echo "Error: Minimum battery percentage must be a number."
exit 1
fi
# Start caffeinate in the background
caffeinate -di &
caffeinate_pid=$!
# Clean up function
cleanup() {
trap '' SIGINT SIGTERM
if [[ $caffeinate_pid -eq 0 ]]; then
log -e "\nExiting. Stopping caffeinate."
kill $caffeinate_pid
fi
exit 0
}
# Trap SIGINT and SIGTERM for cleanup
trap cleanup SIGINT SIGTERM
# Main loop
log -e "Preventing sleep until battery goes below ${min_battery}%.\n"
while true; do
status="$(pmset -g batt)"
current_battery=$(grep -Eo "\d+%" <<< "$status" | cut -d% -f1)
if [[ $current_battery -lt $min_battery ]]; then
if [[ $caffeinate_pid -gt 0 ]]; then
log -e "\nBattery has dropped below ${min_battery}%."
kill $caffeinate_pid
caffeinate_pid=0
fi
elif [[ $current_battery -gt $min_battery ]]; then
if [[ $caffeinate_pid -eq 0 ]]; then
log -e "\nBattery has raised above ${min_battery}%."
caffeinate -di &
caffeinate_pid=$!
fi
fi
display_battery_bar "$status"
sleep 1
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment