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.
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)
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 :/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With