summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornicolargo <nicolas@nicolargo.com>2017-02-11 16:53:31 +0100
committernicolargo <nicolas@nicolargo.com>2017-02-11 16:53:31 +0100
commitbf533cc13558479880c5ca32f8cb93aae998f4ad (patch)
tree12358e2e119687084db479bfe41b0ebb6bd01fc2
parent9e5051c4d550834260aa9d1a9e407f34131d9cbd (diff)
downloadpsutil-bf533cc13558479880c5ca32f8cb93aae998f4ad.tar.gz
Add new sensors_fans method
-rw-r--r--HISTORY.rst7
-rw-r--r--docs/index.rst19
-rw-r--r--psutil/__init__.py15
-rw-r--r--psutil/_pslinux.py29
-rwxr-xr-xpsutil/tests/test_linux.py13
5 files changed, 82 insertions, 1 deletions
diff --git a/HISTORY.rst b/HISTORY.rst
index 05bbd936..457003df 100644
--- a/HISTORY.rst
+++ b/HISTORY.rst
@@ -2,6 +2,13 @@
*2017-02-07*
+5.1.4
+=====
+
+**Enhancements**
+
+- 971_: [Linux] Add sensors_fans method.
+
5.1.3
=====
diff --git a/docs/index.rst b/docs/index.rst
index 1a0438a1..d8e1af80 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -653,6 +653,25 @@ Sensors
This API is experimental. Backward incompatible changes may occur if
deemed necessary.
+.. function:: sensors_fans()
+
+ Return hardware fans speed. Each entry is a named tuple representing a
+ certain hardware sensor.
+ All speed is expressed in RPM (round per minut). Example::
+
+ >>> import psutil
+ >>> psutil.sensors_fans()
+ defaultdict(<type 'list'>, {'dell_smm': [('Processor Fan', 3028)]})
+
+ Availability: Linux
+
+ .. versionadded:: 5.1.4
+
+ .. warning::
+
+ This API is experimental. Backward incompatible changes may occur if
+ deemed necessary.
+
.. function:: sensors_battery()
Return battery status information as a named tuple including the following
diff --git a/psutil/__init__.py b/psutil/__init__.py
index 7b539ef6..244e6fca 100644
--- a/psutil/__init__.py
+++ b/psutil/__init__.py
@@ -187,7 +187,7 @@ __all__ = [
"net_io_counters", "net_connections", "net_if_addrs", # network
"net_if_stats",
"disk_io_counters", "disk_partitions", "disk_usage", # disk
- # "sensors_temperatures", "sensors_battery", # sensors
+ # "sensors_temperatures", "sensors_battery", "sensors_fans" # sensors
"users", "boot_time", # others
]
__all__.extend(_psplatform.__extra__all__)
@@ -2234,6 +2234,19 @@ if hasattr(_psplatform, "sensors_temperatures"):
__all__.append("sensors_temperatures")
+# Linux
+if hasattr(_psplatform, "sensors_fans"):
+
+ def sensors_fans():
+ """Return fans speed. Each entry is a namedtuple
+ representing a certain hardware sensor.
+ All speed are expressed in RPM (rounds per minute).
+ """
+ return _psplatform.sensors_fans()
+
+ __all__.append("sensors_fans")
+
+
# Linux, Windows, FreeBSD
if hasattr(_psplatform, "sensors_battery"):
diff --git a/psutil/_pslinux.py b/psutil/_pslinux.py
index e019bbcf..ce20e8a0 100644
--- a/psutil/_pslinux.py
+++ b/psutil/_pslinux.py
@@ -1118,6 +1118,35 @@ def sensors_temperatures():
return ret
+def sensors_fans():
+ """Return hardware (CPU and others) fans as a dict
+ including hardware label, current speed.
+
+ Implementation notes:
+ - /sys/class/hwmon looks like the most recent interface to
+ retrieve this info, and this implementation relies on it
+ only (old distros will probably use something else)
+ - lm-sensors on Ubuntu 16.04 relies on /sys/class/hwmon
+ """
+ ret = collections.defaultdict(list)
+ basenames = glob.glob('/sys/class/hwmon/hwmon*/fan*_*')
+ if not basenames:
+ # CentOS has an intermediate /device directory:
+ # https://github.com/giampaolo/psutil/issues/971
+ basenames = glob.glob('/sys/class/hwmon/hwmon*/device/fan*_*')
+
+ basenames = sorted(set([x.split('_')[0] for x in basenames]))
+ for base in basenames:
+ unit_name = cat(os.path.join(os.path.dirname(base), 'name'),
+ binary=False)
+ label = cat(base + '_label', fallback='', binary=False)
+ current = int(cat(base + '_input'))
+
+ ret[unit_name].append((label, current))
+
+ return ret
+
+
def sensors_battery():
"""Return battery information.
Implementation note: it appears /sys/class/power_supply/BAT0/
diff --git a/psutil/tests/test_linux.py b/psutil/tests/test_linux.py
index 80717564..e5fda9ad 100755
--- a/psutil/tests/test_linux.py
+++ b/psutil/tests/test_linux.py
@@ -1021,6 +1021,19 @@ class TestMisc(unittest.TestCase):
@unittest.skipUnless(LINUX, "LINUX only")
+@unittest.skipUnless(hasattr(psutil, "sensors_fans") and
+ psutil.sensors_fans() is not None,
+ "no fan")
+class TestSensorsFans(unittest.TestCase):
+
+ def test_current(self):
+ psutil_value = psutil.sensors_fans()
+ for fk in psutil_value:
+ # Fan speed should always be > 0
+ self.assertTrue(psutil_value[fk][0][1] >= 0)
+
+
+@unittest.skipUnless(LINUX, "LINUX only")
@unittest.skipUnless(hasattr(psutil, "sensors_battery") and
psutil.sensors_battery() is not None,
"no battery")