From a2ae1421aa073ffb31992c2d918744f3b70837cc Mon Sep 17 00:00:00 2001 From: Serhiy Mytrovtsiy Date: Sun, 5 Apr 2020 18:50:44 +0200 Subject: [PATCH] - update Temperature module (add all possible sensors to show); - delete SystemKit; - update Disk module to select the disk to show; - fix interval saving in CPU, RAM and Disk modules; --- Stats.xcodeproj/project.pbxproj | 12 +- Stats/Modules/Battery/Battery.swift | 5 +- Stats/Modules/CPU/CPU.swift | 1 + Stats/Modules/CPU/CPUProcessReader.swift | 1 + Stats/Modules/Disk/Disk.swift | 27 +- Stats/Modules/Disk/DiskCapacityReader.swift | 147 ++++++++-- Stats/Modules/Disk/DiskMenu.swift | 37 +++ Stats/Modules/Module.swift | 1 - Stats/Modules/RAM/RAM.swift | 1 + Stats/Modules/RAM/RAMProcessReader.swift | 1 + Stats/Modules/Temperature/Temperature.swift | 28 +- .../Modules/Temperature/TemperatureMenu.swift | 179 ++++++++---- .../Temperature/TemperatureReader.swift | 21 +- Stats/libs/Extensions.swift | 20 ++ Stats/libs/{SystemKit.c => SMC.c} | 196 ++++++------- Stats/libs/SMC.h | 273 ++++++++++++++++++ Stats/libs/Stats.h | 2 +- Stats/libs/SystemKit.h | 142 --------- 18 files changed, 737 insertions(+), 357 deletions(-) rename Stats/libs/{SystemKit.c => SMC.c} (52%) create mode 100644 Stats/libs/SMC.h delete mode 100644 Stats/libs/SystemKit.h diff --git a/Stats.xcodeproj/project.pbxproj b/Stats.xcodeproj/project.pbxproj index 15991054..66af39ae 100644 --- a/Stats.xcodeproj/project.pbxproj +++ b/Stats.xcodeproj/project.pbxproj @@ -54,7 +54,7 @@ 9AA28DC1243774ED00D2B196 /* Temperature.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9AA28DC0243774ED00D2B196 /* Temperature.swift */; }; 9AA28DC32437752D00D2B196 /* TemperatureMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9AA28DC22437752D00D2B196 /* TemperatureMenu.swift */; }; 9AA28DC52437762C00D2B196 /* TemperatureReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9AA28DC42437762C00D2B196 /* TemperatureReader.swift */; }; - 9AA28DCF2437884200D2B196 /* SystemKit.c in Sources */ = {isa = PBXBuildFile; fileRef = 9AA28DCE2437884200D2B196 /* SystemKit.c */; }; + 9AA28DCF2437884200D2B196 /* SMC.c in Sources */ = {isa = PBXBuildFile; fileRef = 9AA28DCE2437884200D2B196 /* SMC.c */; }; 9AA28DD1243799E500D2B196 /* TemperatureWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9AA28DD0243799E500D2B196 /* TemperatureWidget.swift */; }; 9AF0F31B22DA924000026AE6 /* LineChart.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9AF0F31A22DA924000026AE6 /* LineChart.swift */; }; 9AF0F31D22DA925000026AE6 /* LineChartWithValue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9AF0F31C22DA925000026AE6 /* LineChartWithValue.swift */; }; @@ -148,8 +148,8 @@ 9AA28DC22437752D00D2B196 /* TemperatureMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemperatureMenu.swift; sourceTree = ""; }; 9AA28DC42437762C00D2B196 /* TemperatureReader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemperatureReader.swift; sourceTree = ""; }; 9AA28DC9243780C500D2B196 /* Stats.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Stats.h; sourceTree = ""; }; - 9AA28DCD2437884200D2B196 /* SystemKit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SystemKit.h; sourceTree = ""; }; - 9AA28DCE2437884200D2B196 /* SystemKit.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SystemKit.c; sourceTree = ""; }; + 9AA28DCD2437884200D2B196 /* SMC.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SMC.h; sourceTree = ""; }; + 9AA28DCE2437884200D2B196 /* SMC.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SMC.c; sourceTree = ""; }; 9AA28DD0243799E500D2B196 /* TemperatureWidget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemperatureWidget.swift; sourceTree = ""; }; 9AF0F31A22DA924000026AE6 /* LineChart.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LineChart.swift; sourceTree = ""; }; 9AF0F31C22DA925000026AE6 /* LineChartWithValue.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LineChartWithValue.swift; sourceTree = ""; }; @@ -304,13 +304,13 @@ 9A5B1CBD229E78D2008B9D3C /* libs */ = { isa = PBXGroup; children = ( + 9AA28DCD2437884200D2B196 /* SMC.h */, + 9AA28DCE2437884200D2B196 /* SMC.c */, 9A5B1CC4229E7B40008B9D3C /* Extensions.swift */, 9A426DB722C2B5EE00C064C4 /* MacAppUpdater.swift */, 9A59AE55231EE02F007989D6 /* ChartMarker.swift */, 9A2D15CF23C77BA300C4C417 /* Repeater.swift */, 9AA28DC9243780C500D2B196 /* Stats.h */, - 9AA28DCD2437884200D2B196 /* SystemKit.h */, - 9AA28DCE2437884200D2B196 /* SystemKit.c */, ); path = libs; sourceTree = ""; @@ -533,7 +533,7 @@ 9AA28DD1243799E500D2B196 /* TemperatureWidget.swift in Sources */, 9A2D15FA23CE3BE600C4C417 /* Battery.swift in Sources */, 9A54EF67232AB81800F7DC20 /* BatteryPercentageWidget.swift in Sources */, - 9AA28DCF2437884200D2B196 /* SystemKit.c in Sources */, + 9AA28DCF2437884200D2B196 /* SMC.c in Sources */, 9AA28DC52437762C00D2B196 /* TemperatureReader.swift in Sources */, 9A57A18522A1D26D0033E318 /* MenuBar.swift in Sources */, 9A2D15D923CD036400C4C417 /* CPUMenu.swift in Sources */, diff --git a/Stats/Modules/Battery/Battery.swift b/Stats/Modules/Battery/Battery.swift index 7180842b..a0311585 100644 --- a/Stats/Modules/Battery/Battery.swift +++ b/Stats/Modules/Battery/Battery.swift @@ -11,7 +11,6 @@ import IOKit.ps class Battery: Module { public var name: String = "Battery" - public var updateInterval: Double = 15 public var enabled: Bool = true public var available: Bool { @@ -63,7 +62,9 @@ class Battery: Module { } public func stop() { - (readers[0] as! BatteryReader).stop() + if readers.count > 0 { + (readers[0] as! BatteryReader).stop() + } } public func restart() { diff --git a/Stats/Modules/CPU/CPU.swift b/Stats/Modules/CPU/CPU.swift index 6b5dc5ac..f2b4bfba 100644 --- a/Stats/Modules/CPU/CPU.swift +++ b/Stats/Modules/CPU/CPU.swift @@ -36,6 +36,7 @@ class CPU: Module { if !self.available { return } self.enabled = defaults.object(forKey: name) != nil ? defaults.bool(forKey: name) : true + self.updateInterval = defaults.object(forKey: "\(name)_interval") != nil ? defaults.double(forKey: "\(name)_interval") : self.updateInterval self.widget.type = defaults.object(forKey: "\(name)_widget") != nil ? defaults.float(forKey: "\(name)_widget") : Widgets.Mini self.initWidget() diff --git a/Stats/Modules/CPU/CPUProcessReader.swift b/Stats/Modules/CPU/CPUProcessReader.swift index 22a4686c..6d9dca6e 100644 --- a/Stats/Modules/CPU/CPUProcessReader.swift +++ b/Stats/Modules/CPU/CPUProcessReader.swift @@ -55,6 +55,7 @@ class CPUProcessReader: Reader { try task.run() } catch let error { print(error) + return } let outputData = outputPipe.fileHandleForReading.readDataToEndOfFile() diff --git a/Stats/Modules/Disk/Disk.swift b/Stats/Modules/Disk/Disk.swift index f4329be0..7e4882e0 100644 --- a/Stats/Modules/Disk/Disk.swift +++ b/Stats/Modules/Disk/Disk.swift @@ -10,7 +10,7 @@ import Cocoa class Disk: Module { public var name: String = "SSD" - public var updateInterval: Double = 15 + public var updateInterval: Double = 5 public var enabled: Bool = true public var available: Bool = true @@ -24,12 +24,16 @@ class Disk: Module { internal let defaults = UserDefaults.standard internal var submenu: NSMenu = NSMenu() + internal var selectedDisk: String = "" + internal var disks: disksList = disksList() init() { if !self.available { return } self.enabled = defaults.object(forKey: name) != nil ? defaults.bool(forKey: name) : true + self.updateInterval = defaults.object(forKey: "\(name)_interval") != nil ? defaults.double(forKey: "\(name)_interval") : self.updateInterval self.widget.type = defaults.object(forKey: "\(name)_widget") != nil ? defaults.float(forKey: "\(name)_widget") : Widgets.Mini + self.selectedDisk = defaults.object(forKey: "\(name)_disk") != nil ? defaults.string(forKey: "\(name)_disk")! : self.selectedDisk self.initWidget() self.initMenu() @@ -60,9 +64,26 @@ class Disk: Module { self.start() } - private func usageUpdater(value: Double) { + private func usageUpdater(disks: disksList) { + if self.disks.list.count != disks.list.count && disks.list.count != 0 { + self.disks = disks + self.initMenu() + } + if self.widget.view is Widget { - (self.widget.view as! Widget).setValue(data: [value]) + var d: diskInfo? = disks.getDiskByBSDName(self.selectedDisk) + if d == nil { + d = disks.getRootDisk() + } + + if d != nil { + let total = d!.totalSize + let free = d!.freeSize + let usedSpace = total - free + let percentage = Double(usedSpace) / Double(total) + + (self.widget.view as! Widget).setValue(data: [percentage]) + } } } } diff --git a/Stats/Modules/Disk/DiskCapacityReader.swift b/Stats/Modules/Disk/DiskCapacityReader.swift index af01a62c..47453834 100644 --- a/Stats/Modules/Disk/DiskCapacityReader.swift +++ b/Stats/Modules/Disk/DiskCapacityReader.swift @@ -8,15 +8,67 @@ import Cocoa +struct diskInfo { + var ID: String = ""; + + var name: String = ""; + var model: String = ""; + var path: URL?; + var connection: String = ""; + var fileSystem: String = ""; + + var totalSize: Int64 = 0; + var freeSize: Int64 = 0; + + var mediaBSDName: String = ""; + var root: Bool = false; +} + +struct disksList { + var list: [diskInfo] = [] + + func getDiskByBSDName(_ name: String) -> diskInfo? { + let idx = self.list.firstIndex { $0.mediaBSDName == name } + + if idx == nil { + return nil + } + + return self.list[idx!] + } + + func getDiskByName(_ name: String) -> diskInfo? { + let idx = self.list.firstIndex { $0.name == name } + + if idx == nil { + return nil + } + + return self.list[idx!] + } + + func getRootDisk() -> diskInfo? { + let idx = self.list.firstIndex { $0.root } + + if idx == nil { + return nil + } + + return self.list[idx!] + } +} + class DiskCapacityReader: Reader { public var name: String = "Capacity" public var enabled: Bool = true public var available: Bool = true public var optional: Bool = false public var initialized: Bool = false - public var callback: (Double) -> Void = {_ in} + public var callback: (disksList) -> Void = {_ in} - init(_ updater: @escaping (Double) -> Void) { + private var disks: disksList = disksList() + + init(_ updater: @escaping (disksList) -> Void) { self.callback = updater if self.available { @@ -30,36 +82,91 @@ class DiskCapacityReader: Reader { if !self.enabled && self.initialized { return } self.initialized = true - let total = totalDiskSpaceInBytes() - let free = freeDiskSpaceInBytes() - let usedSpace = total - free + let keys: [URLResourceKey] = [.volumeNameKey] + let paths = FileManager.default.mountedVolumeURLs(includingResourceValuesForKeys: keys)! + if let session = DASessionCreate(kCFAllocatorDefault) { + for url in paths { + if url.pathComponents.count == 1 || (url.pathComponents.count > 1 && url.pathComponents[1] == "Volumes") { + if let disk = DADiskCreateFromVolumePath(kCFAllocatorDefault, session, url as CFURL) { + let BSDName: String = String(cString: DADiskGetBSDName(disk)!) + + if let _: diskInfo = self.disks.getDiskByBSDName(BSDName) { + let idx = self.disks.list.firstIndex { $0.mediaBSDName == BSDName } + self.disks.list[idx!].freeSize = freeDiskSpaceInBytes(self.disks.list[idx!].path!.absoluteString) + continue + } + + self.disks.list.append(getDisk(disk)) + } + } + } + } DispatchQueue.main.async(execute: { - self.callback((Double(usedSpace) / Double(total))) + self.callback(self.disks) }) } - private func totalDiskSpaceInBytes() -> Int64 { - do { - let systemAttributes = try FileManager.default.attributesOfFileSystem(forPath: NSHomeDirectory() as String) - let space = (systemAttributes[FileAttributeKey.systemSize] as? NSNumber)?.int64Value - return space! - } catch { - return 0 - } + public func toggleEnable(_ value: Bool) { + self.enabled = value } - private func freeDiskSpaceInBytes() -> Int64 { + private func getDisk(_ disk: DADisk) -> diskInfo { + var d: diskInfo = diskInfo() + + if let bsdName = DADiskGetBSDName(disk) { + d.mediaBSDName = String(cString: bsdName) + } + + if let diskDescription = DADiskCopyDescription(disk) { + if let dict = diskDescription as? [String: AnyObject] { + if let mediaName = dict[kDADiskDescriptionMediaNameKey as String] { + d.name = mediaName as! String + } + if let mediaSize = dict[kDADiskDescriptionMediaSizeKey as String] { + d.totalSize = Int64(truncating: mediaSize as! NSNumber) + } + if let deviceModel = dict[kDADiskDescriptionDeviceModelKey as String] { + d.model = (deviceModel as! String).trimmingCharacters(in: .whitespacesAndNewlines) + } + if let deviceProtocol = dict[kDADiskDescriptionDeviceProtocolKey as String] { + d.connection = deviceProtocol as! String + } + if let volumePath = dict[kDADiskDescriptionVolumePathKey as String] { + let url = volumePath as? NSURL + if url != nil { + if url!.pathComponents!.count > 1 && url!.pathComponents![1] == "Volumes" { + let lastPath: String = (url?.lastPathComponent)! + if lastPath != "" { + d.name = lastPath + d.path = URL(string: "/Volumes/\(lastPath)") + } + } else if url!.pathComponents!.count == 1 { + d.path = URL(string: "/") + d.root = true + } + } + } + if let volumeKind = dict[kDADiskDescriptionVolumeKindKey as String] { + d.fileSystem = volumeKind as! String + } + } + } + + if d.path != nil { + d.freeSize = freeDiskSpaceInBytes(d.path!.absoluteString) + } + + return d + } + + private func freeDiskSpaceInBytes(_ path: String) -> Int64 { do { - let systemAttributes = try FileManager.default.attributesOfFileSystem(forPath: NSHomeDirectory() as String) + let systemAttributes = try FileManager.default.attributesOfFileSystem(forPath: path) let freeSpace = (systemAttributes[FileAttributeKey.systemFreeSize] as? NSNumber)?.int64Value return freeSpace! } catch { return 0 } } - - public func toggleEnable(_ value: Bool) { - self.enabled = value - } } diff --git a/Stats/Modules/Disk/DiskMenu.swift b/Stats/Modules/Disk/DiskMenu.swift index bf2eb0ba..2c61ae57 100644 --- a/Stats/Modules/Disk/DiskMenu.swift +++ b/Stats/Modules/Disk/DiskMenu.swift @@ -20,6 +20,18 @@ extension Disk { } menu.target = self + self.disks.list.forEach { (d: diskInfo) in + let disk = NSMenuItem(title: d.name, action: #selector(toggleDisk), keyEquivalent: "") + if self.selectedDisk == "" && d.root { + disk.state = NSControl.StateValue.on + } else { + disk.state = self.selectedDisk == d.mediaBSDName ? NSControl.StateValue.on : NSControl.StateValue.off + } + disk.target = self + + submenu.addItem(disk) + } + let mini = NSMenuItem(title: "Mini", action: #selector(toggleWidget), keyEquivalent: "") mini.state = self.widget.type == Widgets.Mini ? NSControl.StateValue.on : NSControl.StateValue.off mini.target = self @@ -28,6 +40,8 @@ extension Disk { barChart.state = self.widget.type == Widgets.BarChart ? NSControl.StateValue.on : NSControl.StateValue.off barChart.target = self + submenu.addItem(NSMenuItem.separator()) + submenu.addItem(mini) submenu.addItem(barChart) @@ -159,4 +173,27 @@ extension Disk { self.defaults.set(interval, forKey: "\(name)_interval") self.task?.reset(.seconds(interval), restart: self.task!.state.isRunning) } + + @objc func toggleDisk(_ sender: NSMenuItem) { + let name: String = sender.title + let d: diskInfo? = self.disks.getDiskByName(name) + if d == nil { + return + } + + if d!.mediaBSDName == self.selectedDisk { + return + } + + for item in self.submenu.items { + if self.disks.getDiskByName(item.title) != nil { + item.state = NSControl.StateValue.off + } + } + + sender.state = NSControl.StateValue.on + self.selectedDisk = d!.mediaBSDName + self.defaults.set(d!.mediaBSDName, forKey: "\(name)_disk") + menuBar!.reload(name: self.name) + } } diff --git a/Stats/Modules/Module.swift b/Stats/Modules/Module.swift index 79cd1e74..07d76885 100644 --- a/Stats/Modules/Module.swift +++ b/Stats/Modules/Module.swift @@ -11,7 +11,6 @@ import Charts protocol Module: class { var name: String { get } // module name - var updateInterval: Double { get } // module update interval var enabled: Bool { get } // determine if module is enabled or disabled var available: Bool { get } // determine if module is available on this PC diff --git a/Stats/Modules/RAM/RAM.swift b/Stats/Modules/RAM/RAM.swift index 5d1647b1..7e3bb779 100644 --- a/Stats/Modules/RAM/RAM.swift +++ b/Stats/Modules/RAM/RAM.swift @@ -36,6 +36,7 @@ class RAM: Module { if !self.available { return } self.enabled = defaults.object(forKey: name) != nil ? defaults.bool(forKey: name) : true + self.updateInterval = defaults.object(forKey: "\(name)_interval") != nil ? defaults.double(forKey: "\(name)_interval") : self.updateInterval self.widget.type = defaults.object(forKey: "\(name)_widget") != nil ? defaults.float(forKey: "\(name)_widget") : Widgets.Mini readers.append(RAMUsageReader(self.usageUpdater)) diff --git a/Stats/Modules/RAM/RAMProcessReader.swift b/Stats/Modules/RAM/RAMProcessReader.swift index 01f5d457..ee518fdb 100644 --- a/Stats/Modules/RAM/RAMProcessReader.swift +++ b/Stats/Modules/RAM/RAMProcessReader.swift @@ -44,6 +44,7 @@ class RAMProcessReader: Reader { try task.run() } catch let error { print(error) + return } let outputData = outputPipe.fileHandleForReading.readDataToEndOfFile() diff --git a/Stats/Modules/Temperature/Temperature.swift b/Stats/Modules/Temperature/Temperature.swift index d2304f7b..57ba6473 100644 --- a/Stats/Modules/Temperature/Temperature.swift +++ b/Stats/Modules/Temperature/Temperature.swift @@ -25,17 +25,19 @@ class Temperature: Module { internal let defaults = UserDefaults.standard internal var submenu: NSMenu = NSMenu() - internal var cpu: String = SMC_TEMP_CPU_0_PROXIMITY - internal var gpu: String = SMC_TEMP_GPU_0_PROXIMITY + internal var value_1: String = "cpu_1_diode" + internal var value_2: String = "gpu_diode" + internal var once: Int = 0 init() { if !self.available { return } self.enabled = defaults.object(forKey: name) != nil ? defaults.bool(forKey: name) : true self.widget.type = defaults.object(forKey: "\(name)_widget") != nil ? defaults.float(forKey: "\(name)_widget") : Widgets.Temperature - self.cpu = (defaults.object(forKey: "\(name)_cpu") != nil ? defaults.string(forKey: "\(name)_cpu") : cpu)! - self.gpu = (defaults.object(forKey: "\(name)_gpu") != nil ? defaults.string(forKey: "\(name)_gpu") : gpu)! + self.value_1 = (defaults.object(forKey: "\(name)_value_1") != nil ? defaults.string(forKey: "\(name)_value_1")! : value_1) + self.value_2 = (defaults.object(forKey: "\(name)_value_2") != nil ? defaults.string(forKey: "\(name)_value_2")! : value_2) + self.initGroups() self.initWidget() self.initMenu() @@ -65,13 +67,23 @@ class Temperature: Module { self.start() } - private func usageUpdater(value: TemperatureValue) { + private func usageUpdater(value: Temperatures) { if self.widget.view is Widget { DispatchQueue.main.async(execute: { - let cpu: Double = self.cpu == SMC_TEMP_CPU_0_DIE ? value.CPUDie : value.CPUProximity - let gpu: Double = self.gpu == SMC_TEMP_GPU_0_DIODE ? value.GPUDie : value.GPUProximity + var value_1: Double = 0 + var value_2: Double = 0 - (self.widget.view as! Widget).setValue(data: [cpu, gpu]) + let v1 = value.asDictionary.first { $0.key == self.value_1 } + let v2 = value.asDictionary.first { $0.key == self.value_2 } + + if v1 != nil { + value_1 = v1!.value as! Double + } + if v2 != nil { + value_2 = v2!.value as! Double + } + + (self.widget.view as! Widget).setValue(data: [value_1, value_2]) }) } } diff --git a/Stats/Modules/Temperature/TemperatureMenu.swift b/Stats/Modules/Temperature/TemperatureMenu.swift index 39d491a2..570c2188 100644 --- a/Stats/Modules/Temperature/TemperatureMenu.swift +++ b/Stats/Modules/Temperature/TemperatureMenu.swift @@ -8,7 +8,86 @@ import Cocoa +struct temperatureMenu { + let name: String + let originalName: String +} + +struct temperatureGroup { + let name: String + var value: String + var menus: [temperatureMenu] + + mutating func addMenu(menu: temperatureMenu) { + self.menus.append(menu) + } + + func findBy(name: String) -> String { + let menu = self.menus.first{ $0.name == name } + if menu != nil { + return menu!.originalName + } + return "" + } +} + +struct temperatureGroupsStruct { + var list: [Int : temperatureGroup] + + mutating func addMenuToGroup(group: String, menu: temperatureMenu) { + let index = self.list.firstIndex{ $0.value.value == group} + if index != nil { + let (k, _) = self.list[index!] + self.list[k]!.menus.append(menu) + } + } + + func getOriginalNameOfSensor(name: String) -> String { + var originalName: String = "" + + self.list.forEach{ (key: Int, value: temperatureGroup) in + if value.findBy(name: name) != "" { + originalName = value.findBy(name: name) + return + } + } + + return originalName + } +} + +var temperatureGroups: temperatureGroupsStruct = temperatureGroupsStruct(list: [ + 0: temperatureGroup(name: "CPU", value: "cpu", menus: []), + 1: temperatureGroup(name: "GPU", value: "gpu", menus: []), + 2: temperatureGroup(name: "Memory", value: "mem", menus: []), + 3: temperatureGroup(name: "Termal zones", value: "termal", menus: []), + 4: temperatureGroup(name: "Sensors", value: "sensor", menus: []), + 5: temperatureGroup(name: "PCI", value: "pci", menus: []), + 6: temperatureGroup(name: "Northbridge", value: "northbridge", menus: []), + 7: temperatureGroup(name: "HDD", value: "hdd", menus: []), + 8: temperatureGroup(name: "Thunderbolt", value: "thunderbolt", menus: []), +]) + extension Temperature { + internal func initGroups() { + var temperatures: Temperatures = Temperatures() + GetTemperatures(&temperatures) + + temperatures.asDictionary.forEach { (arg0) in + let (key, value) = arg0 + if value as! Double != 0 { + let group: String = String(key.split(separator: "_")[0]) + + var name = key.replacingOccurrences(of: "_", with: " ") + if group == "sensor" || group == "termal" { + name = name.replacingOccurrences(of: "\(group) ", with: "") + } + + temperatureGroups.addMenuToGroup(group: group, menu: temperatureMenu(name: name.toUpperCase(), originalName: key)) + } + } + } + public func initMenu() { menu = NSMenuItem(title: name, action: #selector(toggle), keyEquivalent: "") submenu = NSMenu() @@ -20,28 +99,44 @@ extension Temperature { } menu.target = self - let cpuDie: NSMenuItem = NSMenuItem(title: "CPU Die", action: #selector(toggleCPU), keyEquivalent: "") - cpuDie.state = self.cpu == SMC_TEMP_CPU_0_DIE ? NSControl.StateValue.on : NSControl.StateValue.off - cpuDie.target = self + let sensor_1: NSMenuItem = NSMenuItem(title: "Sensor #1", action: nil, keyEquivalent: "") + sensor_1.target = self + sensor_1.submenu = NSMenu() - let cpuProximity: NSMenuItem = NSMenuItem(title: "CPU Proximity", action: #selector(toggleCPU), keyEquivalent: "") - cpuProximity.state = self.cpu == SMC_TEMP_CPU_0_PROXIMITY ? NSControl.StateValue.on : NSControl.StateValue.off - cpuProximity.target = self + let sensor_2: NSMenuItem = NSMenuItem(title: "Sensor #2", action: nil, keyEquivalent: "") + sensor_2.target = self + sensor_2.submenu = NSMenu() - let gpuDie: NSMenuItem = NSMenuItem(title: "GPU Die", action: #selector(toggleGPU), keyEquivalent: "") - gpuDie.state = self.gpu == SMC_TEMP_GPU_0_DIODE ? NSControl.StateValue.on : NSControl.StateValue.off - gpuDie.target = self - - let gpuProximity: NSMenuItem = NSMenuItem(title: "GPU Proximity", action: #selector(toggleGPU), keyEquivalent: "") - gpuProximity.state = self.gpu == SMC_TEMP_GPU_0_PROXIMITY ? NSControl.StateValue.on : NSControl.StateValue.off - gpuProximity.target = self - - submenu.addItem(cpuProximity) - submenu.addItem(cpuDie) - submenu.addItem(NSMenuItem.separator()) - submenu.addItem(gpuProximity) - submenu.addItem(gpuDie) + for i in 0...temperatureGroups.list.count-1 { + let group = temperatureGroups.list[i]! + + if group.menus.count != 0 { + sensor_1.submenu!.addItem(NSMenuItem(title: group.name, action: nil, keyEquivalent: "")) + group.menus.forEach { (m: temperatureMenu) in + let menuPoint: NSMenuItem = NSMenuItem(title: m.name, action: #selector(toggleValue1), keyEquivalent: "") + menuPoint.state = m.originalName == self.value_1 ? NSControl.StateValue.on : NSControl.StateValue.off + menuPoint.target = self + sensor_1.submenu!.addItem(menuPoint) + } + sensor_1.submenu!.addItem(NSMenuItem.separator()) + + sensor_2.submenu!.addItem(NSMenuItem(title: group.name, action: nil, keyEquivalent: "")) + group.menus.forEach { (m: temperatureMenu) in + let menuPoint: NSMenuItem = NSMenuItem(title: m.name, action: #selector(toggleValue2), keyEquivalent: "") + menuPoint.state = m.originalName == self.value_2 ? NSControl.StateValue.on : NSControl.StateValue.off + menuPoint.target = self + sensor_2.submenu!.addItem(menuPoint) + } + sensor_2.submenu!.addItem(NSMenuItem.separator()) + } + } + if sensor_1.submenu?.items.count != 0 { + submenu.addItem(sensor_1) + } + if sensor_2.submenu?.items.count != 0 { + submenu.addItem(sensor_2) + } submenu.addItem(NSMenuItem.separator()) if let view = self.widget.view as? Widget { @@ -71,55 +166,41 @@ extension Temperature { self.restart() } - @objc func toggleCPU(_ sender: NSMenuItem) { - var cpu: String = sender.title - - switch cpu { - case "CPU Die": - cpu = SMC_TEMP_CPU_0_DIE - case "CPU Proximity": - cpu = SMC_TEMP_CPU_0_PROXIMITY - default: - break + @objc func toggleValue1(_ sender: NSMenuItem) { + let val: String = sender.title + let originalName = temperatureGroups.getOriginalNameOfSensor(name: val) + if self.value_1 == originalName { + return } let state = sender.state == NSControl.StateValue.on for item in self.submenu.items { - if item.title == "CPU Die" || item.title == "CPU Proximity" { - item.state = NSControl.StateValue.off - } + item.state = NSControl.StateValue.off } sender.state = state ? NSControl.StateValue.off : NSControl.StateValue.on - self.defaults.set(cpu, forKey: "\(name)_cpu") - self.cpu = cpu + self.defaults.set(originalName, forKey: "\(name)_value_1") + self.value_1 = originalName self.initWidget() self.initMenu() menuBar!.reload(name: self.name) } - @objc func toggleGPU(_ sender: NSMenuItem) { - var gpu: String = sender.title - - switch gpu { - case "GPU Die": - gpu = SMC_TEMP_GPU_0_DIODE - case "GPU Proximity": - gpu = SMC_TEMP_GPU_0_PROXIMITY - default: - break + @objc func toggleValue2(_ sender: NSMenuItem) { + let val: String = sender.title + let originalName = temperatureGroups.getOriginalNameOfSensor(name: val) + if self.value_2 == originalName { + return } let state = sender.state == NSControl.StateValue.on for item in self.submenu.items { - if item.title == "GPU Die" || item.title == "GPU Proximity" { - item.state = NSControl.StateValue.off - } + item.state = NSControl.StateValue.off } sender.state = state ? NSControl.StateValue.off : NSControl.StateValue.on - self.defaults.set(gpu, forKey: "\(name)_gpu") - self.gpu = gpu + self.defaults.set(originalName, forKey: "\(name)_value_2") + self.value_2 = originalName self.initWidget() self.initMenu() menuBar!.reload(name: self.name) diff --git a/Stats/Modules/Temperature/TemperatureReader.swift b/Stats/Modules/Temperature/TemperatureReader.swift index 39a8c928..27fe23aa 100644 --- a/Stats/Modules/Temperature/TemperatureReader.swift +++ b/Stats/Modules/Temperature/TemperatureReader.swift @@ -9,13 +9,6 @@ import IOKit import Foundation -struct TemperatureValue { - var CPUDie: Double = 0 - var CPUProximity: Double = 0 - var GPUDie: Double = 0 - var GPUProximity: Double = 0 -} - class TemperatureReader: Reader { public var name: String = "Temperature" public var enabled: Bool = true @@ -23,9 +16,9 @@ class TemperatureReader: Reader { public var optional: Bool = false public var initialized: Bool = false - public var callback: (TemperatureValue) -> Void = {_ in} + public var callback: (Temperatures) -> Void = {_ in} - init(_ updater: @escaping (TemperatureValue) -> Void) { + init(_ updater: @escaping (Temperatures) -> Void) { self.callback = updater if self.available { @@ -39,14 +32,10 @@ class TemperatureReader: Reader { if !self.enabled && self.initialized { return } self.initialized = true - let temp = TemperatureValue( - CPUDie: GetTemperature(SMC_TEMP_CPU_0_DIE.UTF8CString), - CPUProximity: GetTemperature(SMC_TEMP_CPU_0_PROXIMITY.UTF8CString), - GPUDie: GetTemperature(SMC_TEMP_GPU_0_DIODE.UTF8CString), - GPUProximity: GetTemperature(SMC_TEMP_GPU_0_PROXIMITY.UTF8CString) - ) + var temperatures: Temperatures = Temperatures() + GetTemperatures(&temperatures) - self.callback(temp) + self.callback(temperatures) } func toggleEnable(_ value: Bool) { diff --git a/Stats/libs/Extensions.swift b/Stats/libs/Extensions.swift index fa5d75cc..d2517649 100755 --- a/Stats/libs/Extensions.swift +++ b/Stats/libs/Extensions.swift @@ -274,6 +274,13 @@ extension String { func matches(_ regex: String) -> Bool { return self.range(of: regex, options: .regularExpression, range: nil, locale: nil) != nil } + + func toUpperCase() -> String { + return prefix(1).capitalized + dropFirst() + } + func toLowwerCase() -> String { + return prefix(1).lowercased() + dropFirst() + } } extension URL { @@ -287,3 +294,16 @@ class ChartsNetworkAxisFormatter: IAxisValueFormatter { return Units(bytes: Int64(value)).getReadableSpeed() } } + +extension Temperatures { + var asDictionary : [String: Any] { + let mirror = Mirror(reflecting: self) + + var dict: Dictionary = [:] + for (_, element) in mirror.children.enumerated() { + dict[element.label!] = element.value + } + + return dict + } +} diff --git a/Stats/libs/SystemKit.c b/Stats/libs/SMC.c similarity index 52% rename from Stats/libs/SystemKit.c rename to Stats/libs/SMC.c index 461335b6..5114aba9 100644 --- a/Stats/libs/SystemKit.c +++ b/Stats/libs/SMC.c @@ -1,5 +1,5 @@ // -// SystemKit.c +// SMC.c // Stats // // SMC code borrowed from https://github.com/lavoiesl/osx-cpu-temp. @@ -8,13 +8,14 @@ // Copyright © 2020 Serhiy Mytrovtsiy. All rights reserved. // -#include -#include #include #include #include -#include "SystemKit.h" +#include +#include + +#include "SMC.h" static io_connect_t conn; @@ -151,6 +152,79 @@ double GetTemperature(char* key) { return 0.0; } +void GetTemperatures(Temperatures *list) { + list->termal_zone_0 = GetTemperature(SMC_TEMP_TERMALZONE_0); + list->termal_zone_1 = GetTemperature(SMC_TEMP_TERMALZONE_1); + list->termal_ambient_0 = GetTemperature(SMC_TEMP_AMBIENT_AIR_0); + list->termal_ambient_1 = GetTemperature(SMC_TEMP_AMBIENT_AIR_1); + list->termal_heatpipe_0 = GetTemperature(SMC_TEMP_HEATPIPE_0); + list->termal_heatpipe_1 = GetTemperature(SMC_TEMP_HEATPIPE_1); + list->termal_heatpipe_2 = GetTemperature(SMC_TEMP_HEATPIPE_2); + list->termal_heatpipe_3 = GetTemperature(SMC_TEMP_HEATPIPE_3); + + list->cpu_0_die = GetTemperature(SMC_TEMP_CPU_0_DIE); + list->cpu_0_diode = GetTemperature(SMC_TEMP_CPU_0_DIODE); + list->cpu_0_heatsink = GetTemperature(SMC_TEMP_CPU_0_HEATSINK); + list->cpu_0_proximity = GetTemperature(SMC_TEMP_CPU_0_PROXIMITY); + list->cpu_1_die = GetTemperature(SMC_TEMP_CPU_1_DIE); + list->cpu_1_diode = GetTemperature(SMC_TEMP_CPU_1_DIODE); + list->cpu_1_heatsink = GetTemperature(SMC_TEMP_CPU_1_HEATSINK); + list->cpu_1_proximity = GetTemperature(SMC_TEMP_CPU_1_PROXIMITY); + + list->cpu_1 = GetTemperature(SMC_TEMP_CPU_CORE_1); + list->cpu_2 = GetTemperature(SMC_TEMP_CPU_CORE_2); + list->cpu_3 = GetTemperature(SMC_TEMP_CPU_CORE_3); + list->cpu_4 = GetTemperature(SMC_TEMP_CPU_CORE_4); + list->cpu_5 = GetTemperature(SMC_TEMP_CPU_CORE_5); + list->cpu_6 = GetTemperature(SMC_TEMP_CPU_CORE_6); + list->cpu_7 = GetTemperature(SMC_TEMP_CPU_CORE_7); + list->cpu_8 = GetTemperature(SMC_TEMP_CPU_CORE_8); + + list->gpu_diode = GetTemperature(SMC_TEMP_GPU_0_DIODE); + list->gpu_heatsink = GetTemperature(SMC_TEMP_GPU_0_HEATSINK); + list->gpu_proximity = GetTemperature(SMC_TEMP_GPU_0_PROXIMITY); + + list->mem_proximity = GetTemperature(SMC_TEMP_MEM_SLOTS); + list->mem_0 = GetTemperature(SMC_TEMP_MEM_SLOT_0); + list->mem_1 = GetTemperature(SMC_TEMP_MEM_SLOT_1); + list->mem_2 = GetTemperature(SMC_TEMP_MEM_SLOT_2); + list->mem_3 = GetTemperature(SMC_TEMP_MEM_SLOT_3); + + list->pci_proximity = GetTemperature(SMC_TEMP_PCI_SLOTS); + list->pci_0 = GetTemperature(SMC_TEMP_PCI_SLOT_0); + list->pci_1 = GetTemperature(SMC_TEMP_PCI_SLOT_1); + list->pci_2 = GetTemperature(SMC_TEMP_PCI_SLOT_2); + list->pci_3 = GetTemperature(SMC_TEMP_PCI_SLOT_3); + + list->sensor_mainboard = GetTemperature(SMC_TEMP_MAINBOARD_PROXIMITY); + list->sensor_powerboard = GetTemperature(SMC_TEMP_POWERBOARD_PROXIMITY); + list->sensor_battery = GetTemperature(SMC_TEMP_BATTERY_PROXIMITY); + list->sensor_airport = GetTemperature(SMC_TEMP_AIRPORT_PROXIMITY); + list->sensor_lcd = GetTemperature(SMC_TEMP_LCD_PROXIMITY); + list->sensor_odd = GetTemperature(SMC_TEMP_ODD_PROXIMITY); + + list->northbridge_die = GetTemperature(SMC_TEMP_NORTHBRIDGE_DIE); + list->northbridge_proximity = GetTemperature(SMC_TEMP_NORTHBRIDGE_PROXIMITY); + + list->hdd_0 = GetTemperature(SMC_TEMP_HDD_0); + list->hdd_1 = GetTemperature(SMC_TEMP_HDD_1); + list->hdd_2 = GetTemperature(SMC_TEMP_HDD_2); + list->hdd_3 = GetTemperature(SMC_TEMP_HDD_3); + + list->thunderbolt_0 = GetTemperature(SMC_TEMP_THUNDERBOLT_0); + list->thunderbolt_1 = GetTemperature(SMC_TEMP_THUNDERBOLT_1); + list->thunderbolt_2 = GetTemperature(SMC_TEMP_THUNDERBOLT_2); + list->thunderbolt_3 = GetTemperature(SMC_TEMP_THUNDERBOLT_3); +} + +void GetVoltages(Voltages *list) { + +} + +void GetPowers(Powers *list) { + +} + float GetFanRPM(char* key) { SMCVal_t val; kern_return_t result; @@ -166,112 +240,16 @@ float GetFanRPM(char* key) { return -1.f; } -PowerManagmentInformation *GetPowerInfo() { - PowerManagmentInformation *info = malloc(sizeof(PowerManagmentInformation)); - - CFTypeRef power_sources = IOPSCopyPowerSourcesInfo(); - CFTypeRef external_adapter = IOPSCopyExternalPowerAdapterDetails(); - - /* Get information aboud external adapter */ - if (external_adapter != NULL) { - CFNumberRef watts = CFDictionaryGetValue(external_adapter, CFSTR(kIOPSPowerAdapterWattsKey)); - if (watts) { - CFNumberGetValue(watts, kCFNumberDoubleType, &info->ACWatts); - CFRelease(watts); - } - - CFRelease(external_adapter); - } - - if(power_sources == NULL) { - return NULL; - } - - CFArrayRef list = IOPSCopyPowerSourcesList(power_sources); - CFDictionaryRef battery = NULL; - if(list == NULL) { - CFRelease(power_sources); - return NULL; - } - - /* Get the battery */ - for(int i = 0; i < CFArrayGetCount(list) && battery == NULL; ++i) { - CFDictionaryRef candidate = IOPSGetPowerSourceDescription(power_sources, CFArrayGetValueAtIndex(list, i)); - CFStringRef type; - - if(candidate != NULL) { - type = (CFStringRef) CFDictionaryGetValue(candidate, CFSTR(kIOPSTransportTypeKey)); +int64_t GetCPUFrequency() { + int mib[2]; + unsigned int freq; + size_t len; - if(kCFCompareEqualTo == CFStringCompare(type, CFSTR(kIOPSInternalType), 0)) { - CFRetain(candidate); - battery = candidate; - } - } - } + mib[0] = CTL_HW; + mib[1] = HW_CPU_FREQ; + len = sizeof(freq); + sysctl(mib, 2, &freq, &len, NULL, 0); - if(battery != NULL) { - CFStringRef power_state = CFDictionaryGetValue(battery, CFSTR(kIOPSPowerSourceStateKey)); - - CFNumberRef max_capacity = CFDictionaryGetValue(battery, CFSTR(kIOPSMaxCapacityKey)); - CFNumberRef design_capacity = CFDictionaryGetValue(battery, CFSTR(kIOPSDesignCapacityKey)); - CFNumberRef current_capacity = CFDictionaryGetValue(battery, CFSTR(kIOPSCurrentCapacityKey)); - - CFNumberRef amperage = CFDictionaryGetValue(battery, CFSTR(kIOPSCurrentKey)); - CFNumberRef voltage = CFDictionaryGetValue(battery, CFSTR(kIOPSVoltageKey)); - CFNumberRef temperature = CFDictionaryGetValue(battery, CFSTR(kIOPSTemperatureKey)); - - /* Determine the AC state */ - info->isCharging = kCFCompareEqualTo == CFStringCompare(power_state, CFSTR(kIOPSACPowerValue), 0); - - /* Get capacity */ - if (max_capacity) { - CFNumberGetValue(max_capacity, kCFNumberDoubleType, &info->maxCapacity); - CFRelease(max_capacity); - } - if (design_capacity) { - CFNumberGetValue(design_capacity, kCFNumberDoubleType, &info->designCapacity); - CFRelease(design_capacity); - } - if (current_capacity) { - CFNumberGetValue(current_capacity, kCFNumberDoubleType, &info->currentCapacity); - CFRelease(current_capacity); - } - - /* Determine the level */ - if (info->currentCapacity && info->maxCapacity) { - info->level = (info->currentCapacity * 100.0) / info->maxCapacity; - } - - /* Get the parameters */ - if (amperage) { - CFNumberGetValue(amperage, kCFNumberDoubleType, &info->amperage); - CFRelease(amperage); - } - if (voltage) { - printf("2\n"); - CFNumberGetValue(voltage, kCFNumberDoubleType, &info->voltage); - CFRelease(voltage); - } - if (temperature) { - printf("3\n"); - CFNumberGetValue(temperature, kCFNumberDoubleType, &info->voltage); - CFRelease(temperature); - } - -// printf("%f\n", info->amperage); -// printf("%f\n", test); -// printf("%f\n", info->temperature); -// printf("\n%hhu\n", info->isCharging); - -// printf("%u", info->level); - - CFRelease(battery); - } - - CFRelease(list); - CFRelease(power_sources); - - free(info); - return info; + return freq; } diff --git a/Stats/libs/SMC.h b/Stats/libs/SMC.h new file mode 100644 index 00000000..59295989 --- /dev/null +++ b/Stats/libs/SMC.h @@ -0,0 +1,273 @@ +// +// SMC.h +// Stats +// +// Created by Serhiy Mytrovtsiy on 03/04/2020. +// Copyright © 2020 Serhiy Mytrovtsiy. All rights reserved. +// + +typedef struct { + double termal_zone_0; + double termal_zone_1; + double termal_ambient_0; + double termal_ambient_1; + double termal_heatpipe_0; + double termal_heatpipe_1; + double termal_heatpipe_2; + double termal_heatpipe_3; + + double cpu_0_die; + double cpu_0_diode; + double cpu_0_heatsink; + double cpu_0_proximity; + double cpu_1_die; + double cpu_1_diode; + double cpu_1_heatsink; + double cpu_1_proximity; + + double cpu_1; + double cpu_2; + double cpu_3; + double cpu_4; + double cpu_5; + double cpu_6; + double cpu_7; + double cpu_8; + + double gpu_diode; + double gpu_heatsink; + double gpu_proximity; + + double mem_proximity; + double mem_0; + double mem_1; + double mem_2; + double mem_3; + + double pci_proximity; + double pci_0; + double pci_1; + double pci_2; + double pci_3; + + double sensor_mainboard; + double sensor_powerboard; + double sensor_battery; + double sensor_airport; + double sensor_lcd; + double sensor_misc; + double sensor_odd; + + double northbridge_die; + double northbridge_proximity; + + double hdd_0; + double hdd_1; + double hdd_2; + double hdd_3; + + double thunderbolt_0; + double thunderbolt_1; + double thunderbolt_2; + double thunderbolt_3; +} Temperatures; + +typedef struct { +} Voltages; + +typedef struct { +} Powers; + +kern_return_t SMCOpen(void); +kern_return_t SMCClose(void); + +double GetTemperature(char* key); +float GetFanRPM(char* key); + +void GetTemperatures(Temperatures* list); +void GetVoltages(Voltages* list); +void GetPowers(Powers* list); + +int64_t GetCPUFrequency(void); + +#define SMC_TEMP_AMBIENT_AIR_0 "TA0P" +#define SMC_TEMP_AMBIENT_AIR_1 "TA1P" +#define SMC_TEMP_HEATPIPE_0 "Th0H" +#define SMC_TEMP_HEATPIPE_1 "Th1H" +#define SMC_TEMP_HEATPIPE_2 "Th2H" +#define SMC_TEMP_HEATPIPE_3 "Th3H" +#define SMC_TEMP_TERMALZONE_0 "TZ0C" +#define SMC_TEMP_TERMALZONE_1 "TZ1C" + +#define SMC_TEMP_CPU_0_DIE "TC0F" +#define SMC_TEMP_CPU_0_DIODE "TC0D" +#define SMC_TEMP_CPU_0_HEATSINK "TC0H" +#define SMC_TEMP_CPU_0_PROXIMITY "TC0P" +#define SMC_TEMP_CPU_1_DIE "TCAD" +#define SMC_TEMP_CPU_1_DIODE "TC1D" +#define SMC_TEMP_CPU_1_HEATSINK "TC1H" +#define SMC_TEMP_CPU_1_PROXIMITY "TC1P" + +#define SMC_TEMP_CPU_CORE_1 "TC1C" +#define SMC_TEMP_CPU_CORE_2 "TC2C" +#define SMC_TEMP_CPU_CORE_3 "TC3C" +#define SMC_TEMP_CPU_CORE_4 "TC4C" +#define SMC_TEMP_CPU_CORE_5 "TC5C" +#define SMC_TEMP_CPU_CORE_6 "TC6C" +#define SMC_TEMP_CPU_CORE_7 "TC7C" +#define SMC_TEMP_CPU_CORE_8 "TC8C" + +#define SMC_TEMP_GPU_0_DIODE "TG0D" +#define SMC_TEMP_GPU_0_HEATSINK "TG0H" +#define SMC_TEMP_GPU_0_PROXIMITY "TG0P" + +#define SMC_TEMP_MEM_SLOTS "Ts0S" +#define SMC_TEMP_MEM_SLOT_0 "TM0S" +#define SMC_TEMP_MEM_SLOT_1 "TM1S" +#define SMC_TEMP_MEM_SLOT_2 "TM2S" +#define SMC_TEMP_MEM_SLOT_3 "TM3S" + +#define SMC_TEMP_PCI_SLOTS "TS0C" +#define SMC_TEMP_PCI_SLOT_0 "TA0S" +#define SMC_TEMP_PCI_SLOT_1 "TA1S" +#define SMC_TEMP_PCI_SLOT_2 "TA2S" +#define SMC_TEMP_PCI_SLOT_3 "TA3S" + +#define SMC_TEMP_MAINBOARD_PROXIMITY "Tm0P" +#define SMC_TEMP_POWERBOARD_PROXIMITY "Tp0P" +#define SMC_TEMP_BATTERY_PROXIMITY "TB1T" + +#define SMC_TEMP_AIRPORT_PROXIMITY "TW0P" +#define SMC_TEMP_LCD_PROXIMITY "TL0P" +#define SMC_TEMP_ODD_PROXIMITY "TO0P" + +#define SMC_TEMP_NORTHBRIDGE_DIE "TN0D" +#define SMC_TEMP_NORTHBRIDGE_PROXIMITY "TN0P" + +#define SMC_TEMP_HDD_0 "TH0P" +#define SMC_TEMP_HDD_1 "TH1P" +#define SMC_TEMP_HDD_2 "TH2P" +#define SMC_TEMP_HDD_3 "TH3P" + +#define SMC_TEMP_THUNDERBOLT_0 "TI0P" +#define SMC_TEMP_THUNDERBOLT_1 "TI1P" +#define SMC_TEMP_THUNDERBOLT_2 "TI2P" +#define SMC_TEMP_THUNDERBOLT_3 "TI3P" + +#define SMC_VOLTAGE_CPU_VRM "VS0C" +#define SMC_VOLTAGE_CPU_CORE_0 "VC0C" +#define SMC_VOLTAGE_CPU_CORE_1 "VC1C" +#define SMC_VOLTAGE_CPU_CORE_2 "VC2C" +#define SMC_VOLTAGE_CPU_CORE_3 "VC3C" +#define SMC_VOLTAGE_CPU_CORE_4 "VC4C" +#define SMC_VOLTAGE_CPU_CORE_5 "VC5C" +#define SMC_VOLTAGE_CPU_CORE_6 "VC6C" +#define SMC_VOLTAGE_CPU_CORE_7 "VC7C" +#define SMC_VOLTAGE_CPU_CORE_8 "VC8C" + +#define SMC_VOLTAGE_GPU "VG0C" +#define SMC_VOLTAGE_MEMORY "VM0R" +#define SMC_VOLTAGE_BATTERY "VBAT" +#define SMC_VOLTAGE_CMOS "Vb0R" + +#define SMC_VOLTAGE_MAINBOARD "VD0R" +#define SMC_VOLTAGE_12V_RAIL "VP0R" +#define SMC_VOLTAGE_12V_VCC "Vp0C" +#define SMC_VOLTAGE_3V "VV2S" +#define SMC_VOLTAGE_3_3V "VR3R" +#define SMC_VOLTAGE_5V "VV1S" +#define SMC_VOLTAGE_12V "VV9S" +#define SMC_VOLTAGE_PCI_12V "VeES" + +#define SMC_VOLTAGE_BATT0_VOLT "B0AV" +#define SMC_CURRENT_BATT0 "B0AC" + +#define SMC_WATT_CPU_PACKAGE_CORE "PCPC" +#define SMC_WATT_CPU_PACKAGE_TOTAL "PCPT" +#define SMC_WATT_IGPU_PACKAGE "PCPG" + +#define SMC_FREQUENCY_CPU_PACKAGE_MULTI "MPkC" +#define SMC_FREQUENCY_CPU_CORE_0_MULTI "MC0C" +#define SMC_FREQUENCY_CPU_CORE_1_MULTI "MC1C" +#define SMC_FREQUENCY_CPU_CORE_2_MULTI "MC2C" +#define SMC_FREQUENCY_CPU_CORE_3_MULTI "MC3C" +#define SMC_FREQUENCY_CPU_CORE_4_MULTI "MC4C" +#define SMC_FREQUENCY_CPU_CORE_5_MULTI "MC5C" +#define SMC_FREQUENCY_CPU_CORE_6_MULTI "MC6C" +#define SMC_FREQUENCY_CPU_CORE_7_MULTI "MC7C" +#define SMC_FREQUENCY_CPU_CORE_0 "FRC0" +#define SMC_FREQUENCY_CPU_CORE_1 "FRC1" +#define SMC_FREQUENCY_CPU_CORE_2 "FRC2" +#define SMC_FREQUENCY_CPU_CORE_3 "FRC3" +#define SMC_FREQUENCY_CPU_CORE_4 "FRC4" +#define SMC_FREQUENCY_CPU_CORE_5 "FRC5" +#define SMC_FREQUENCY_CPU_CORE_6 "FRC6" +#define SMC_FREQUENCY_CPU_CORE_7 "FRC7" + +#define SMC_FREQUENCY_GPU_0 "CG0C" +#define SMC_FREQUENCY_GPU_1 "CG1C" +#define SMC_FREQUENCY_GPU_0_SHADER "CG0S" +#define SMC_FREQUENCY_GPU_1_SHADER "CG1S" +#define SMC_FREQUENCY_GPU_0_MEMORY "CG1M" +#define SMC_FREQUENCY_GPU_1_MEMORY "CG0M" + +#define SMC_FAN0_RPM "F0Ac" + +#define KERNEL_INDEX_SMC 2 + +#define SMC_CMD_READ_BYTES 5 +#define SMC_CMD_WRITE_BYTES 6 +#define SMC_CMD_READ_INDEX 8 +#define SMC_CMD_READ_KEYINFO 9 +#define SMC_CMD_READ_PLIMIT 11 +#define SMC_CMD_READ_VERS 12 + +#define DATATYPE_FPE2 "fpe2" +#define DATATYPE_UINT8 "ui8 " +#define DATATYPE_UINT16 "ui16" +#define DATATYPE_UINT32 "ui32" +#define DATATYPE_SP78 "sp78" + +typedef char UInt32Char_t[5]; +typedef char SMCBytes_t[32]; + +typedef struct { + UInt32Char_t key; + UInt32 dataSize; + UInt32Char_t dataType; + SMCBytes_t bytes; +} SMCVal_t; + +typedef struct { + char major; + char minor; + char build; + char reserved[1]; + UInt16 release; +} SMCKeyData_vers_t; + +typedef struct { + UInt16 version; + UInt16 length; + UInt32 cpuPLimit; + UInt32 gpuPLimit; + UInt32 memPLimit; +} SMCKeyData_pLimitData_t; + +typedef struct { + UInt32 dataSize; + UInt32 dataType; + char dataAttributes; +} SMCKeyData_keyInfo_t; + +typedef struct { + UInt32 key; + SMCKeyData_vers_t vers; + SMCKeyData_pLimitData_t pLimitData; + SMCKeyData_keyInfo_t keyInfo; + char result; + char status; + char data8; + UInt32 data32; + SMCBytes_t bytes; +} SMCKeyData_t; diff --git a/Stats/libs/Stats.h b/Stats/libs/Stats.h index 4f51e865..aaf9f7de 100644 --- a/Stats/libs/Stats.h +++ b/Stats/libs/Stats.h @@ -8,7 +8,7 @@ #import -#import "SystemKit.h" +#import "SMC.h" //! Project version number for SMCKit. FOUNDATION_EXPORT double SMCKitVersionNumber; diff --git a/Stats/libs/SystemKit.h b/Stats/libs/SystemKit.h deleted file mode 100644 index dfbccb1c..00000000 --- a/Stats/libs/SystemKit.h +++ /dev/null @@ -1,142 +0,0 @@ -// -// SystemKit.h -// Stats -// -// Created by Serhiy Mytrovtsiy on 03/04/2020. -// Copyright © 2020 Serhiy Mytrovtsiy. All rights reserved. -// - -#define SMC_TEMP_AMBIENT_AIR_0 "TA0P" -#define SMC_TEMP_AMBIENT_AIR_1 "TA1P" - -#define SMC_TEMP_CPU_0_DIE "TC0F" -#define SMC_TEMP_CPU_0_DIODE "TC0D" -#define SMC_TEMP_CPU_0_HEATSINK "TC0H" -#define SMC_TEMP_CPU_0_PROXIMITY "TC0P" - -#define SMC_TEMP_ENCLOSURE_BASE_0 "TB0T" -#define SMC_TEMP_ENCLOSURE_BASE_1 "TB1T" -#define SMC_TEMP_ENCLOSURE_BASE_2 "TB2T" -#define SMC_TEMP_ENCLOSURE_BASE_3 "TB3T" - -#define SMC_TEMP_GPU_0_DIODE "TG0D" -#define SMC_TEMP_GPU_0_HEATSINK "TG0H" -#define SMC_TEMP_GPU_0_PROXIMITY "TG0P" - -#define SMC_TEMP_HDD_PROXIMITY "TH0P" -#define SMC_TEMP_LCD_PROXIMITY "TL0P" -#define SMC_TEMP_MISC_PROXIMITY "Tm0P" -#define SMC_TEMP_ODD_PROXIMITY "TO0P" - -#define SMC_TEMP_HEATSINK_0 "Th0H" -#define SMC_TEMP_HEATSINK_1 "Th1H" -#define SMC_TEMP_HEATSINK_2 "Th2H" - -#define SMC_TEMP_MEM_SLOT_0 "TM0S" -#define SMC_TEMP_MEM_SLOTS_PROXIMITY "TM0P" - -#define SMC_TEMP_NORTHBRIDGE "TN0H" -#define SMC_TEMP_NORTHBRIDGE_DIODE "TN0D" -#define SMC_TEMP_NORTHBRIDGE_PROXIMITY "TN0P" - -#define SMC_TEMP_PALM_REST "Ts0P" -#define PWR_TEMP_SUPPLY_PROXIMITY "Tp0P" - -#define SMC_TEMP_THUNDERBOLT_0 "TI0P" -#define SMC_TEMP_THUNDERBOLT_1 "TI1P" - -#define SMC_FAN0_RPM "F0Ac" - -typedef enum { - Off_line, - AC_Power, - Battery_Power -} PowerSource; - -typedef struct { - unsigned int level; - Boolean isCharging; - - double amperage; - double voltage; - double temperature; - - double cycles; - - double currentCapacity; - double maxCapacity; - double designCapacity; - - double timeToEmpty; - double timeToFull; - - PowerSource powerSource; - double ACWatts; -} PowerManagmentInformation; - -kern_return_t SMCOpen(void); -kern_return_t SMCClose(void); - -double GetTemperature(char* key); -float GetFanRPM(char* key); -//PowerManagmentInformation *GetPowerInfo(void); - -// INTERNAL -#define KERNEL_INDEX_SMC 2 - -#define SMC_CMD_READ_BYTES 5 -#define SMC_CMD_WRITE_BYTES 6 -#define SMC_CMD_READ_INDEX 8 -#define SMC_CMD_READ_KEYINFO 9 -#define SMC_CMD_READ_PLIMIT 11 -#define SMC_CMD_READ_VERS 12 - -#define DATATYPE_FPE2 "fpe2" -#define DATATYPE_UINT8 "ui8 " -#define DATATYPE_UINT16 "ui16" -#define DATATYPE_UINT32 "ui32" -#define DATATYPE_SP78 "sp78" - -typedef char UInt32Char_t[5]; -typedef char SMCBytes_t[32]; - -typedef struct { - UInt32Char_t key; - UInt32 dataSize; - UInt32Char_t dataType; - SMCBytes_t bytes; -} SMCVal_t; - -typedef struct { - char major; - char minor; - char build; - char reserved[1]; - UInt16 release; -} SMCKeyData_vers_t; - -typedef struct { - UInt16 version; - UInt16 length; - UInt32 cpuPLimit; - UInt32 gpuPLimit; - UInt32 memPLimit; -} SMCKeyData_pLimitData_t; - -typedef struct { - UInt32 dataSize; - UInt32 dataType; - char dataAttributes; -} SMCKeyData_keyInfo_t; - -typedef struct { - UInt32 key; - SMCKeyData_vers_t vers; - SMCKeyData_pLimitData_t pLimitData; - SMCKeyData_keyInfo_t keyInfo; - char result; - char status; - char data8; - UInt32 data32; - SMCBytes_t bytes; -} SMCKeyData_t;