Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

new CLI feature: maintain battery in a certain range #261

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
18 changes: 13 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ Example usage:
```shell
# This will enable charging when your battery dips under 80, and disable it when it exceeds 80
battery maintain 80
# This will enable charging when your battery dips under 30, and disable it when it exceeds 70
battery maintain 30-70
```

After running a command like `battery charging off` you can verify the change visually by looking at the battery icon:
Expand All @@ -71,17 +73,23 @@ After running `battery charging on` you will see it change to this:
For help, run `battery` without parameters:

```
Battery CLI utility v1.0.1
Battery CLI utility v1.2.0

Usage:

battery status
output battery SMC status, % and time remaining

battery maintain LEVEL[1-100,stop]
reboot-persistent battery level maintenance: turn off charging above, and on below a certain value
eg: battery maintain 80
eg: battery maintain stop
battery maintain LEVEL[value/minvalue-maxvalue/stop]
reboot-persistent battery level maintenance. There are two modes:
threshold mode:
turn off charging above, and on below a certain value.
range mode:
turn off charging above the maximum value, and on below the minimum value.
it has the option of a --force-discharge flag that discharges even when plugged in (this does NOT work well with clamshell mode)
eg: battery maintain 80 // threshold mode
eg: battery maintain 20-80 // range mode
eg: battery maintain stop // disable maintain mode

battery charging SETTING[on/off]
manually set the battery to (not) charge
Expand Down
50 changes: 38 additions & 12 deletions battery.sh
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,16 @@ Usage:
output logs of the battery CLI and GUI
eg: battery logs 100

battery maintain PERCENTAGE[1-100,stop]
reboot-persistent battery level maintenance: turn off charging above, and on below a certain value
it has the option of a --force-discharge flag that discharges even when plugged in (this does NOT work well with clamshell mode)
eg: battery maintain 80
eg: battery maintain stop
battery maintain PERCENTAGE[value,minvalue-maxvalue,stop]
reboot-persistent battery level maintenance. There are two modes:
threshold mode:
turn off charging above, and on below a certain value.
range mode:
turn off charging above the maximum value, and on below the minimum value.
it has the option of a --force-discharge flag that discharges even when plugged in (this does NOT work well with clamshell mode)
eg: battery maintain 80 // threshold mode
eg: battery maintain 20-80 // range mode
eg: battery maintain stop // disable maintain mode

battery maintain VOLTAGE[${voltage_min}V-${voltage_max}V,stop] (HYSTERESIS[${voltage_hyst_min}V-${voltage_hyst_max}V])
reboot-persistent battery level maintenance: keep battery at a certain voltage
Expand Down Expand Up @@ -552,7 +557,15 @@ if [[ "$action" == "maintain_synchronous" ]]; then
# Start charging
battery_percentage=$(get_battery_percentage)

log "Charging to and maintaining at $setting% from $battery_percentage%"
# Extract values from $setting
lower_threshold=${setting/-*/}
upper_threshold=${setting/*-/}
if [[ "$lower_threshold" -eq "$upper_threshold" ]]; then
# the string had no "-", both threasholds are the same
log "Charging to and maintaining at $lower_threshold% from $battery_percentage%"
else
log "Charging to and maintaining in range of $lower_threshold% to $upper_threshold% from $battery_percentage%"
fi

# Loop until battery percent is exceeded
while true; do
Expand All @@ -561,17 +574,17 @@ if [[ "$action" == "maintain_synchronous" ]]; then
is_charging=$(get_smc_charging_status)
ac_attached=$(get_charger_state)

if [[ "$battery_percentage" -ge "$setting" && ("$is_charging" == "enabled" || "$ac_attached" == "1") ]]; then
if [[ "$battery_percentage" -ge "$upper_threshold" && ("$is_charging" == "enabled" || "$ac_attached" == "1") ]]; then

log "Charge above $setting"
if [[ "$is_charging" == "enabled" ]]; then
disable_charging
fi
change_magsafe_led_color "green"

elif [[ "$battery_percentage" -lt "$setting" && "$is_charging" == "disabled" ]]; then
elif [[ "$battery_percentage" -lt "$lower_threshold" && "$is_charging" == "disabled" ]]; then

log "Charge below $setting"
log "Charge below $lower_threshold"
enable_charging
change_magsafe_led_color "orange"

Expand Down Expand Up @@ -660,6 +673,20 @@ if [[ "$action" == "maintain" ]]; then
exit 0
fi

# Check if setting is a legal range
if [[ "$setting" =~ ^[0-9]+-?[0-9]+$ ]]; then
log "Called with range $setting $action"
# Extract upper and lower if necessary and then check if values are legal
lower_threshold=${setting/-*/}
upper_threshold=${setting/*-/}
if [[ "$lower_threshold" -lt 1 ]] || [[ "$lower_threshold" -gt 100 ]] ||
[[ "$upper_threshold" -lt 1 ]] || [[ "$upper_threshold" -gt 100 ]] ||
[[ "$lower_threshold" -gt "$upper_threshold" ]]; then
log "Error: $setting is not a valid range setting for battery maintain. The min/max value should between 1 and 100. A range example like 30-80"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The min/max value should be between 1 and 100.

exit 1
fi
# Check if setting is value between 1 and 100
else
# Check if setting is a voltage
is_voltage=false
if valid_voltage "$setting"; then
Expand All @@ -685,12 +712,11 @@ if [[ "$action" == "maintain" ]]; then
# Check if setting is value between 0 and 100
elif ! valid_percentage "$setting"; then
log "Called with $setting $action"
# If non 0-100 setting is not a special keyword, exit with an error.
# If setting is not a special keyword, exit with an error.
if ! { [[ "$setting" == "stop" ]] || [[ "$setting" == "recover" ]]; }; then
log "Error: $setting is not a valid setting for battery maintain. Please use a number between 0 and 100, or an action keyword like 'stop' or 'recover'."
log "Error: $setting is not a valid setting for battery maintain. Please use a number between 1 and 100, or an action keyword like 'stop' or 'recover'."
exit 1
fi

fi

# Start maintenance script
Expand Down