aboutsummaryrefslogtreecommitdiff
path: root/.local/bin/bat-thresh-toggle
blob: cc5ca338d9d5b69c67f0f8688e6e5a452ad77873 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#!/bin/sh

THRESH_START_PATH="/sys/class/power_supply/BAT0/charge_control_start_threshold"
THRESH_STOP_PATH="/sys/class/power_supply/BAT0/charge_control_end_threshold"
TLP_DROP_IN="/etc/tlp.d/05-bat-thresh.conf"

TRAVEL_START=85
TRAVEL_STOP=97
DOCKED_START=75
DOCKED_STOP=87
DEFAULT_START=96
DEFAULT_STOP=100

usage() {
    cat <<EOF
usage: $(basename "$0") [OPTION]

toggles BAT0 charge thresholds between travel and docked modes,
writing a persistent TLP drop-in to ${TLP_DROP_IN}.

options:
  (none)             toggle between travel (${TRAVEL_START}/${TRAVEL_STOP}%) and docked (${DOCKED_START}/${DOCKED_STOP}%)
  -d                 restore TLP built-in defaults (${DEFAULT_START}/${DEFAULT_STOP}%) and remove drop-in
  -h, --help         show this help message and exit

modes:
  travel            START_CHARGE_THRESH_BAT0=${TRAVEL_START}    STOP_CHARGE_THRESH_BAT0=${TRAVEL_STOP}
  docked            START_CHARGE_THRESH_BAT0=${DOCKED_START}    STOP_CHARGE_THRESH_BAT0=${DOCKED_STOP}
  default (-d)      START_CHARGE_THRESH_BAT0=${DEFAULT_START}   STOP_CHARGE_THRESH_BAT0=${DEFAULT_STOP}

EOF
}

case "${1}" in
    -h|--help) usage; exit 0 ;;
esac

# gotta be root to write to sysfs
if [ "$(id -u)" -ne 0 ]; then
    usage
    sleep 1
    echo "error: script must be run as root."; echo ""
    exit 1
fi

# make sure the sysfs nodes are actually there
[ -f "$THRESH_START_PATH" ] || { echo "error: $THRESH_START_PATH not found — is thinkpad_acpi loaded?"; exit 1; }
[ -f "$THRESH_STOP_PATH" ]  || { echo "error: $THRESH_STOP_PATH not found — is thinkpad_acpi loaded?"; exit 1; }

# --system-default: remove drop-in and restore TLP built-in defaults (96/100)
if [ "${1}" = "-d" ]; then
    printf "%s" "$DEFAULT_STOP"  > "$THRESH_STOP_PATH"  || { echo "error: failed to write stop threshold.";  exit 1; }
    printf "%s" "$DEFAULT_START" > "$THRESH_START_PATH" || { echo "error: failed to write start threshold."; exit 1; }
    echo "restored system defaults — start: ${DEFAULT_START}%  stop: ${DEFAULT_STOP}%"
    if [ -f "$TLP_DROP_IN" ]; then
        rm "$TLP_DROP_IN" \
            && echo "${TLP_DROP_IN} removed — TLP will use its built-in defaults after reboot." \
            || echo "error: failed to remove ${TLP_DROP_IN}."
    else
        echo "note: ${TLP_DROP_IN} was not present — nothing to remove."
    fi
    exit 0
fi

current_stop=$(cat "$THRESH_STOP_PATH")

# determine which mode to switch INTO based on the current stop threshold
case "$current_stop" in
    "$TRAVEL_STOP")
        target_mode="docked"
        new_start="$DOCKED_START"
        new_stop="$DOCKED_STOP"
        ;;
    *)
        target_mode="travel"
        new_start="$TRAVEL_START"
        new_stop="$TRAVEL_STOP"
        ;;
esac

# the kernel enforces start < stop at all times, so write order matters
case "$target_mode" in
    travel)
        printf "%s" "$new_stop"  > "$THRESH_STOP_PATH"  || { echo "error: failed to write stop threshold.";  exit 1; }
        printf "%s" "$new_start" > "$THRESH_START_PATH" || { echo "error: failed to write start threshold."; exit 1; }
        ;;
    docked)
        printf "%s" "$new_start" > "$THRESH_START_PATH" || { echo "error: failed to write start threshold."; exit 1; }
        printf "%s" "$new_stop"  > "$THRESH_STOP_PATH"  || { echo "error: failed to write stop threshold.";  exit 1; }
        ;;
esac

echo "switched to $target_mode mode — start: ${new_start}%  stop: ${new_stop}%"

# write a dedicated drop-in so thresholds survive a reboot; no sed fragility
if [ -d "/etc/tlp.d" ]; then
    printf '# managed by bat-thresh-toggle — do not edit by hand\nSTART_CHARGE_THRESH_BAT0=%s\nSTOP_CHARGE_THRESH_BAT0=%s\n' \
        "$new_start" "$new_stop" > "$TLP_DROP_IN" \
        && echo "${TLP_DROP_IN} written" \
        || echo "error: failed to write ${TLP_DROP_IN}."
else
    echo "note: /etc/tlp.d not found - sysfs write is not persistent across reboots."
fi