diff options
author | Giampaolo Rodola <g.rodola@gmail.com> | 2017-01-26 18:29:20 +0100 |
---|---|---|
committer | Giampaolo Rodola <g.rodola@gmail.com> | 2017-01-26 18:29:20 +0100 |
commit | 109f873ea81b28c9f82142a556f75e68256dbaa5 (patch) | |
tree | 8ce8b83bdde772db984e69b823849b33e57aa8b2 | |
parent | 13114eefc8da22a7b18a8e7f0b877044ac0e1897 (diff) | |
download | psutil-109f873ea81b28c9f82142a556f75e68256dbaa5.tar.gz |
#955: sensors_batter() win impl
-rw-r--r-- | docs/index.rst | 28 | ||||
-rw-r--r-- | psutil/__init__.py | 2 | ||||
-rw-r--r-- | psutil/_common.py | 13 | ||||
-rw-r--r-- | psutil/_pslinux.py | 2 | ||||
-rw-r--r-- | psutil/_psutil_windows.c | 27 | ||||
-rw-r--r-- | psutil/_pswindows.py | 26 | ||||
-rwxr-xr-x | psutil/tests/test_system.py | 5 |
7 files changed, 101 insertions, 2 deletions
diff --git a/docs/index.rst b/docs/index.rst index 0131b56a..8db5b111 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -617,6 +617,25 @@ Network .. versionadded:: 3.0.0 +Sensors +------- + +.. function:: sensors_battery() + + Return a namedtuple with the following values: + + - **percent**: battery power left as a percentage. + - **secsleft**: number of seconds left before battery run out of power; this + may also be :data:`psutil.POWER_TIME_UNKNOWN <psutil.POWER_TIME_UNKNOWN>` + or :data:`psutil.POWER_TIME_UNLIMITED <psutil.POWER_TIME_UNLIMITED>`. + + If no battery is installed this function will return ``None``. + + Availability: Linux, Windows + + .. versionadded:: 5.1.0 + + Other system info ----------------- @@ -1984,6 +2003,15 @@ Constants .. versionadded:: 3.0.0 +.. _const-power: +.. data:: POWER_TIME_UNKNOWN +.. data:: POWER_TIME_UNLIMITED + + This can be the value of *secsleft* field of + :func:`psutil.sensors_battery()`. + + .. versionadded:: 5.1.0 + .. _const-version-info: .. data:: version_info diff --git a/psutil/__init__.py b/psutil/__init__.py index 7e3217df..745d66fd 100644 --- a/psutil/__init__.py +++ b/psutil/__init__.py @@ -171,6 +171,8 @@ __all__ = [ "NIC_DUPLEX_FULL", "NIC_DUPLEX_HALF", "NIC_DUPLEX_UNKNOWN", + "POWER_TIME_UNKNOWN", "POWER_TIME_UNLIMITED", + "BSD", "FREEBSD", "LINUX", "NETBSD", "OPENBSD", "OSX", "POSIX", "SUNOS", "WINDOWS", diff --git a/psutil/_common.py b/psutil/_common.py index 4342d254..b28af999 100644 --- a/psutil/_common.py +++ b/psutil/_common.py @@ -121,6 +121,17 @@ else: globals().update(NicDuplex.__members__) +# sensors_battery() +if enum is None: + POWER_TIME_UNKNOWN = -1 + POWER_TIME_UNLIMITED = -2 +else: + class Power(enum.IntEnum): + POWER_TIME_UNKNOWN = -1 + POWER_TIME_UNLIMITED = -2 + + globals().update(NicDuplex.__members__) + # =================================================================== # --- namedtuples @@ -159,7 +170,7 @@ scpustats = namedtuple( # psutil.cpu_freq() scpufreq = namedtuple('scpufreq', ['current', 'min', 'max']) # psutil.sensors_battery() -sbattery = namedtuple('sbattery', ['percent']) +sbattery = namedtuple('sbattery', ['percent', 'secsleft']) # --- for Process methods diff --git a/psutil/_pslinux.py b/psutil/_pslinux.py index 1a5304a6..0fba0fa6 100644 --- a/psutil/_pslinux.py +++ b/psutil/_pslinux.py @@ -1075,7 +1075,7 @@ def sensors_battery(): # energy_full = int(cat(root + "energy_full")) # secsleft = 3600 * energy_now / power_now percent = int(cat(root + "capacity")) - return _common.sbattery(percent) + return _common.sbattery(percent, 0) # ===================================================================== diff --git a/psutil/_psutil_windows.c b/psutil/_psutil_windows.c index 4caace7d..74edc6cd 100644 --- a/psutil/_psutil_windows.c +++ b/psutil/_psutil_windows.c @@ -3456,6 +3456,31 @@ error: } +/* + * Return battery usage stats. + */ +static PyObject * +psutil_sensors_battery(PyObject *self, PyObject *args) { + SYSTEM_POWER_STATUS sps; + + if (GetSystemPowerStatus(&sps) == 0) { + PyErr_SetFromWindowsErr(0); + return NULL; + } + return Py_BuildValue( + "iiiI", + sps.ACLineStatus, // whether AC is connected: 0=no, 1=yes, 255=unknown + // status flag: + // 1, 2, 4 = high, low, critical + // 8 = charging + // 128 = no battery + sps.BatteryFlag, + sps.BatteryLifePercent, // percent + sps.BatteryLifeTime // remaining secs + ); +} + + // ------------------------ Python init --------------------------- static PyMethodDef @@ -3562,6 +3587,8 @@ PsutilMethods[] = { "Return NICs stats."}, {"cpu_freq", psutil_cpu_freq, METH_VARARGS, "Return CPU frequency."}, + {"sensors_battery", psutil_sensors_battery, METH_VARARGS, + "Return battery metrics usage."}, // --- windows services {"winservice_enumerate", psutil_winservice_enumerate, METH_VARARGS, diff --git a/psutil/_pswindows.py b/psutil/_pswindows.py index da8552e1..80faec91 100644 --- a/psutil/_pswindows.py +++ b/psutil/_pswindows.py @@ -362,6 +362,32 @@ def net_if_addrs(): # ===================================================================== +# --- sensors +# ===================================================================== + + +def sensors_battery(): + acline_status, flags, percent, secsleft = cext.sensors_battery() + power_connected = acline_status == 1 + no_battery = bool(flags & 128) + charging = bool(flags & 8) + + # print("acline_status=%s, flags=%s, percent=%s, secsleft=%s" % ( + # acline_status, flags, percent, secsleft)) + # print("power_connected=%s, no_battery=%s, charging=%s" % ( + # power_connected, no_battery, charging)) + + if no_battery: + return None + if power_connected or charging: + secsleft = _common.POWER_TIME_UNLIMITED + elif secsleft == -1: + secsleft = _common.POWER_TIME_UNKNOWN + + return _common.sbattery(percent, secsleft) + + +# ===================================================================== # --- other system functions # ===================================================================== diff --git a/psutil/tests/test_system.py b/psutil/tests/test_system.py index 58b7c9c0..906641e4 100755 --- a/psutil/tests/test_system.py +++ b/psutil/tests/test_system.py @@ -758,9 +758,14 @@ class TestSystemAPIs(unittest.TestCase): "platform not supported") def test_sensors_battery(self): ret = psutil.sensors_battery() + if ret is None: + return # no battery if ret.percent is not None: self.assertGreaterEqual(ret.percent, 0) self.assertLessEqual(ret.percent, 100) + if ret.secsleft not in (psutil.POWER_TIME_UNKNOWN, + psutil.POWER_TIME_UNLIMITED): + self.assertGreaterEqual(ret.secsleft, 0) if __name__ == '__main__': |