Getting Battery Capacity in Windows with Python
Asked Answered
S

6

12

I am looking to figure out both the current Battery Capacity and the Design Capacity.

So far what I could get to work is using the Win32_Battery() class which doesn't give all the information I need (at least not on my system). I used the pure-python wmi library for that.

On the other hand I found this which works In Python, how can I detect whether the computer is on battery power?, but unfortunately it doesn't provide any information on Capacity neither.

The Battery Information structure and the Battery Status structure seem perfect for this. Now I know that I have to use the DeviceIoControl function to do so and I found this C++ code that explains it a little.

I would prefer something that simply uses ctypes and not the python win32api provided by pywin32. If you have an idea how to do this in python please let me know!

Thanks in advance.

Socialite answered 5/5, 2013 at 1:0 Comment(2)
I assume you don't want to use win32api because you want to use the code across other platforms, so I'm not sure about alternative ways to do this because all systems have different APIs. If u don't need other platforms i may be able to help uHake
I have the code working for linux and mac os. I am trying to get something for windows now, the pywin32, win32api would be fine. I was originally just trying to avoid having an external library requirement.Socialite
P
12

Tim Golden's excellent wmi module will, I believe, give you everything you want. You'll just have to do several queries to get everything:

import wmi

c = wmi.WMI()
t = wmi.WMI(moniker = "//./root/wmi")

batts1 = c.CIM_Battery(Caption = 'Portable Battery')
for i, b in enumerate(batts1):
    print 'Battery %d Design Capacity: %d mWh' % (i, b.DesignCapacity or 0)


batts = t.ExecQuery('Select * from BatteryFullChargedCapacity')
for i, b in enumerate(batts):
    print ('Battery %d Fully Charged Capacity: %d mWh' % 
          (i, b.FullChargedCapacity))

batts = t.ExecQuery('Select * from BatteryStatus where Voltage > 0')
for i, b in enumerate(batts):
    print '\nBattery %d ***************' % i
    print 'Tag:               ' + str(b.Tag)
    print 'Name:              ' + b.InstanceName

    print 'PowerOnline:       ' + str(b.PowerOnline)
    print 'Discharging:       ' + str(b.Discharging)
    print 'Charging:          ' + str(b.Charging)
    print 'Voltage:           ' + str(b.Voltage)
    print 'DischargeRate:     ' + str(b.DischargeRate)
    print 'ChargeRate:        ' + str(b.ChargeRate)
    print 'RemainingCapacity: ' + str(b.RemainingCapacity)
    print 'Active:            ' + str(b.Active)
    print 'Critical:          ' + str(b.Critical)

This is certainly not cross-platform, and it requires a 3rd party resource, but it does work very well.

Philbin answered 5/5, 2013 at 3:5 Comment(2)
I tried this already and two problems came up. First the CIM_Battery class does not give you the current Capacity as far as I know. It also generally just doesn't seem to give me most of the data (Meaning I get 0's or other default values). The last part looks interesting though, I am going to try it out and let you know if it worked.Socialite
Thanks a lot pretty much solved all my problems. I have one issue left, the DesignCapacity always returns 0 for me. I tried performing queries and everything but even those just give me errors. I am testing this on bootcamp with windows 8 so that might be the problem there but whatever I can live without the DesignCapacity for now. Thanks a lot for your help.Socialite
O
13

The most reliable way to retrieve this information is by using GetSystemPowerStatus instead of WMI. psutil exposes this information under Linux, Windows and FreeBSD:

>>> import psutil
>>>
>>> def secs2hours(secs):
...     mm, ss = divmod(secs, 60)
...     hh, mm = divmod(mm, 60)
...     return "%d:%02d:%02d" % (hh, mm, ss)
...
>>> battery = psutil.sensors_battery()
>>> battery
sbattery(percent=93, secsleft=16628, power_plugged=False)
>>> print("charge = %s%%, time left = %s" % (battery.percent, secs2hours(battery.secsleft)))
charge = 93%, time left = 4:37:08

The relevant commit is here.

Oral answered 1/2, 2017 at 19:55 Comment(3)
Lots of problems in it (Maybe for me only).Malefaction
psutil.sensors_battery() return None if powered from battery on HP machine superuser.com/questions/1394191/…Imogen
@Imogen not for me (HP Spectre x360 Convertible)Laddy
P
12

Tim Golden's excellent wmi module will, I believe, give you everything you want. You'll just have to do several queries to get everything:

import wmi

