‹ back home

Setting a battery charge threshold

2023-11-24 #alpine #hardware #openrc

Modern batteries degrade faster if continuously charged to 100%. Some vendors provide software implementations to avoid continuously feeding the battery when full to avoid overloading it. Usually this is tricky, since they have to invent some kind of mechanism to determine whether the user wants the battery fully charged or not.

In the case of my laptop, the grand majority of my usages happens while plugged into a power source. Continuously charging the battery in this state merely serves to reduce its battery life and keep it warm, neither of which is desirable.

I decided to set the maximum charge to 80% to avoid this. Sadly, I don’t have a second identical laptop to use as control group, so I’ll never know if this has the impact that I expect. The theory indicates that it should.

Setting the threshold

The Linux battery driver exposes a value to configure the charge threshold. Changing it is as simple as writing a number into the charge_stop_threshold file:

echo 80 > /sys/class/power_supply/BAT0/charge_stop_threshold

The above won’t work unless it is executed as root. The following approach works as an unprivileged user:

echo 80 | doas tee /sys/class/power_supply/BAT0/charge_stop_threshold

However, when the system reboots, the driver is loaded in its default state, and this setting is not preserved. It needs to be specified at each start-up.

Running a command after each start-up

I could write a system service that does this, but it seems like an overkill for a one-liner.

Alpine currently uses OpenRC, which includes a very simple mechanism to run custom scripts during start-up. Basically, they just need to be placed in the /etc/local.d/ directory, with the extension .start.

The main caveat to keep in mind is that these scripts are in a blocking manner; the next service won’t start until they’re done. Fortunately, this specific script is near-instantaneous, so this isn’t a problem.

For a more in-depth explanation on this feature, see the relevant article in the Gentoo wiki.

Setting the threshold after each start-up

Create the file /etc/local.d/20-batery-threshold.start:

#!/bin/sh

for battery in /sys/class/power_supply/*/charge_stop_threshold; do
	echo 80 > $battery;
done

Make it executable:

doas chmod +x /etc/local.d/20-batery-threshold.start

Enable and start the local service:

doas rc-update add local default
doas service local start

Over-engineering this idea

It would be useful to have a privileged daemon that lets me change this at runtime (likely via a control socket). I could then have a widget in my status bar that indicates the current threshold and lets me toggle it.

For now, the above approach is sufficient.

Have comments or want to discuss this topic?
Send an email to my public inbox: ~whynothugo/public-inbox@lists.sr.ht.
Or feel free to reply privately by email: hugo@whynothugo.nl.

— § —