From 0ae11ae6c9e805da7daae09d40e67c3fd5546612 Mon Sep 17 00:00:00 2001 From: Nicola De Rosa Date: Tue, 22 Aug 2023 16:04:25 +0200 Subject: [PATCH 01/33] Battery calibration --- battery.sh | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/battery.sh b/battery.sh index cd09d1c..4bc61a0 100755 --- a/battery.sh +++ b/battery.sh @@ -65,6 +65,9 @@ Usage: manually set the adapter to (not) charge even when plugged in eg: battery adapter off + battery calibrate + battery calibration + battery charge LEVEL[1-100] charge the battery to a certain percentage, and disable charging when that percentage is reached eg: battery charge 90 @@ -568,3 +571,36 @@ if [[ "$action" == "logs" ]]; then exit 0 fi + +# Battery calibration +if [[ "$action" == "calibrate" ]]; then + log "Starting calibration" + + # Stop the maintaining + battery maintain stop + + # Discharge battery to 15% + battery discharge 15 + + while true; do + log "checking if at 100%" + # Check if battery level has reached 100% + if battery status | head -n 1 | grep -q "Battery at 100%"; then + break + else + sleep 300 + continue + fi + done + + # Wait before discharging to target level + log "reached 100%, maintaining for 1 hour" + sleep 3600 + + # Discharge battery to 80% + battery discharge 80 + + # Maintain battery to 80% + battery maintain 80 + exit 0 +fi \ No newline at end of file From 62e783ad9f126bbd237a0dc595e8545cb34a29bb Mon Sep 17 00:00:00 2001 From: Nicola De Rosa Date: Thu, 24 Aug 2023 18:17:15 +0200 Subject: [PATCH 02/33] Addedd comment --- battery.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/battery.sh b/battery.sh index 4bc61a0..f44225f 100755 --- a/battery.sh +++ b/battery.sh @@ -66,7 +66,7 @@ Usage: eg: battery adapter off battery calibrate - battery calibration + calibrate the battery by discharding it to 15%, then recharging it to 100%, and keeping it there for 1 hour battery charge LEVEL[1-100] charge the battery to a certain percentage, and disable charging when that percentage is reached From 58ab5aaf77780b857c9fc32f82b2c0af7cd85296 Mon Sep 17 00:00:00 2001 From: Nicola De Rosa Date: Sat, 26 Aug 2023 17:01:24 +0200 Subject: [PATCH 03/33] Calibration process checking with pid --- .DS_Store | Bin 0 -> 6148 bytes battery.sh | 97 +++++++++++++++++++++++++++++++++++------------------ 2 files changed, 64 insertions(+), 33 deletions(-) create mode 100644 .DS_Store diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..8444e48e3a60bdd22617ec589c6cc7a5c15ad92b GIT binary patch literal 6148 zcmeHK%WB&|6ulF>u^gx1MGM&!1l=0fNlhVi8d?D|GNUbc1tv-2~CD^Vf`M#)BK}MO~OR^^K@cX`A>fm zM`_k-{SsTH@}2F9Q*mm}2k%VIy=Yi|KX#j z$D{N3B9ULU=mOs)Wp@o;!Z$R`Y(9I_B$ml1jBxZelt^)flu^2-#}D}PdhC#o=nPj# zQ~E+p@Xm@H@nDU!OFeo;FX@DiX-Hjqjn)wTXKOru!u-9;6i|fx*;?H1wYUmBN4_2n zkkg|c`t$V?%Cj6qvZ6D* zWt&vW$5&NkpwtboWw1VZ2D;X6tbkb`PVL4_ORx%91#Y_n{C#jy7&``68r7!*l{x|d z%NSOMw)*)8x;y~v7+h(@2ux@yP*a6DVhD3~5Sk8u$HcERYB~vZXXG(=7UqN^%+W)* zDx5?|qpht1R)L}dCEcy_{y*4!{x6bj&njRQxK#>>a^LHBF(tFNUYQ*4wJyp>6gG}q nX;c(cW;<35-ir57l)>k61K2UR(ufh5{Si/dev/null fi + if test -f "$calibrate_pidfile"; then + pid=$(cat "$calibrate_pidfile" 2>/dev/null) + log "🚨 Calibration is running, please run 'battery calibrate stop' or wait for it to finish" + fi + if [[ "$setting" == "stop" ]]; then log "Killing running maintain daemons & enabling charging as default state" rm $pidfile 2>/dev/null @@ -523,6 +529,64 @@ if [[ "$action" == "maintain" ]]; then fi +# Battery calibration +if [[ "$action" == "calibrate_synchronous" ]]; then + log "Starting calibration" + + # Stop the maintaining + battery maintain stop + + # Discharge battery to 15% + battery discharge 15 + + while true; do + log "checking if at 100%" + # Check if battery level has reached 100% + if battery status | head -n 1 | grep -q "Battery at 100%"; then + break + else + sleep 300 + continue + fi + done + + # Wait before discharging to target level + log "reached 100%, maintaining for 1 hour" + sleep 3600 + + # Discharge battery to 80% + battery discharge 80 + + # Maintain battery to 80% + battery maintain 80 + exit 0 +fi + +# Asynchronous battery level maintenance +if [[ "$action" == "calibrate" ]]; then + # Kill old process silently + if test -f "$calibrate_pidfile"; then + pid=$(cat "$calibrate_pidfile" 2>/dev/null) + kill $pid &>/dev/null + fi + + if [[ "$setting" == "stop" ]]; then + log "Killing running calibration daemon" + kill $calibrate_pidfile &>/dev/null + rm $calibrate_pidfile 2>/dev/null + + exit 0 + fi + + # Start calibration script + log "Starting calibration script" + nohup ./battery.sh calibrate_synchronous >>$logfile & + + # Store pid of calibration process and setting + echo $! >$calibrate_pidfile + pid=$(cat "$calibrate_pidfile" 2>/dev/null) +fi + # Status logger if [[ "$action" == "status" ]]; then @@ -635,37 +699,4 @@ if [[ "$action" == "logs" ]]; then exit 0 -fi - -# Battery calibration -if [[ "$action" == "calibrate" ]]; then - log "Starting calibration" - - # Stop the maintaining - battery maintain stop - - # Discharge battery to 15% - battery discharge 15 - - while true; do - log "checking if at 100%" - # Check if battery level has reached 100% - if battery status | head -n 1 | grep -q "Battery at 100%"; then - break - else - sleep 300 - continue - fi - done - - # Wait before discharging to target level - log "reached 100%, maintaining for 1 hour" - sleep 3600 - - # Discharge battery to 80% - battery discharge 80 - - # Maintain battery to 80% - battery maintain 80 - exit 0 fi \ No newline at end of file From e723d7945e54cdbe936c636eec6e3821955f815f Mon Sep 17 00:00:00 2001 From: Nicola De Rosa Date: Sat, 26 Aug 2023 17:05:00 +0200 Subject: [PATCH 04/33] Checking also in synch process --- battery.sh | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/battery.sh b/battery.sh index 2a5f99f..c648834 100755 --- a/battery.sh +++ b/battery.sh @@ -410,6 +410,12 @@ fi # Maintain at level if [[ "$action" == "maintain_synchronous" ]]; then + + # Checking if the calibration process is running + if test -f "$calibrate_pidfile"; then + pid=$(cat "$calibrate_pidfile" 2>/dev/null) + log "🚨 Calibration is running, please run 'battery calibrate stop' or wait for it to finish" + fi # Recover old maintain status if old setting is found if [[ "$setting" == "recover" ]]; then @@ -580,7 +586,7 @@ if [[ "$action" == "calibrate" ]]; then # Start calibration script log "Starting calibration script" - nohup ./battery.sh calibrate_synchronous >>$logfile & + nohup battery calibrate_synchronous >>$logfile & # Store pid of calibration process and setting echo $! >$calibrate_pidfile From f257b9d9dc5d223efffe3a2c01dbf0c5cca5baf4 Mon Sep 17 00:00:00 2001 From: Nicola De Rosa Date: Sun, 27 Aug 2023 14:32:24 +0200 Subject: [PATCH 05/33] Maintain recover at the and of calibration --- battery.sh | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/battery.sh b/battery.sh index c648834..832ace9 100755 --- a/battery.sh +++ b/battery.sh @@ -560,11 +560,8 @@ if [[ "$action" == "calibrate_synchronous" ]]; then log "reached 100%, maintaining for 1 hour" sleep 3600 - # Discharge battery to 80% - battery discharge 80 - - # Maintain battery to 80% - battery maintain 80 + # Recover old maintain status + battery maintain recover exit 0 fi From 4777260f9acad2f18e4d47dc150e096bb73063e6 Mon Sep 17 00:00:00 2001 From: Nicola De Rosa Date: Sun, 27 Aug 2023 16:54:10 +0200 Subject: [PATCH 06/33] The battery need to be discharged before maint. --- battery.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/battery.sh b/battery.sh index 832ace9..7929977 100755 --- a/battery.sh +++ b/battery.sh @@ -560,7 +560,10 @@ if [[ "$action" == "calibrate_synchronous" ]]; then log "reached 100%, maintaining for 1 hour" sleep 3600 - # Recover old maintain status + # Discharge battery to 80% + battery discharge 80 + + # Maintain battery to 80% battery maintain recover exit 0 fi From 3c6ae140d4c3d0684da5e5e44ee1f60936039728 Mon Sep 17 00:00:00 2001 From: Nicola De Rosa Date: Sun, 27 Aug 2023 16:55:50 +0200 Subject: [PATCH 07/33] changed comment --- battery.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/battery.sh b/battery.sh index 7929977..a1696c5 100755 --- a/battery.sh +++ b/battery.sh @@ -563,7 +563,7 @@ if [[ "$action" == "calibrate_synchronous" ]]; then # Discharge battery to 80% battery discharge 80 - # Maintain battery to 80% + # Recover old maintain status battery maintain recover exit 0 fi From d3bc676814915eac8a7c7fa4cc8bed2722b48091 Mon Sep 17 00:00:00 2001 From: Alex Ibrado Date: Tue, 19 Sep 2023 08:05:17 +0800 Subject: [PATCH 08/33] Check if AC is connected when charge is above threshold --- battery.sh | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/battery.sh b/battery.sh index 42815d6..96c51fe 100755 --- a/battery.sh +++ b/battery.sh @@ -204,6 +204,11 @@ function get_remaining_time() { echo "$time_remaining" } +function get_charger_state() { + ac_attached=$(pmset -g batt | tail -n1 | awk '{ x=match($0, /AC attached/) > 0; print x }') + echo "$ac_attached" +} + function get_maintain_percentage() { maintain_percentage=$(cat $maintain_percentage_tracker_file 2>/dev/null) echo "$maintain_percentage" @@ -443,8 +448,9 @@ if [[ "$action" == "maintain_synchronous" ]]; then # Keep track of status is_charging=$(get_smc_charging_status) + ac_attached=$(get_charger_state) - if [[ "$battery_percentage" -ge "$setting" && "$is_charging" == "enabled" ]]; then + if [[ "$battery_percentage" -ge "$setting" && ( "$is_charging" == "enabled" || "$ac_attached" == "1" ) ]]; then log "Charge above $setting" disable_charging From 7977d5f874adfc0685780f9d98f30c787e8e1b5d Mon Sep 17 00:00:00 2001 From: Alex Ibrado Date: Tue, 19 Sep 2023 08:14:19 +0800 Subject: [PATCH 09/33] Disable charging only if enabled --- battery.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/battery.sh b/battery.sh index 96c51fe..55e51df 100755 --- a/battery.sh +++ b/battery.sh @@ -453,7 +453,9 @@ if [[ "$action" == "maintain_synchronous" ]]; then if [[ "$battery_percentage" -ge "$setting" && ( "$is_charging" == "enabled" || "$ac_attached" == "1" ) ]]; then log "Charge above $setting" - disable_charging + if [[ "$is_charging" == "enabled" ]]; then + disable_charging + fi change_magsafe_led_color "green" elif [[ "$battery_percentage" -lt "$setting" && "$is_charging" == "disabled" ]]; then From 5883bbe70c4dbdd070734a06cec6f11a44a1d8fd Mon Sep 17 00:00:00 2001 From: Nicola De Rosa Date: Wed, 17 Jan 2024 12:55:57 +0100 Subject: [PATCH 10/33] Style Fix --- .DS_Store | Bin 6148 -> 6148 bytes .vscode/settings.json | 2 +- app/.DS_Store | Bin 0 -> 6148 bytes battery.sh | 170 ++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 164 insertions(+), 8 deletions(-) create mode 100644 app/.DS_Store diff --git a/.DS_Store b/.DS_Store index 8444e48e3a60bdd22617ec589c6cc7a5c15ad92b..74a78db103bc6f056aec745b79a5a7660681a3ba 100644 GIT binary patch delta 175 zcmZoMXfc@J&&aniU^g=(-((&ZYsPJpJy;4=#j2|fbQFwDjB0fhsx6IxY!fq++FDKy zQDuGWp!n>Z+`Rmb$q!iM89OJj-V|kFNMXoiC}t>0DlaZb%E?b+U|=B8AjwXk9=JJW Z!9{sF`FZI;F~-f;SbZ5cvvd6A2LR5PFz5gP delta 64 zcmV-G0Kfl)FoZCWPXP?EP`d*G43i85I{~

