6

I'm testing an app to let users know when to plug and unplug their laptop to get the most life out of their laptop battery. As well as this I'm trying to replicate the tooltip from the Windows power meter.

It's fairly successful so far with a couple of differences.

  1. The Windows time remaining notification, e.g. "X hr XX min (XX%) remaining", doesn't show up until after around a minute.
  2. The Windows time remaining seems more stable under changing battery loads

These lead me to think that the Windows time remaining algorithm is averaging over the past minute or so but I can't find any documentation of that. Does anyone know exactly what it does so I can reproduce it?

Here's my implementation (in Python but the question is language-agnostic). I'm thinking I'll need to average the most recent x discharge rates from polling every y seconds but need to know the values for x and y.

t = wmi.WMI(moniker = "//./root/wmi")
batts = t.ExecQuery('Select * from BatteryStatus where Voltage > 0')

time_left = 0
for _i, b in enumerate(batts):
    time_left += float(b.RemainingCapacity) / float(b.DischargeRate)

hours = int(time_left)
mins = 60 * (time_left % 1.0)
return '%i hr %i min' % (hours, mins)
Jamie Bull
  • 12,889
  • 15
  • 77
  • 116
  • Just a clarification - are you using [any of these functions](http://msdn.microsoft.com/en-us/library/windows/desktop/aa373163%28v=vs.85%29.aspx) somewhere? – admdrew Feb 06 '14 at 19:33
  • 1
    It is an estimate of course. It doesn't have a time machine to know that you are going to start playing a game and quickly drain your battery. – Hans Passant Feb 06 '14 at 20:10
  • 1
    @admdrew I'm using `wmi`, a Python package which presumably at some level wraps those functions. I'm following the implementation from [this answer](http://stackoverflow.com/a/16380996/1706564). – Jamie Bull Feb 06 '14 at 20:32
  • @HansPassant, thanks. I'm looking for how that estimate is made. Any idea? – Jamie Bull Feb 06 '14 at 20:33
  • 2
    Are you aware of the structure: http://msdn.microsoft.com/en-us/library/windows/desktop/aa372667.aspx . It has the BatteryEstimatedTime level you can use. Example in C on how to query for this is provided here: http://msdn.microsoft.com/en-us/library/windows/desktop/bb204769.aspx (needs to be adapted for BatteryEstimatedTime level) – Simon Mourier Feb 14 '14 at 07:12
  • I hadn't seen that. I'll look into it, thanks. – Jamie Bull Feb 14 '14 at 22:33
  • I've found an answer, though not quite where you pointed to, @SimonMourier I found what I needed [here](msdn.microsoft.com/en-us/library/aa394074%28VS.85%29.aspx) – Jamie Bull Feb 20 '14 at 09:00

1 Answers1

6

Windows follows the ACPI specification, and given the specification gives a method of calculating remaining battery time, I'd assume this would be how they'd do it.

Edit: Found a somewhat confirming source.

I'm referring specifically to chapter 3.9.3 "Battery Gas Gauge".

Remaining Battery Percentage[%] = Battery Remaining Capacity [mAh/mWh] / Last Full Charged Capacity [mAh/mWh]* 100

if you need that in hours:

Remaining Battery Life [h]= Battery Remaining Capacity [mAh/mWh] / Battery Present Drain Rate [mA/mW]

This essentially represents the current rate of change in charge capacity per unit time, you'll need to look at the ACPI spec to see how Windows implements it specifically.

The variables in question I'd assume would have to be queried from the battery controller and I'd let Windows handle all the compatibility issues there. For this there exists the Windows Management Instrumentation classes Win32_Battery and (probably more appropriate) Win32_PortableBattery. Upon some further digging, it seems like these classes calculate the remaining time for you and don't expose the current charge of the battery (probably to encourage people to have it calculated only one way/rounding issues, etc). The closest "cool" thing you can do is estimate/calculate battery wear by FullChargeCapacity / DesignCapacity. The next best thing I could find appears to be a lower level API exposed through IOCTL_BATTERY_QUERY_INFORMATION, but that seems like it also doesn't give current charge capacity in milliWatt-Hours. tl;dr Use the remaining times and percentages calculated for you by the above classes if possible :/


As an aside, some laptop manufacturers bundle their own tools to calculate time remaining and query specific micro controller implementations in their own batteries and are able to make a more informed/non-linear guestimate about remaining battery.
lberezy
  • 450
  • 5
  • 19
  • This is great. If you could add in how to query it from Windows as described in msdn.microsoft.com/en-us/library/aa394074%28VS.85%29.aspx the bounty's yours. – Jamie Bull Feb 20 '14 at 09:02