Last active
March 18, 2023 22:51
-
-
Save WinkelCode/13be9bdec07f5f77a23b6181d580e6f6 to your computer and use it in GitHub Desktop.
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
#!/usr/bin/env bash | |
if [ "$EUID" != '0' ]; then | |
echo "This script must be run as root" | |
exit 1 | |
fi | |
# Or just run the parts below in the terminal as root! | |
mkdir -p '/var/lib/sd-battmgr/' | |
echo "Downloading script" | |
curl -fL https://gist.githubusercontent.com/WinkelCode/13be9bdec07f5f77a23b6181d580e6f6/raw/sd-battmgr.sh >'/var/lib/sd-battmgr/sd-battmgr.sh' | |
chmod +x '/var/lib/sd-battmgr/sd-battmgr.sh' | |
echo "Downloading systemd unit" | |
curl -fL https://gist.githubusercontent.com/WinkelCode/13be9bdec07f5f77a23b6181d580e6f6/raw/sd-battmgr.service >'/etc/systemd/system/sd-battmgr.service' | |
systemctl enable --now 'sd-battmgr.service' | |
sleep 2 | |
systemctl status 'sd-battmgr.service' |
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
[Unit] | |
Description=Steam Deck Battery Manager | |
[Service] | |
# Path to script, minimum charge, nominal charge | |
ExecStart='/var/lib/sd-battmgr/sd-battmgr.sh' 45 55 | |
User=root | |
Restart=always | |
[Install] | |
WantedBy=multi-user.target |
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
#!/usr/bin/env bash | |
set -e | |
batctrl_path='/usr/share/jupiter_controller_fw_updater/RA_bootloader_updater/linux_host_tools/BatCtrl' | |
min_charge="$1" | |
[[ "$min_charge" =~ ^[0-9]+$ ]] || { echo "Error: Invalid minimum charge level: '$min_charge'"; exit 1; } | |
nom_charge="$2" | |
[[ "$nom_charge" =~ ^[0-9]+$ ]] || { echo "Error: Invalid nominal charge level: '$nom_charge'"; exit 1; } | |
if [ "$EUID" != '0' ]; then | |
echo "This script must be run as root" | |
exit 1 | |
fi | |
log() { | |
echo "$(date -Is) (Batt@${bat_level}%) $1" | |
} | |
sanity_checks() { | |
[[ "$ac_status" =~ ^[01]$ ]] || { echo "Error: Unexpected value for ACAD/online: '$ac_status'"; exit 1; } | |
[[ "$bat_status" =~ ^(Unknown|Charging|Discharging|Full)$ ]] || { echo "Error: Unexpected value for BAT1/status: '$bat_status'"; exit 1; } | |
[[ "$bat_level" =~ ^[0-9]{1,3}$ ]] || { echo "Error: Unexpected value for BAT1/capacity: '$bat_level'"; exit 1; } | |
} | |
set_batt_mode() { | |
case "$1" in | |
'charge') | |
if [ "$bat_status" = 'Charging' ]; then | |
return | |
fi | |
log "Telling BatCtrl to charge" | |
$batctrl_path ChargeMode 2 &>/dev/null | |
;; | |
'idle') | |
if [ "$bat_status" = 'Unknown' ] || [ $bat_status = 'Full' ]; then | |
return | |
fi | |
log "Telling BatCtrl to idle" | |
$batctrl_path ChargeMode 1 &>/dev/null | |
;; | |
'discharge') | |
if [ "$bat_status" = 'Discharging' ]; then | |
return | |
fi | |
log "Telling BatCtrl to discharge" | |
$batctrl_path ChargeMode 0 &>/dev/null | |
;; | |
esac | |
} | |
ac_loop() { | |
if [ "$1" == 'init' ] && [ "$ac_status" = '1' ]; then | |
log "AC adapter connected, starting normal operation" | |
elif [ "$ac_status" = '0' ]; then | |
log "AC adapter not connected, waiting for AC power" | |
while [ "$ac_status" = "0" ]; do | |
sleep 5 | |
get_pwr_state aconly | |
done | |
log "AC adapter connected, resuming normal operation" | |
fi | |
} | |
get_pwr_state() { | |
if [ "$1" != 'aconly' ]; then | |
bat_status="$(cat /sys/class/power_supply/BAT1/status)" | |
bat_level="$(cat /sys/class/power_supply/BAT1/capacity)" | |
fi | |
ac_status="$(cat /sys/class/power_supply/ACAD/online)" | |
sanity_checks | |
} | |
# Main loop | |
# --------- | |
echo "$(date -Is) Starting battery manager with min_charge='${min_charge}%', nom_charge='${nom_charge}%'..." | |
get_pwr_state | |
ac_loop init | |
while true; do | |
get_pwr_state | |
ac_loop | |
case "$mode" in | |
'charge') | |
if [ "$bat_level" -ge "$nom_charge" ]; then | |
log "Battery at or above nominal charge level (>=${nom_charge}%), switching to idle mode" | |
mode="idle" | |
set_batt_mode idle | |
else | |
set_batt_mode charge | |
fi | |
;; | |
'idle') | |
if [ "$bat_level" -lt "$min_charge" ]; then | |
log "Battery below minimum charge level (<${min_charge}%), switching to charge mode" | |
mode="charge" | |
set_batt_mode charge | |
else | |
set_batt_mode idle | |
fi | |
;; | |
*) | |
log "Initializing charge behavior..." | |
if [ "$bat_level" -ge "$nom_charge" ]; then | |
log "Init: Found battery at or above nominal charge level (>=${nom_charge}%), starting in idle mode" | |
mode="idle" | |
set_batt_mode idle | |
elif [ "$bat_level" -lt "$min_charge" ]; then | |
log "Init: Found battery below minimum charge level (<${min_charge}%), starting in charge mode" | |
mode="charge" | |
set_batt_mode charge | |
else | |
log "Init: Found battery in normal range (=${min_charge}%-${nom_charge}%), starting in idle mode" | |
mode="idle" | |
set_batt_mode idle | |
fi | |
esac | |
sleep 5 | |
done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment