Open jakl opened 11 years ago
So is an all-perl script even faster. Oh yeah.
[thirteen:~/git/batlog] link$ time ./batlog
real 0m0.034s
user 0m0.016s
sys 0m0.017s
Here's the perl version.
#!/usr/bin/perl
use strict;
use warnings;
use File::Basename;
use POSIX qw(uname strftime);
my $BATDIR = dirname($0);
my $batinfo = "$BATDIR/batinfo.csv";
my $batdata = "$BATDIR/batlog.csv";
my @ioreg = split /\n/, `/usr/sbin/ioreg -rk BatterySerialNumber`;
batinfo() unless (-s $batinfo);
unless (-s $batdata) {
open BATDATA, '>', $batdata or die "Can't write $batdata";
print BATDATA "year,month,day,hour,minute,cycle,charge,max_charge,decay_percent,plugged_in,charging,charged,charge_time,deplete_time,amps,volts,temperature\n";
close BATDATA;
}
batdata();
exit;
sub ioreg_value
{
my ($arg) = @_;
for (@ioreg) {
if (/"$arg" = (.+)/) {
return $1;
}
}
die "Couldn't find value $arg";
}
sub batinfo
{
open BATINFO, '>', $batinfo or die "Can't write $batinfo";
print BATINFO "kernel,max_charge_new,manufacturer,device,serial,firmware\n";
my @data;
my ($os, $host, $kernel, $date, $arch) = uname();
push(@data, $kernel);
push(@data, ioreg_value('DesignCapacity'));
push(@data, ioreg_value('Manufacturer'));
push(@data, ioreg_value('DeviceName'));
push(@data, ioreg_value('BatterySerialNumber'));
push(@data, ioreg_value('FirmwareSerialNumber'));
print BATINFO join(",", @data)."\n";
close BATINFO;
}
sub batdata
{
open BATDATA, '>>', $batdata or die "Can't append $batdata";
my @data;
# Date in UTC time in case you cross time zones
push(@data, strftime "%Y,%m,%d,%H,%M", gmtime);
push(@data, ioreg_value('CycleCount'));
push(@data, ioreg_value('CurrentCapacity'));
my $maxcap = ioreg_value('MaxCapacity');
my $descap = ioreg_value('DesignCapacity');
push(@data, $maxcap);
# Calcuate battery decay as percentage
my $decay = $maxcap * 100 / $descap;
push(@data, sprintf('%0.2f', $decay));
push(@data, ioreg_value('ExternalConnected'));
push(@data, ioreg_value('IsCharging'));
push(@data, ioreg_value('FullyCharged'));
push(@data, ioreg_value('AvgTimeToFull'));
push(@data, ioreg_value('InstantTimeToEmpty'));
push(@data, ioreg_value('Amperage'));
push(@data, ioreg_value('Voltage'));
push(@data, ioreg_value('Temperature'));
print BATDATA join(",", @data)."\n";
close BATDATA;
}
Wow this is really awesome work, thanks! I hope this request is accepted.
Or, just use egrep to grab as many stats as you need with one invocation. See my bug report. If you are concerned about bash being big and heavy, you could use csh instead, but in any event I prefer to use a really simple data collector and do the heavy parsing only when a report is needed.
That's a good approach for sure. Reflecting on my own off-hand assumptions, I predicted:
I'm not sure what you mean by "installing dependencies". On my Mac (and every Unix system I've ever used), egrep is part of the standard installation, right alongside grep. And looking just now, I also see z- and bz- variants of all three, which I never knew existed! Cool!
As for viewing the data, the collection script will run maybe 1200 times a week (assuming you have your laptop turned on four hours a day, five days a week). I prefer to only start up Perl when I want to view the data as I believe it will save power in the long run. But everyone's situation is different, so feel free to disagree.
Oh I assumed csh
was through brew - didn't know it's standard. Neat!
As far as energy use of this cron, I have faith it uses a negligible amount compared to everything else competing for my battery. It wouldn't hurt to run it every 10+ minutes though; every minute shows unnecessary jittery noise for me.
time ./battest.perl
real 0m0.036s
user 0m0.019s
sys 0m0.015s
Laptop Power Usage from Lifehacker:
Chart's similar to my droid where the screen is the vast majority, then games, then a long tail of everything else.
Ew! Thou shalt not invoke ioreg and perl 13 times per minute in the name of statistics (along with even more invocations of the slow, giant shell known as bash).
A single invocation of ioreg is enough (the output can be cached in memory easily enough, even in shell). All your bash scripts can be rewritten as shell functions inside battest.sh and the perl... well you should really avoid that if you're trying to do all this in shell, else you may as well rewrite everything in perl to avoid calling out to the various utility programs you're using now.
Here's what I got without actually rewriting everything in perl...
Is it faster? You bet.
I'm gonna re-do it in perl now.