Skip to content

Commit

Permalink
Refactor and add gpu/fan
Browse files Browse the repository at this point in the history
  • Loading branch information
lavoiesl committed Sep 11, 2018
1 parent 22a86f5 commit e3c44d4
Show file tree
Hide file tree
Showing 2 changed files with 160 additions and 37 deletions.
196 changes: 159 additions & 37 deletions smc.c
Original file line number Diff line number Diff line change
Expand Up @@ -173,11 +173,11 @@ double SMCGetFanSpeed(char *key)
if (result == kIOReturnSuccess) {
// read succeeded - check returned value
if (val.dataSize > 0) {
if (strcmp(val.dataType, DATATYPE_FPE2) == 0) {
// convert fpe2 value to rpm
int intValue = (unsigned char)val.bytes[0] * 256 + (unsigned char)val.bytes[1];
return intValue / 4.0;
}
if (strcmp(val.dataType, DATATYPE_FPE2) == 0) {
// convert fpe2 value to rpm
int intValue = (unsigned char)val.bytes[0] * 256 + (unsigned char)val.bytes[1];
return intValue / 4.0;
}
}
}
// read failed
Expand All @@ -189,52 +189,174 @@ double convertToFahrenheit(double celsius) {
return (celsius * (9.0 / 5.0)) + 32.0;
}

// Requires SMCOpen()
void readAndPrintCpuTemp(int show_title, char scale) {
double temperature = SMCGetTemperature(SMC_KEY_CPU_TEMP);
if (scale == 'F') {
temperature = convertToFahrenheit(temperature);
}

char *title = "";
if (show_title) {
title = "CPU: ";
}
printf("%s%0.1f°%c\n", title, temperature, scale);
}

// Requires SMCOpen()
void readAndPrintGpuTemp(int show_title, char scale) {
double temperature = SMCGetTemperature(SMC_KEY_GPU_TEMP);
if (scale == 'F') {
temperature = convertToFahrenheit(temperature);
}

char *title = "";
if (show_title) {
title = "GPU: ";
}
printf("%s%0.1f°%c\n", title, temperature, scale);
}

float SMCGetFanRPM(char *key)
{
SMCVal_t val;
kern_return_t result;

result = SMCReadKey(key, &val);
if (result == kIOReturnSuccess) {
// read succeeded - check returned value
if (val.dataSize > 0) {
if (strcmp(val.dataType, DATATYPE_FPE2) == 0) {
// convert fpe2 value to RPM
return ntohs(*(UInt16*)val.bytes) / 4.0;
}
}
}
// read failed
return -1.f;
}

// Requires SMCOpen()
void readAndPrintFanRPMs(void)
{
kern_return_t result;
SMCVal_t val;
UInt32Char_t key;
int totalFans, i;

result = SMCReadKey("FNum", &val);

if(result == kIOReturnSuccess)
{
totalFans = _strtoul((char *)val.bytes, val.dataSize, 10);

printf("Num fans: %d\n", totalFans);
for(i = 0; i < totalFans; i++) {
sprintf(key, "F%dID", i);
result = SMCReadKey(key, &val);
if (result != kIOReturnSuccess) {
continue;
}
char* name = val.bytes + 4;

sprintf(key, "F%dAc", i);
float actual_speed = SMCGetFanRPM(key);
if (actual_speed < 0.f) {
continue;
}

sprintf(key, "F%dMn", i);
float minimum_speed = SMCGetFanRPM(key);
if (minimum_speed < 0.f) {
continue;
}

sprintf(key, "F%dMx", i);
float maximum_speed = SMCGetFanRPM(key);
if (maximum_speed < 0.f) {
continue;
}

float rpm = actual_speed - minimum_speed;
if (rpm < 0.f) {
rpm = 0.f;
}
float pct = rpm / (maximum_speed - minimum_speed);

pct *= 100.f;
printf("Fan %d - %s at %.0f RPM (%.0f%%)\n", i, name, rpm, pct);

//sprintf(key, "F%dSf", i);
//SMCReadKey(key, &val);
//printf(" Safe speed : %.0f\n", strtof(val.bytes, val.dataSize, 2));
//sprintf(key, "F%dTg", i);
//SMCReadKey(key, &val);
//printf(" Target speed : %.0f\n", strtof(val.bytes, val.dataSize, 2));
//SMCReadKey("FS! ", &val);
//if ((_strtoul((char *)val.bytes, 2, 16) & (1 << i)) == 0)
// printf(" Mode : auto\n");
//else
// printf(" Mode : forced\n");
}
}
}

int main(int argc, char *argv[])
{
char scale = 'C';
int cpu = 0;
int fan = 0;
int gpu = 0;

int c;
while ((c = getopt(argc, argv, "CFf")) != -1) {
switch (c) {
case 'F':
case 'C':
scale = c;
break;
case 'f':
fan = 1;
break;
}
while ((c = getopt(argc, argv, "CFcfgh?")) != -1) {
switch (c) {
case 'F':
case 'C':
scale = c;
break;
case 'c':
cpu = 1;
break;
case 'f':
fan = 1;
break;
case 'g':
gpu = 1;
break;
case 'h':
case '?':
printf("usage: osx-cpu-temp <options>\n");
printf("Options:\n");
printf(" -F Display temperatures in degrees Fahrenheit.\n");
printf(" -C Display temperatures in degrees Celsius (Default).\n");
printf(" -c Display CPU temperature (Default).\n");
printf(" -g Display GPU temperature.\n");
printf(" -f Display fan speeds.\n");
printf(" -h Display this help.\n");
printf("\nIf more than one of -c, -f, or -g are specified, titles will be added\n");
return -1;
}
}

if (!fan && !gpu) {
cpu = 1;
}

int nfans = 0;
double fans[10];
int show_title = fan + gpu + cpu > 1;

SMCOpen();
double temperature = SMCGetTemperature(SMC_KEY_CPU_TEMP);
int i;
for (i = 0; i < 10; i++) {
char key[5] = SMC_KEY_FAN0_RPM_CUR;
key[1] += i;
double speed = SMCGetFanSpeed(key);
if (speed != 0) {
fans[nfans++] = speed;
}
}
SMCClose();

if (scale == 'F') {
temperature = convertToFahrenheit(temperature);
if (cpu) {
readAndPrintCpuTemp(show_title, scale);
}
if (gpu) {
readAndPrintGpuTemp(show_title, scale);
}

printf("%0.1f°%c", temperature, scale);
if (fan) {
int i;
for (i = 0; i < nfans; i++) {
printf(" %0.1frpm", fans[i]);
}
readAndPrintFanRPMs();
}
printf("\n");

SMCClose();
return 0;
}
1 change: 1 addition & 0 deletions smc.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@

// key values
#define SMC_KEY_CPU_TEMP "TC0P"
#define SMC_KEY_GPU_TEMP "TG0P"
#define SMC_KEY_FAN0_RPM_CUR "F0Ac"

typedef struct {
Expand Down

0 comments on commit e3c44d4

Please sign in to comment.