tshakalekholoane / bat

Battery management utility for Linux laptops.
https://tshaka.dev/x/bat
MIT License
280 stars 22 forks source link

Error setting (end) threshold on Lenovo ThinkPad T14 Gen1 when the start threshold is higher #97

Open SylChamber opened 1 month ago

SylChamber commented 1 month ago

Computer: Lenovo ThinkPad T14 Gen 1 AMD (manufactured in 2021) CPU: AMD Ryzen PRO 7 4750U OS: Ubuntu 24.04

I could not set a battery threshold on my Lenovo ThinkPad T14 Gen1 (while it works on my Asus ROG Strix G15 2021). I got the following error:

$ sudo bat threshold 80
A fatal error occurred. Please rerun the command with the `--debug` flag enabled
and file an issue with the resulting output at the following address
https://github.com/tshakalekholoane/bat/issues/new.

with the debug flag:

$ sudo bat threshold 80 --debug
write /sys/class/power_supply/BAT0/charge_control_end_threshold: invalid argument

goroutine 1 [running]:
runtime/debug.Stack()
    /opt/homebrew/Cellar/go/1.22.0/libexec/src/runtime/debug/stack.go:24 +0x5e
main.main.func1()
    /Users/tshaka/x/bat/main_linux.go:111 +0x57
panic({0x5383a0?, 0xc000124270?})
    /opt/homebrew/Cellar/go/1.22.0/libexec/src/runtime/panic.go:770 +0x132
main.main()
    /Users/tshaka/x/bat/main_linux.go:247 +0x1125

When searching on the battery system path, I found the UbuntuHandbook page on setting battery threshold. Trying to set the end threshold manually failed as well:

$ sudo sh -c "echo 80 > /sys/class/power_supply/BAT0/charge_control_end_threshold"
sh: 1: echo: echo: I/O error

It led me to try manually setting the lower charging threshold to a lower value than the end value:

sudo sh -c "echo 20 > /sys/class/power_supply/BAT0/charge_control_start_threshold"

Which I unfortunately did before trying to read the current value. :-( I don't know what it was before. Afterwards, I could set the end threshold, manually or with bat.

I gather that the end threshold must not be lower than the start threshold.

SylChamber commented 1 month ago

Uh... actually, I think I got the threshold backwards. I'm comparing with values on my Asus ROG Strix G15. It only has one value: charge_control_end_threshold. And I set it to 80. There is no start threshold.

My Lenovo ThinkPad T14 G1 has two thresholds:

as well as two legacy APIs that are supposedly synchronized with those two.

pepa65 commented 1 month ago

Thank you for reporting this. Do you have any idea how charge_control_start_threshold should be handled? It seems like it could be set by the user, but maybe there is a sane default, depending on charge_control_end_threshold..?

SylChamber commented 1 month ago

Yes, I found the way it works in the Device Compatibility section on ThinkPad in the Battery Health Charging GNOME extension documentation. It depends on the direction of the movement of the thresholds: up or down. The threshold closest to the target must be modified first. That's why bat failed to lower my ThinkPad's threshold from 100 to 80. It was decreasing the end threshold to a lower value than the start. And manually setting the start threshold to a lower value allowed bat to set the end threshold.

Battery Health Charging supports 3 profiles and their defaults define 5 percent windows with the sart/end thresholds:

If the thresholds are decreased (e.g. from 100 to 60), then charge_control_start_threshold must be set first (e.g. to 55), then charge_control_end_threshold (e.g. to 60):

echo '55' | sudo tee /sys/class/power_supply/BAT0/charge_control_start_threshold
echo '60' | sudo tee /sys/class/power_supply/BAT0/charge_control_end_threshold

If the thresholds are increased (e.g. from 60 to 80), then charge_control_end_threshold must be set first (e.g. to 80), then charge_control_start_threshold (e.g. to 75):

echo '80' | pkexec tee /sys/class/power_supply/BAT0/charge_control_end_threshold
echo '75' | pkexec tee /sys/class/power_supply/BAT0/charge_control_start_threshold
pepa65 commented 1 month ago

OK, I think just set the start value 5 lower than the end, and check which one needs to be set first.