mirror of
https://github.com/morgan9e/macos-stats
synced 2026-04-14 00:04:15 +09:00
feat: add a SMCHelper to work with SMC
This commit is contained in:
@@ -105,18 +105,6 @@ public extension Int {
|
||||
return NSColor.controlAccentColor
|
||||
}
|
||||
}
|
||||
|
||||
init(fromFPE2 bytes: (UInt8, UInt8)) {
|
||||
self = (Int(bytes.0) << 6) + (Int(bytes.1) >> 2)
|
||||
}
|
||||
}
|
||||
|
||||
extension Float {
|
||||
init?(_ bytes: [UInt8]) {
|
||||
self = bytes.withUnsafeBytes {
|
||||
return $0.load(fromByteOffset: 0, as: Self.self)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public extension Double {
|
||||
@@ -403,36 +391,6 @@ extension URL {
|
||||
}
|
||||
}
|
||||
|
||||
// swiftlint:disable large_tuple
|
||||
extension UInt32 {
|
||||
init(bytes: (UInt8, UInt8, UInt8, UInt8)) {
|
||||
self = UInt32(bytes.0) << 24 | UInt32(bytes.1) << 16 | UInt32(bytes.2) << 8 | UInt32(bytes.3)
|
||||
}
|
||||
}
|
||||
|
||||
extension UInt16 {
|
||||
init(bytes: (UInt8, UInt8)) {
|
||||
self = UInt16(bytes.0) << 8 | UInt16(bytes.1)
|
||||
}
|
||||
}
|
||||
|
||||
extension FourCharCode {
|
||||
init(fromString str: String) {
|
||||
precondition(str.count == 4)
|
||||
|
||||
self = str.utf8.reduce(0) { sum, character in
|
||||
return sum << 8 | UInt32(character)
|
||||
}
|
||||
}
|
||||
|
||||
func toString() -> String {
|
||||
return String(describing: UnicodeScalar(self >> 24 & 0xff)!) +
|
||||
String(describing: UnicodeScalar(self >> 16 & 0xff)!) +
|
||||
String(describing: UnicodeScalar(self >> 8 & 0xff)!) +
|
||||
String(describing: UnicodeScalar(self & 0xff)!)
|
||||
}
|
||||
}
|
||||
|
||||
public extension NSColor {
|
||||
convenience init(hexString: String, alpha: CGFloat = 1.0) {
|
||||
let hexString: String = hexString.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
|
||||
|
||||
@@ -878,3 +878,68 @@ public class SettingsContainerView: NSStackView {
|
||||
self.resize()
|
||||
}
|
||||
}
|
||||
|
||||
public class SMCHelper {
|
||||
public static let shared = SMCHelper()
|
||||
private let smc: String
|
||||
|
||||
public init() {
|
||||
self.smc = Bundle.main.path(forResource: "smc", ofType: nil)!
|
||||
}
|
||||
|
||||
public func setFanSpeed(_ id: Int, speed: Int) {
|
||||
if !self.checkRights() {
|
||||
if !self.ensureRights() {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
_ = syncShell("\(self.smc) fan -id \(id) -v \(speed)")
|
||||
}
|
||||
|
||||
public func setFanMode(_ id: Int, mode: Int) {
|
||||
if !self.checkRights() {
|
||||
if !self.ensureRights() {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
_ = syncShell("\(self.smc) fan -id \(id) -m \(mode)")
|
||||
}
|
||||
|
||||
private func checkRights() -> Bool {
|
||||
do {
|
||||
let attributes = try FileManager.default.attributesOfItem(atPath: self.smc)
|
||||
guard let owner = attributes[FileAttributeKey(rawValue: "NSFileOwnerAccountName")] as? String,
|
||||
let ownerGroup = attributes[FileAttributeKey(rawValue: "NSFileGroupOwnerAccountName")] as? String,
|
||||
let permissions = attributes[FileAttributeKey(rawValue: "NSFilePosixPermissions")] as? Int else {
|
||||
print("some of the smc attributes is missing")
|
||||
return false
|
||||
}
|
||||
|
||||
if owner == "root" && ownerGroup == "admin" && permissions == 3437 {
|
||||
return true
|
||||
}
|
||||
} catch let error {
|
||||
print("get smc attributes, \(error)")
|
||||
return false
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
private func ensureRights() -> Bool {
|
||||
guard let script = NSAppleScript(source: "do shell script \"/usr/sbin/chown root:admin \(self.smc) && /bin/chmod 6555 \(self.smc)\" with administrator privileges") else {
|
||||
return false
|
||||
}
|
||||
|
||||
var err: NSDictionary? = nil
|
||||
script.executeAndReturnError(&err)
|
||||
if err != nil {
|
||||
print("cannot upgrade owner to root: \(String(describing: err))")
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user