mirror of
https://github.com/morgan9e/macos-stats
synced 2026-04-14 00:04:15 +09:00
fix: fixed fan control on macs with T2 (#430)
This commit is contained in:
@@ -15,6 +15,7 @@ enum CMDType: String {
|
||||
case list
|
||||
case set
|
||||
case fan
|
||||
case fans
|
||||
case help
|
||||
case unknown
|
||||
|
||||
@@ -23,6 +24,7 @@ enum CMDType: String {
|
||||
case "list": self = .list
|
||||
case "set": self = .set
|
||||
case "fan": self = .fan
|
||||
case "fans": self = .fans
|
||||
case "help": self = .help
|
||||
default: self = .unknown
|
||||
}
|
||||
@@ -47,6 +49,7 @@ enum FlagsType: String {
|
||||
}
|
||||
}
|
||||
|
||||
// swiftlint:disable function_body_length
|
||||
func main() {
|
||||
var args = CommandLine.arguments.dropFirst()
|
||||
let cmd = CMDType(value: args.first ?? "")
|
||||
@@ -98,6 +101,7 @@ func main() {
|
||||
guard let idIndex = args.firstIndex(where: { $0 == "-id" }),
|
||||
args.indices.contains(idIndex+1),
|
||||
let id = Int(args[idIndex+1]) else {
|
||||
print("[ERROR]: missing id")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -113,14 +117,33 @@ func main() {
|
||||
}
|
||||
|
||||
print("[ERROR]: missing value or mode")
|
||||
case .fans:
|
||||
guard let count = SMC.shared.getValue("FNum") else {
|
||||
print("FNum not found")
|
||||
return
|
||||
}
|
||||
print("Number of fans: \(count)\n")
|
||||
|
||||
for i in 0..<Int(count) {
|
||||
print("\(i): \(SMC.shared.getStringValue("F\(i)ID") ?? "Fan #\(i)")")
|
||||
print("Actual speed:", SMC.shared.getValue("F\(i)Ac") ?? -1)
|
||||
print("Minimal speed:", SMC.shared.getValue("F\(i)Mn") ?? -1)
|
||||
print("Maximum speed:", SMC.shared.getValue("F\(i)Mx") ?? -1)
|
||||
print("Target speed:", SMC.shared.getValue("F\(i)Tg") ?? -1)
|
||||
print("Mode:", FanMode(rawValue: Int(SMC.shared.getValue("F\(i)Md") ?? -1)) ?? .forced)
|
||||
|
||||
print()
|
||||
}
|
||||
case .help, .unknown:
|
||||
print("SMC tool\n")
|
||||
print("Usage:")
|
||||
print(" ./smc [command]\n")
|
||||
print("Available Commands:")
|
||||
print(" list list keys and values")
|
||||
print(" set set value to a key")
|
||||
print(" help help menu\n")
|
||||
print(" list list keys and values")
|
||||
print(" set set value to a key")
|
||||
print(" fan set fan speed")
|
||||
print(" fans list of fans")
|
||||
print(" help help menu\n")
|
||||
print("Available Flags:")
|
||||
print(" -t list temperature sensors")
|
||||
print(" -v list voltage sensors (list cmd) / value (set cmd)")
|
||||
|
||||
@@ -147,6 +147,10 @@ extension Float {
|
||||
return $0.load(fromByteOffset: 0, as: Self.self)
|
||||
}
|
||||
}
|
||||
|
||||
var bytes: [UInt8] {
|
||||
withUnsafeBytes(of: self, Array.init)
|
||||
}
|
||||
}
|
||||
|
||||
public class SMC {
|
||||
@@ -187,7 +191,7 @@ public class SMC {
|
||||
}
|
||||
}
|
||||
|
||||
public func close() -> kern_return_t{
|
||||
public func close() -> kern_return_t {
|
||||
return IOServiceClose(conn)
|
||||
}
|
||||
|
||||
@@ -202,7 +206,7 @@ public class SMC {
|
||||
}
|
||||
|
||||
if val.dataSize > 0 {
|
||||
if val.bytes.first(where: { $0 != 0}) == nil && val.key != "FS! " {
|
||||
if val.bytes.first(where: { $0 != 0 }) == nil && val.key != "FS! " && val.key != "F0Md" && val.key != "F1Md" {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -346,6 +350,30 @@ public class SMC {
|
||||
// MARK: - fans
|
||||
|
||||
public func setFanMode(_ id: Int, mode: FanMode) {
|
||||
if self.getValue("F\(id)Md") != nil {
|
||||
var result: kern_return_t = 0
|
||||
var value = SMCVal_t("F\(id)Md")
|
||||
|
||||
result = read(&value)
|
||||
if result != kIOReturnSuccess {
|
||||
print("Error read fan mode: " + (String(cString: mach_error_string(result), encoding: String.Encoding.ascii) ?? "unknown error"))
|
||||
return
|
||||
}
|
||||
|
||||
value.bytes = [UInt8(mode.rawValue), UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0),
|
||||
UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0),
|
||||
UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0),
|
||||
UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0),
|
||||
UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0),
|
||||
UInt8(0), UInt8(0)]
|
||||
|
||||
result = write(value)
|
||||
if result != kIOReturnSuccess {
|
||||
print("Error write: " + (String(cString: mach_error_string(result), encoding: String.Encoding.ascii) ?? "unknown error"))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
let fansMode = Int(self.getValue("FS! ") ?? 0)
|
||||
var newMode: UInt8 = 0
|
||||
|
||||
@@ -406,16 +434,29 @@ public class SMC {
|
||||
return
|
||||
}
|
||||
|
||||
var result: kern_return_t = 0
|
||||
var value = SMCVal_t("F\(id)Tg")
|
||||
value.dataSize = 2
|
||||
value.bytes = [UInt8(speed >> 6), UInt8((speed << 2) ^ ((speed >> 6) << 8)), UInt8(0), UInt8(0), UInt8(0), UInt8(0),
|
||||
UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0),
|
||||
UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0),
|
||||
UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0),
|
||||
UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0),
|
||||
UInt8(0), UInt8(0)]
|
||||
|
||||
let result = write(value)
|
||||
result = read(&value)
|
||||
if result != kIOReturnSuccess {
|
||||
print("Error read fan value: " + (String(cString: mach_error_string(result), encoding: String.Encoding.ascii) ?? "unknown error"))
|
||||
return
|
||||
}
|
||||
|
||||
if value.dataType == "flt " {
|
||||
let bytes = Float(speed).bytes
|
||||
value.bytes[0] = bytes[0]
|
||||
value.bytes[1] = bytes[1]
|
||||
value.bytes[2] = bytes[2]
|
||||
value.bytes[3] = bytes[3]
|
||||
} else if value.dataType == "fpe2" {
|
||||
value.bytes[0] = UInt8(speed >> 6)
|
||||
value.bytes[1] = UInt8((speed << 2) ^ ((speed >> 6) << 8))
|
||||
value.bytes[2] = UInt8(0)
|
||||
value.bytes[3] = UInt8(0)
|
||||
}
|
||||
|
||||
result = write(value)
|
||||
if result != kIOReturnSuccess {
|
||||
print("Error write: " + (String(cString: mach_error_string(result), encoding: String.Encoding.ascii) ?? "unknown error"))
|
||||
return
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
debugAsWhichUser = "root"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
@@ -55,6 +56,14 @@
|
||||
argument = "list"
|
||||
isEnabled = "NO">
|
||||
</CommandLineArgument>
|
||||
<CommandLineArgument
|
||||
argument = "fans"
|
||||
isEnabled = "NO">
|
||||
</CommandLineArgument>
|
||||
<CommandLineArgument
|
||||
argument = "fan -id 0 -v 2761"
|
||||
isEnabled = "YES">
|
||||
</CommandLineArgument>
|
||||
<CommandLineArgument
|
||||
argument = "set -k "FS! " -v 0000"
|
||||
isEnabled = "NO">
|
||||
|
||||
Reference in New Issue
Block a user