Open Vxider opened 4 years ago
I'm interested in working on this, if nobody else is! (I'm experiencing this issue on macOS 10.15.4 with my new MacBook Pro)
powermetrics
still returns an RPM for "Fan" (sudo powermetrics --samplers smc -i1 -n1
to get a single SMC sample).
Just guessing here, I know nothing about macOS or SMC, but maybe the library this uses to get SMC information is finally incompatible with a macOS update? If so, maybe another library I ran into today trying to get my computer's temperature may help: DanielStormApps/SMC. It's written in Swift not C, but perhaps it would be useful.
Again, just riffing. If nobody has come back to this before I do again (which may be a long while) I'll look at it closer. With any luck it'll be a small change, but 🤷
I found a useful tool istats which allows grabbing the CPU temperature, fan speeds and battery information on OS X.
iStats is cool, but I'm a minimalist ;)
I'd use powermetrics if the single-sample command wasn't so hard to remember.
This is a command-line tool, not the famous iStat Menu.
Yeah, I know :)
Regardless, I'm experiencing this issue and would like to try to fix it. Issues #19 and #21 report similar problems with strange reports of fans. @lavoiesl mentioned in #21 that taking some fan-printing code from smcFanControl would be wise. Both of these projects are GPLv2 licensed, so although I'm not well versed in how one usually goes about crediting such it seems very doable. Again, I haven't looked at the code so maybe it's more difficult that it seems.
The datatype in SMCGetFanRPM doesn't match. This fixes getting the data:
#define IS_FLT(A) *(UInt32*)(A.dataType) == *(UInt32*)("flt ")
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 (IS_FLT(val)) return *((float*)val.bytes);
else if (strcmp(val.dataType, DATATYPE_FPE2) == 0) {
// convert fpe2 value to RPM
return ntohs(*(UInt16*)val.bytes) / 4.0;
}
}
}
// read failed
return -1.f;
}
Also I'm not sure what values are supposed to be printed. I changed it to:
printf("Fan %d - %s at %.0f RPM (%.0f%%)\n", i, name, actual_speed, 100*actual_speed/maximum_speed);
The code formatting doesn't work very well. The important lines are the two with IS_FLT in.
Get fan speed but returns fan number