[plug] Super ugly bash stuff

Brad Campbell brad at wasp.net.au
Tue May 3 03:58:19 WST 2005


G'day all,

I have found myself on aircraft a bit lately, and as my pile of steaming crud Acer Travelmate 740 
lies through its teeth about battery life via ACPI, I decided to hack together a nasty script to 
give me more realistic time estimates on battery charge/discharge.

This smelly lump of poo simply tells me I'm going to get 4 hours on a battery, and a linear 
interpolation of this as related to battery percentage. Now, under windows, with all hardware shut 
off, the hard disk spun down and editing a text file with notepad it might well hit 4 hours, but as 
my recently dismantled "5880mAh" battery pack built from 4200mAh worth of cells (gotta love 
marketing) shows, they can't lie straight in bed.

This horrid script simply checks every 10 seconds for a change in battery percentage, looks at the 
number of seconds (or 10 second periods) it took for the percentage to change, smooths it over 10% 
change and converts this to a rough time value. It also goes the other way and monitors charging.

I hacked this up on a recent flight, and have given it a belting with two different batteries (well, 
they are the same but one has a lot more cycles on it and a reduced runtime) over a couple of 
charge/discharge cycles and it's surprisingly accurate.

I post it here for a couple of reasons.

A) it's a great example of a little knowledge can be dangerous when related to programming anything
B) It's probably got loads of great examples of what not to do when writing bash scripts
&
C) It might actually be of use to someone, although I'm sure sane manufacturers actually calculate 
runtime rather than just blindly shoving estimates at the user. Even under windows this tank gets it 
very wrong.

I get about 2 hours when watching an mpeg4 or mpeg2, and about 2.5 hours when editing documents. The 
bios insists I'm going to get 4 hours regardless.

I guess it is 4 years old and the batteries are 3 years old, so I should not complain. I probably 
got close to 4 hours from them new.

Oh, and the clever sed script is not mine, I ripped it out of someone else's script (I'm a regex 
retard too)

#!/bin/bash
let secs=0
let average=0
let loops=0
while true ; do
levels=`acpi -b | sed -n -e 's/.*[^0-9]\([0-9][0-9]*\)%.*/\1/p'`
if [ "$levels" != "$oldlevels" ] ; then
         let loops++
         echo $secs seconds per percent
         if acpi -a | grep -q on-line ; then
                 let remaining=100-$levels
                 message="charged"
         else
                 let remaining=$levels
                 message="empty"
         fi
         let average=$(( $average + ($secs*$remaining) ))
         [ $loops -eq 2 ] && let average=$average*2
         if [ $loops -le 10 ] ; then
                 let avs=$(( $average / $loops ))
         else
                 let avs=$average/10
         fi;
         if [ $loops -ge 10 ] ; then
                 let average=$average-$avs
         fi;
         let minutes=$avs/60
         let hours=$minutes/60
         let minutes=$(( $minutes - ($hours*60) ))
         let raw=$(( $secs*$remaining ))
         echo $avs  seconds \(smoothed\) $raw  seconds \(unsmoothed\)
         echo `printf "%.2d:%.2d" $hours $minutes` remaining till $message \
                 $levels\% currently
         echo
         let secs=0
         oldlevels=$levels
         fi;
let secs+=10
sleep 10
done;

-- 
"Human beings, who are almost unique in having the ability
to learn from the experience of others, are also remarkable
for their apparent disinclination to do so." -- Douglas Adams



More information about the plug mailing list