Skip to content

Commit

Permalink
Osx temps (#1284)
Browse files Browse the repository at this point in the history
OSX: add temperatures() and fans()
  • Loading branch information
amanusk authored and giampaolo committed Jun 26, 2018
1 parent d20b993 commit 196802d
Show file tree
Hide file tree
Showing 8 changed files with 535 additions and 5 deletions.
4 changes: 2 additions & 2 deletions psutil/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2175,7 +2175,7 @@ def net_if_stats():
# =====================================================================


# Linux
# Linux, OSX
if hasattr(_psplatform, "sensors_temperatures"):

def sensors_temperatures(fahrenheit=False):
Expand Down Expand Up @@ -2213,7 +2213,7 @@ def convert(n):
__all__.append("sensors_temperatures")


# Linux
# Linux, OSX
if hasattr(_psplatform, "sensors_fans"):

def sensors_fans():
Expand Down
2 changes: 1 addition & 1 deletion psutil/_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ class BatteryTime(enum.IntEnum):
'shwtemp', ['label', 'current', 'high', 'critical'])
# psutil.sensors_battery()
sbattery = namedtuple('sbattery', ['percent', 'secsleft', 'power_plugged'])
# psutil.sensors_battery()
# psutil.sensors_fans()
sfan = namedtuple('sfan', ['label', 'current'])

# --- for Process methods
Expand Down
146 changes: 146 additions & 0 deletions psutil/_psosx.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import contextlib
import errno
import collections
import functools
import os
from socket import AF_INET
Expand Down Expand Up @@ -62,6 +63,110 @@
cext.SZOMB: _common.STATUS_ZOMBIE,
}

temperatures = (
# group, key, label

# --- CPU
("CPU", "TCXC", "PECI CPU"),
("CPU", "TCXc", "PECI CPU"),
("CPU", "TC0P", "CPU 1 Proximity"),
("CPU", "TC0H", "CPU 1 Heatsink"),
("CPU", "TC0D", "CPU 1 Package"),
("CPU", "TC0E", "CPU 1"),
("CPU", "TC1C", "CPU Core 1"),
("CPU", "TC2C", "CPU Core 2"),
("CPU", "TC3C", "CPU Core 3"),
("CPU", "TC4C", "CPU Core 4"),
("CPU", "TC5C", "CPU Core 5"),
("CPU", "TC6C", "CPU Core 6"),
("CPU", "TC7C", "CPU Core 7"),
("CPU", "TC8C", "CPU Core 8"),
("CPU", "TCAH", "CPU 1 Heatsink Alt."),
("CPU", "TCAD", "CPU 1 Package Alt."),
("CPU", "TC1P", "CPU 2 Proximity"),
("CPU", "TC1H", "CPU 2 Heatsink"),
("CPU", "TC1D", "CPU 2 Package"),
("CPU", "TC1E", "CPU 2"),
("CPU", "TCBH", "CPU 2 Heatsink Alt."),
("CPU", "TCBD", "CPU 2 Package Alt."),

("CPU", "TCSC", "PECI SA"),
("CPU", "TCSc", "PECI SA"),
("CPU", "TCSA", "PECI SA"),

# --- GPU
("GPU", "TCGC", "PECI GPU"),
("GPU", "TCGc", "PECI GPU"),
("GPU", "TG0P", "GPU Proximity"),
("GPU", "TG0D", "GPU Die"),
("GPU", "TG1D", "GPU Die"),
("GPU", "TG0H", "GPU Heatsink"),
("GPU", "TG1H", "GPU Heatsink"),

# --- Memory
("Memory", "Ts0S", "Memory Proximity"),
("Memory", "TM0P", "Mem Bank A1"),
("Memory", "TM1P", "Mem Bank A2"),
("Memory", "TM8P", "Mem Bank B1"),
("Memory", "TM9P", "Mem Bank B2"),
("Memory", "TM0S", "Mem Module A1"),
("Memory", "TM1S", "Mem Module A2"),
("Memory", "TM8S", "Mem Module B1"),
("Memory", "TM9S", "Mem Module B2"),

# --- HDD
("HDD", "TH0P", "HDD Bay 1"),
("HDD", "TH1P", "HDD Bay 2"),
("HDD", "TH2P", "HDD Bay 3"),
("HDD", "TH3P", "HDD Bay 4"),

# --- Battery
("Battery", "TB0T", "Battery TS_MAX"),
("Battery", "TB1T", "Battery 1"),
("Battery", "TB2T", "Battery 2"),
("Battery", "TB3T", "Battery"),

# --- Others
("Others", "TN0D", "Northbridge Die"),
("Others", "TN0P", "Northbridge Proximity 1"),
("Others", "TN1P", "Northbridge Proximity 2"),
("Others", "TN0C", "MCH Die"),
("Others", "TN0H", "MCH Heatsink"),
("Others", "TP0D", "PCH Die"),
("Others", "TPCD", "PCH Die"),
("Others", "TP0P", "PCH Proximity"),

("Others", "TA0P", "Airflow 1"),
("Others", "TA1P", "Airflow 2"),
("Others", "Th0H", "Heatpipe 1"),
("Others", "Th1H", "Heatpipe 2"),
("Others", "Th2H", "Heatpipe 3"),

("Others", "Tm0P", "Mainboard Proximity"),
("Others", "Tp0P", "Powerboard Proximity"),
("Others", "Ts0P", "Palm Rest"),
("Others", "Tb0P", "BLC Proximity"),

("Others", "TL0P", "LCD Proximity"),
("Others", "TW0P", "Airport Proximity"),
("Others", "TO0P", "Optical Drive"),

("Others", "Tp0P", "Power Supply 1"),
("Others", "Tp0C", "Power Supply 1 Alt."),
("Others", "Tp1P", "Power Supply 2"),
("Others", "Tp1C", "Power Supply 2 Alt."),
("Others", "Tp2P", "Power Supply 3"),
("Others", "Tp3P", "Power Supply 4"),
("Others", "Tp4P", "Power Supply 5"),
("Others", "Tp5P", "Power Supply 6"),

("Others", "TS0C", "Expansion Slots"),
("Others", "TA0S", "PCI Slot 1 Pos 1"),
("Others", "TA1S", "PCI Slot 1 Pos 2"),
("Others", "TA2S", "PCI Slot 2 Pos 1"),
("Others", "TA3S", "PCI Slot 2 Pos 2"),
)

