## March 9, 2008

### Battery

Having dithered during the last (cheaper) round, I signed us up for wind power. As a result, our fuel charge (one component of our electric bill) is now pegged at a small premium to the current rate, but is guaranteed for the next 14 years.

In other electrical news, …

My iBook’s battery’s slow, inexorable decline had reached the point of 25 minutes of use, before it would put the machine to sleep. So I decided to get a replacement.

Alas, I have two complaints

1. The new battery is rated at 5000 mAH. But, when you plug it in, you find its ‘current’ capacity is 4400 mAH. The manufacturer says that it will reach its rated capacity after a few discharge/recharge cycles. I have not found this to be the case, and have given up trying.
2. Related, but much more annoying: the OEM batteries, when they get low, issue a dialog box, warning you that they are running low, and then a few minutes later, they put the computer to sleep. With this battery, there’s no warning dialog box and, rather than going to sleep, the computer abruptly shuts down, losing all your work.

After having Tech support walk me through the usual useless magical incantations, I sent back the first battery as defective, but when the second battery exhibited exactly the same problems, I threw up my hands, and decided I needed to learn to live with it.

I’m not sure what to say about problem 1, but it’s fairly easy to understand the origin of problem 2. There are two controllers monitoring the state of the battery, one in the Power Management Unit of the computer, and one built into the battery. The battery starts out, when fully charged, with a voltage of approximately 16.5 V. As it discharges, that voltage slowly drops. When the PMU observes that the battery voltage has dropped below some critical value, it throws up the aforementioned dialog box. When it observes the voltage to have dropped still further, it puts the computer to sleep.

Alas, the controller built into the battery is also monitoring the voltage in the cells in the battery. Low voltage will damage the cells, perhaps even causing a fire. So, when it observes the voltage dropping below some critical value, it simply shuts off the output of the battery, dropping the voltage seen by the PMU to zero, and causing the computer to abruptly shut down. For whatever inscrutable reason, the shutoff voltage of the controller on this battery is higher than the one at which the PMU puts the computer to sleep.

Now that I understand the problem, the fix is easy to arrange. We just need to monitor the battery voltage, and put the computer to sleep before the battery controller decides to shut off the battery. Save the following script as /Library/LaunchDaemons/battery

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>org.voltage_monitor</string>
<key>OnDemand</key>
<false/>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/voltage_monitor.pl</string>
<string>12500</string>
</array>
<true/>
</dict>
</plist>

and the following Perl script as /usr/local/bin/voltage_monitor.pl (making sure it’s owned by root and executable)

#!/usr/bin/perl
use strict;
use Sys::Syslog;
my ($voltage,$charge, $growl) = 0; my$minvoltage = $ARGV[0] || 13000; my$low_warn = 1.02 * $minvoltage; eval { use Mac::Growl ':all'; RegisterNotifications('Battery Monitor', ['notify'], ['notify'], 'Battery Monitor');$growl = 1;
};
while ($voltage >$minvoltage || $voltage == 0) {$_ = ioreg -l -w 0;
/IOBatteryInfo.*"Voltage"=([\d]+),.*"Current"=([\d]+)/;
$voltage =$1;
$charge =$2;
'Battery Voltage has dropped to '. $voltage . ' millivolts. The computer will sleep soon.') if ($voltage < $low_warn &&$growl);
sleep 5;
}
openlog('Battery Monitor', 'cons,pid', 'user');
syslog('notice', 'Battery level: %d millivolts, %d mAH at shutdown.', $voltage,$charge);
closelog();
system('pmset sleepnow');

This will monitor the battery voltage, and put the computer to sleep when the voltage drops below some critical level. Just before putting the computer to sleep, it records the voltage, and nominal remaining charge of the battery in the System logs. The “sleep” voltage (in milliVolts) is a commandline argument. I initially set it to 13 V and, based on the syslog entries, slowly lowered it in the LaunchDaemon script. (Anyone with better information, about what it should be set to, should feel free to chime in and save us some laborious experimentation.)

If you have Growl, and if you install the relevant Perl modules

% sudo cpan Mac::Glue Mac::Growl

this dæmon will also display a low-battery notification, just like old times.

Posted by distler at March 9, 2008 10:11 PM

TrackBack URL for this Entry:   http://golem.ph.utexas.edu/cgi-bin/MT-3.0/dxy-tb.fcgi/1627