SMCKit icon indicating copy to clipboard operation
SMCKit copied to clipboard

fanSetMinSpeed() doesn't seem to work?

Open PKBeam opened this issue 7 years ago • 9 comments

Running this code as root (with SIP off):

import SMCKit

func setMinimumFanspeed5000() {
        do {
            try SMCKit.open()

            do {
                try SMCKit.fanSetMinSpeed(0, speed: 5000)
            } catch {
                print("Error - could not set fan speed")
            }

            do {
                print(try SMCKit.fanMinSpeed(0))
            } catch {
                print("Error.")
            }

            let _ = SMCKit.close()
        } catch {
            print("Error - could not open connection to SMC")
        }
    }

setMinimumFanspeed5000()

Prints 5000 as expected, but the fan itself does not seem to change its speed - there is no audible sound and SMCKit.fanCurrentSpeed(0) still returns 0.

PKBeam avatar Nov 27 '16 02:11 PKBeam

From a quick test, this works for me. I'm on a MacBookPro11,5 running 10.11.6. What machine are you running this on? MacBookPro13,2 with 10.12.1 (#28)? Could be due to that. I don't have a machine running Sierra to test with at the moment unfortunately. At the same time, could be a change with the new hardware.

Aside:

  • You can cross check the current fan speed with Apple's tool, like so (though it only gives you the first fan). You'll need to have the power adapter plugged in (won't output results otherwise):

sudo powermetrics --sampler smc --sample-count 1

  • Interestingly, having SIP off isn't needed

beltex avatar Nov 27 '16 22:11 beltex

Yes, it's a MacBookPro13,2 with 10.12.1.

smcFanControl is likewise broken on this computer, but Macs Fan Control does change the fan speed as expected.

PKBeam avatar Nov 27 '16 23:11 PKBeam

Macs Fan Control does change the fan speed as expected.

ah! Don't have a thought as to what it could be then offhand. Will investigate.

beltex avatar Nov 27 '16 23:11 beltex

After some testing I found some interesting results.

The MacBookPro13,2 will idle with fans at 0 RPM, as reported by powermetrics. I think this is true for the older Retina models as well.

fanSetMinSpeed() has a visible effect only after macOS raises the fan speed by itself. For example, setting a fan speed of 2400 RPM while the fans are not spinning won't do anything. But as soon as macOS turns them on, the fans will jump up to 2400 RPM.

Trying to reset the fan speed with SMCKit.fanSetMinSpeed(0, speed: 1) will drop the fans to ~1300 RPM (which seems to be the lowest speed the fans will spin at when on). An SMC reset will fix this.

It seems that SMCKit can't actually turn the fans on or off?

PKBeam avatar Nov 28 '16 07:11 PKBeam

The MacBookPro13,2 will idle with fans at 0 RPM, as reported by powermetrics. I think this is true for the older Retina models as well.

hmm, I don't ever recall this happening (would be surprised!), on older models that is. Based on how many samples from powermetrics?

fanSetMinSpeed() has a visible effect only after macOS raises the fan speed by itself.

It usually responds right away, but seems to have additional internal logic to override and such, as needed. As stated in docs:

By minimum we mean that OS X can interject and raise the fan speed if needed, however it will not go below this.

Trying to reset the fan speed with SMCKit.fanSetMinSpeed(0, speed: 1) will drop the fans to ~1300 RPM (which seems to be the lowest speed the fans will spin at when on).

The SMC driver likely has builtin safe guards to prevent dropping the fan to zero (or rather, below the default, which ~1300 RPM sounds right for a 13" model).

An SMC reset will fix this.

Rebooting should reset everything (set fan min via SMCKit is not persistent between boots), but yes an SMC reset may be needed on occasion it seems to correct any issues.

It seems that SMCKit can't actually turn the fans on or off?

Not off, but as mentioned, raising the min usually has the system respond fairly quickly ("on"). I recall there being a fan force bit to entirely override control from the OS, but I never added it since it seems to be a narrow use case, and frankly dangerous :)

beltex avatar Nov 29 '16 04:11 beltex

Based on how many samples from powermetrics?

5 just then, all returning 0 rpm, along with SMCKit, smcFanControl and Macs Fan Control.

PKBeam avatar Nov 29 '16 08:11 PKBeam

Interesting!

beltex avatar Nov 30 '16 01:11 beltex

fanSetMinSpeed() has a visible effect only after macOS raises the fan speed by itself. For example, setting a fan speed of 2400 RPM while the fans are not spinning won't do anything. But as soon as macOS turns them on, the fans will jump up to 2400 RPM.

For the record, macOS doesn't do this : the SMC does, based on its own algorithm and input from the temp sensors. Although I guess the OS could forcefully set the fan speed by using the "force bit" – a way to entirely override control and transfer from the SMC to the OS. In normal operation though, the SMC handles things by itself and may or may not perform commands issued to it.

perfaram avatar Jun 03 '17 17:06 perfaram

I've not tried anything, but if the minimum fan speed only has an effect after macOS sets the fan speed, you could try to force the SMC to update by setting the fan speed to the minimum value. So, after fanSetMinSpeed(2400RPM), do fanSetSpeed(2400RPM). Then, as long as the force bit isn't set, the SMC should revv up the fans whenever needed, but never lower it below 2400RPM.

Regarding "fanSetSpeed", this function doesn't currently exist in SMCKit. It would work in the same way fanSetMinSpeed does, except by setting the key FnTg, where n is the fan number, using 0-based indexing. Its type is the same as FnMn, that is to say, fpe2.

perfaram avatar Oct 15 '17 14:10 perfaram