Keeping my Thinkpad battery ship-shape on Ubuntu (19.10)

Recently, I felt like my laptop battery (Lenovo Thinkpad) was draining a lot faster than before. I’m not sure if something triggered a particular spike, but I looked into it and found it’s really easy for me to adopt better battery practices on Ubuntu.

First, to find out just how sad my battery is, I used the command

upower -i $(upower -e | grep '/battery')
  native-path:          BAT0
  vendor:               LGC
  model:                01AV457
  serial:               969
  power supply:         yes
  updated:              Wed 07 Aug 2019 01:56:41 PM ADT (40 seconds ago)
  has history:          yes
  has statistics:       yes
    present:             yes
    rechargeable:        yes
    state:               discharging
    warning-level:       none
    energy:              28.85 Wh
    energy-empty:        0 Wh
    energy-full:         40.02 Wh
    energy-full-design:  56 Wh
    energy-rate:         7.468 W
    voltage:             15.958 V
    time to empty:       3.9 hours
    percentage:          72%
    capacity:            70.8929%
    technology:          lithium-polymer
    icon-name:          'battery-full-symbolic'
  History (charge):
    1565197001	72.000	discharging
  History (rate):
    1565197001	7.468	discharging

My full battery is 56 Wh, and now it’s only 40 Wh two years in! Nearly a (16/56) = 30% decrease!

Whew. That means if I had 6.5 hours of battery life before, now I have only 5 hours.

So, I looked up online. The key things to do are

1) Change the threshold for starting/stopping battery charging, to stop the battery from charging to 100%
2) Keep the laptop plugged in more, and
3) Keep the laptop cool

Guess I need to figure out a way to use my laptop in bed without setting it on the blankets. Or, get a proper desk and table.

Here’s the deets.


For maximum lifespan if you rarely use the battery, set Custom charge thresholds to start charging at 40% capacity and stop at 50%, and keep the ThinkPad cool. The thresholds can be adjusted in the Battery Maintenance settings of the Lenovo Power Manager.

If you do use your battery somewhat frequently, set the start threshold at say 85% and stop at 90%. This will still give a good lifespan benefit over keeping it charged to 100%.

The simplest way to optimize for battery lifespan is to select Automatic in the Power Manager Battery Maintenance settings, and let it manage your battery charge thresholds for you.

And from

About battery discharge, it is better not to allow battery to reach full discharge before recharging it. Best care for Li battery is keeping it between 20-80 %. Avoid low discharge and overcharge . Battery drain should only be done to calibrate wrong battery recognition or if there is a battery problem.
Now, how to do this in Ubuntu? Turns out it’s really easy for thinkpads.

Note: TLP and ThinkPad-related packages below are available via the official Ubuntu repository. Nevertheless it is recommended to use the PPA to stay with the latest TLP version.

sudo add-apt-repository ppa:linrunner/tlp
sudo apt-get update 
sudo apt-get install tlp tlp-rdw 
sudo apt-get install tp-smapi-dkms acpi-call-dkms
rui@chaiX1YG2:~$ sudo tlp setcharge 70 90 BAT0
Setting temporary charge thresholds for BAT0:
  stop  = 90
  start = 70
rui@chaiX1YG2:~$ sudo tlp start
TLP started in battery mode

Or, for a permanent change, edit the file “/etc/default/tlp

rui@chaiX1YG2:~$ sudo vi /etc/default/tlp

And uncomment the lines (around line 273)


setting the thresholds to whatever you think is best.

Shortly before I head out, I’ll probably run
sudo tlp setcharge 70 80 BAT0
since 3 to 4 hours of battery life is plenty for me. But I do want to be conservative since my power button no longer works, so if it completely dies then I have to unscrew the back cover and unplug the battery + CMOS battery briefly, then plug in/screw in/plug in power charger in order to start it again. I really only have myself to blame, not thinkpad — I’m sure it has something to do with shorting 24V / 3 amps through the USB port when I was working on motor controller things for my final project in underactuated robotics. Yea… that wasn’t great, and I’m really impressed the laptop survived and the USB port even still works!


Bash timer script (for pomodoro / general use)

Whew every so often I feel very self conscious about my blog, especially the previous very messy half-notes post, so here is a nice clean code snippet to refresh the palate:

From 1 minute timer


# script to create timer in terminal
# Jason Atwood
# 2013/6/22

# Edited: Nouyang, 2019/08/05
# Added bell sound, speech of "your time is up", & popup notification
# Added bigger font option, window resizing
# And changed colors: red background by default, flashing green for time's up 
# Usage: `./ 25` & set terminal to "always on top" and "always on visible workspace"

# start up 
#echo "starting timer script ..." 
#sleep 1 # seconds

# get input from user
if [[ $1 ]]; then
    read -p "Timer for how many minutes? (Default 25) " -e DURATION 
    #read -p "Timer for how many minutes? " -i 25 -e DURATION 
    if [[ !DURATION ]]; then
DURATION=$(( $DURATION*60 )) # convert minutes to seconds

# get start time
START=$(date +%s)
setterm -term linux -back red -fore white # use setterm to change background color
printf '\e[8;4;1t'

# infinite loop
while [ -1 ]; do

	# do math	
	NOW=$(date +%s)				# get time now in seconds
	DIF=$(( $NOW-$START ))			# compute diff in seconds
	ELAPSE=$(( $DURATION-$DIF ))		# compute elapsed time in seconds
	MINS=$(( $ELAPSE/60 ))			# convert to minutes... (dumps remainder from division)
	SECS=$(( $ELAPSE - ($MINS*60) )) 	# ... and seconds

	# conditional
	if [ $MINS == 0 ] && [ $SECS == 0 ]	# if mins = 0 and secs = 0 (i.e. if time expired)
	then 					# blink screen
        #zenity --info --text "$(date);$(pwd)"
        notify-send "Time's up! $((DURATION/60)) minutes"
        #spd-say ""
        #spd-say "Your time is up! $((DURATION/60)) minutes"
        echo "Your time is up! $((DURATION/60)) minutes" | festival --tts

        play "./Computer_Magic.wav"
		for i in `seq 1 180`;    		# for i = 1:180 (i.e. 180 seconds)
			clear					# flash on
			setterm -term linux -back green -fore white # use setterm to change background color
			echo "00:00                             		" # extra tabs for visibiltiy

			sleep 0.5

			clear					# flash off
			setterm -term linux -default		# clear setterm changes from above 
			echo "00:00" 				# (i.e. go back to white text on black background)
			sleep 0.5	
		done  					# end for loop 
		break					# end script

	else 					# else, time is not expired
        OUTPUT=$(clear; echo "$MINS:$SECS" | toilet -f future --filter crop ) # display time
        #OUTPUT=$(clear; echo "$MINS:$SECS" | toilet -f mono12 --filter crop ) # display time
        echo "$OUTPUT"
		sleep 1 # sleep 1 second
	fi					# end if
done	# end while loop	

To run, use

$ ./terminalTimer 25 # in minutes

What it looks like while running:

From 3 minute timer