kinfo_proc_map = dict(
ppid=0,
ruid=1,
Expand Down Expand Up @@ -212,6 +317,35 @@ def disk_partitions(all=False):
# =====================================================================


def sensors_temperatures():
"""Returns a dictionary of regions of temperature sensors:
CPU/GPU/Memory/Others
Each entry contains a list of results of all the successfully polled
SMC keys from the system.
References for SMC keys and meaning:
https://stackoverflow.com/questions/28568775/
description-for-apples-smc-keys/31033665#31033665
https://github.com/Chris911/iStats/blob/
09b159f85a9481b59f347a37259f6d272f65cc05/lib/iStats/smc.rb
http://web.archive.org/web/20140714090133/http://www.parhelia.ch:80/
blog/statics/k3_keys.html
"""
ret = collections.defaultdict(list)

for group, key, label in temperatures:
result = cext.smc_get_temperature(key)
result = round(result, 1)
if result <= 0:
continue
ret[group].append((label, result, None, None))

return dict(ret)


def sensors_battery():
"""Return battery information.
"""
Expand All @@ -230,6 +364,18 @@ def sensors_battery():
return _common.sbattery(percent, secsleft, power_plugged)


def sensors_fans():
"""Return fans speed information.
"""
ret = collections.defaultdict(list)
rawlist = cext.sensors_fans()
if rawlist is not None:
for fan in rawlist:
ret["Fans"].append(_common.sfan(fan[0], fan[1]))

return dict(ret)


# =====================================================================
# --- network
# =====================================================================
Expand Down
68 changes: 68 additions & 0 deletions psutil/_psutil_osx.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
#include "_psutil_common.h"
#include "_psutil_posix.h"
#include "arch/osx/process_info.h"
#include "arch/osx/smc.h"


#define PSUTIL_TV2DOUBLE(t) ((t).tv_sec + (t).tv_usec / 1000000.0)
Expand Down Expand Up @@ -896,6 +897,68 @@ psutil_boot_time(PyObject *self, PyObject *args) {
return Py_BuildValue("f", (float)boot_time);
}

/*
* Return a Python float indicating the value of the temperature
* measured by an SMC key
*/
static PyObject *
psutil_smc_get_temperature(PyObject *self, PyObject *args) {
char* key;
float temp;

if (! PyArg_ParseTuple(args, "s", &key)) {
return NULL;
}
temp = SMCGetTemperature(key);
return Py_BuildValue("d", temp);
}


/*
* Return a Python list of tuples of fan label and speed
*/
static PyObject *
psutil_sensors_fans(PyObject *self, PyObject *args) {
int key;
int speed;
char fan[7];
int fan_count;
PyObject *py_tuple = NULL;
PyObject *py_retlist = PyList_New(0);

if (py_retlist == NULL)
return NULL;

fan_count = SMCGetFanNumber(SMC_KEY_FAN_NUM);
if (fan_count < 0) {
fan_count = 0;
}
for (key =0; key < fan_count; key++) {
sprintf(fan, "Fan %d", key);
speed = SMCGetFanSpeed(key);
if (speed < 0) {
continue;
}
py_tuple = Py_BuildValue(
"(si)",
fan, // label
speed // value
);
if (!py_tuple)
goto error;

if (PyList_Append(py_retlist, py_tuple)) {
goto error;
}
Py_XDECREF(py_tuple);
}

return py_retlist;
error:
Py_XDECREF(py_tuple);
Py_XDECREF(py_retlist);
return NULL;
}

/*
* Return a list of tuples including device, mount point and fs type
Expand Down Expand Up @@ -1828,6 +1891,7 @@ psutil_cpu_stats(PyObject *self, PyObject *args) {
}



/*
* Return battery information.
*/
Expand Down Expand Up @@ -1980,6 +2044,10 @@ PsutilMethods[] = {
"Return currently connected users as a list of tuples"},
{"cpu_stats", psutil_cpu_stats, METH_VARARGS,
"Return CPU statistics"},
{"smc_get_temperature", psutil_smc_get_temperature, METH_VARARGS,
"Temperature of SMC key as float"},
{"sensors_fans", psutil_sensors_fans, METH_VARARGS,
"Return the RPM of the fan with SMC key"},
{"sensors_battery", psutil_sensors_battery, METH_VARARGS,
"Return battery information."},

Expand Down
Loading

0 comments on commit 196802d

Please sign in to comment.