I'm playing around with pygame, and one thing I'd like to do is reduce the number of frames per second when the computer is on battery power (to lower the CPU usage and extend battery life).
How can I detect, from Python, whether the computer is currently on battery power?
I'm using Python 3.1 on Windows.
If you want to do it without win32api
, you can use the built-in ctypes
module. I usually run CPython without win32api
, so I kinda like these solutions.
It's a tiny bit more work for GetSystemPowerStatus()
because you have to define the SYSTEM_POWER_STATUS
structure, but not bad.
# Get power status of the system using ctypes to call GetSystemPowerStatus
import ctypes
from ctypes import wintypes
class SYSTEM_POWER_STATUS(ctypes.Structure):
_fields_ = [
('ACLineStatus', wintypes.BYTE),
('BatteryFlag', wintypes.BYTE),
('BatteryLifePercent', wintypes.BYTE),
('Reserved1', wintypes.BYTE),
('BatteryLifeTime', wintypes.DWORD),
('BatteryFullLifeTime', wintypes.DWORD),
]
SYSTEM_POWER_STATUS_P = ctypes.POINTER(SYSTEM_POWER_STATUS)
GetSystemPowerStatus = ctypes.windll.kernel32.GetSystemPowerStatus
GetSystemPowerStatus.argtypes = [SYSTEM_POWER_STATUS_P]
GetSystemPowerStatus.restype = wintypes.BOOL
status = SYSTEM_POWER_STATUS()
if not GetSystemPowerStatus(ctypes.pointer(status)):
raise ctypes.WinError()
print 'ACLineStatus', status.ACLineStatus
print 'BatteryFlag', status.BatteryFlag
print 'BatteryLifePercent', status.BatteryLifePercent
print 'BatteryLifeTime', status.BatteryLifeTime
print 'BatteryFullLifeTime', status.BatteryFullLifeTime
On my system that prints this (basically meaning "desktop, plugged in"):
ACLineStatus 1
BatteryFlag -128
BatteryLifePercent -1
BatteryLifeTime 4294967295
BatteryFullLifeTime 4294967295
It is easy, all you have to do is to call Windows API function GetSystemPowerStatus from Python, probably by importing win32api
module.
EDIT: GetSystemPowerStatus()
is not yet implemented in win32api
as of build 219 (2014-05-04).
The most reliable way to retrieve this information in C is by using GetSystemPowerStatus. If no battery is present ACLineStatus
will be set to 128
. psutil exposes this information under Linux, Windows and FreeBSD, so to check if battery is present you can do this
>>> import psutil
>>> has_battery = psutil.sensors_battery() is not None
If a battery is present and you want to know whether the power cable is plugged in you can do this:
>>> import psutil
>>> psutil.sensors_battery()
sbattery(percent=99, secsleft=20308, power_plugged=True)
>>> psutil.sensors_battery().power_plugged
True
>>>
A simple method for cross platform power status indication is the 'power' module which you can install with pip
import power
ans = power.PowerManagement().get_providing_power_source_type()
if not ans:
print "plugged into wall socket"
else:
print "on battery"