RSS Amplifier

Blogs by otaku - Coding Otaku · Nov 2, 2025

Setting Charge Level Threshold in Lenovo Laptops

0
Sign in to vote or save

Coding Otaku · Coding Otaku

Looking at /sys/class/power_supply/BAT0/capacity_level, I see that the capacity is stored in 0-100 percentage values. This makes things easier.

What we need to modify are the following:

  1. Set when to stop charging: /sys/class/power_supply/BAT0/charge_stop_threshold
  2. Set until when the battery should start charging when plugged in: /sys/class/power_supply/BAT0/charge_start_threshold

The charge_start_threshold used to confuse me. So a table would help.

Assume that charge_start_threshold is 50, and charge_stop_threshold is 100.

Current Battery LevelCurrent Battery StatusNew Battery Status
45DischargingCharging
45ChargingCharging
55DischargingNot Charging
55ChargingCharging

The key one is the last two rows, if the battery level is above the charge_stop_threshold and is unplugged, it would not charge the battery. But If the batter was already charging and hit the charge_start_threshold, it would continue to charge until charge_stop_threshold is met.

I also noticed that when the charge_start_threshold needs to be changed, the kernel would not allow setting it above charge_stop_threshold. The reverse is also true.

Keeping it all in mind, I will set three battery profiles.

ProfileCharge startCharge stop
Home4550
Away7580
Full95100

Like all my other utility scripts, this will also use fzf.

Selecting profile

profile=$(printf 'Home\t45%%\t50%%\nAway\t75%%\t80%%\nFull\t95%%\t100%%' | fzf --height=6 --header="$(printf 'Type\tStart\tMax')" --layout=reverse --prompt='Charge level > ' | cut -f1)

This gives me a tabular view of the profiles and charge level in case I forget the values.

Functions to set charge levels

set_start() {
    echo "${1}" | sudo tee /sys/class/power_supply/BAT0/charge_start_threshold >/dev/null
}
set_stop() {
    echo "${1}" | sudo tee /sys/class/power_supply/BAT0/charge_stop_threshold >/dev/null
}

Now that I am looking at this, I probably should remove sudo dependency from the script. But I use it excessively in my daily life, feel free to remove it or replace it with other tools.

Set charge level based on selected profile

if [ "${profile}" = "Home" ]; then
    set_start 45
    set_stop 50
elif [ "${profile}" = "Away" ]; then
    start=$(head -n 1 /sys/class/power_supply/BAT0/charge_start_threshold)
    # Handle charge level conflict
    if [ "${start}" -gt 75 ]; then
        set_stop 80
        set_start 75
    else
        set_start 75
        set_stop 80
    fi
elif [ "${profile}" = "Full" ]; then
    set_stop 100
    set_start 95
else
    exit 137
fi

The complete script

Combine them all, and ensure POSIX compatibility.

#!/usr/bin/env sh
profile=$(printf 'Home\t45%%\t50%%\nAway\t75%%\t80%%\nFull\t95%%\t100%%' | fzf --height=6 --header="$(printf 'Type\tStart\tMax')" --layout=reverse --prompt='Charge level > ' | cut -f1)
set_start() {
    echo "${1}" | sudo tee /sys/class/power_supply/BAT0/charge_start_threshold >/dev/null
}
set_stop() {
    echo "${1}" | sudo tee /sys/class/power_supply/BAT0/charge_stop_threshold >/dev/null
}
if [ "${profile}" = "Home" ]; then
    set_start 45
    set_stop 50
elif [ "${profile}" = "Away" ]; then
    start=$(head -n 1 /sys/class/power_supply/BAT0/charge_start_threshold)
    if [ "${start}" -gt 75 ]; then
        set_stop 80
        set_start 75
    else
        set_start 75
        set_stop 80
    fi
elif [ "${profile}" = "Full" ]; then
    set_stop 100
    set_start 95
else
    exit 137
fi

Read the original on codingotaku.com

Comments

Nothing yet. Say the first thing.

    Sign in to join the conversation.