c = wmi.WMI()
t = wmi.WMI(moniker = "//./root/wmi")

batts1 = c.CIM_Battery(Caption = 'Portable Battery')
for i, b in enumerate(batts1):
    print 'Battery %d Design Capacity: %d mWh' % (i, b.DesignCapacity or 0)


batts = t.ExecQuery('Select * from BatteryFullChargedCapacity')
for i, b in enumerate(batts):
    print ('Battery %d Fully Charged Capacity: %d mWh' % 
          (i, b.FullChargedCapacity))

batts = t.ExecQuery('Select * from BatteryStatus where Voltage > 0')
for i, b in enumerate(batts):
    print '\nBattery %d ***************' % i
    print 'Tag:               ' + str(b.Tag)
    print 'Name:              ' + b.InstanceName

    print 'PowerOnline:       ' + str(b.PowerOnline)
    print 'Discharging:       ' + str(b.Discharging)
    print 'Charging:          ' + str(b.Charging)
    print 'Voltage:           ' + str(b.Voltage)
    print 'DischargeRate:     ' + str(b.DischargeRate)
    print 'ChargeRate:        ' + str(b.ChargeRate)
    print 'RemainingCapacity: ' + str(b.RemainingCapacity)
    print 'Active:            ' + str(b.Active)
    print 'Critical:          ' + str(b.Critical)

This is certainly not cross-platform, and it requires a 3rd party resource, but it does work very well.

Philbin answered 5/5, 2013 at 3:5 Comment(2)
I tried this already and two problems came up. First the CIM_Battery class does not give you the current Capacity as far as I know. It also generally just doesn't seem to give me most of the data (Meaning I get 0's or other default values). The last part looks interesting though, I am going to try it out and let you know if it worked.Socialite
Thanks a lot pretty much solved all my problems. I have one issue left, the DesignCapacity always returns 0 for me. I tried performing queries and everything but even those just give me errors. I am testing this on bootcamp with windows 8 so that might be the problem there but whatever I can live without the DesignCapacity for now. Thanks a lot for your help.Socialite
P
0
import psutil

battery = psutil.sensors_battery()
plugged = battery.power_plugged
percent = str(battery.percent)

The variable percent will have the battery percent. I have written a small piece of code using python to notify when the battery is fully charged

https://github.com/Mitzzzzz/Battery-Full-Indicator

Kindly check!!

Polypary answered 14/5, 2020 at 15:8 Comment(2)
Why 'secsleft=4294967295' ??? It's 19884 hours. I have only 30% on batteryGnathion
@AlexZab that most likely means that it is not able to retrieve the secsleft... since this number 4294967295 seems to be the max limit of an unsigned 32-bit integer, indicating a failureBlackthorn
J
0
**Checking the battery percentage in python can be done using the psutil module as 
follows **

# Installing the psutil module
from  pip._internal import  main
main(["install", "psutil"])
import psutil

battery = psutil.sensors_battery();

# checking if the charger is plugged
if battery.power_plugged:
    print("Charging: ", battery.percent)
else:
    print("Not Charging", battery.percent ,"%");
    print( "Discharge time ", int(battery.secsleft)," sec_lft")
Jevons answered 24/5, 2020 at 16:14 Comment(3)
\ Why 'secsleft=4294967295' ??? It's 19884 hours. I have only 30% on batteryGnathion
Im not sure, it have been long let me go and check the documentation, then i will come back to you but i think those units aren't actually secondJevons
Go ahead and check this script it may help you to get the actual time left. If it doesn't help you hit me up i will fix it for you. github.com/giampaolo/psutil/blob/master/scripts/battery.pyJevons
M
0

The Most Easiest Form to Know the Battery With Python is using Psutil Module...

import psutil    #pip install psutil
battery_detecting = psutil.sensors_battery()
plugged = battery_detecting.power_plugged
percent_battery = str(battery_detecting.percent)
plugged = "Plugged In" if plugged else "Not Plugged In"
print(percent_battery+'% | '+plugged)
Macneil answered 3/2, 2021 at 2:18 Comment(0)
C
0

Try This Code

import psutil
import time
battery = psutil.sensors_battery()
while True:
    print("Battery percentage : ", battery.percent)
    print("Power plugged in : ", battery.power_plugged)
    if battery.percent < 35 and battery.power_plugged == False:
        print("Your battry is low")
    time.sleep(5)

But this code will run continously until it get's interrupted

Culhert answered 18/7, 2021 at 7:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.