Geoffrey Wiseman

Scheduled Monitoring of MacBook Batteries

I found James Davenport's "The (De-)evolution of My Laptop Battery" to be an interesting read, and I followed from the post to his GitHub repository, which was also an interesting read.

James Davenport's script to monitor his battery life is very simplistic, but it does the job of recording the data and allowing him to process it later. It immediately made me think of ways to improve the process (and clearly I'm not the only one).

Of course, being a developer makes me want it my way, not James Davenport's way or James Koval's way, or, really, anyone else's.

In particular:

  • I wanted to record more information than James Davenport's script did.
  • I didn't want to parse more ioreg data than I had to.
  • I didn't want a complicated program / shell script

Since ioreg's output is parseable but not ideal for data storage, I wanted something that could parse text reasonably well and had a reputation for speed. I wanted something very simple, not something that looked like a program when I was done, or I might have used Ruby. I didn't want Perl for the same reasons, but also because despite Perl's strengths in text processing, I've never really enjoyed reading or writing it. It seemed like this would be a good use for awk, so I brushed up my Awk skills and wrote this:

1
2
3
4
5
6
/"CycleCount"/ { cycleCount = $3 }
/"CurrentCapacity"/ { currentCapacity = $3 }
/"MaxCapacity"/ { maxCapacity = $3 }
/"DesignCapacity"/ { designCapacity = $3 }
/"ExternalConnected"/ { externalConnected = $3 }
END { OFS=","; print date, cycleCount, designCapacity, maxCapacity, currentCapacity, externalConnected }

And a shell script to invoke it:

1
2
3
#!/bin/bash
# Get battery data from ioreg, parse it with awk and save it to a CSV log file
ioreg -n AppleSmartBattery -r | awk -v date="$(date -u)" -f log-battery.awk >> ~/.battery-log.csv

And finally a launchd plist to schedule the invocation:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.codiform.OSXBatteryLogger</string>
    <key>ProgramArguments</key>
    <array>
        <string>/path/to/repo/log-battery.sh</string>
    </array>
    <key>StartInterval</key>
    <integer>60</integer>
    <key>WorkingDirectory</key>
    <string>/path/to/repo</string>
</dict>
</plist>

I forked James Davenport's repo and modified it to match the above, so if you want to dig into my fork, osx-battery-logger, feel free.