mirror of
https://github.com/morgan9e/macos-stats
synced 2026-04-14 00:04:15 +09:00
feat: initialized SMC as a command-line app ($454)
This commit is contained in:
47
SMC/main.swift
Normal file
47
SMC/main.swift
Normal file
@@ -0,0 +1,47 @@
|
||||
//
|
||||
// main.swift
|
||||
// SMC
|
||||
//
|
||||
// Created by Serhiy Mytrovtsiy on 25/05/2021.
|
||||
// Using Swift 5.0.
|
||||
// Running on macOS 10.15.
|
||||
//
|
||||
// Copyright © 2021 Serhiy Mytrovtsiy. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
func main() {
|
||||
let args = CommandLine.arguments.dropFirst()
|
||||
let cmd = CMDType(value: args.first ?? "")
|
||||
|
||||
switch cmd {
|
||||
case .list:
|
||||
var keys = SMC.shared.getAllKeys()
|
||||
args.dropFirst().forEach { (arg: String) in
|
||||
let flag = FlagsType(value: arg)
|
||||
if flag != .all {
|
||||
keys = keys.filter{ $0.hasPrefix(flag.rawValue)}
|
||||
}
|
||||
}
|
||||
|
||||
keys.forEach { (key: String) in
|
||||
let value = SMC.shared.getValue(key)
|
||||
print("[\(key)] ", value ?? 0)
|
||||
}
|
||||
case .help, .unknown:
|
||||
print("SMC tool\n")
|
||||
print("Usage:")
|
||||
print(" ./smc [command]\n")
|
||||
print("Available Commands:")
|
||||
print(" list list keys and values")
|
||||
print(" help help menu\n")
|
||||
print("Available Flags:")
|
||||
print(" -t list temperature sensors")
|
||||
print(" -v list voltage sensors")
|
||||
print(" -p list power sensors")
|
||||
print(" -f list fans\n")
|
||||
}
|
||||
}
|
||||
|
||||
main()
|
||||
348
SMC/smc.swift
Normal file
348
SMC/smc.swift
Normal file
@@ -0,0 +1,348 @@
|
||||
//
|
||||
// smc.swift
|
||||
// SMC
|
||||
//
|
||||
// Created by Serhiy Mytrovtsiy on 25/05/2021.
|
||||
// Using Swift 5.0.
|
||||
// Running on macOS 10.15.
|
||||
//
|
||||
// Copyright © 2021 Serhiy Mytrovtsiy. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import IOKit
|
||||
|
||||
public class SMC {
|
||||
public static let shared = SMC()
|
||||
|
||||
private var conn: io_connect_t = 0
|
||||
|
||||
public init() {
|
||||
var result: kern_return_t
|
||||
var iterator: io_iterator_t = 0
|
||||
let device: io_object_t
|
||||
|
||||
let matchingDictionary: CFMutableDictionary = IOServiceMatching("AppleSMC")
|
||||
result = IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDictionary, &iterator)
|
||||
if result != kIOReturnSuccess {
|
||||
print("Error IOServiceGetMatchingServices(): " + (String(cString: mach_error_string(result), encoding: String.Encoding.ascii) ?? "unknown error"))
|
||||
return
|
||||
}
|
||||
|
||||
device = IOIteratorNext(iterator)
|
||||
IOObjectRelease(iterator)
|
||||
if device == 0 {
|
||||
print("Error IOIteratorNext(): " + (String(cString: mach_error_string(result), encoding: String.Encoding.ascii) ?? "unknown error"))
|
||||
return
|
||||
}
|
||||
|
||||
result = IOServiceOpen(device, mach_task_self_, 0, &conn)
|
||||
IOObjectRelease(device)
|
||||
if result != kIOReturnSuccess {
|
||||
print("Error IOServiceOpen(): " + (String(cString: mach_error_string(result), encoding: String.Encoding.ascii) ?? "unknown error"))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
deinit {
|
||||
let result = self.close()
|
||||
if result != kIOReturnSuccess {
|
||||
print("error close smc connection: " + (String(cString: mach_error_string(result), encoding: String.Encoding.ascii) ?? "unknown error"))
|
||||
}
|
||||
}
|
||||
|
||||
public func close() -> kern_return_t{
|
||||
return IOServiceClose(conn)
|
||||
}
|
||||
|
||||
public func getValue(_ key: String) -> Double? {
|
||||
var result: kern_return_t = 0
|
||||
var val: SMCVal_t = SMCVal_t(key)
|
||||
|
||||
result = read(&val)
|
||||
if result != kIOReturnSuccess {
|
||||
print("Error read(\(key)): " + (String(cString: mach_error_string(result), encoding: String.Encoding.ascii) ?? "unknown error"))
|
||||
return nil
|
||||
}
|
||||
|
||||
if val.dataSize > 0 {
|
||||
if val.bytes.first(where: { $0 != 0}) == nil && val.key != "FS! " {
|
||||
return nil
|
||||
}
|
||||
|
||||
switch val.dataType {
|
||||
case SMCDataType.UI8.rawValue:
|
||||
return Double(val.bytes[0])
|
||||
case SMCDataType.UI16.rawValue:
|
||||
return Double(UInt16(bytes: (val.bytes[0], val.bytes[1])))
|
||||
case SMCDataType.UI32.rawValue:
|
||||
return Double(UInt32(bytes: (val.bytes[0], val.bytes[1], val.bytes[2], val.bytes[3])))
|
||||
case SMCDataType.SP1E.rawValue:
|
||||
let result: Double = Double(UInt16(val.bytes[0]) * 256 + UInt16(val.bytes[1]))
|
||||
return Double(result / 16384)
|
||||
case SMCDataType.SP3C.rawValue:
|
||||
let result: Double = Double(UInt16(val.bytes[0]) * 256 + UInt16(val.bytes[1]))
|
||||
return Double(result / 4096)
|
||||
case SMCDataType.SP4B.rawValue:
|
||||
let result: Double = Double(UInt16(val.bytes[0]) * 256 + UInt16(val.bytes[1]))
|
||||
return Double(result / 2048)
|
||||
case SMCDataType.SP5A.rawValue:
|
||||
let result: Double = Double(UInt16(val.bytes[0]) * 256 + UInt16(val.bytes[1]))
|
||||
return Double(result / 1024)
|
||||
case SMCDataType.SP69.rawValue:
|
||||
let result: Double = Double(UInt16(val.bytes[0]) * 256 + UInt16(val.bytes[1]))
|
||||
return Double(result / 512)
|
||||
case SMCDataType.SP78.rawValue:
|
||||
let intValue: Double = Double(Int(val.bytes[0]) * 256 + Int(val.bytes[1]))
|
||||
return Double(intValue / 256)
|
||||
case SMCDataType.SP87.rawValue:
|
||||
let intValue: Double = Double(Int(val.bytes[0]) * 256 + Int(val.bytes[1]))
|
||||
return Double(intValue / 128)
|
||||
case SMCDataType.SP96.rawValue:
|
||||
let intValue: Double = Double(Int(val.bytes[0]) * 256 + Int(val.bytes[1]))
|
||||
return Double(intValue / 64)
|
||||
case SMCDataType.SPB4.rawValue:
|
||||
let intValue: Double = Double(Int(val.bytes[0]) * 256 + Int(val.bytes[1]))
|
||||
return Double(intValue / 16)
|
||||
case SMCDataType.SPF0.rawValue:
|
||||
let intValue: Double = Double(Int(val.bytes[0]) * 256 + Int(val.bytes[1]))
|
||||
return intValue
|
||||
case SMCDataType.FLT.rawValue:
|
||||
let value: Float? = Float(val.bytes)
|
||||
if value != nil {
|
||||
return Double(value!)
|
||||
}
|
||||
return nil
|
||||
case SMCDataType.FPE2.rawValue:
|
||||
return Double(Int(fromFPE2: (val.bytes[0], val.bytes[1])))
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
public func getStringValue(_ key: String) -> String? {
|
||||
var result: kern_return_t = 0
|
||||
var val: SMCVal_t = SMCVal_t(key)
|
||||
|
||||
result = read(&val)
|
||||
if result != kIOReturnSuccess {
|
||||
print("Error read(): " + (String(cString: mach_error_string(result), encoding: String.Encoding.ascii) ?? "unknown error"))
|
||||
return nil
|
||||
}
|
||||
|
||||
if val.dataSize > 0 {
|
||||
if val.bytes.first(where: { $0 != 0}) == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
switch val.dataType {
|
||||
case SMCDataType.FDS.rawValue:
|
||||
let c1 = String(UnicodeScalar(val.bytes[4]))
|
||||
let c2 = String(UnicodeScalar(val.bytes[5]))
|
||||
let c3 = String(UnicodeScalar(val.bytes[6]))
|
||||
let c4 = String(UnicodeScalar(val.bytes[7]))
|
||||
let c5 = String(UnicodeScalar(val.bytes[8]))
|
||||
let c6 = String(UnicodeScalar(val.bytes[9]))
|
||||
let c7 = String(UnicodeScalar(val.bytes[10]))
|
||||
let c8 = String(UnicodeScalar(val.bytes[11]))
|
||||
let c9 = String(UnicodeScalar(val.bytes[12]))
|
||||
let c10 = String(UnicodeScalar(val.bytes[13]))
|
||||
let c11 = String(UnicodeScalar(val.bytes[14]))
|
||||
let c12 = String(UnicodeScalar(val.bytes[15]))
|
||||
|
||||
return (c1 + c2 + c3 + c4 + c5 + c6 + c7 + c8 + c9 + c10 + c11 + c12).trimmingCharacters(in: .whitespaces)
|
||||
default:
|
||||
print("unsupported data type \(val.dataType) for key: \(key)")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
private func read(_ value: UnsafeMutablePointer<SMCVal_t>) -> kern_return_t {
|
||||
var result: kern_return_t = 0
|
||||
var input = SMCKeyData_t()
|
||||
var output = SMCKeyData_t()
|
||||
|
||||
input.key = FourCharCode(fromString: value.pointee.key)
|
||||
input.data8 = SMCKeys.READ_KEYINFO.rawValue
|
||||
|
||||
result = call(SMCKeys.KERNEL_INDEX.rawValue, input: &input, output: &output)
|
||||
if result != kIOReturnSuccess {
|
||||
return result
|
||||
}
|
||||
|
||||
value.pointee.dataSize = UInt32(output.keyInfo.dataSize)
|
||||
value.pointee.dataType = output.keyInfo.dataType.toString()
|
||||
input.keyInfo.dataSize = output.keyInfo.dataSize
|
||||
input.data8 = SMCKeys.READ_BYTES.rawValue
|
||||
|
||||
result = call(SMCKeys.KERNEL_INDEX.rawValue, input: &input, output: &output)
|
||||
if result != kIOReturnSuccess {
|
||||
return result
|
||||
}
|
||||
|
||||
memcpy(&value.pointee.bytes, &output.bytes, Int(value.pointee.dataSize))
|
||||
|
||||
return kIOReturnSuccess
|
||||
}
|
||||
|
||||
private func write(_ value: SMCVal_t) -> kern_return_t {
|
||||
var input = SMCKeyData_t()
|
||||
var output = SMCKeyData_t()
|
||||
|
||||
input.key = FourCharCode(fromString: value.key)
|
||||
input.data8 = SMCKeys.WRITE_BYTES.rawValue
|
||||
input.keyInfo.dataSize = IOByteCount(value.dataSize)
|
||||
input.bytes = (value.bytes[0], value.bytes[1], value.bytes[2], value.bytes[3], value.bytes[4], value.bytes[5],
|
||||
value.bytes[6], value.bytes[7], value.bytes[8], value.bytes[9], value.bytes[10], value.bytes[11],
|
||||
value.bytes[12], value.bytes[13], value.bytes[14], value.bytes[15], value.bytes[16], value.bytes[17],
|
||||
value.bytes[18], value.bytes[19], value.bytes[20], value.bytes[21], value.bytes[22], value.bytes[23],
|
||||
value.bytes[24], value.bytes[25], value.bytes[26], value.bytes[27], value.bytes[28], value.bytes[29],
|
||||
value.bytes[30], value.bytes[31])
|
||||
|
||||
let result = self.call(SMCKeys.KERNEL_INDEX.rawValue, input: &input, output: &output)
|
||||
if result != kIOReturnSuccess {
|
||||
print("Error call(WRITE_BYTES): " + (String(cString: mach_error_string(result), encoding: String.Encoding.ascii) ?? "unknown error"))
|
||||
return result
|
||||
}
|
||||
|
||||
return kIOReturnSuccess
|
||||
}
|
||||
|
||||
private func call(_ index: UInt8, input: inout SMCKeyData_t, output: inout SMCKeyData_t) -> kern_return_t {
|
||||
let inputSize = MemoryLayout<SMCKeyData_t>.stride
|
||||
var outputSize = MemoryLayout<SMCKeyData_t>.stride
|
||||
|
||||
return IOConnectCallStructMethod(
|
||||
conn,
|
||||
UInt32(index),
|
||||
&input,
|
||||
inputSize,
|
||||
&output,
|
||||
&outputSize
|
||||
)
|
||||
}
|
||||
|
||||
public func getAllKeys() -> [String] {
|
||||
var list: [String] = []
|
||||
|
||||
let keysNum: Double? = self.getValue("#KEY")
|
||||
if keysNum == nil {
|
||||
print("ERROR no keys count found")
|
||||
return list
|
||||
}
|
||||
|
||||
var result: kern_return_t = 0
|
||||
var input: SMCKeyData_t = SMCKeyData_t()
|
||||
var output: SMCKeyData_t = SMCKeyData_t()
|
||||
|
||||
for i in 0...Int(keysNum!) {
|
||||
input = SMCKeyData_t()
|
||||
output = SMCKeyData_t()
|
||||
|
||||
input.data8 = SMCKeys.READ_INDEX.rawValue
|
||||
input.data32 = UInt32(i)
|
||||
|
||||
result = call(SMCKeys.KERNEL_INDEX.rawValue, input: &input, output: &output)
|
||||
if result != kIOReturnSuccess {
|
||||
continue
|
||||
}
|
||||
|
||||
list.append(output.key.toString())
|
||||
}
|
||||
|
||||
return list
|
||||
}
|
||||
|
||||
public func setFanMode(_ id: Int, mode: FanMode) {
|
||||
let fansMode = Int(self.getValue("FS! ") ?? 0)
|
||||
var newMode: UInt8 = 0
|
||||
|
||||
if fansMode == 0 && id == 0 && mode == .forced {
|
||||
newMode = 1
|
||||
} else if fansMode == 0 && id == 1 && mode == .forced {
|
||||
newMode = 2
|
||||
} else if fansMode == 1 && id == 0 && mode == .automatic {
|
||||
newMode = 0
|
||||
} else if fansMode == 1 && id == 1 && mode == .forced {
|
||||
newMode = 3
|
||||
} else if fansMode == 2 && id == 1 && mode == .automatic {
|
||||
newMode = 0
|
||||
} else if fansMode == 2 && id == 0 && mode == .forced {
|
||||
newMode = 3
|
||||
} else if fansMode == 3 && id == 0 && mode == .automatic {
|
||||
newMode = 2
|
||||
} else if fansMode == 3 && id == 1 && mode == .automatic {
|
||||
newMode = 1
|
||||
}
|
||||
|
||||
if fansMode == newMode {
|
||||
return
|
||||
}
|
||||
|
||||
var result: kern_return_t = 0
|
||||
var value = SMCVal_t("FS! ")
|
||||
|
||||
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 = [0, newMode, 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
|
||||
}
|
||||
}
|
||||
|
||||
public func resetFans() {
|
||||
var value = SMCVal_t("FS! ")
|
||||
value.dataSize = 2
|
||||
|
||||
let result = write(value)
|
||||
if result != kIOReturnSuccess {
|
||||
print("Error write: " + (String(cString: mach_error_string(result), encoding: String.Encoding.ascii) ?? "unknown error"))
|
||||
}
|
||||
}
|
||||
|
||||
public func setFanSpeed(_ id: Int, speed: Int) {
|
||||
let minSpeed = Int(self.getValue("F\(id)Mn") ?? 2500)
|
||||
let maxSpeed = Int(self.getValue("F\(id)Mx") ?? 4000)
|
||||
|
||||
if speed < minSpeed {
|
||||
print("new fan speed (\(speed)) is less than minimum speed (\(minSpeed))")
|
||||
return
|
||||
} else if speed > maxSpeed {
|
||||
print("new fan speed (\(speed)) is more than maximum speed (\(maxSpeed))")
|
||||
return
|
||||
}
|
||||
|
||||
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)
|
||||
if result != kIOReturnSuccess {
|
||||
print("Error write: " + (String(cString: mach_error_string(result), encoding: String.Encoding.ascii) ?? "unknown error"))
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
188
SMC/types.swift
Normal file
188
SMC/types.swift
Normal file
@@ -0,0 +1,188 @@
|
||||
//
|
||||
// types.swift
|
||||
// SMC
|
||||
//
|
||||
// Created by Serhiy Mytrovtsiy on 25/05/2021.
|
||||
// Using Swift 5.0.
|
||||
// Running on macOS 10.15.
|
||||
//
|
||||
// Copyright © 2021 Serhiy Mytrovtsiy. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
// MARK: - main
|
||||
|
||||
enum CMDType: String {
|
||||
case list
|
||||
case help
|
||||
case unknown
|
||||
|
||||
init(value: String) {
|
||||
switch value {
|
||||
case "list": self = .list
|
||||
case "help": self = .help
|
||||
default: self = .unknown
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum FlagsType: String {
|
||||
case temperature = "T"
|
||||
case voltage = "V"
|
||||
case power = "P"
|
||||
case fans = "F"
|
||||
case all
|
||||
|
||||
init(value: String) {
|
||||
switch value {
|
||||
case "-t": self = .temperature
|
||||
case "-v": self = .voltage
|
||||
case "-p": self = .power
|
||||
case "-f": self = .fans
|
||||
default: self = .all
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - smc
|
||||
|
||||
internal enum SMCDataType: String {
|
||||
case UI8 = "ui8 "
|
||||
case UI16 = "ui16"
|
||||
case UI32 = "ui32"
|
||||
case SP1E = "sp1e"
|
||||
case SP3C = "sp3c"
|
||||
case SP4B = "sp5b"
|
||||
case SP5A = "sp5a"
|
||||
case SP69 = "sp669"
|
||||
case SP78 = "sp78"
|
||||
case SP87 = "sp87"
|
||||
case SP96 = "sp96"
|
||||
case SPB4 = "spb4"
|
||||
case SPF0 = "spf0"
|
||||
case FLT = "flt "
|
||||
case FPE2 = "fpe2"
|
||||
case FP2E = "fp2e"
|
||||
case FDS = "{fds"
|
||||
}
|
||||
|
||||
// swiftlint:disable identifier_name
|
||||
internal enum SMCKeys: UInt8 {
|
||||
case KERNEL_INDEX = 2
|
||||
case READ_BYTES = 5
|
||||
case WRITE_BYTES = 6
|
||||
case READ_INDEX = 8
|
||||
case READ_KEYINFO = 9
|
||||
case READ_PLIMIT = 11
|
||||
case READ_VERS = 12
|
||||
}
|
||||
|
||||
public enum FanMode: Int {
|
||||
case automatic = 0
|
||||
case forced = 1
|
||||
}
|
||||
|
||||
internal struct SMCKeyData_t {
|
||||
typealias SMCBytes_t = (UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8,
|
||||
UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8,
|
||||
UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8,
|
||||
UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8,
|
||||
UInt8, UInt8, UInt8, UInt8)
|
||||
|
||||
struct vers_t {
|
||||
var major: CUnsignedChar = 0
|
||||
var minor: CUnsignedChar = 0
|
||||
var build: CUnsignedChar = 0
|
||||
var reserved: CUnsignedChar = 0
|
||||
var release: CUnsignedShort = 0
|
||||
}
|
||||
|
||||
struct LimitData_t {
|
||||
var version: UInt16 = 0
|
||||
var length: UInt16 = 0
|
||||
var cpuPLimit: UInt32 = 0
|
||||
var gpuPLimit: UInt32 = 0
|
||||
var memPLimit: UInt32 = 0
|
||||
}
|
||||
|
||||
struct keyInfo_t {
|
||||
var dataSize: IOByteCount = 0
|
||||
var dataType: UInt32 = 0
|
||||
var dataAttributes: UInt8 = 0
|
||||
}
|
||||
|
||||
var key: UInt32 = 0
|
||||
var vers = vers_t()
|
||||
var pLimitData = LimitData_t()
|
||||
var keyInfo = keyInfo_t()
|
||||
var padding: UInt16 = 0
|
||||
var result: UInt8 = 0
|
||||
var status: UInt8 = 0
|
||||
var data8: UInt8 = 0
|
||||
var data32: UInt32 = 0
|
||||
|
||||
var bytes: SMCBytes_t = (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), UInt8(0))
|
||||
}
|
||||
|
||||
internal struct SMCVal_t {
|
||||
var key: String
|
||||
var dataSize: UInt32 = 0
|
||||
var dataType: String = ""
|
||||
var bytes: [UInt8] = Array(repeating: 0, count: 32)
|
||||
|
||||
init(_ key: String) {
|
||||
self.key = key
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - extensions
|
||||
|
||||
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)!)
|
||||
}
|
||||
}
|
||||
|
||||
extension UInt16 {
|
||||
init(bytes: (UInt8, UInt8)) {
|
||||
self = UInt16(bytes.0) << 8 | UInt16(bytes.1)
|
||||
}
|
||||
}
|
||||
|
||||
// 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 Int {
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -111,6 +111,11 @@
|
||||
9ABFF914248C30A800C9041A /* popup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9ABFF913248C30A800C9041A /* popup.swift */; };
|
||||
9AD33AC624BCD3EE007E8820 /* helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9AD33AC524BCD3EE007E8820 /* helpers.swift */; };
|
||||
9AD64FA224BF86C100419D59 /* settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9AD64FA124BF86C100419D59 /* settings.swift */; };
|
||||
9ADE6FDB265D032100D2FBA8 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9ADE6FDA265D032100D2FBA8 /* main.swift */; };
|
||||
9ADE702B265D03D100D2FBA8 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9ADE7005265D039300D2FBA8 /* IOKit.framework */; };
|
||||
9ADE7039265D059000D2FBA8 /* smc.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9ADE7038265D059000D2FBA8 /* smc.swift */; };
|
||||
9ADE7053265D542C00D2FBA8 /* types.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9ADE7052265D542C00D2FBA8 /* types.swift */; };
|
||||
9ADE7061265D8E5300D2FBA8 /* smc in CopyFiles */ = {isa = PBXBuildFile; fileRef = 9ADE6FD8265D032100D2FBA8 /* smc */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||
9AE29ADC249A50350071B02D /* Sensors.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9AE29AD5249A50350071B02D /* Sensors.framework */; };
|
||||
9AE29ADD249A50350071B02D /* Sensors.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9AE29AD5249A50350071B02D /* Sensors.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
9AE29AE1249A50640071B02D /* ModuleKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9AABEADD243FB13500668CB0 /* ModuleKit.framework */; };
|
||||
@@ -353,6 +358,25 @@
|
||||
name = "Copy Files";
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
9ADE6FD6265D032100D2FBA8 /* CopyFiles */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = /usr/share/man/man1/;
|
||||
dstSubfolderSpec = 0;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 1;
|
||||
};
|
||||
9ADE7060265D8E4E00D2FBA8 /* CopyFiles */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = "";
|
||||
dstSubfolderSpec = 7;
|
||||
files = (
|
||||
9ADE7061265D8E5300D2FBA8 /* smc in CopyFiles */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
9AECEF3D24ACF98800DB95D4 /* Copy Files */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
@@ -477,6 +501,11 @@
|
||||
9ABFF913248C30A800C9041A /* popup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = popup.swift; sourceTree = "<group>"; };
|
||||
9AD33AC524BCD3EE007E8820 /* helpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = helpers.swift; sourceTree = "<group>"; };
|
||||
9AD64FA124BF86C100419D59 /* settings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = settings.swift; sourceTree = "<group>"; };
|
||||
9ADE6FD8265D032100D2FBA8 /* smc */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = smc; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
9ADE6FDA265D032100D2FBA8 /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = "<group>"; };
|
||||
9ADE7005265D039300D2FBA8 /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; };
|
||||
9ADE7038265D059000D2FBA8 /* smc.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = smc.swift; sourceTree = "<group>"; };
|
||||
9ADE7052265D542C00D2FBA8 /* types.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = types.swift; sourceTree = "<group>"; };
|
||||
9AE29AD5249A50350071B02D /* Sensors.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Sensors.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
9AE29AEC249A50960071B02D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; name = Info.plist; path = Modules/Sensors/Info.plist; sourceTree = SOURCE_ROOT; };
|
||||
9AE29AF1249A50CD0071B02D /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = main.swift; path = Modules/Sensors/main.swift; sourceTree = SOURCE_ROOT; };
|
||||
@@ -595,6 +624,14 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
9ADE6FD5265D032100D2FBA8 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
9ADE702B265D03D100D2FBA8 /* IOKit.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
9AE29AD2249A50350071B02D /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
@@ -639,8 +676,9 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9A1410F7229E721100D29793 /* Stats */,
|
||||
9A0C82DB24460F7200FAE3D4 /* StatsKit */,
|
||||
9A343528243E26A0006B19F9 /* LaunchAtLogin */,
|
||||
9ADE6FD9265D032100D2FBA8 /* SMC */,
|
||||
9A0C82DB24460F7200FAE3D4 /* StatsKit */,
|
||||
9AABEADE243FB13500668CB0 /* ModuleKit */,
|
||||
9AB14B75248CEEC600DC6731 /* Modules */,
|
||||
9A1410F6229E721100D29793 /* Products */,
|
||||
@@ -663,6 +701,7 @@
|
||||
9A90E18924EAD2BB00471E9A /* GPU.framework */,
|
||||
9A97CECA2537331B00742D8F /* CPU.framework */,
|
||||
9A8DE587253DEFA9006A748F /* Fans.framework */,
|
||||
9ADE6FD8265D032100D2FBA8 /* smc */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
@@ -796,6 +835,7 @@
|
||||
9A998CD622A199920087ADE7 /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9ADE7005265D039300D2FBA8 /* IOKit.framework */,
|
||||
9A97CE2A25371B2300742D8F /* IntelPowerGadget.framework */,
|
||||
9A998CD922A199970087ADE7 /* ServiceManagement.framework */,
|
||||
9A998CD722A199920087ADE7 /* Cocoa.framework */,
|
||||
@@ -854,6 +894,16 @@
|
||||
path = Battery;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9ADE6FD9265D032100D2FBA8 /* SMC */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9ADE6FDA265D032100D2FBA8 /* main.swift */,
|
||||
9ADE7038265D059000D2FBA8 /* smc.swift */,
|
||||
9ADE7052265D542C00D2FBA8 /* types.swift */,
|
||||
);
|
||||
path = SMC;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9AE29AD6249A50350071B02D /* Sensors */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -988,6 +1038,7 @@
|
||||
9A6698E72326AB16001D00E1 /* Embed Frameworks */,
|
||||
9AECEF3D24ACF98800DB95D4 /* Copy Files */,
|
||||
9A88E2672659002E00E2B7B0 /* ShellScript */,
|
||||
9ADE7060265D8E4E00D2FBA8 /* CopyFiles */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
@@ -1172,6 +1223,23 @@
|
||||
productReference = 9ABFF8F6248BEBCB00C9041A /* Battery.framework */;
|
||||
productType = "com.apple.product-type.framework";
|
||||
};
|
||||
9ADE6FD7265D032100D2FBA8 /* SMC */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 9ADE6FDC265D032100D2FBA8 /* Build configuration list for PBXNativeTarget "SMC" */;
|
||||
buildPhases = (
|
||||
9ADE6FD4265D032100D2FBA8 /* Sources */,
|
||||
9ADE6FD5265D032100D2FBA8 /* Frameworks */,
|
||||
9ADE6FD6265D032100D2FBA8 /* CopyFiles */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = SMC;
|
||||
productName = SMC;
|
||||
productReference = 9ADE6FD8265D032100D2FBA8 /* smc */;
|
||||
productType = "com.apple.product-type.tool";
|
||||
};
|
||||
9AE29AD4249A50350071B02D /* Sensors */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 9AE29ADE249A50350071B02D /* Build configuration list for PBXNativeTarget "Sensors" */;
|
||||
@@ -1221,8 +1289,8 @@
|
||||
KnownAssetTags = (
|
||||
New,
|
||||
);
|
||||
LastSwiftUpdateCheck = 1150;
|
||||
LastUpgradeCheck = 1220;
|
||||
LastSwiftUpdateCheck = 1240;
|
||||
LastUpgradeCheck = 1240;
|
||||
ORGANIZATIONNAME = "Serhiy Mytrovtsiy";
|
||||
TargetAttributes = {
|
||||
9A0C82D924460F7200FAE3D4 = {
|
||||
@@ -1272,6 +1340,9 @@
|
||||
CreatedOnToolsVersion = 11.5;
|
||||
LastSwiftMigration = 1150;
|
||||
};
|
||||
9ADE6FD7265D032100D2FBA8 = {
|
||||
CreatedOnToolsVersion = 12.4;
|
||||
};
|
||||
9AE29AD4249A50350071B02D = {
|
||||
CreatedOnToolsVersion = 11.5;
|
||||
LastSwiftMigration = 1240;
|
||||
@@ -1332,6 +1403,7 @@
|
||||
9ABFF8F5248BEBCB00C9041A /* Battery */,
|
||||
9AE29AD4249A50350071B02D /* Sensors */,
|
||||
9A8DE586253DEFA9006A748F /* Fans */,
|
||||
9ADE6FD7265D032100D2FBA8 /* SMC */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
@@ -1583,6 +1655,16 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
9ADE6FD4265D032100D2FBA8 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
9ADE7053265D542C00D2FBA8 /* types.swift in Sources */,
|
||||
9ADE6FDB265D032100D2FBA8 /* main.swift in Sources */,
|
||||
9ADE7039265D059000D2FBA8 /* smc.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
9AE29AD1249A50350071B02D /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
@@ -2541,6 +2623,34 @@
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
9ADE6FDD265D032100D2FBA8 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CODE_SIGN_ENTITLEMENTS = "";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEVELOPMENT_TEAM = RP2S87B72W;
|
||||
ENABLE_HARDENED_RUNTIME = NO;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.14;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = eu.exelban.Stats.SMC;
|
||||
PRODUCT_NAME = smc;
|
||||
SWIFT_VERSION = 5.0;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
9ADE6FDE265D032100D2FBA8 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CODE_SIGN_ENTITLEMENTS = "";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEVELOPMENT_TEAM = RP2S87B72W;
|
||||
ENABLE_HARDENED_RUNTIME = NO;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.14;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = eu.exelban.Stats.SMC;
|
||||
PRODUCT_NAME = smc;
|
||||
SWIFT_VERSION = 5.0;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
9AE29ADF249A50350071B02D /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
@@ -2769,6 +2879,15 @@
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
9ADE6FDC265D032100D2FBA8 /* Build configuration list for PBXNativeTarget "SMC" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
9ADE6FDD265D032100D2FBA8 /* Debug */,
|
||||
9ADE6FDE265D032100D2FBA8 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
9AE29ADE249A50350071B02D /* Build configuration list for PBXNativeTarget "Sensors" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1220"
|
||||
LastUpgradeVersion = "1240"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
||||
88
Stats.xcodeproj/xcshareddata/xcschemes/SMC.xcscheme
Normal file
88
Stats.xcodeproj/xcshareddata/xcschemes/SMC.xcscheme
Normal file
@@ -0,0 +1,88 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1240"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "9ADE6FD7265D032100D2FBA8"
|
||||
BuildableName = "smc"
|
||||
BlueprintName = "SMC"
|
||||
ReferencedContainer = "container:Stats.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "9ADE6FD7265D032100D2FBA8"
|
||||
BuildableName = "smc"
|
||||
BlueprintName = "SMC"
|
||||
ReferencedContainer = "container:Stats.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
<CommandLineArguments>
|
||||
<CommandLineArgument
|
||||
argument = "list"
|
||||
isEnabled = "NO">
|
||||
</CommandLineArgument>
|
||||
<CommandLineArgument
|
||||
argument = "-t"
|
||||
isEnabled = "NO">
|
||||
</CommandLineArgument>
|
||||
</CommandLineArguments>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "9ADE6FD7265D032100D2FBA8"
|
||||
BuildableName = "smc"
|
||||
BlueprintName = "SMC"
|
||||
ReferencedContainer = "container:Stats.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1220"
|
||||
LastUpgradeVersion = "1240"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
||||
Reference in New Issue
Block a user