在Python中,我如何检测计算机是否使用电池电源



我正在玩pygame,我想做的一件事是在计算机使用电池时减少每秒帧数(以降低CPU使用率并延长电池寿命)。

如何从Python中检测计算机当前是否处于电池供电状态?

我在Windows上使用Python 3.1。

如果您想在没有win32api的情况下完成此操作,可以使用内置的ctypes模块。我通常在没有win32api的情况下运行CPython,所以我有点喜欢这些解决方案。

对于GetSystemPowerStatus()来说,这是一项稍微多一些的工作,因为您必须定义SYSTEM_POWER_STATUS结构,但这还不错。

# 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)

在我的打印系统上(基本意思是"桌面,插入"):

ACLineStatus 1
BatteryFlag -128
BatteryLifePercent -1
BatteryLifeTime 4294967295
BatteryFullLifeTime 4294967295

在C中检索此信息最可靠的方法是使用GetSystemPowerStatus。如果没有电池,则ACLineStatus将被设置为128。psutil在Linux、Windows和FreeBSD下公开了这些信息,所以为了检查电池是否存在,可以进行

>>> import psutil
>>> has_battery = psutil.sensors_battery() is not None

如果有电池,并且你想知道电源线是否插入,你可以这样做:

>>> import psutil
>>> psutil.sensors_battery()
sbattery(percent=99, secsleft=20308, power_plugged=True)
>>> psutil.sensors_battery().power_plugged
True
>>> 

很容易,您所要做的就是从Python调用Windows API函数GetSystemPowerStatus,可能是通过导入win32api模块

EDIT:GetSystemPowerStatus()尚未在版本219(2014-05-04)的win32api中实现。

跨平台电源状态指示的一个简单方法是使用pip 安装"电源"模块

    import power
    ans = power.PowerManagement().get_providing_power_source_type()
    if not ans:
        print "plugged into wall socket"
    else:
        print "on battery"

您可以安装acpi。从wikipedia

在计算机中,高级配置和电源接口提供了一个开放标准,操作系统可以使用该标准来发现和配置计算机硬件组件,通过使未使用的组件休眠来执行电源管理,以及执行状态监视。

然后使用python 中的subprocess模块

import subprocess
cmd = 'acpi -b'
# for python 3.7+
p = subprocess.run(cmd.split(), shell=True, capture_output=True)
battery_info, error = p.stdout.decode(), p.stderr.decode()
# for python3.x (x<6)
battery_info = subprocess.check_output(cmd.split(), shell=True).decode('utf-8')
print (battery_info) 

[SO]:在Python中,如何检测计算机是否处于电池供电状态?(@BenHoyt的答案)是可移植的,不需要额外的包,但它受到CTypesWinTypes)错误的负面影响(直到Pythonv3.12
有关该错误的更多详细信息(以及修复、解决方法):[SO]:为什么ctypes.wintypes.BYTE是签名的,而本机窗口BYTE是未签名的?(@CristiFati的回答)。

无论如何,我提交了[GitHub]:mhammond/pywin32-为GetSystemPowerStatus添加GetSystemPowerStates包装器,以便在Win32API中使用。

本地构建win32api.pyd并覆盖站点包目录中的一个(正如我在测试部分中提到的),会产生:

[cfati@CFATI-5510-0:e:WorkDevStackOverflowq006153860]> sopr.bat
### Set shorter prompt to better fit when pasted in StackOverflow (or other) pages ###
[prompt]>
[prompt]> :: Power cable unplugged
[prompt]> "e:WorkDevVEnvspy_pc064_03.10_test1_pw32Scriptspython.exe" -c "import win32api as wapi;from pprint import pprint as pp;pp(wapi.GetSystemPowerStatus(), sort_dicts=0);print("nDone.n")"
{'ACLineStatus': 0,
 'BatteryFlag': 1,
 'BatteryLifePercent': 99,
 'SystemStatusFlag': 0,
 'BatteryLifeTime': 13094,
 'BatteryFullLifeTime': 4294967295}
Done.

[prompt]>
[prompt]> :: Plug in power cable
[prompt]> "e:WorkDevVEnvspy_pc064_03.10_test1_pw32Scriptspython.exe" -c "import win32api as wapi;from pprint import pprint as pp;pp(wapi.GetSystemPowerStatus(), sort_dicts=0);print("nDone.n")"
{'ACLineStatus': 1,
 'BatteryFlag': 1,
 'BatteryLifePercent': 100,
 'SystemStatusFlag': 0,
 'BatteryLifeTime': 4294967295,
 'BatteryFullLifeTime': 4294967295}
Done.

检查[SO]:如何使用python&win32print(@CristiFati的答案)(最后),了解从(上面)补丁中获益的可能方法。

值得一提的是(如果[SO]:在Python中,我如何检测计算机是否处于电池供电状态?(@GiampaoloRodolà的回答)还不够清楚)[PyPI]:psutil还使用GetSystemPowerStatus来检索电池信息。

相关内容

最新更新