Created
December 15, 2023 17:18
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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