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

发布于 2024-11-10 06:28:53 字数 136 浏览 0 评论 0 原文

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

如何从 Python 检测计算机当前是否使用电池供电?

我在 Windows 上使用 Python 3.1。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

≈。彩虹 2024-11-17 06:28:53

如果您想在没有 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

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
泪眸﹌ 2024-11-17 06:28:53

在 C 中检索此信息的最可靠方法是使用 获取系统电源状态。如果没有电池,ACLineStatus 将设置为 128psutil 在 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
>>> 

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
>>> 
夜访吸血鬼 2024-11-17 06:28:53

很简单,你所要做的就是调用Windows API函数GetSystemPowerStatus 从 Python,可能通过导入 win32api 模块。

编辑:自 build 219 (2014-05-04) 起,Win32api 尚未实现 GetSystemPowerStatus()

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

多彩岁月 2024-11-17 06:28:53

跨平台电源状态指示的一个简单方法是“电源”模块,您可以使用 pip 安装该模块

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

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"
愛上了 2024-11-17 06:28:53

您可以安装acpi。来自维基百科

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

然后使用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) 

You can install acpi.From wikipedia

In a computer, the Advanced Configuration and Power Interface provides an open standard that operating systems can use to discover and configure computer hardware components, to perform power management by putting unused components to sleep, and to perform status monitoring.

Then use the subprocess module in python

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) 
苍暮颜 2024-11-17 06:28:53

[SO]:在Python中,如何检测计算机是否使用电池电源? (@BenHoyt 的回答) 是可移植的,不需要额外的包,但它受到 CTypes 的负面影响(直到Python v3.12WinTypes)错误。
有关错误的更多详细信息(以及修复、解决方法):[SO]:为什么 ctypes.wintypes.BYTE 已签名,但本机 Windows BYTE 是未签名? (@CristiFati 的回答)

无论如何,我提交了 [GitHub]:mhammond/pywin32 - 添加 GetSystemPowerStatus 包装器 GetSystemPowerStatus 函数在 Win32API 中可用。

在本地构建 win32api.pyd 并覆盖 site-packages 目录中的文件(正如我在测试部分中提到的),会产生:

<代码>[cfati@CFATI-5510-0:e:\Work\Dev\StackOverflow\q006153860]> sopr.bat
### 设置较短的提示,以便在粘贴到 StackOverflow(或其他)页面时更好地适应 ###

[提示]>
[提示]> :: 电源线未插入
[提示]> "e:\Work\Dev\VEnvs\py_pc064_03.10_test1_pw32\Scripts\python.exe" -c "导入 win32api 作为 wapi;从 pprint 导入 pprint 作为 pp;pp(wapi.GetSystemPowerStatus(), sort_dicts=0);print( \"\n完成。\n\")"
{'ACLineStatus':0,
 '电池标志':1,
 “电池寿命百分比”:99,
 '系统状态标志': 0,
 “电池寿命”:13094,
 “电池寿命”:4294967295}

完毕。


[提示]>
[提示]> :: 插入电源线
[提示]> "e:\Work\Dev\VEnvs\py_pc064_03.10_test1_pw32\Scripts\python.exe" -c "导入 win32api 作为 wapi;从 pprint 导入 pprint 作为 pp;pp(wapi.GetSystemPowerStatus(), sort_dicts=0);print( \"\n完成。\n\")"
{'ACLineStatus':1,
 '电池标志':1,
 “电池寿命百分比”:100,
 '系统状态标志': 0,
 “电池寿命”:4294967295,
 “电池寿命”:4294967295}

完毕。

检查[SO]:如何使用 python & 更改打印队列中作业的用户名win32print(@CristiFati 的回答)(最后)了解从(上述)补丁中受益的可能方法。

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

[SO]: In Python, how can I detect whether the computer is on battery power? (@BenHoyt's answer) is portable and doesn't require extra packages, but it's negatively impacted (until Python v3.12) by a CTypes (WinTypes) bug.
More details about the bug (and fix, workaround): [SO]: Why ctypes.wintypes.BYTE is signed, but native windows BYTE is unsigned? (@CristiFati's answer).

Anyway, I submitted [GitHub]: mhammond/pywin32 - Add GetSystemPowerStatus wrapper for GetSystemPowerStatus function to be available in Win32API.

Building win32api.pyd locally and overwriting the one from site-packages directory (as I mentioned in the Test section), yields:

[cfati@CFATI-5510-0:e:\Work\Dev\StackOverflow\q006153860]> sopr.bat
### Set shorter prompt to better fit when pasted in StackOverflow (or other) pages ###

[prompt]>
[prompt]> :: Power cable unplugged
[prompt]> "e:\Work\Dev\VEnvs\py_pc064_03.10_test1_pw32\Scripts\python.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:\Work\Dev\VEnvs\py_pc064_03.10_test1_pw32\Scripts\python.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.

Check [SO]: How to change username of job in print queue using python & win32print (@CristiFati's answer) (at the end) for possible ways to benefit from the (above) patch.

Worth mentioning (if [SO]: In Python, how can I detect whether the computer is on battery power? (@GiampaoloRodolà's answer) is not clear enough about it) that [PyPI]: psutil also uses GetSystemPowerStatus in order to retrieve battery information.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文