;-WO7<+p$IW#OFGcc3E1RMd1lima$ W0gIFV1lhB_21)^ufaJ3W2>lP1Fcu>K diff --git a/.vscode/settings.json b/.vscode/settings.json index 2296389..febebe8 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -10,7 +10,7 @@ "typescriptreact" ], "editor.codeActionsOnSave": { - "source.fixAll.eslint": true + "source.fixAll.eslint": "explicit" }, "editor.renderWhitespace": "all", "editor.formatOnSave": true, diff --git a/app/.DS_Store b/app/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..563238f6823579c4bf57edf8e2132df4f400eabe GIT binary patch literal 6148 zcmeHK&2G~`5S~rb#vvdD2@n?~OI%9`C8~tDn2;VgaH$a-00p~_T2t2>#SS?{k$eR4 z4t<5*c$B_NPw>s|R@hB)r4`z-X203pnO*Pa{qYi!=ue|(L~SB+pp5lfNLC2fvo1-^ zlyIC-ZRC`_N#sG8$Z*Nq7FY%>12>HUUb|ZqP=;qj)%DAp!YgR!w-WX0n-tQNVoE3~ zt#tN0Tkjdpva#6{eud*C&hl>eT+}w|n_CU1;k2C3{*j#dd5}-DelYpSxpz_~;iVmf z@8i*I*uM8#rg;#jqlpTLqY+#_eTdUY&iZniMwyEBb%oP(n#1;k`MkUBKJV=;w%z%Q z9oW6y-eS>o?mvF|a({T7oTT!*8XF1hVoL59yo4VxN+bW~PtruDhbZNU)?ZF&NJk{` z99MQi@FO0|JPQZIiDRt=UlK0OQ-jX74pWr){cUf-x;)?fO8l&w4yhT8V@PC3R zsq(5X*lG3a)p#uBx4V6%g*9<%ew>!(N0atx52XWo3+!NwtL8~L0v%hq76#00cUsrd zyY196U>Uf{4DkNoLK!`Sg+{e?AW>HUU>(IuVDrxa$G8SPgM~)aK!gqj>QG^>7($1m z+% 13.0 have a native charge threshold that +# does not required any userspace daemon running. +# This native limit works even when the laptop is sleeping or powered off therefore +# it is preferable to the userspace daemon. +# Nonetheless, it only works with fixed thresholds (80% as upper limit and 70% as +# lower limit). +# +# Thanks to @marcan for the implementation details in the Asahi Linux kernel: +# https://github.com/AsahiLinux/linux/commit/107ed86e21d1522d5d5d9d629f1d9c371e37df7f#diff-6b2c1b57b60e2829a9973ea707f596a3ff85fa787eca5d6d3b8ac79ebdd0381cR453 +# https://oftc.irclog.whitequark.org/asahi-dev/2023-04-18#32076880 + +# CHWA key is the one used to enable/disable the native limit. 01 = 80% limit, 00 = no limit +chwa_key="$( sudo smc -r -k CHWA | grep -q "no data" && echo "unavailable" || echo "available" )" + +function enable_native_limit() { + log " Enabling native limit at 80%" + sudo smc -k CHWA -w 01 +} + +function disable_native_limit() { + log " Disabling native limit" + sudo smc -k CHWA -w 00 +} +function get_native_limit_status() { + if [[ "$chwa_key" == "unavailable" ]]; then + echo "disabled" + else + hex_status=$( smc -k CHWA -r | awk '{print $4}' | sed s:\):: ) + if [[ "$hex_status" == "00" ]]; then + echo "disabled" + else + echo "enabled" + fi + fi +} + +function get_native_limit() { + if [[ "$(get_native_limit_status)" == "enabled" ]]; then + echo "80" + else + echo "" + fi +} + +# both the daemon and the native limit can be set at the same time so this function +# returns the lowest of the two. +# When both are set, the daemonic limit is the one that is used while the mac is awake +# and the native limit is the one that is used when the mac is sleeping or powered off. +function get_actual_limit() { + native=$( get_native_limit ) + daemon=$( get_maintain_percentage ) + + # if both are set, return the lowest + if [[ ! -z "$native" ]] && [[ ! -z "$daemon" ]]; then + if [[ "$native" -lt "$daemon" ]]; then + echo "$native" + else + echo "$daemon" + fi + # if only one is set, return that one + elif [[ ! -z "$native" ]]; then + echo "$native" + elif [[ ! -z "$daemon" ]]; then + echo "$daemon" + else + # if neither is set, return nothing + echo "" + fi +} + + function get_smc_charging_status() { hex_status=$(smc -k CH0B -r | awk '{print $4}' | sed s:\)::) if [[ "$hex_status" == "00" ]]; then @@ -433,6 +510,41 @@ if [[ "$action" == "maintain_synchronous" ]]; then fi fi + # if maintain percentage is 80 and CHWA is available, exit. This daemon is not needed. + # This condition could happen in some rare cases, for example when the daemon is started before + # updating the tool or before CHWA is available. + if [[ "$chwa_key" == "available" ]]; then + if [[ "$setting" == "80" ]]; then + log "Skipping daemon start as CHWA is available and maintain percentage is $setting" + # Disable daemon + battery maintain stop + battery disable_daemon + # Activate the native limit in case this is the first restart after the update of MacOs + # or of this tool + if [[ "$( get_native_limit_status )" == "disabled" ]]; then + enable_native_limit + fi + exit 0 + else + # If $setting is below 80 activate the native charging limiter as a mixed strategy. At + # least during sleep it will get as high as 80%, closer to the desired $setting than 100%. + if [[ "$setting" -lt "80" ]]; then + log "Using mixed limiter (daemon: $setting% / native: 80%)" + if [[ "$( get_native_limit_status )" == "disabled" ]]; then + enable_native_limit + fi + else + # Disabling native charging limiter if the limit > 80% as it would interfere with + # the daemon. + if [[ "$( get_native_limit_status )" == "enabled" ]]; then + disable_native_limit + fi + fi + + + fi + fi + # Check if the user requested that the battery maintenance first discharge to the desired level if [[ "$subsetting" == "--force-discharge" ]]; then # Before we start maintaining the battery level, first discharge to the target level @@ -514,6 +626,23 @@ if [[ "$action" == "maintain" ]]; then fi + # Use CHWA method if available an 80% is used (it's the only level supported by CHWA) + if [[ "$chwa_key" == "available" ]]; then + if [[ "$setting" == "80" ]]; then + if test -f "$pidfile"; then + kill_daemon + battery disable_daemon + log "Killing and disabling daemon as native limiter is available" + fi + enable_native_limit + exit 0 + else + log "Native charging limiter is available but only supports 80% limit. Consider using 80% because it works even during sleep." + fi + fi + + kill_daemon + # Start maintenance script log "Starting battery maintenance at $setting% $subsetting" nohup battery maintain_synchronous $setting $subsetting >>$logfile & @@ -548,9 +677,10 @@ if [[ "$action" == "calibrate_synchronous" ]]; then while true; do log "checking if at 100%" # Check if battery level has reached 100% - if battery status | head -n 1 | grep -q "Battery at 100%"; then + if battery status | head -n 1 | grep -q "Battery at 100%"; + then break - else + else sleep 300 continue fi @@ -595,11 +725,37 @@ fi # Status logger if [[ "$action" == "status" ]]; then + daemon_limit=$( get_maintain_percentage ) + native_limit=$( get_native_limit ) + actual_limit=$( get_actual_limit ) - log "Battery at $(get_battery_percentage)% ($(get_remaining_time) remaining), smc charging $(get_smc_charging_status)" - if test -f $pidfile; then - maintain_percentage=$(cat $maintain_percentage_tracker_file 2>/dev/null) - log "Your battery is currently being maintained at $maintain_percentage%" + log "Battery at $( get_battery_percentage )% ($( get_remaining_time ) remaining), smc charging $( get_smc_charging_status )" + + if [[ ! -z "$actual_limit" ]]; then + limit_status="Battery maintenance is set to $actual_limit%" + # if both daemon and native limiters are enabled, show both as: " using mixed daemon/native limiter. While your mac is awake the limit will be $setting% and during sleep it will be $native_limit%." + if [[ ! -z "$daemon_limit" ]] && [[ ! -z "$native_limit" ]]; then + limit_status="$limit_status using mixed daemon/native limiter ($daemon_limit% while your mac is awake / $native_limit% during sleep)." + elif [[ ! -z "$native_limit" ]]; then + limit_status="$limit_status using native limiter." + elif [[ ! -z "$daemon_limit" ]]; then + limit_status="$limit_status using daemon limiter (only works while your mac is awake)." + else + limit_status="$limit_status." + fi + + + if [[ "$chwa_key" == "available" ]] && [[ ! -z "$daemon_limit" ]]; then + limit_status="$limit_status Consider using native limit of 80% instead of $daemon_limit% to improve battery health." + fi + fi + + if [[ "$chwa_key" != "available" ]]; then + limit_status="$limit_status Consider upgrading to macOS to enable native battery limiter. It works even during sleep." + fi + + if [[ ! -z "$limit_status" ]]; then + log "$limit_status" fi exit 0 From 6021aa9d497fa5118a0ef61baca8fd42e1e02a04 Mon Sep 17 00:00:00 2001 From: Nicola De Rosa Date: Wed, 17 Jan 2024 16:23:44 +0100 Subject: [PATCH 11/33] Calibration Stop --- battery.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/battery.sh b/battery.sh index 4c2a50f..74c26e6 100755 --- a/battery.sh +++ b/battery.sh @@ -491,7 +491,8 @@ if [[ "$action" == "maintain_synchronous" ]]; then # Checking if the calibration process is running if test -f "$calibrate_pidfile"; then pid=$(cat "$calibrate_pidfile" 2>/dev/null) - log "🚨 Calibration is running, please run 'battery calibrate stop' or wait for it to finish" + battery calibrate stop + log "🚨 Calibration was running, now the calibration process have been Stopped" fi # Recover old maintain status if old setting is found @@ -601,7 +602,8 @@ if [[ "$action" == "maintain" ]]; then if test -f "$calibrate_pidfile"; then pid=$(cat "$calibrate_pidfile" 2>/dev/null) - log "🚨 Calibration is running, please run 'battery calibrate stop' or wait for it to finish" + battery calibrate stop + log "🚨 Calibration was running, now the calibration process have been Stopped" fi if [[ "$setting" == "stop" ]]; then From 13159c75f72da8a3f8c9687d6c9d61a60e289c5c Mon Sep 17 00:00:00 2001 From: Nicola De Rosa Date: Sun, 21 Jan 2024 00:50:22 +0100 Subject: [PATCH 12/33] Recovered Right files --- battery.sh | 184 ++++------------------------------------------------- 1 file changed, 13 insertions(+), 171 deletions(-) diff --git a/battery.sh b/battery.sh index 74c26e6..a1696c5 100755 --- a/battery.sh +++ b/battery.sh @@ -4,10 +4,10 @@ ## Update management ## variables are used by this binary as well at the update script ## ############### -BATTERY_CLI_VERSION="v1.1.6" +BATTERY_CLI_VERSION="v1.1.5" # Path fixes for unexpected environments -PATH=/bin:/usr/bin:/usr/local/bin:/usr/sbin:/opt/homebrew/bin:/opt/homebrew/sbin:/opt/homebrew +PATH=/bin:/usr/bin:/usr/local/bin:/usr/sbin:/opt/homebrew ## ############### ## Variables @@ -67,7 +67,7 @@ Usage: eg: battery adapter off battery calibrate - calibrate the battery by discharging it to 15%, then recharging it to 100%, and keeping it there for 1 hour + calibrate the battery by discharding it to 15%, then recharging it to 100%, and keeping it there for 1 hour battery charge LEVEL[1-100] charge the battery to a certain percentage, and disable charging when that percentage is reached @@ -101,17 +101,11 @@ Cmnd_Alias BATTERYON = $binfolder/smc -k CH0B -w 00, $binfolder/smc -k CH0C Cmnd_Alias DISCHARGEOFF = $binfolder/smc -k CH0I -w 00, $binfolder/smc -k CH0I -r Cmnd_Alias DISCHARGEON = $binfolder/smc -k CH0I -w 01 Cmnd_Alias LEDCONTROL = $binfolder/smc -k ACLC -w 04, $binfolder/smc -k ACLC -w 03, $binfolder/smc -k ACLC -w 00, $binfolder/smc -k ACLC -r -Cmnd_Alias NATIVELIMITOFF = $binfolder/smc -k CHWA -w 00 -Cmnd_Alias NATIVELIMITON = $binfolder/smc -k CHWA -w 01 -Cmnd_Alias NATIVELIMITREAD = $binfolder/smc -k CHWA -r ALL ALL = NOPASSWD: BATTERYOFF ALL ALL = NOPASSWD: BATTERYON ALL ALL = NOPASSWD: DISCHARGEOFF ALL ALL = NOPASSWD: DISCHARGEON ALL ALL = NOPASSWD: LEDCONTROL -ALL ALL = NOPASSWD: NATIVELIMITOFF -ALL ALL = NOPASSWD: NATIVELIMITON -ALL ALL = NOPASSWD: NATIVELIMITREAD " # Get parameters @@ -182,77 +176,6 @@ function disable_charging() { sudo smc -k CH0C -w 02 } -# Apple Silicon laptops with firmware > 13.0 have a native charge threshold that -# does not required any userspace daemon running. -# This native limit works even when the laptop is sleeping or powered off therefore -# it is preferable to the userspace daemon. -# Nonetheless, it only works with fixed thresholds (80% as upper limit and 70% as -# lower limit). -# -# Thanks to @marcan for the implementation details in the Asahi Linux kernel: -# https://github.com/AsahiLinux/linux/commit/107ed86e21d1522d5d5d9d629f1d9c371e37df7f#diff-6b2c1b57b60e2829a9973ea707f596a3ff85fa787eca5d6d3b8ac79ebdd0381cR453 -# https://oftc.irclog.whitequark.org/asahi-dev/2023-04-18#32076880 - -# CHWA key is the one used to enable/disable the native limit. 01 = 80% limit, 00 = no limit -chwa_key="$( sudo smc -r -k CHWA | grep -q "no data" && echo "unavailable" || echo "available" )" - -function enable_native_limit() { - log " Enabling native limit at 80%" - sudo smc -k CHWA -w 01 -} - -function disable_native_limit() { - log " Disabling native limit" - sudo smc -k CHWA -w 00 -} -function get_native_limit_status() { - if [[ "$chwa_key" == "unavailable" ]]; then - echo "disabled" - else - hex_status=$( smc -k CHWA -r | awk '{print $4}' | sed s:\):: ) - if [[ "$hex_status" == "00" ]]; then - echo "disabled" - else - echo "enabled" - fi - fi -} - -function get_native_limit() { - if [[ "$(get_native_limit_status)" == "enabled" ]]; then - echo "80" - else - echo "" - fi -} - -# both the daemon and the native limit can be set at the same time so this function -# returns the lowest of the two. -# When both are set, the daemonic limit is the one that is used while the mac is awake -# and the native limit is the one that is used when the mac is sleeping or powered off. -function get_actual_limit() { - native=$( get_native_limit ) - daemon=$( get_maintain_percentage ) - - # if both are set, return the lowest - if [[ ! -z "$native" ]] && [[ ! -z "$daemon" ]]; then - if [[ "$native" -lt "$daemon" ]]; then - echo "$native" - else - echo "$daemon" - fi - # if only one is set, return that one - elif [[ ! -z "$native" ]]; then - echo "$native" - elif [[ ! -z "$daemon" ]]; then - echo "$daemon" - else - # if neither is set, return nothing - echo "" - fi -} - - function get_smc_charging_status() { hex_status=$(smc -k CH0B -r | awk '{print $4}' | sed s:\)::) if [[ "$hex_status" == "00" ]]; then @@ -424,9 +347,9 @@ if [[ "$action" == "adapter" ]]; then # Set charging to on and off if [[ "$setting" == "on" ]]; then - disable_discharging - elif [[ "$setting" == "off" ]]; then enable_discharging + elif [[ "$setting" == "off" ]]; then + disable_discharging fi exit 0 @@ -491,8 +414,7 @@ if [[ "$action" == "maintain_synchronous" ]]; then # Checking if the calibration process is running if test -f "$calibrate_pidfile"; then pid=$(cat "$calibrate_pidfile" 2>/dev/null) - battery calibrate stop - log "🚨 Calibration was running, now the calibration process have been Stopped" + log "🚨 Calibration is running, please run 'battery calibrate stop' or wait for it to finish" fi # Recover old maintain status if old setting is found @@ -511,41 +433,6 @@ if [[ "$action" == "maintain_synchronous" ]]; then fi fi - # if maintain percentage is 80 and CHWA is available, exit. This daemon is not needed. - # This condition could happen in some rare cases, for example when the daemon is started before - # updating the tool or before CHWA is available. - if [[ "$chwa_key" == "available" ]]; then - if [[ "$setting" == "80" ]]; then - log "Skipping daemon start as CHWA is available and maintain percentage is $setting" - # Disable daemon - battery maintain stop - battery disable_daemon - # Activate the native limit in case this is the first restart after the update of MacOs - # or of this tool - if [[ "$( get_native_limit_status )" == "disabled" ]]; then - enable_native_limit - fi - exit 0 - else - # If $setting is below 80 activate the native charging limiter as a mixed strategy. At - # least during sleep it will get as high as 80%, closer to the desired $setting than 100%. - if [[ "$setting" -lt "80" ]]; then - log "Using mixed limiter (daemon: $setting% / native: 80%)" - if [[ "$( get_native_limit_status )" == "disabled" ]]; then - enable_native_limit - fi - else - # Disabling native charging limiter if the limit > 80% as it would interfere with - # the daemon. - if [[ "$( get_native_limit_status )" == "enabled" ]]; then - disable_native_limit - fi - fi - - - fi - fi - # Check if the user requested that the battery maintenance first discharge to the desired level if [[ "$subsetting" == "--force-discharge" ]]; then # Before we start maintaining the battery level, first discharge to the target level @@ -602,8 +489,7 @@ if [[ "$action" == "maintain" ]]; then if test -f "$calibrate_pidfile"; then pid=$(cat "$calibrate_pidfile" 2>/dev/null) - battery calibrate stop - log "🚨 Calibration was running, now the calibration process have been Stopped" + log "🚨 Calibration is running, please run 'battery calibrate stop' or wait for it to finish" fi if [[ "$setting" == "stop" ]]; then @@ -628,23 +514,6 @@ if [[ "$action" == "maintain" ]]; then fi - # Use CHWA method if available an 80% is used (it's the only level supported by CHWA) - if [[ "$chwa_key" == "available" ]]; then - if [[ "$setting" == "80" ]]; then - if test -f "$pidfile"; then - kill_daemon - battery disable_daemon - log "Killing and disabling daemon as native limiter is available" - fi - enable_native_limit - exit 0 - else - log "Native charging limiter is available but only supports 80% limit. Consider using 80% because it works even during sleep." - fi - fi - - kill_daemon - # Start maintenance script log "Starting battery maintenance at $setting% $subsetting" nohup battery maintain_synchronous $setting $subsetting >>$logfile & @@ -679,10 +548,9 @@ if [[ "$action" == "calibrate_synchronous" ]]; then while true; do log "checking if at 100%" # Check if battery level has reached 100% - if battery status | head -n 1 | grep -q "Battery at 100%"; - then + if battery status | head -n 1 | grep -q "Battery at 100%"; then break - else + else sleep 300 continue fi @@ -727,37 +595,11 @@ fi # Status logger if [[ "$action" == "status" ]]; then - daemon_limit=$( get_maintain_percentage ) - native_limit=$( get_native_limit ) - actual_limit=$( get_actual_limit ) - log "Battery at $( get_battery_percentage )% ($( get_remaining_time ) remaining), smc charging $( get_smc_charging_status )" - - if [[ ! -z "$actual_limit" ]]; then - limit_status="Battery maintenance is set to $actual_limit%" - # if both daemon and native limiters are enabled, show both as: " using mixed daemon/native limiter. While your mac is awake the limit will be $setting% and during sleep it will be $native_limit%." - if [[ ! -z "$daemon_limit" ]] && [[ ! -z "$native_limit" ]]; then - limit_status="$limit_status using mixed daemon/native limiter ($daemon_limit% while your mac is awake / $native_limit% during sleep)." - elif [[ ! -z "$native_limit" ]]; then - limit_status="$limit_status using native limiter." - elif [[ ! -z "$daemon_limit" ]]; then - limit_status="$limit_status using daemon limiter (only works while your mac is awake)." - else - limit_status="$limit_status." - fi - - - if [[ "$chwa_key" == "available" ]] && [[ ! -z "$daemon_limit" ]]; then - limit_status="$limit_status Consider using native limit of 80% instead of $daemon_limit% to improve battery health." - fi - fi - - if [[ "$chwa_key" != "available" ]]; then - limit_status="$limit_status Consider upgrading to macOS to enable native battery limiter. It works even during sleep." - fi - - if [[ ! -z "$limit_status" ]]; then - log "$limit_status" + log "Battery at $(get_battery_percentage)% ($(get_remaining_time) remaining), smc charging $(get_smc_charging_status)" + if test -f $pidfile; then + maintain_percentage=$(cat $maintain_percentage_tracker_file 2>/dev/null) + log "Your battery is currently being maintained at $maintain_percentage%" fi exit 0 From 26346918797461c8e8324f3641fe992498f7c728 Mon Sep 17 00:00:00 2001 From: Nicola De Rosa Date: Sun, 21 Jan 2024 00:52:08 +0100 Subject: [PATCH 13/33] Indentation fix --- battery.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/battery.sh b/battery.sh index a1696c5..6ed54cb 100755 --- a/battery.sh +++ b/battery.sh @@ -550,7 +550,7 @@ if [[ "$action" == "calibrate_synchronous" ]]; then # Check if battery level has reached 100% if battery status | head -n 1 | grep -q "Battery at 100%"; then break - else + else sleep 300 continue fi From acc0322d6dc373eb28b9e7407e863c4754777594 Mon Sep 17 00:00:00 2001 From: Nicola De Rosa Date: Sun, 21 Jan 2024 00:58:45 +0100 Subject: [PATCH 14/33] Fix --- battery.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/battery.sh b/battery.sh index 6ed54cb..7f9df6a 100755 --- a/battery.sh +++ b/battery.sh @@ -67,7 +67,7 @@ Usage: eg: battery adapter off battery calibrate - calibrate the battery by discharding it to 15%, then recharging it to 100%, and keeping it there for 1 hour + calibrate the battery by discharging it to 15%, then recharging it to 100%, and keeping it there for 1 hour battery charge LEVEL[1-100] charge the battery to a certain percentage, and disable charging when that percentage is reached @@ -414,7 +414,8 @@ if [[ "$action" == "maintain_synchronous" ]]; then # Checking if the calibration process is running if test -f "$calibrate_pidfile"; then pid=$(cat "$calibrate_pidfile" 2>/dev/null) - log "🚨 Calibration is running, please run 'battery calibrate stop' or wait for it to finish" + kill $calibrate_pidfile &>/dev/null + log "🚨 Calibration process have been stopped" fi # Recover old maintain status if old setting is found @@ -489,7 +490,8 @@ if [[ "$action" == "maintain" ]]; then if test -f "$calibrate_pidfile"; then pid=$(cat "$calibrate_pidfile" 2>/dev/null) - log "🚨 Calibration is running, please run 'battery calibrate stop' or wait for it to finish" + kill $calibrate_pidfile &>/dev/null + log "🚨 Calibration process have been stopped" fi if [[ "$setting" == "stop" ]]; then From dc223842ee25459e45a241d7f0c31c929cd1532c Mon Sep 17 00:00:00 2001 From: Theodore Murphy Date: Sun, 3 Mar 2024 16:01:25 +1100 Subject: [PATCH 15/33] Sleeps for 20 instead of 60 within 3% --- battery.sh | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/battery.sh b/battery.sh index e4bdea6..8f733cb 100755 --- a/battery.sh +++ b/battery.sh @@ -442,24 +442,28 @@ if [[ "$action" == "maintain_synchronous" ]]; then while true; do # Keep track of status - is_charging=$(get_smc_charging_status) + if [[ "$battery_percentage" -ge "$((setting - 3))" && "$battery_percentage" -lt "$setting" && "$is_charging" == "enabled" ]]; then + sleep 20 - if [[ "$battery_percentage" -ge "$setting" && "$is_charging" == "enabled" ]]; then + else - log "Charge above $setting" - disable_charging - change_magsafe_led_color "green" + if [[ "$battery_percentage" -ge "$setting" && "$is_charging" == "enabled" ]]; then + log "Charge above $setting" + disable_charging + change_magsafe_led_color "green" - elif [[ "$battery_percentage" -lt "$setting" && "$is_charging" == "disabled" ]]; then + elif [[ "$battery_percentage" -lt "$setting" && "$is_charging" == "disabled" ]]; then + log "Charge below $setting" + enable_charging + change_magsafe_led_color "orange" - log "Charge below $setting" - enable_charging - change_magsafe_led_color "orange" + fi + sleep 60 + + fi fi - sleep 60 - battery_percentage=$(get_battery_percentage) done From afe19c53a0160961ddca89bbdf0f07455e23bf89 Mon Sep 17 00:00:00 2001 From: Theodore Murphy <130824397+thdrmrphy@users.noreply.github.com> Date: Sun, 24 Mar 2024 10:09:59 +1100 Subject: [PATCH 16/33] Bug fix Remove accidental `fi` --- battery.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/battery.sh b/battery.sh index 2d1d560..9951057 100755 --- a/battery.sh +++ b/battery.sh @@ -487,7 +487,6 @@ if [[ "$action" == "maintain_synchronous" ]]; then sleep 60 fi - fi battery_percentage=$(get_battery_percentage) From cc0ecbcba29652084a8686ad906eaf28ad8f0b34 Mon Sep 17 00:00:00 2001 From: Chris Lasher Date: Sun, 24 Mar 2024 14:58:32 -0400 Subject: [PATCH 17/33] Reorder paths. --- app/modules/battery.js | 2 +- battery.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/modules/battery.js b/app/modules/battery.js index a03dcf8..818a772 100644 --- a/app/modules/battery.js +++ b/app/modules/battery.js @@ -4,7 +4,7 @@ const { exec } = require( 'node:child_process' ) const { log, alert, wait, confirm } = require( './helpers' ) const { get_force_discharge_setting } = require( './settings' ) const { USER } = process.env -const path_fix = 'PATH=/bin:/usr/bin:/usr/local/bin:/usr/sbin:/opt/homebrew/bin:/opt/homebrew/sbin:/opt/homebrew' +const path_fix = 'PATH=/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin' const battery = `${ path_fix } battery` const shell_options = { shell: '/bin/bash', diff --git a/battery.sh b/battery.sh index e12e263..b1e8d03 100755 --- a/battery.sh +++ b/battery.sh @@ -7,7 +7,7 @@ BATTERY_CLI_VERSION="v1.1.6" # Path fixes for unexpected environments -PATH=/bin:/usr/bin:/usr/local/bin:/usr/sbin:/opt/homebrew/bin:/opt/homebrew/sbin:/opt/homebrew +PATH=/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin ## ############### ## Variables From 51304aa9deb0013bd25de28ab7a6e25772332737 Mon Sep 17 00:00:00 2001 From: Theodore Murphy <130824397+thdrmrphy@users.noreply.github.com> Date: Thu, 28 Mar 2024 11:19:17 +1100 Subject: [PATCH 18/33] Use validation PR from upstream --- battery.sh | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/battery.sh b/battery.sh index e12e263..e9cfc77 100755 --- a/battery.sh +++ b/battery.sh @@ -117,6 +117,14 @@ function log() { echo -e "$(date +%D-%T) - $1" } +function validate_percentage() { + if ! [[ "$1" =~ ^[0-9]+$ ]] || [[ "$1" -lt 0 ]] || [[ "$1" -gt 100 ]]; then + echo false + else + echo true + fi +} + ## ################# ## SMC Manipulation ## ################# @@ -374,6 +382,11 @@ fi # Charging on/off controller if [[ "$action" == "charge" ]]; then + if ! $(validate_percentage "$setting"); then + log "Error: $setting is not a valid setting for battery maintain. Please use a number between 0 and 100" + exit 1 + fi + # Check if percentage is an integer [1-100] if ! [[ $setting =~ ^[1-9][0-9]?$|^100$ ]]; then log "Specified percentage ($setting) is not valid. Please specify an integer [1-100]." @@ -410,6 +423,11 @@ fi # Discharging on/off controller if [[ "$action" == "discharge" ]]; then + if ! $(validate_percentage "$setting"); then + log "Error: $setting is not a valid setting for battery maintain. Please use a number between 0 and 100" + exit 1 + fi + # Start charging battery_percentage=$(get_battery_percentage) log "Discharging to $setting% from $battery_percentage%" @@ -432,6 +450,11 @@ fi # Maintain at level if [[ "$action" == "maintain_synchronous" ]]; then + if ! $(validate_percentage "$setting"); then + log "Error: $setting is not a valid setting for battery maintain. Please use a number between 0 and 100" + exit 1 + fi + # Recover old maintain status if old setting is found if [[ "$setting" == "recover" ]]; then @@ -513,7 +536,7 @@ if [[ "$action" == "maintain" ]]; then fi # Check if setting is value between 0 and 100 - if ! [[ "$setting" =~ ^[0-9]+$ ]] || [[ "$setting" -lt 0 ]] || [[ "$setting" -gt 100 ]]; then + if ! $(validate_percentage "$setting"); then log "Called with $setting $action" # If non 0-100 setting is not a special keyword, exit with an error. From e404c0219fb344dc6ef609ea096ab8ebf782faa2 Mon Sep 17 00:00:00 2001 From: Theodore Murphy <130824397+thdrmrphy@users.noreply.github.com> Date: Thu, 28 Mar 2024 11:25:11 +1100 Subject: [PATCH 19/33] End eternal loop from battery charging on command --- battery.sh | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/battery.sh b/battery.sh index e9cfc77..0c9cd8a 100755 --- a/battery.sh +++ b/battery.sh @@ -166,7 +166,15 @@ function disable_discharging() { # Keep track of status is_charging=$(get_smc_charging_status) - if [[ "$battery_percentage" -ge "$setting" && "$is_charging" == "enabled" ]]; then + if ! [[ $setting =~ ^[1-9][0-9]?$|^100$ ]]; then + + log "No valid maintain percentage set, charging freely" + # use direct commands since enable_charging also calls disable_discharging, and causing an eternal loop + sudo smc -k CH0B -w 00 + sudo smc -k CH0C -w 00 + change_magsafe_led_color "orange" + + elif [[ "$battery_percentage" -ge "$setting" && "$is_charging" == "enabled" ]]; then log "Charge above $setting" disable_charging From 5a028d0d35deb836f75822d7b57e8956bf12de3c Mon Sep 17 00:00:00 2001 From: Theodore Murphy <130824397+thdrmrphy@users.noreply.github.com> Date: Thu, 28 Mar 2024 11:26:08 +1100 Subject: [PATCH 20/33] Fix with new function --- battery.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/battery.sh b/battery.sh index 0c9cd8a..db573cf 100755 --- a/battery.sh +++ b/battery.sh @@ -166,7 +166,7 @@ function disable_discharging() { # Keep track of status is_charging=$(get_smc_charging_status) - if ! [[ $setting =~ ^[1-9][0-9]?$|^100$ ]]; then + if ! $(validate_percentage "$setting"); then log "No valid maintain percentage set, charging freely" # use direct commands since enable_charging also calls disable_discharging, and causing an eternal loop From 51a797ad2f9e85ee25295d5d9f3e0ce947d0c884 Mon Sep 17 00:00:00 2001 From: Theodore Murphy <130824397+thdrmrphy@users.noreply.github.com> Date: Thu, 28 Mar 2024 12:10:16 +1100 Subject: [PATCH 21/33] Sorry to bunch all of this into one commit! Lots of changes trying to debug, better logging, etc. Will revert some of it. --- battery.sh | 66 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 37 insertions(+), 29 deletions(-) diff --git a/battery.sh b/battery.sh index db573cf..cf3e47f 100755 --- a/battery.sh +++ b/battery.sh @@ -118,11 +118,12 @@ function log() { } function validate_percentage() { - if ! [[ "$1" =~ ^[0-9]+$ ]] || [[ "$1" -lt 0 ]] || [[ "$1" -gt 100 ]]; then - echo false - else - echo true - fi + log "Validating $1" + if ! [[ "$1" =~ ^[0-9]+$ ]] || [[ "$1" -lt 0 ]] || [[ "$1" -gt 100 ]]; then + echo false + else + echo true + fi } ## ################# @@ -132,6 +133,7 @@ function validate_percentage() { # Change magsafe color # see community sleuthing: https://github.com/actuallymentor/battery/issues/71 function change_magsafe_led_color() { + log "MagSafe LED function invoked" color=$1 # Check whether user can run color changes without password (required for backwards compatibility) @@ -143,11 +145,14 @@ function change_magsafe_led_color() { fi if [[ "$color" == "green" ]]; then + log "setting LED to green" sudo smc -k ACLC -w 03 elif [[ "$color" == "orange" ]]; then + log "setting LED to orange" sudo smc -k ACLC -w 04 else # Default action: reset. Value 00 is a guess and needs confirmation + log "resetting LED" sudo smc -k ACLC -w 00 fi } @@ -166,24 +171,26 @@ function disable_discharging() { # Keep track of status is_charging=$(get_smc_charging_status) - if ! $(validate_percentage "$setting"); then + if ! validate_percentage "$setting"; then - log "No valid maintain percentage set, charging freely" - # use direct commands since enable_charging also calls disable_discharging, and causing an eternal loop + log "Disabling discharging: No valid maintain percentage set, enabling charging" + # use direct commands since enable_charging also calls disable_discharging, and causes an eternal loop sudo smc -k CH0B -w 00 sudo smc -k CH0C -w 00 change_magsafe_led_color "orange" elif [[ "$battery_percentage" -ge "$setting" && "$is_charging" == "enabled" ]]; then - log "Charge above $setting" + log "Disabling discharging: Charge above $setting, disabling charging" disable_charging change_magsafe_led_color "green" elif [[ "$battery_percentage" -lt "$setting" && "$is_charging" == "disabled" ]]; then - log "Charge below $setting" - enable_charging + log "Disabling discharging: Charge below $setting, enabling charging" + # use direct commands since enable_charging also calls disable_discharging, and causes an eternal loop + sudo smc -k CH0B -w 00 + sudo smc -k CH0C -w 00 change_magsafe_led_color "orange" fi @@ -362,6 +369,9 @@ if [[ "$action" == "charging" ]]; then enable_charging elif [[ "$setting" == "off" ]]; then disable_charging + else + log "Error: $setting is not \"on\" or \"off\"." + exit 1 fi exit 0 @@ -381,6 +391,9 @@ if [[ "$action" == "adapter" ]]; then disable_discharging elif [[ "$setting" == "off" ]]; then enable_discharging + else + log "Error: $setting is not \"on\" or \"off\"." + exit 1 fi exit 0 @@ -390,17 +403,11 @@ fi # Charging on/off controller if [[ "$action" == "charge" ]]; then - if ! $(validate_percentage "$setting"); then - log "Error: $setting is not a valid setting for battery maintain. Please use a number between 0 and 100" + if ! validate_percentage "$setting"; then + log "Error: $setting is not a valid setting for battery charge. Please use a number between 0 and 100" exit 1 fi - # Check if percentage is an integer [1-100] - if ! [[ $setting =~ ^[1-9][0-9]?$|^100$ ]]; then - log "Specified percentage ($setting) is not valid. Please specify an integer [1-100]." - exit 1 - fi - # Disable running daemon battery maintain stop @@ -410,14 +417,16 @@ if [[ "$action" == "charge" ]]; then # Start charging battery_percentage=$(get_battery_percentage) log "Charging to $setting% from $battery_percentage%" - enable_charging + enable_charging # also disables discharging # Loop until battery percent is exceeded while [[ "$battery_percentage" -lt "$setting" ]]; do - log "Battery at $battery_percentage%" - caffeinate -is sleep 60 - battery_percentage=$(get_battery_percentage) + if [[ "$battery_percentage" -ge "$((setting-3))" ]]; then + sleep 20 + else + caffeinate -is sleep 60 + fi done @@ -431,8 +440,8 @@ fi # Discharging on/off controller if [[ "$action" == "discharge" ]]; then - if ! $(validate_percentage "$setting"); then - log "Error: $setting is not a valid setting for battery maintain. Please use a number between 0 and 100" + if ! validate_percentage "$setting"; then + log "Error: $setting is not a valid setting for battery discharge. Please use a number between 0 and 100" exit 1 fi @@ -458,7 +467,7 @@ fi # Maintain at level if [[ "$action" == "maintain_synchronous" ]]; then - if ! $(validate_percentage "$setting"); then + if ! validate_percentage "$setting"; then log "Error: $setting is not a valid setting for battery maintain. Please use a number between 0 and 100" exit 1 fi @@ -538,13 +547,12 @@ if [[ "$action" == "maintain" ]]; then rm $pidfile 2>/dev/null battery disable_daemon enable_charging - change_magsafe_led_color battery status exit 0 fi # Check if setting is value between 0 and 100 - if ! $(validate_percentage "$setting"); then + if ! validate_percentage "$setting"; then log "Called with $setting $action" # If non 0-100 setting is not a special keyword, exit with an error. @@ -688,4 +696,4 @@ if [[ "$action" == "logs" ]]; then exit 0 -fi +fi \ No newline at end of file From a316b556aa8a3d47dd8952746d25018de1e7c31b Mon Sep 17 00:00:00 2001 From: Theodore Murphy <130824397+thdrmrphy@users.noreply.github.com> Date: Fri, 5 Apr 2024 17:49:03 +1100 Subject: [PATCH 22/33] =?UTF-8?q?Not=20sure=20what=20this=20commit's=20doi?= =?UTF-8?q?ng=20=C2=AF\=5F(=E3=83=84)=5F/=C2=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- battery.sh | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/battery.sh b/battery.sh index 2ee87c7..cf3e47f 100755 --- a/battery.sh +++ b/battery.sh @@ -507,26 +507,23 @@ if [[ "$action" == "maintain_synchronous" ]]; then while true; do # Keep track of status - if [[ "$battery_percentage" -ge "$((setting - 3))" && "$battery_percentage" -lt "$setting" && "$is_charging" == "enabled" ]]; then - sleep 20 + is_charging=$(get_smc_charging_status) - else + if [[ "$battery_percentage" -ge "$setting" && "$is_charging" == "enabled" ]]; then - if [[ "$battery_percentage" -ge "$setting" && "$is_charging" == "enabled" ]]; then - log "Charge above $setting" - disable_charging - change_magsafe_led_color "green" + log "Charge above $setting" + disable_charging + change_magsafe_led_color "green" - elif [[ "$battery_percentage" -lt "$setting" && "$is_charging" == "disabled" ]]; then - log "Charge below $setting" - enable_charging - change_magsafe_led_color "orange" + elif [[ "$battery_percentage" -lt "$setting" && "$is_charging" == "disabled" ]]; then - fi + log "Charge below $setting" + enable_charging + change_magsafe_led_color "orange" - sleep 60 + fi - fi + sleep 60 battery_percentage=$(get_battery_percentage) From 5f8210030c6315bb1ef56c330a0e480e1eb94ce7 Mon Sep 17 00:00:00 2001 From: Christoph Date: Sun, 21 Apr 2024 16:38:46 +0200 Subject: [PATCH 23/33] fixes several issues fixes battery not found if not running in path fixes validate_percentage and rename to valid_percentage removes in --- battery.sh | 43 +++++++++++++++++++++---------------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/battery.sh b/battery.sh index cf3e47f..80a69a2 100755 --- a/battery.sh +++ b/battery.sh @@ -105,6 +105,7 @@ ALL ALL = NOPASSWD: LEDCONTROL " # Get parameters +battery_binary=$0 action=$1 setting=$2 subsetting=$3 @@ -117,12 +118,11 @@ function log() { echo -e "$(date +%D-%T) - $1" } -function validate_percentage() { - log "Validating $1" +function valid_percentage() { if ! [[ "$1" =~ ^[0-9]+$ ]] || [[ "$1" -lt 0 ]] || [[ "$1" -gt 100 ]]; then - echo false + return 1 else - echo true + return 0 fi } @@ -171,7 +171,7 @@ function disable_discharging() { # Keep track of status is_charging=$(get_smc_charging_status) - if ! validate_percentage "$setting"; then + if ! valid_percentage "$setting"; then log "Disabling discharging: No valid maintain percentage set, enabling charging" # use direct commands since enable_charging also calls disable_discharging, and causes an eternal loop @@ -349,7 +349,7 @@ if [[ "$action" == "uninstall" ]]; then fi enable_charging disable_discharging - battery remove_daemon + $battery_binary remove_daemon sudo rm -v "$binfolder/smc" "$binfolder/battery" $visudo_file sudo rm -v -r "$configfolder" pkill -f "/usr/local/bin/battery.*" @@ -362,7 +362,7 @@ if [[ "$action" == "charging" ]]; then log "Setting $action to $setting" # Disable running daemon - battery maintain stop + $battery_binary maintain stop # Set charging to on and off if [[ "$setting" == "on" ]]; then @@ -384,7 +384,7 @@ if [[ "$action" == "adapter" ]]; then log "Setting $action to $setting" # Disable running daemon - battery maintain stop + $battery_binary maintain stop # Set charging to on and off if [[ "$setting" == "on" ]]; then @@ -403,16 +403,16 @@ fi # Charging on/off controller if [[ "$action" == "charge" ]]; then - if ! validate_percentage "$setting"; then + if ! valid_percentage "$setting"; then log "Error: $setting is not a valid setting for battery charge. Please use a number between 0 and 100" exit 1 fi # Disable running daemon - battery maintain stop + $battery_binary maintain stop # Disable charge blocker if enabled - battery adapter on + $battery_binary adapter on # Start charging battery_percentage=$(get_battery_percentage) @@ -440,7 +440,7 @@ fi # Discharging on/off controller if [[ "$action" == "discharge" ]]; then - if ! validate_percentage "$setting"; then + if ! valid_percentage "$setting"; then log "Error: $setting is not a valid setting for battery discharge. Please use a number between 0 and 100" exit 1 fi @@ -492,7 +492,7 @@ if [[ "$action" == "maintain_synchronous" ]]; then if [[ "$subsetting" == "--force-discharge" ]]; then # Before we start maintaining the battery level, first discharge to the target level log "Triggering discharge to $setting before enabling charging limiter" - battery discharge "$setting" + $battery_binary discharge "$setting" log "Discharge pre battery-maintenance complete, continuing to battery maintenance loop" else log "Not triggering discharge as it is not requested" @@ -545,14 +545,13 @@ if [[ "$action" == "maintain" ]]; then if [[ "$setting" == "stop" ]]; then log "Killing running maintain daemons & enabling charging as default state" rm $pidfile 2>/dev/null - battery disable_daemon - enable_charging - battery status + $battery_binary disable_daemon + $battery_binary status exit 0 fi # Check if setting is value between 0 and 100 - if ! validate_percentage "$setting"; then + if ! valid_percentage "$setting"; then log "Called with $setting $action" # If non 0-100 setting is not a special keyword, exit with an error. @@ -565,7 +564,7 @@ if [[ "$action" == "maintain" ]]; then # Start maintenance script log "Starting battery maintenance at $setting% $subsetting" - nohup battery maintain_synchronous $setting $subsetting >>$logfile & + nohup $battery_binary maintain_synchronous $setting $subsetting >>$logfile & # Store pid of maintenance process and setting echo $! >$pidfile @@ -578,7 +577,7 @@ if [[ "$action" == "maintain" ]]; then fi # Enable the daemon that continues maintaining after reboot - battery create_daemon + $battery_binary create_daemon exit 0 @@ -691,9 +690,9 @@ if [[ "$action" == "logs" ]]; then ls -lah $configfolder echo -e "\n⚙️ Battery data:\n" - battery status - battery | grep -E "v\d.*" + $battery_binary status + $battery_binary | grep -E "v\d.*" exit 0 -fi \ No newline at end of file +fi From 610b1682c7b2cba2d99a5457fe66c24752e38cea Mon Sep 17 00:00:00 2001 From: John McDowell <11021373+johnmcdowell@users.noreply.github.com> Date: Thu, 2 May 2024 13:41:13 -0700 Subject: [PATCH 24/33] Address confusion that brew install does not directly complete command line installation --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8496fa1..b3cc768 100644 --- a/README.md +++ b/README.md @@ -10,10 +10,12 @@ This is an app for Apple Silicon Macs. It will not work on Intel macs. Do you ha ### Installation -- Option 1: install through brew with `brew install battery` -- Option 2: [You can download the latest app dmg version here](https://github.com/actuallymentor/battery/releases/). +- Option 1: install the app through brew with `brew install battery` +- Option 2: [download the latest app dmg version here](https://github.com/actuallymentor/battery/releases/) - Option 3: command-line only installation (see section below) +When installing via brew or dmg, opening the macOS app is required to complete the installation. + The first time you open the app, it will ask for your administator password so it can install the needed components. Please note that the app: - Discharges your battery until it reaches 80%, **even when plugged in** From 5d1c8807569141c0c35d546f0d5ef6c004574f2b Mon Sep 17 00:00:00 2001 From: John McDowell <11021373+johnmcdowell@users.noreply.github.com> Date: Thu, 2 May 2024 13:43:16 -0700 Subject: [PATCH 25/33] vscode 1.85 in Nov 2023 deprecated "source.fixAll.eslint": true --- .vscode/settings.json | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 2296389..eccda49 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,19 +1,17 @@ { - "i18n-ally.localesPaths": [ - "public/locales" - ], - "i18n-ally.keystyle": "nested", - "eslint.validate": [ - "javascript", - "javascriptreact", - "typescript", - "typescriptreact" - ], - "editor.codeActionsOnSave": { - "source.fixAll.eslint": true - }, - "editor.renderWhitespace": "all", - "editor.formatOnSave": true, - "eslint.format.enable": true, - "eslint.run": "onType" -} \ No newline at end of file + "i18n-ally.localesPaths": ["public/locales"], + "i18n-ally.keystyle": "nested", + "eslint.validate": [ + "javascript", + "javascriptreact", + "typescript", + "typescriptreact" + ], + "editor.codeActionsOnSave": { + "source.fixAll.eslint": "explicit" + }, + "editor.renderWhitespace": "all", + "editor.formatOnSave": true, + "eslint.format.enable": true, + "eslint.run": "onType" +} From d1ac40fdb9e5cba550c394d8332607cf69d07fa4 Mon Sep 17 00:00:00 2001 From: John McDowell <11021373+johnmcdowell@users.noreply.github.com> Date: Sat, 4 May 2024 01:16:43 -0700 Subject: [PATCH 26/33] minor wording tweaks --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b3cc768..9dcb23d 100644 --- a/README.md +++ b/README.md @@ -11,8 +11,8 @@ This is an app for Apple Silicon Macs. It will not work on Intel macs. Do you ha ### Installation - Option 1: install the app through brew with `brew install battery` -- Option 2: [download the latest app dmg version here](https://github.com/actuallymentor/battery/releases/) -- Option 3: command-line only installation (see section below) +- Option 2: [download the app dmg version here](https://github.com/actuallymentor/battery/releases/) +- Option 3: install ONLY the command line interface (see section below) When installing via brew or dmg, opening the macOS app is required to complete the installation. From 0f163af64053d2e623bc2343b364d1e0a455b30e Mon Sep 17 00:00:00 2001 From: Ryan Burnett Date: Tue, 14 May 2024 09:37:46 -0400 Subject: [PATCH 27/33] Update README.md Changed "Enabled charging when your battery is under 80% charged" to "Enables charging when your battery is under 80% charged" --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8496fa1..37a0822 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ The first time you open the app, it will ask for your administator password so i - Discharges your battery until it reaches 80%, **even when plugged in** - Disables charging when your battery is above 80% charged -- Enabled charging when your battery is under 80% charged +- Enables charging when your battery is under 80% charged - Keeps the limit engaged even after rebooting - Keeps the limit engaged even after closing the tray app - Also automatically installs the `battery` command line tool. If you want a custom charging percentage, the CLI is the only way to do that. From e025614d268d8d3ee708cc5486b77a6f395d2362 Mon Sep 17 00:00:00 2001 From: Rene Date: Wed, 17 Jan 2024 20:07:12 +0100 Subject: [PATCH 28/33] voltage limit draft --- battery.sh | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/battery.sh b/battery.sh index e12e263..058aca8 100755 --- a/battery.sh +++ b/battery.sh @@ -228,6 +228,11 @@ function get_maintain_percentage() { echo "$maintain_percentage" } +function get_voltage() { + voltage=$(ioreg -l -n AppleSmartBattery -r | grep "\"Voltage\" =" | awk '{ print $3/1000 }') + echo "$voltage" +} + ## ############### ## Actions ## ############### @@ -429,6 +434,34 @@ if [[ "$action" == "discharge" ]]; then fi +# Voltage min/max controller +if [[ "$action" == "voltage" ]]; then + + voltage=$(get_voltage) + log "Keeping voltage between ${setting}V and ${subsetting}V" + + # Loop + while true; do + is_charging=$(get_smc_charging_status) + + log "Battery at ${voltage}V" + + if (( $(echo "$voltage < $setting" | bc -l) && "$is_charging" == "disabled" )); then + enable_charging + fi + if (( $(echo "$voltage >= $subsetting" | bc -l) && "$is_charging" == "enabled" )); then + disable_charging + fi + + caffeinate -is sleep 60 + voltage=$(get_voltage) + + done + + exit 0 + +fi + # Maintain at level if [[ "$action" == "maintain_synchronous" ]]; then @@ -548,7 +581,7 @@ fi # Status logger if [[ "$action" == "status" ]]; then - log "Battery at $(get_battery_percentage)% ($(get_remaining_time) remaining), smc charging $(get_smc_charging_status)" + log "Battery at $(get_battery_percentage)% ($(get_remaining_time) remaining), $(get_voltage)V, smc charging $(get_smc_charging_status)" if test -f $pidfile; then maintain_percentage=$(cat $maintain_percentage_tracker_file 2>/dev/null) log "Your battery is currently being maintained at $maintain_percentage%" From f50bad8f3cfc962472d9b42dcc795b87792102d3 Mon Sep 17 00:00:00 2001 From: Rene Date: Wed, 17 Jan 2024 20:33:26 +0100 Subject: [PATCH 29/33] fix brackets --- battery.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/battery.sh b/battery.sh index 058aca8..c45a781 100755 --- a/battery.sh +++ b/battery.sh @@ -446,10 +446,10 @@ if [[ "$action" == "voltage" ]]; then log "Battery at ${voltage}V" - if (( $(echo "$voltage < $setting" | bc -l) && "$is_charging" == "disabled" )); then + if (( $(echo "$voltage < $setting" | bc -l) )) && [[ "$is_charging" == "disabled" ]]; then enable_charging fi - if (( $(echo "$voltage >= $subsetting" | bc -l) && "$is_charging" == "enabled" )); then + if (( $(echo "$voltage >= $subsetting" | bc -l) )) && [[ "$is_charging" == "enabled" ]]; then disable_charging fi From fa2028d2e359ff616e208c11110d41fc8b3e53bb Mon Sep 17 00:00:00 2001 From: Rene Date: Wed, 20 Mar 2024 09:05:50 +0100 Subject: [PATCH 30/33] add support for ',' decimal seperator --- battery.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/battery.sh b/battery.sh index c45a781..6fcaeef 100755 --- a/battery.sh +++ b/battery.sh @@ -229,7 +229,7 @@ function get_maintain_percentage() { } function get_voltage() { - voltage=$(ioreg -l -n AppleSmartBattery -r | grep "\"Voltage\" =" | awk '{ print $3/1000 }') + voltage=$(ioreg -l -n AppleSmartBattery -r | grep "\"Voltage\" =" | awk '{ print $3/1000 }' | tr ',' '.') echo "$voltage" } From 827f271eb64484a4162ce37c0eb32b5a57c90080 Mon Sep 17 00:00:00 2001 From: Rene Date: Wed, 19 Jun 2024 22:07:09 +0200 Subject: [PATCH 31/33] added voltage maintenance to daemon --- battery.sh | 157 ++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 120 insertions(+), 37 deletions(-) diff --git a/battery.sh b/battery.sh index 6fcaeef..9cb7642 100755 --- a/battery.sh +++ b/battery.sh @@ -19,8 +19,15 @@ configfolder=$HOME/.battery pidfile=$configfolder/battery.pid logfile=$configfolder/battery.log maintain_percentage_tracker_file=$configfolder/maintain.percentage +maintain_voltage_tracker_file=$configfolder/maintain.voltage daemon_path=$HOME/Library/LaunchAgents/battery.plist +# Voltage limits +voltage_min="10.5" +voltage_max="12.6" +voltage_hyst_min="0.1" +voltage_hyst_max="2" + ## ############### ## Housekeeping ## ############### @@ -51,12 +58,18 @@ Usage: output logs of the battery CLI and GUI eg: battery logs 100 - battery maintain LEVEL[1-100,stop] + 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 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 + default hysteresis: 0.1V + eg: battery maintain 11.4V # keeps battery between 11.3V and 11.5V + eg: battery maintain 11.4V 0.3V # keeps battery between 11.1V and 11.7V + battery charging SETTING[on/off] manually set the battery to (not) charge eg: battery charging on @@ -434,34 +447,6 @@ if [[ "$action" == "discharge" ]]; then fi -# Voltage min/max controller -if [[ "$action" == "voltage" ]]; then - - voltage=$(get_voltage) - log "Keeping voltage between ${setting}V and ${subsetting}V" - - # Loop - while true; do - is_charging=$(get_smc_charging_status) - - log "Battery at ${voltage}V" - - if (( $(echo "$voltage < $setting" | bc -l) )) && [[ "$is_charging" == "disabled" ]]; then - enable_charging - fi - if (( $(echo "$voltage >= $subsetting" | bc -l) )) && [[ "$is_charging" == "enabled" ]]; then - disable_charging - fi - - caffeinate -is sleep 60 - voltage=$(get_voltage) - - done - - exit 0 - -fi - # Maintain at level if [[ "$action" == "maintain_synchronous" ]]; then @@ -526,6 +511,54 @@ if [[ "$action" == "maintain_synchronous" ]]; then fi +# Maintain at voltage +if [[ "$action" == "maintain_voltage_synchronous" ]]; then + + # Recover old maintain status if old setting is found + if [[ "$setting" == "recover" ]]; then + + # Before doing anything, log out environment details as a debugging trail + log "Debug trail. User: $USER, config folder: $configfolder, logfile: $logfile, file called with 1: $1, 2: $2" + + maintain_voltage=$(cat $maintain_voltage_tracker_file 2>/dev/null) + if [[ $maintain_voltage ]]; then + log "Recovering maintenance voltage $maintain_voltage" + setting=$(echo $maintain_voltage | awk '{print $1}') + subsetting=$(echo $maintain_voltage | awk '{print $2}') + else + log "No setting to recover, exiting" + exit 0 + fi + fi + + voltage=$(get_voltage) + lower_voltage=$(echo "$setting - $subsetting" | bc -l) + upper_voltage=$(echo "$setting + $subsetting" | bc -l) + log "Keeping voltage between ${lower_voltage}V and ${upper_voltage}V" + + # Loop + while true; do + is_charging=$(get_smc_charging_status) + + if (( $(echo "$voltage < $lower_voltage" | bc -l) )) && [[ "$is_charging" == "disabled" ]]; then + log "Battery at ${voltage}V" + enable_charging + fi + if (( $(echo "$voltage >= $upper_voltage" | bc -l) )) && [[ "$is_charging" == "enabled" ]]; then + log "Battery at ${voltage}V" + disable_charging + fi + + sleep 60 + + voltage=$(get_voltage) + + done + + exit 0 + +fi + # Asynchronous battery level maintenance if [[ "$action" == "maintain" ]]; then @@ -545,8 +578,30 @@ if [[ "$action" == "maintain" ]]; then exit 0 fi + # Check if setting is a voltage + is_voltage=false + if [[ "$setting" =~ ^[0-9]+(\.[0-9]+)?V$ ]]; then + setting="${setting//V}" + + if [[ "$subsetting" =~ ^[0-9]+(\.[0-9]+)?V$ ]]; then + subsetting="${subsetting//V}" + else + subsetting="0.1" + fi + + if (( $(echo "$setting < $voltage_min" | bc -l) || $(echo "$setting > $voltage_max" | bc -l) )); then + log "Error: ${setting}V is not a valid setting. Please use a value between ${voltage_min}V and ${voltage_max}V" + exit 1 + fi + if (( $(echo "$subsetting < $voltage_hyst_min" | bc -l) || $(echo "$subsetting > $voltage_max" | bc -l) )); then + log "Error: ${subsetting}V is not a valid setting. Please use a value between ${voltage_hyst_min}V and ${voltage_hyst_max}V" + exit 1 + fi + + is_voltage=true + # Check if setting is value between 0 and 100 - if ! [[ "$setting" =~ ^[0-9]+$ ]] || [[ "$setting" -lt 0 ]] || [[ "$setting" -gt 100 ]]; then + elif ! [[ "$setting" =~ ^[0-9]+$ ]] || [[ "$setting" -lt 0 ]] || [[ "$setting" -gt 100 ]]; then log "Called with $setting $action" # If non 0-100 setting is not a special keyword, exit with an error. @@ -557,18 +612,35 @@ if [[ "$action" == "maintain" ]]; then fi + exit 1 + # Start maintenance script - log "Starting battery maintenance at $setting% $subsetting" - nohup battery maintain_synchronous $setting $subsetting >>$logfile & + if [ "$is_voltage" = true ]; then + log "Starting battery maintenance at ${setting}V ±${subsetting}V" + nohup battery maintain_voltage_synchronous $setting $subsetting >>$logfile & + else + log "Starting battery maintenance at $setting% $subsetting" + nohup battery maintain_synchronous $setting $subsetting >>$logfile & + fi # Store pid of maintenance process and setting echo $! >$pidfile pid=$(cat "$pidfile" 2>/dev/null) if ! [[ "$setting" == "recover" ]]; then - log "Writing new setting $setting to $maintain_percentage_tracker_file" - echo $setting >$maintain_percentage_tracker_file - log "Maintaining battery at $setting%" + + rm "$maintain_percentage_tracker_file" "$maintain_voltage_tracker_file" 2> /dev/null + + if [[ "$is_voltage" = true ]]; then + log "Writing new setting $setting $subsetting to $maintain_voltage_tracker_file" + echo "$setting $subsetting" >$maintain_voltage_tracker_file + log "Maintaining battery at ${setting}V ±${subsetting}V" + + else + log "Writing new setting $setting to $maintain_percentage_tracker_file" + echo $setting >$maintain_percentage_tracker_file + log "Maintaining battery at $setting%" + fi fi # Enable the daemon that continues maintaining after reboot @@ -584,7 +656,13 @@ if [[ "$action" == "status" ]]; then log "Battery at $(get_battery_percentage)% ($(get_remaining_time) remaining), $(get_voltage)V, smc charging $(get_smc_charging_status)" if test -f $pidfile; then maintain_percentage=$(cat $maintain_percentage_tracker_file 2>/dev/null) - log "Your battery is currently being maintained at $maintain_percentage%" + if [[ $maintain_percentage ]]; then + maintain_level="$maintain_percentage%" + else + maintain_level=$(cat $maintain_voltage_tracker_file 2>/dev/null) + maintain_level=$(echo "$maintain_level" | awk '{print $1 "V ±" $2 "V"}') + fi + log "Your battery is currently being maintained at $maintain_level" fi exit 0 @@ -600,6 +678,11 @@ fi # launchd daemon creator, inspiration: https://www.launchd.info/ if [[ "$action" == "create_daemon" ]]; then + call_action="maintain_synchronous" + if test -f "$maintain_voltage_tracker_file"; then + call_action="maintain_voltage_synchronous" + fi + daemon_definition=" @@ -610,7 +693,7 @@ if [[ "$action" == "create_daemon" ]]; then ProgramArguments $binfolder/battery - maintain_synchronous + $call_action recover StandardOutPath From af2e61ebc4b32a2a33341b99b35328882b0029db Mon Sep 17 00:00:00 2001 From: Rene Date: Wed, 19 Jun 2024 22:11:26 +0200 Subject: [PATCH 32/33] remove testing code --- battery.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/battery.sh b/battery.sh index 9cb7642..875595a 100755 --- a/battery.sh +++ b/battery.sh @@ -612,8 +612,6 @@ if [[ "$action" == "maintain" ]]; then fi - exit 1 - # Start maintenance script if [ "$is_voltage" = true ]; then log "Starting battery maintenance at ${setting}V ±${subsetting}V" From 0be64aeb33d5442cecfbda773dbe4b197d62ba33 Mon Sep 17 00:00:00 2001 From: Mentor Date: Fri, 28 Jun 2024 11:30:00 +0200 Subject: [PATCH 33/33] =?UTF-8?q?=F0=9F=90=9B=20fix=20syntax=20errors=20in?= =?UTF-8?q?troduced=20in=20pull=20request=20merged?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- battery.sh | 146 +++++++++++++++++++++++++++-------------------------- 1 file changed, 74 insertions(+), 72 deletions(-) diff --git a/battery.sh b/battery.sh index c1c042e..be2c3a3 100755 --- a/battery.sh +++ b/battery.sh @@ -4,7 +4,7 @@ ## Update management ## variables are used by this binary as well at the update script ## ############### -BATTERY_CLI_VERSION="v1.1.5" +BATTERY_CLI_VERSION="v1.2.2" # Path fixes for unexpected environments PATH=/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin @@ -418,8 +418,8 @@ if [[ "$action" == "adapter" ]]; then enable_discharging elif [[ "$setting" == "off" ]]; then disable_discharging - else - log "Error: $setting is not \"on\" or \"off\"." + else + log "Error: $setting is not \"on\" or \"off\"." exit 1 fi @@ -432,7 +432,7 @@ if [[ "$action" == "charge" ]]; then if ! valid_percentage "$setting"; then log "Error: $setting is not a valid setting for battery charge. Please use a number between 0 and 100" - exit 1 + exit 1 fi # Disable running daemon @@ -449,10 +449,10 @@ if [[ "$action" == "charge" ]]; then # Loop until battery percent is exceeded while [[ "$battery_percentage" -lt "$setting" ]]; do - if [[ "$battery_percentage" -ge "$((setting-3))" ]]; then + if [[ "$battery_percentage" -ge "$((setting - 3))" ]]; then sleep 20 else - caffeinate -is sleep 60 + caffeinate -is sleep 60 fi done @@ -469,7 +469,7 @@ if [[ "$action" == "discharge" ]]; then if ! valid_percentage "$setting"; then log "Error: $setting is not a valid setting for battery discharge. Please use a number between 0 and 100" - exit 1 + exit 1 fi # Start charging @@ -493,7 +493,7 @@ fi # Maintain at level if [[ "$action" == "maintain_synchronous" ]]; then - + # Checking if the calibration process is running if test -f "$calibrate_pidfile"; then pid=$(cat "$calibrate_pidfile" 2>/dev/null) @@ -503,7 +503,7 @@ if [[ "$action" == "maintain_synchronous" ]]; then if ! validate_percentage "$setting"; then log "Error: $setting is not a valid setting for battery maintain. Please use a number between 0 and 100" - exit 1 + exit 1 fi # Recover old maintain status if old setting is found @@ -544,7 +544,7 @@ 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 "$setting" && ("$is_charging" == "enabled" || "$ac_attached" == "1") ]]; then log "Charge above $setting" if [[ "$is_charging" == "enabled" ]]; then @@ -573,22 +573,22 @@ fi # Maintain at voltage if [[ "$action" == "maintain_voltage_synchronous" ]]; then - # Recover old maintain status if old setting is found - if [[ "$setting" == "recover" ]]; then + # Recover old maintain status if old setting is found + if [[ "$setting" == "recover" ]]; then - # Before doing anything, log out environment details as a debugging trail - log "Debug trail. User: $USER, config folder: $configfolder, logfile: $logfile, file called with 1: $1, 2: $2" + # Before doing anything, log out environment details as a debugging trail + log "Debug trail. User: $USER, config folder: $configfolder, logfile: $logfile, file called with 1: $1, 2: $2" - maintain_voltage=$(cat $maintain_voltage_tracker_file 2>/dev/null) - if [[ $maintain_voltage ]]; then - log "Recovering maintenance voltage $maintain_voltage" - setting=$(echo $maintain_voltage | awk '{print $1}') - subsetting=$(echo $maintain_voltage | awk '{print $2}') - else - log "No setting to recover, exiting" - exit 0 - fi - fi + maintain_voltage=$(cat $maintain_voltage_tracker_file 2>/dev/null) + if [[ $maintain_voltage ]]; then + log "Recovering maintenance voltage $maintain_voltage" + setting=$(echo $maintain_voltage | awk '{print $1}') + subsetting=$(echo $maintain_voltage | awk '{print $2}') + else + log "No setting to recover, exiting" + exit 0 + fi + fi voltage=$(get_voltage) lower_voltage=$(echo "$setting - $subsetting" | bc -l) @@ -599,12 +599,12 @@ if [[ "$action" == "maintain_voltage_synchronous" ]]; then while true; do is_charging=$(get_smc_charging_status) - if (( $(echo "$voltage < $lower_voltage" | bc -l) )) && [[ "$is_charging" == "disabled" ]]; then - log "Battery at ${voltage}V" + if (($(echo "$voltage < $lower_voltage" | bc -l))) && [[ "$is_charging" == "disabled" ]]; then + log "Battery at ${voltage}V" enable_charging fi - if (( $(echo "$voltage >= $upper_voltage" | bc -l) )) && [[ "$is_charging" == "enabled" ]]; then - log "Battery at ${voltage}V" + if (($(echo "$voltage >= $upper_voltage" | bc -l))) && [[ "$is_charging" == "enabled" ]]; then + log "Battery at ${voltage}V" disable_charging fi @@ -641,27 +641,28 @@ if [[ "$action" == "maintain" ]]; then exit 0 fi - # Check if setting is a voltage - is_voltage=false - if [[ "$setting" =~ ^[0-9]+(\.[0-9]+)?V$ ]]; then - setting="${setting//V}" + # Check if setting is a voltage + is_voltage=false + if [[ "$setting" =~ ^[0-9]+(\.[0-9]+)?V$ ]]; then + setting="${setting//V/}" - if [[ "$subsetting" =~ ^[0-9]+(\.[0-9]+)?V$ ]]; then - subsetting="${subsetting//V}" - else - subsetting="0.1" - fi + if [[ "$subsetting" =~ ^[0-9]+(\.[0-9]+)?V$ ]]; then + subsetting="${subsetting//V/}" + else + subsetting="0.1" + fi - if (( $(echo "$setting < $voltage_min" | bc -l) || $(echo "$setting > $voltage_max" | bc -l) )); then - log "Error: ${setting}V is not a valid setting. Please use a value between ${voltage_min}V and ${voltage_max}V" - exit 1 - fi - if (( $(echo "$subsetting < $voltage_hyst_min" | bc -l) || $(echo "$subsetting > $voltage_max" | bc -l) )); then - log "Error: ${subsetting}V is not a valid setting. Please use a value between ${voltage_hyst_min}V and ${voltage_hyst_max}V" - exit 1 - fi + if (($(echo "$setting < $voltage_min" | bc -l) || $(echo "$setting > $voltage_max" | bc -l))); then + log "Error: ${setting}V is not a valid setting. Please use a value between ${voltage_min}V and ${voltage_max}V" + exit 1 + fi + if (($(echo "$subsetting < $voltage_hyst_min" | bc -l) || $(echo "$subsetting > $voltage_max" | bc -l))); then + log "Error: ${subsetting}V is not a valid setting. Please use a value between ${voltage_hyst_min}V and ${voltage_hyst_max}V" + exit 1 + fi - is_voltage=true + is_voltage=true + fi # Check if setting is value between 0 and 100 if ! valid_percentage "$setting"; then @@ -678,11 +679,11 @@ if [[ "$action" == "maintain" ]]; then log "Starting battery maintenance at $setting% $subsetting" nohup $battery_binary maintain_synchronous $setting $subsetting >>$logfile & if [ "$is_voltage" = true ]; then - log "Starting battery maintenance at ${setting}V ±${subsetting}V" - nohup battery maintain_voltage_synchronous $setting $subsetting >>$logfile & + log "Starting battery maintenance at ${setting}V ±${subsetting}V" + nohup battery maintain_voltage_synchronous $setting $subsetting >>$logfile & else - log "Starting battery maintenance at $setting% $subsetting" - nohup battery maintain_synchronous $setting $subsetting >>$logfile & + log "Starting battery maintenance at $setting% $subsetting" + nohup battery maintain_synchronous $setting $subsetting >>$logfile & fi # Store pid of maintenance process and setting @@ -691,18 +692,19 @@ if [[ "$action" == "maintain" ]]; then if ! [[ "$setting" == "recover" ]]; then - rm "$maintain_percentage_tracker_file" "$maintain_voltage_tracker_file" 2> /dev/null + rm "$maintain_percentage_tracker_file" "$maintain_voltage_tracker_file" 2>/dev/null - if [[ "$is_voltage" = true ]]; then - log "Writing new setting $setting $subsetting to $maintain_voltage_tracker_file" - echo "$setting $subsetting" >$maintain_voltage_tracker_file - log "Maintaining battery at ${setting}V ±${subsetting}V" + if [[ "$is_voltage" = true ]]; then + log "Writing new setting $setting $subsetting to $maintain_voltage_tracker_file" + echo "$setting $subsetting" >$maintain_voltage_tracker_file + log "Maintaining battery at ${setting}V ±${subsetting}V" + + else + log "Writing new setting $setting to $maintain_percentage_tracker_file" + echo $setting >$maintain_percentage_tracker_file + log "Maintaining battery at $setting%" + fi - else - log "Writing new setting $setting to $maintain_percentage_tracker_file" - echo $setting >$maintain_percentage_tracker_file - log "Maintaining battery at $setting%" - fi fi # Enable the daemon that continues maintaining after reboot @@ -734,7 +736,7 @@ if [[ "$action" == "calibrate_synchronous" ]]; then done # Wait before discharging to target level - log "reached 100%, maintaining for 1 hour" + log "reached 100%, maintaining for 1 hour" sleep 3600 # Discharge battery to 80% @@ -757,7 +759,7 @@ if [[ "$action" == "calibrate" ]]; then log "Killing running calibration daemon" kill $calibrate_pidfile &>/dev/null rm $calibrate_pidfile 2>/dev/null - + exit 0 fi @@ -777,10 +779,10 @@ if [[ "$action" == "status" ]]; then if test -f $pidfile; then maintain_percentage=$(cat $maintain_percentage_tracker_file 2>/dev/null) if [[ $maintain_percentage ]]; then - maintain_level="$maintain_percentage%" + maintain_level="$maintain_percentage%" else - maintain_level=$(cat $maintain_voltage_tracker_file 2>/dev/null) - maintain_level=$(echo "$maintain_level" | awk '{print $1 "V ±" $2 "V"}') + maintain_level=$(cat $maintain_voltage_tracker_file 2>/dev/null) + maintain_level=$(echo "$maintain_level" | awk '{print $1 "V ±" $2 "V"}') fi log "Your battery is currently being maintained at $maintain_level" fi @@ -798,10 +800,10 @@ fi # launchd daemon creator, inspiration: https://www.launchd.info/ if [[ "$action" == "create_daemon" ]]; then - call_action="maintain_synchronous" - if test -f "$maintain_voltage_tracker_file"; then - call_action="maintain_voltage_synchronous" - fi + call_action="maintain_synchronous" + if test -f "$maintain_voltage_tracker_file"; then + call_action="maintain_voltage_synchronous" + fi daemon_definition=" @@ -881,16 +883,16 @@ if [[ "$action" == "logs" ]]; then echo -e "👾 Battery CLI logs:\n" tail -n $amount $logfile - echo -e "\n🖥️ Battery GUI logs:\n" + echo -e "\n🖥️ Battery GUI logs:\n" tail -n $amount "$configfolder/gui.log" echo -e "\n📁 Config folder details:\n" ls -lah $configfolder - echo -e "\n⚙️ Battery data:\n" + echo -e "\n⚙️ Battery data:\n" $battery_binary status $battery_binary | grep -E "v\d.*" exit 0 -fi \ No newline at end of file +fi