summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiampaolo Rodola <g.rodola@gmail.com>2017-02-02 22:41:23 +0100
committerGiampaolo Rodola <g.rodola@gmail.com>2017-02-02 22:41:23 +0100
commit4157e6fe5a6f25400342f8c89b44456cc566ac9d (patch)
tree2aa3ce109b1585c5434bd8244b01e157288ea26e
parent11150d2588f47ec4b335ab2ec3591662fc6e88d7 (diff)
downloadpsutil-4157e6fe5a6f25400342f8c89b44456cc566ac9d.tar.gz
#966: sensors_battery() fails with no such file error
-rw-r--r--HISTORY.rst2
-rw-r--r--psutil/_pslinux.py48
-rwxr-xr-xscripts/battery.py2
3 files changed, 47 insertions, 5 deletions
diff --git a/HISTORY.rst b/HISTORY.rst
index 073f5b50..1a21983b 100644
--- a/HISTORY.rst
+++ b/HISTORY.rst
@@ -11,6 +11,8 @@
decoding character on Python 3.
- 965_: [Linux] disk_io_counters() may miscalculate sector size and report the
wrong number of bytes read and written.
+- 966_: [Linux] sensors_battery() fails with no such file error.
+
5.1.0
=====
diff --git a/psutil/_pslinux.py b/psutil/_pslinux.py
index 32c81370..a06ee73f 100644
--- a/psutil/_pslinux.py
+++ b/psutil/_pslinux.py
@@ -1101,16 +1101,56 @@ def sensors_temperatures():
def sensors_battery():
+ """Return battery information.
+ Implementation note: it appears /sys/class/power_supply/BAT0/
+ directory structure may vary and provide files with the same
+ meaning but under different names, see:
+ https://github.com/giampaolo/psutil/issues/966
+ """
+ null = object()
+
+ def multi_cat(*paths):
+ """Read content of multiple files which may not exist.
+ # If none of them exist returns None.
+ """
+ for path in paths:
+ ret = cat(path, fallback=null)
+ if ret != null:
+ return int(ret)
+ return None
+
root = os.path.join(POWER_SUPPLY_PATH, "BAT0")
if not os.path.exists(root):
return None
+ # Base metrics.
+ energy_now = multi_cat(
+ root + "/energy_now",
+ root + "/charge_now")
+ power_now = multi_cat(
+ root + "/power_now",
+ root + "/current_now")
+ energy_full = multi_cat(
+ root + "/energy_full",
+ root + "/charge_full")
+ if energy_now is None or power_now is None:
+ return None
+
+ # Percent. If we have energy_full the percentage will be more
+ # accurate compared to reading /capacity file (float vs. int).
+ if energy_full is not None:
+ try:
+ percent = 100.0 * energy_now / energy_full
+ except ZeroDivisionError:
+ percent = 0.0
+ else:
+ percent = int(cat(root + "/capacity"), fallback=null)
+ if percent == null:
+ return None
+
+ # Secs left.
power_plugged = cat(os.path.join(POWER_SUPPLY_PATH, "AC0/online"),
fallback=b"0") == b"1"
- energy_now = int(cat(root + "/energy_now"))
- power_now = int(cat(root + "/power_now"))
- percent = int(cat(root + "/capacity"))
-
if power_plugged:
secsleft = _common.POWER_TIME_UNLIMITED
else:
diff --git a/scripts/battery.py b/scripts/battery.py
index eb8b16bb..23e0f669 100755
--- a/scripts/battery.py
+++ b/scripts/battery.py
@@ -33,7 +33,7 @@ def main():
if batt is None:
return sys.exit("no battery is installed")
- print("charge: %s%%" % batt.percent)
+ print("charge: %s%%" % round(batt.percent, 2))
if batt.power_plugged:
print("status: %s" % (
"charging" if batt.percent < 100 else "fully charged"))