Instantly share code, notes, and snippets.

@cmavr8 /batsaver
Last active Aug 29, 2015

Embed
What would you like to do?
Thinkpad battery saver - Helps you prolong the service life of your Lenovo Thinkpad battery pack
#!/bin/bash
# Thinkpad battery saver - Helps you prolong the service life of your Lenovo Thinkpad battery pack
# By Chris Mavrakis - cmavrakis.com
# v0.2 - 6-May-15
# Intro:
# Based on this: http://www.batteryuniversity.com/learn/article/how_to_prolong_lithium_based_batteries and motivated by this: https://news.ycombinator.com/item?id=9487903
# One can do a few things to prolong battery life. Two of them are:
# 1. Reduce full charge Voltage to 4.00V/cell. This will give shorter run times, but battery should last double the time before needing replacement (measured in years of use).
# 2. Keep the battery at 50% State of charge while running off AC. This is user unfriendly, because you have to remember to charge the battery before heading off the grid, but is practical for laptops that are mostly used on AC, only occasionally taken to trips. 60% is chosen as the default value, but 50% should be used by the more conscious users.
# This is also useful for bringing your battery to "storage voltage", which is recommended for long-term storage of lithium packs. (Long-term: anything over a few hours)
# Prerequisites:
# - Tp_smapi kernel module (http://www.thinkwiki.org/wiki/Tp_smapi). Should be there in Ubuntu.
# - Willingness of the user to participate. Otherwise they may be left without power in the train :P.
# - Sudo access :(
# Usage:
# - Install in /usr/bin or ~/bin, or not...
# - Run as superuser: sudo batsaver [store | charge]
# Todo:
# - Reboot persistance
# - More tp_smapi's tricks available as options to the user
# Also see bathealth (https://gist.github.com/cmavr8/bdf591d8dc66290ae87a) for battery health/status monitoring.
############ CONFIGURATION ############
# State-Of-Charge (SOC) that should be used while in storage mode.
# Recommended values: 50-70%, or wherever the cells' voltage is around 3.80V.
SOC_store=60
# SOC to use when battery is expected to be full.
# System default is 98, which will keep the battery between 96 and 100%, giving max capacity but shortening service life.
# Recommended value: 96 (keeping battery between 94-98%, should be around 4.0V per cell).
SOC_full=96
# Battery to work on (no trailing slash)
bat="/sys/devices/platform/smapi/BAT0"
######## END OF CONFIGURATION #########
################ SETUP ################
# Delta for setting SOC thresholds
plusminus=2
# Thresholds for storage mode
SOC_store_high=$(($SOC_store + $plusminus))
SOC_store_low=$(($SOC_store - $plusminus))
# Thresholds for full charge mode
SOC_full_high=$(($SOC_full + $plusminus))
SOC_full_low=$(($SOC_full - $plusminus))
############# END OF SETUP ############
############## FUNCTIONS ##############
# Writes something to a file inside $bat directory.
# Parameters:
# $1: filename to write to
# $2: what to write in the file
function echotobat {
echo $2 > $bat/$1
}
# Discharges the battery down to the "storage" SOC.
function discharge {
# Get current SOC (state of charge)
SOC_current=$(cat $bat/remaining_percent)
while [ $SOC_current -gt $SOC_store_high ]
do
echo "SOC ($SOC_current) higher than threshold ($SOC_store_high). Discharging for 30 more seconds..."
echotobat force_discharge 1
sleep 30
SOC_current=$(cat $bat/remaining_percent)
done
# Turn discharging OFF
echotobat force_discharge 0
}
########## END OF FUNCTIONS ###########
# Main part starting
# Read user choice and act
case "$1" in
store)
# User wants to bring battery to storage voltage. Set charge start/stop thresholds to storage
echo Storage voltage mode.
echotobat stop_charge_thresh $SOC_store_high
echotobat start_charge_thresh $SOC_store_low
# If needed, bring the battery down to storage voltage
discharge
echo "The battery is at the correct storage level ($SOC_store_low% to $SOC_store_high%) or lower."
;;
charge)
# User wants a fully charged battery. Set charge start/stop thresholds to high values
echo "Charging fully... Program will exit, but battery will take some time to charge."
echotobat stop_charge_thresh $SOC_full_high
echotobat start_charge_thresh $SOC_full_low
# Cancel any discharging actions that may be pending
echotobat force_discharge 0
;;
*)
echo "Usage: sudo batsaver [store | charge]"
esac
echo All done.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment