Accessing battery information

Discussion in 'Mac Programming' started by thundersteele, Jan 6, 2012.

  1. macrumors 68030

    Oct 19, 2011
    Ok, so I've been teaching myself some Objective C/Cocoa, using Xcode 4.2 on Lion. The goal is to get something like Coconut Battery with some added functionality. I've got it running and it works fine, but right now I'm unhappy with the way I get the battery information.

    What I do is call "ioreg -c AppleSmartBattery" from within the class that provides the battery information, and then I read out the information I want from the output. This is not very elegant, and I think there should be a better way to get this information, without calling a shell program.

    I found three places that give access to detailed battery information:
    1) ioreg in the console
    2) system report -> Power
    3) IOregistryExplorer in /Developer/Tools

    Now, there is the IOKit class in the OSX Dev package. In particular, IOPowerSources.h and IOPSKeys.h provide methods to get battery information, so tried to use those. To my surprise, the information is much less detailed, I only got the current and maximal charge in %, and the battery health, also in %. This was somewhat disappointing.

    There must be a better way to get this information, after all the IOregistryExplorer must do it somehow. It seems I will have to find a way to access the IOservices tree. If anyone has any ideas or hints, I would be thankful.
  2. macrumors 68040

    Feb 2, 2008
    My understanding is that ioreg outputs the io registry available to IOKit. You should be able to iterate this tree from IOKit and the IOService api to get what you currently get from the ioreg program.
  3. thread starter macrumors 68030

    Oct 19, 2011
    Thanks for your reply. I found a few examples how to get system information (MAC addresses etc) using the IOKit, and will probably go from there.
  4. thread starter macrumors 68030

    Oct 19, 2011
    Ok, after another day of trial and error, I got it sorted out :)
    The relevant code ended up being very short!

    #import <Foundation/Foundation.h>
    #import <IOKit/IOKitLib.h>
        CFMutableDictionaryRef properties;
        kern_return_t tester;
        // go to battery entry!    
        io_registry_entry_t ioRegistryRoot = 
            IORegistryEntryFromPath(kIOMasterPortDefault, "IOService:/AppleACPIPlatformExpert/SMB0/AppleECSMBusController/AppleSmartBatteryManager/AppleSmartBattery");
        // read out properties
        tester=IORegistryEntryCreateCFProperties(ioRegistryRoot, &properties, kCFAllocatorDefault,0);
        // set variables to the values from the IOregistry
        CFNumberGetValue((CFNumberRef) CFDictionaryGetValue(properties, CFSTR("CycleCount")), 9, &CycleCount);
        [... and so on...];
    The hardest part was getting into non-object oriented programming. And of course finding all the small bits and pieces on how to get a number out of the CFDictionary.
    Another useful code sniplet can be found here:
    This helped me to see how and where to start.
  5. macrumors 6502


    Dec 5, 2013
    The Netherlands
    I know this is an old topic. But I'm very interested in this charge cycle part.

    I want to know more about these stored charge cycles.
    When are these increasing ? When an device is fully dead, and fully charged back? Or what, because for my iphone, the charge cycle amount stays 10.
  6. macrumors 6502

    Madd the Sane

    Nov 8, 2010
    Fun fact: you can cast most Core Foundation objects into Objective C classes.

    Also, in the code snippet you gave, the use of "9" is ambiguous: it took me awhile to remember it's an enum value for the data type of the number you are getting. As it is, it's a "magic number," the use of which is discouraged: if the constant that a magic number (or magic string) is supposed to represent changes, it can result I unexpected behaviors which can lead to bugs.
  7. macrumors 604

    Aug 9, 2009

Share This Page