ACPI Battery Check
Requirements: Linux kernel with ACPI support
This guide assumes you have a laptop, Linux, and something between your ears (preferably a brain). The script I've written will do the job on any machine with any battery running any Linux distribution. I'm wonderful, I know.
I feel its right to explain why I wrote this script in the first place, so here it goes... One day I was sitting in class playing a game on my laptop when suddenly it turned off. This came without warning, so I didn't get a chance to save my game, successfully making those past 20 minutes a waste of time. Perhaps I was being tought a lesson from you know who that in class, I should be doing something other than playing computer games. However, I'd like to believe it was just a way to get me to finally write a script to check my battery state and do something about it if need be!
Now, I know that there are tons of full-featured ACPI scripts out there. Most, if not ALL, of these have things written into them that I either don't want or that my laptop doesn't support. XScreenSaver already takes care of putting my display on standby and such and my ACPI modules already take care of fan usage, so why bother using some huge, bloated script? If you want a script like that, then what I've written isn't for you.
Okay, enough talk, its time for some code...
Once you have ACPI support in your kernel, /etc/acpi should be created automatically. If not, create it and an events directory and file as root like so:
mkdir /etc/acpi
mkdir /etc/acpi/events
touch /etc/acpi/events/default
If /etc/acpi and the other files already exist, then doing that is not needed. Regardless, /etc/acpi/events/default must be modified. Add the following lines into that file as root:
event=.*
action=/etc/acpi/battery_check.pl
Now it comes time to put that battery_check.pl script in /etc/acpi, as specified in the event-rules above. First, create /etc/acpi/battery_check.pl as root like this:
touch /etc/acpi/battery_check.pl
Then, open /etc/acpi/battery_check.pl with your favorite text-editor and paste the following into it:
#!/usr/bin/perl
#
#battery_check.pl
#
#Used to check ACPI battery state in /proc/acpi
#and warn users or halsts system if charge is
#too low.
#
#Written by ateam (derek@backdrifts.net)
$warning_message = "ACPI - Battery critically low!";
$halt_message = "ACPI - Battery too low, halting system NOW!";
chop (@pts = `ls /dev/pts/`);
($pts_length = @pts) --;
chop (@bat_state = `cat /proc/acpi/battery/BAT0/state`);
chop (@bat_info = `cat /proc/acpi/battery/BAT0/info`);
$charge_state = @bat_state[2];
$charge_state =~ s#(charging state: )##g;
$remaining = @bat_state[4];
$remaining =~ s#(remaining capacity: )##g;
$remaining =~ s#( mAh)##g;
$warning = @bat_info[5];
$warning =~ s#(design capacity warning: )##g;
$warning =~ s#( mAh)##g;
$low = @bat_info[6];
$low =~ s#(design capacity low: )##g;
$low =~ s#( mAh)##g;
if ($charge_state eq "discharging" && $remaining <= $warning && $remaining > $low) {
for ($i = 0; $i <= $pts_length; $i ++) {
system "echo \"$warning_message\" > /dev/pts/@pts[$i]";
}
system "echo \"$warning_message\" > /dev/tty1";
system "logger \"$warning_message\"";
} elsif ($charge_state eq "discharging" && $remaining <= $low) {
for ($i = 0; $i <= $pts_length; $i ++) {
system "echo \"$halt_message\" > /dev/pts/@pts[$i]";
}
system "echo \"$halt_message\" > /dev/tty1";
system "logger \"$halt_message\"";
system "/sbin/init 0";
} else {
system "logger \"ACPI - battery ok, no warning sent, system not halting\"";
}
If your perl interpreter binary is located somewhere other than /usr/bin/perl, then modify the code appropriately.
In my opinion, code is worth nothing to a user if he deson't understand how it works. In addition, I don't want you to be running some script on your machine that you're unfamiliar with. So, I'll explain.
Very simply, the script collects information regarding your battery's capacity, warning level, low level and state. When an ACPI event occurs, which is less than every minute, this script is run, checking your battery status. If your battery has reached its warning level, then a message is sent to tty1 and all virtual terminals (pts/*) warning you with "ACPI - Battery critically low!" If your battery is so low that your system needs to be halted in order to protect your hard disks, then the message will read "ACPI - Battery too low, halting system NOW!" All activity is logged in /var/log/messages to ensure that you know what's going on, or more importantly, what went on.
About modification of this script; if you don't wish to monitor BAT0, then change the script accordingly. In addition, you may not want your machine to be halted for you if your battery is about to die. I reccomend that you do, however.
Enjoy :) |