diff options
author | Giampaolo Rodola <g.rodola@gmail.com> | 2017-02-02 22:41:23 +0100 |
---|---|---|
committer | Giampaolo Rodola <g.rodola@gmail.com> | 2017-02-02 22:41:23 +0100 |
commit | 4157e6fe5a6f25400342f8c89b44456cc566ac9d (patch) | |
tree | 2aa3ce109b1585c5434bd8244b01e157288ea26e | |
parent | 11150d2588f47ec4b335ab2ec3591662fc6e88d7 (diff) | |
download | psutil-4157e6fe5a6f25400342f8c89b44456cc566ac9d.tar.gz |
#966: sensors_battery() fails with no such file error
-rw-r--r-- | HISTORY.rst | 2 | ||||
-rw-r--r-- | psutil/_pslinux.py | 48 | ||||
-rwxr-xr-x | scripts/battery.py | 2 |
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")) |