Just a little AppleScript I made for personal purposes and felt like sharing. Note that it does take a while to gather the information, but it doesn’t eat up RAM. Please credit me if you do use part/all of my code. A comment line at the top referencing this URL would do just fine.
I’ll bet a dab hand at bash scripting could make this into one script that would be much faster than six calls to system_profiler and grep, but it works nicely (albeit slowly) on my MBP.
Yeah, is there a way to possibly shorten the time? I’ve searched the internet and found this shell command.
do shell script "ioreg -l | grep Capacity | less"
A bit of parsing it and I can get the info I need. I’m busy at the moment, but will rewrite that in a short bit and update it. Thanks for checking it out, Adam.
Sorry for the bump. Can you tell me what your cycle count is? You can find it in System Profiler. The only way the script would fail would be if the values weren’t returned or if either “Charge remaining” or “Full charge capacity” weren’t numbers. And judging by the error you got, I’d say your cycle count (3rd item of the list) isn’t being returned.
Hi n8henrie. Welcome to MacScripter and thanks for your post.
Your script doesn’t work on my Snow Leopard system because only the first word in each multi-word label is capitalised, eg. “Charge remaining”, not “Charge Remaining”. It works both ways if the initial letters are replaced with regex classes “[Cc]harge [Rr]emaining”). Or, given the unlikelihood of clashes in these cases, they could be simply be replaced with dots (“.harge .emaining”)!
I’d prefer the shell script results to include the labels, to ensure that the figures are attributed to the correct properties instead of simply assuming they occur in a particular order. Edit: I don’t know how to do this with “awk”, but with “sed” it could be something like this:
set battery_data to paragraphs of (do shell script "system_profiler SPPowerDataType | sed -En '/Charge [Rr]emaining|Full [Cc]harge [Cc]apacity/ p ; s/[^A-Z]*Cycle [Cc]ount/Cycles/p ; s/[^A-Z]*(Amperage|Voltage) \\(([^)]+)\\): ([0-9-]+)/\\1: \\3 \\2/p ;'")
if (battery_data is {}) then
display dialog "Are you sure this machine's a portable?" buttons "Er." default button 1 with title "Battery Monitor" with icon stop
else
set output to ""
repeat with this_detail in battery_data
if (this_detail contains "Remaining") then
set charge to word -1 of this_detail
else if (this_detail contains "Capacity") then
set capacity to word -1 of this_detail
else
set output to output & return & this_detail
end if
end repeat
display dialog ("Charge: " & (charge / capacity * 100) & "%" & output) with title "Battery Monitor"
end if
Thanks for the welcome - I’ve found MacScripter helpful many times in the past, so I’m glad to have finally created an account.
Interesting, on 10.8 I had to capitalize all words of a multi-word phrase (as they appear in System Profiler) to get it to work. Good catch.
Good point about labeling the variables as you go - I just opened System Profiler to ensure that the dialog displayed the correct results, but your solution is much more generalizable. Thanks again!
Model: Macbook Pro
Browser: Safari 536.26.17
Operating System: Mac OS X (10.8)
Weird, I’m on a snow leopard machine and the first letter of every word is capitalized and n8henrie script works as expected. When I go a little back his script seems to work in leopard as well.
You can do the same thing with AWK as Nigel did with sed. Personally I prefer to make everything lowercase first and I like your awk better, only because it’s much better readable. So to make everything lowercase I put tr in between or use the tolower function in AWK.
set battery_data to paragraphs of (do shell script "system_profiler SPPowerDataType | tr [A-Z] [a-z] | awk '/(charge remaining)|(full charge capacity)|(cycle count)|(amperage)|(voltage)/ {print $NF}'")
--or make lowercase with AWK itself
set battery_data to paragraphs of (do shell script "system_profiler SPPowerDataType | awk 'tolower($0) ~ /(charge remaining)|(full charge capacity)|(cycle count)|(amperage)|(voltage)/ {print $NF}'")
set {battery_remaining, battery_capacity, cycles, amperage, voltage} to battery_data
set percent_charge to (((battery_remaining / battery_capacity) * 100) & " %")
display dialog "Charge: " & percent_charge & return & "Cycles: " & cycles & return & "Amperage: " & amperage & "mA" & return & "Voltage: " & voltage & " mV" with title "Battery Monitor"
edit: The reason I choose to make everything lowercase is that standard POSIX awk doesn’t have the case insensitive option while GNU AWK (or just GAWK) have this option. In theory it’s the same, most applications with case insensitive string functions is just making every string lowercase before starting to process.
The system_profile result is a mixture of “title case” and “sentence case” on my Snow Leopard machine (MacBook Pro, 10.6.8), but the labels tested for the current purpose only have the initial characters of their first words capitalised.
I’ve just tried pulling out the power lead to see if, by some very unlikely chance, that makes any difference. It doesn’t. Not to case anyway. It does make the Amperage figure go negative, which causes my sed code not to return it. I’ve now adjusted the code to allow for the possibility of a minus sign.
All the scripts error on my Leopard machine, which isn’t a portable. (I’ve also edited my script to catch this.) Everything returned there by “system_profiler SPPowerDataType” is in title case and those same labels are also in title case on the Snow Leopard machine.
I prefer Nigels approach, as by the way he performs the case transformations, doesn’t make you have to readjust the case when you are printing the report! It is nitpicking! And within the output of his do shell script. ( I like to have this turn up in a log now and then.)
It is a nice script, I changed the last line to make the capacity look better, (with maybe a rounding error of the third decimal ).
display dialog (("Charge: " & text 1 thru 5 of ((charge / capacity * 100) as text)) & " %" & output) with title "Battery Monitor"
I like to see the whole story as well:
set theText to do shell script "system_profiler SPPowerDataType" without altering line endings
tell application "TextEdit"
make new document
set text of its document 1 to theText
end tell
do shell script "open -b \"com.apple.textedit\""
tell application "System Events"
tell application process "TextEdit"
set position of its window 1 to {100, 22}
set size of its window 1 to {600, 950}
end tell
end tell
Well it makes it more odd then… Both my solutions to n8henrie script works for Leopard, Snow Leopard and Mountain Lion (don’t have an Lion Machine here). Every word is capitalized and only the words ‘on’ are lowercase. I have an old(er) MacBookPro8.2 running Snow Leopard (which took a lot of effort to remove Lion and install Snow Leopard), an MacBookPro10.1 Mountain Lion machine (which gives the right Amperage), an MacBookPro7.1 running Snow Leopard and an old MacBookPro4.1 running Leopard.
All of them return in capitalized content so I don’t think that the capitalization-issue is OS depended. Maybe it’s hardware depended (MacBookPro model number) or localization issues. My $LANG settings are null for do shell scripts (default is “C”).
set theText to do shell script "system_profiler SPPowerDataType" without altering line endings
tell application "TextEdit"
activate
if (count documents) = 0 or length of (get text of document 1) > 0 then make new document
set text of document 1 to theText
set bounds of window 1 to {100, 22, 700, 972}
end tell