10

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.

cwoebker
  • 3,158
  • 5
  • 27
  • 43
  • 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 u – PurityLake May 05 '13 at 02:00
  • 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. – cwoebker May 05 '13 at 02:30

7 Answers7

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.

knobiDev
  • 462
  • 1
  • 5
  • 17
Giampaolo Rodolà
  • 12,488
  • 6
  • 68
  • 60
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.

MikeHunter
  • 4,144
  • 1
  • 19
  • 14
  • I tried this already and two problems came up. First the [CIM_Battery](http://msdn.microsoft.com/en-us/library/windows/desktop/aa387189%28v=vs.85%29.aspx) 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. – cwoebker May 05 '13 at 03:15
  • 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. – cwoebker May 07 '13 at 01:09
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!!

Mithil Mohan
  • 223
  • 2
  • 11
  • Why 'secsleft=4294967295' ??? It's 19884 hours. I have only 30% on battery –  Sep 16 '20 at 08:49
  • @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 failure – Sreenikethan I Jun 04 '21 at 17:20
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")
crispengari
  • 7,901
  • 7
  • 45
  • 53
  • 1
    \ Why 'secsleft=4294967295' ??? It's 19884 hours. I have only 30% on battery –  Sep 16 '20 at 08:49
  • 1
    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 second** – crispengari Sep 17 '20 at 09:27
  • 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. https://github.com/giampaolo/psutil/blob/master/scripts/battery.py – crispengari Sep 17 '20 at 09:34
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)
Shmuel Kamensky
  • 411
  • 1
  • 5
  • 13
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

Mandalorian
  • 77
  • 1
  • 10
0

If you are talking about Full Charge Capacity of a battery try this: I AM USING POWERSHELL NONINTERACTIVE SHELL TO USE THIS COMMAND. THIS IS ONE OF THE EASIEST WAYS TO KNOW BATTERY INFO.

systeminfo = subprocess.run(["Powershell", "-NonInteractive", "-Command", "Get-WmiObject", "-Namespace",  "'root\wmi'", "-Query",  "'select FullChargedCapacity  from BatteryFullChargedCapacity'"], capture_output=True).stdout.decode().strip()
print(systeminfo[292:-21])

NOTE: THIS ONLY WORKS ON WINDOWS

Pranav
  • 1
  • 2