diff options
author | Alex Manuskin <amanusk@protonmail.com> | 2018-11-03 16:06:13 +0200 |
---|---|---|
committer | Giampaolo Rodola <g.rodola@gmail.com> | 2018-11-03 07:06:13 -0700 |
commit | bb5d032be76980a9e110f03f1203bd35fa85a793 (patch) | |
tree | 8341ee50730726aaaf86ca116e92c1f6fa7839e2 | |
parent | 648d8ba39eff4867d461a45a77d1245e2a909234 (diff) | |
download | psutil-bb5d032be76980a9e110f03f1203bd35fa85a793.tar.gz |
FreeBSD adding temperature sensors (WIP) (#1350)
FreeBSD: add temperature sensors
-rw-r--r-- | psutil/_psbsd.py | 18 | ||||
-rw-r--r-- | psutil/_psutil_bsd.c | 2 | ||||
-rw-r--r-- | psutil/arch/freebsd/specific.c | 36 | ||||
-rw-r--r-- | psutil/arch/freebsd/specific.h | 1 | ||||
-rwxr-xr-x | psutil/tests/test_bsd.py | 17 | ||||
-rwxr-xr-x | psutil/tests/test_contracts.py | 4 |
6 files changed, 76 insertions, 2 deletions
diff --git a/psutil/_psbsd.py b/psutil/_psbsd.py index c2896cb7..0727dd2e 100644 --- a/psutil/_psbsd.py +++ b/psutil/_psbsd.py @@ -11,6 +11,7 @@ import os import xml.etree.ElementTree as ET from collections import namedtuple from socket import AF_INET +from collections import defaultdict from . import _common from . import _psposix @@ -437,6 +438,23 @@ if FREEBSD: secsleft = minsleft * 60 return _common.sbattery(percent, secsleft, power_plugged) + def sensors_temperatures(): + "Return CPU cores temperatures if available, else an empty dict." + ret = defaultdict(list) + num_cpus = cpu_count_logical() + for cpu in range(num_cpus): + try: + current, high = cext.sensors_cpu_temperature(cpu) + if high <= 0: + high = None + name = "Core %s" % cpu + ret["coretemp"].append( + _common.shwtemp(name, current, high, high)) + except NotImplementedError: + pass + + return ret + # ===================================================================== # --- other system functions diff --git a/psutil/_psutil_bsd.c b/psutil/_psutil_bsd.c index 4e91c02e..6b366f13 100644 --- a/psutil/_psutil_bsd.c +++ b/psutil/_psutil_bsd.c @@ -981,6 +981,8 @@ PsutilMethods[] = { #if defined(PSUTIL_FREEBSD) {"sensors_battery", psutil_sensors_battery, METH_VARARGS, "Return battery information."}, + {"sensors_cpu_temperature", psutil_sensors_cpu_temperature, METH_VARARGS, + "Return temperature information for a given CPU core number."}, #endif // --- others diff --git a/psutil/arch/freebsd/specific.c b/psutil/arch/freebsd/specific.c index 177ac8a6..14be26b3 100644 --- a/psutil/arch/freebsd/specific.c +++ b/psutil/arch/freebsd/specific.c @@ -31,6 +31,7 @@ #define PSUTIL_TV2DOUBLE(t) ((t).tv_sec + (t).tv_usec / 1000000.0) #define PSUTIL_BT2MSEC(bt) (bt.sec * 1000 + (((uint64_t) 1000000000 * (uint32_t) \ (bt.frac >> 32) ) >> 32 ) / 1000000) +#define DECIKELVIN_2_CELCIUS(t) (t - 2731) / 10 #ifndef _PATH_DEVNULL #define _PATH_DEVNULL "/dev/null" #endif @@ -1010,3 +1011,38 @@ error: PyErr_SetFromErrno(PyExc_OSError); return NULL; } + + +/* + * Return temperature information for a given CPU core number. + */ +PyObject * +psutil_sensors_cpu_temperature(PyObject *self, PyObject *args) { + int current; + int tjmax; + int core; + char sensor[26]; + size_t size = sizeof(current); + + if (! PyArg_ParseTuple(args, "i", &core)) + return NULL; + sprintf(sensor, "dev.cpu.%d.temperature", core); + if (sysctlbyname(sensor, ¤t, &size, NULL, 0)) + goto error; + current = DECIKELVIN_2_CELCIUS(current); + + // Return -273 in case of faliure. + sprintf(sensor, "dev.cpu.%d.coretemp.tjmax", core); + if (sysctlbyname(sensor, &tjmax, &size, NULL, 0)) + tjmax = 0; + tjmax = DECIKELVIN_2_CELCIUS(tjmax); + + return Py_BuildValue("ii", current, tjmax); + +error: + if (errno == ENOENT) + PyErr_SetString(PyExc_NotImplementedError, "no temperature sensors"); + else + PyErr_SetFromErrno(PyExc_OSError); + return NULL; +} diff --git a/psutil/arch/freebsd/specific.h b/psutil/arch/freebsd/specific.h index 0df66ecc..cb71ff61 100644 --- a/psutil/arch/freebsd/specific.h +++ b/psutil/arch/freebsd/specific.h @@ -29,4 +29,5 @@ PyObject* psutil_virtual_mem(PyObject* self, PyObject* args); PyObject* psutil_cpu_stats(PyObject* self, PyObject* args); #if defined(PSUTIL_FREEBSD) PyObject* psutil_sensors_battery(PyObject* self, PyObject* args); +PyObject* psutil_sensors_cpu_temperature(PyObject* self, PyObject* args); #endif diff --git a/psutil/tests/test_bsd.py b/psutil/tests/test_bsd.py index 7846c1ca..df43a023 100755 --- a/psutil/tests/test_bsd.py +++ b/psutil/tests/test_bsd.py @@ -427,6 +427,23 @@ class FreeBSDSpecificTestCase(unittest.TestCase): sysctl("hw.acpi.acline") self.assertIsNone(psutil.sensors_battery()) + # --- sensors_temperatures + + def test_sensors_temperatures_against_sysctl(self): + num_cpus = psutil.cpu_count(True) + for cpu in range(num_cpus): + sensor = "dev.cpu.%s.temperature" % cpu + # sysctl returns a string in the format 46.0C + sysctl_result = int(float(sysctl(sensor)[:-1])) + self.assertAlmostEqual( + psutil.sensors_temperatures()["coretemp"][cpu].current, + sysctl_result, delta=10) + + sensor = "dev.cpu.%s.coretemp.tjmax" % cpu + sysctl_result = int(float(sysctl(sensor)[:-1])) + self.assertEqual( + psutil.sensors_temperatures()["coretemp"][cpu].high, + sysctl_result) # ===================================================================== # --- OpenBSD diff --git a/psutil/tests/test_contracts.py b/psutil/tests/test_contracts.py index d936eaf8..8ff41e5b 100755 --- a/psutil/tests/test_contracts.py +++ b/psutil/tests/test_contracts.py @@ -119,7 +119,7 @@ class TestAvailability(unittest.TestCase): def test_sensors_temperatures(self): self.assertEqual( - hasattr(psutil, "sensors_temperatures"), LINUX) + hasattr(psutil, "sensors_temperatures"), LINUX or FREEBSD) def test_sensors_fans(self): self.assertEqual(hasattr(psutil, "sensors_fans"), LINUX) @@ -337,7 +337,7 @@ class TestFetchAllProcesses(unittest.TestCase): self.assertEqual(err.name, p.name()) assert str(err) assert err.msg - except Exception as err: + except Exception: s = '\n' + '=' * 70 + '\n' s += "FAIL: test_%s (proc=%s" % (name, p) if ret != default: |