diff --git a/Modules/Disk/settings.swift b/Modules/Disk/settings.swift
index e07b4c82..d502c8f7 100644
--- a/Modules/Disk/settings.swift
+++ b/Modules/Disk/settings.swift
@@ -78,13 +78,18 @@ internal class Settings: NSView, Settings_v {
}
private func addDiskSelector() {
- let view: NSView = NSView(frame: NSRect(x: Constants.Settings.margin, y: Constants.Settings.margin*2 + 30, width: self.frame.width, height: 29))
+ let view: NSView = NSView(frame: NSRect(
+ x: Constants.Settings.margin,
+ y: Constants.Settings.margin*2 + 30,
+ width: self.frame.width - Constants.Settings.margin*2,
+ height: 30
+ ))
let rowTitle: NSTextField = LabelField(frame: NSRect(x: 0, y: (view.frame.height - 16)/2, width: view.frame.width - 52, height: 17), "Disk to show")
rowTitle.font = NSFont.systemFont(ofSize: 13, weight: .light)
rowTitle.textColor = .textColor
- self.button = NSPopUpButton(frame: NSRect(x: view.frame.width - 140 - Constants.Settings.margin*2, y: -1, width: 140, height: 30))
+ self.button = NSPopUpButton(frame: NSRect(x: view.frame.width - 140, y: -1, width: 140, height: 30))
self.button!.target = self
self.button?.action = #selector(self.handleSelection)
diff --git a/Modules/GPU/config.plist b/Modules/GPU/config.plist
index 43302fd6..c9c64a7a 100644
--- a/Modules/GPU/config.plist
+++ b/Modules/GPU/config.plist
@@ -6,5 +6,55 @@
GPU
State
+ Widgets
+
+ mini
+
+ Default
+
+ Preview
+
+ Value
+ 0.32
+
+ Unsupported colors
+
+ pressure
+
+ Order
+ 0
+
+ line_chart
+
+ Default
+
+ Color
+ systemAccent
+ Unsupported colors
+
+ pressure
+
+ Order
+ 1
+
+ bar_chart
+
+ Default
+
+ Preview
+
+ Value
+ 0.36,0.28,0.32,0.26
+ Color
+
+
+ Unsupported colors
+
+ pressure
+
+ Order
+ 2
+
+
diff --git a/Modules/GPU/main.swift b/Modules/GPU/main.swift
index c6ab28a2..61e18f7b 100644
--- a/Modules/GPU/main.swift
+++ b/Modules/GPU/main.swift
@@ -13,33 +13,103 @@ import Cocoa
import ModuleKit
import StatsKit
-public struct GPU_Load {}
+public struct GPU_Info {
+ public let name: String
+ public let IOclass: String
+ public var state: Bool = false
+
+ public var utilization: Double = 0
+
+ public var totalVram: Int = 0
+ public var freeVram: Int = 0
+ public var coreClock: Int = 0
+ public var power: Int = 0
+ public var temperature: Int = 0
+}
+
+public struct GPUs: value_t {
+ public var list: [GPU_Info] = []
+
+ internal func active() -> [GPU_Info] {
+ return self.list.filter{ $0.state }
+ }
+
+ internal func igpu() -> GPU_Info? {
+ return self.active().first{ $0.IOclass == "IntelAccelerator" }
+ }
+
+ public var widget_value: Double {
+ get {
+ return list[0].utilization
+ }
+ }
+}
public class GPU: Module {
private let smc: UnsafePointer?
private let store: UnsafePointer
- private var loadReader: LoadReader? = nil
+ private var infoReader: InfoReader? = nil
+ private var settingsView: Settings
+ private var popupView: Popup = Popup()
+
+ private var selectedGPU: String = ""
public init(_ store: UnsafePointer, _ smc: UnsafePointer) {
self.store = store
self.smc = smc
+ self.settingsView = Settings("GPU", store: store)
super.init(
store: store,
- popup: nil,
- settings: nil
+ popup: self.popupView,
+ settings: self.settingsView
)
guard self.available else { return }
- self.loadReader = LoadReader()
+ self.infoReader = InfoReader()
+ self.infoReader?.smc = smc
+ self.selectedGPU = store.pointee.string(key: "\(self.config.name)_gpu", defaultValue: self.selectedGPU)
- self.loadReader?.readyCallback = { [unowned self] in
+ self.infoReader?.readyCallback = { [unowned self] in
self.readyHandler()
}
+ self.infoReader?.callbackHandler = { [unowned self] value in
+ self.infoCallback(value)
+ }
- if let reader = self.loadReader {
+ self.settingsView.selectedGPUHandler = { [unowned self] value in
+ self.selectedGPU = value
+ self.infoReader?.read()
+ }
+ self.settingsView.setInterval = { [unowned self] value in
+ self.infoReader?.setInterval(value)
+ }
+
+ if let reader = self.infoReader {
self.addReader(reader)
}
}
+
+ private func infoCallback(_ value: GPUs?) {
+ guard value != nil else {
+ return
+ }
+
+ self.popupView.infoCallback(value!)
+ self.settingsView.setList(value!)
+
+ let activeGPU = value!.active()
+ let selectedGPU = activeGPU.first{ $0.name == self.selectedGPU } ?? value!.igpu() ?? value!.list[0]
+
+ if let widget = self.widget as? Mini {
+ widget.setValue(selectedGPU.utilization, sufix: "%")
+ }
+ if let widget = self.widget as? LineChart {
+ widget.setValue(selectedGPU.utilization)
+ }
+ if let widget = self.widget as? BarChart {
+ widget.setValue([selectedGPU.utilization])
+ }
+ }
}
diff --git a/Modules/GPU/popup.swift b/Modules/GPU/popup.swift
new file mode 100644
index 00000000..10d7e8a8
--- /dev/null
+++ b/Modules/GPU/popup.swift
@@ -0,0 +1,32 @@
+//
+// popup.swift
+// GPU
+//
+// Created by Serhiy Mytrovtsiy on 17/08/2020.
+// Using Swift 5.0.
+// Running on macOS 10.15.
+//
+// Copyright © 2020 Serhiy Mytrovtsiy. All rights reserved.
+//
+
+import Cocoa
+import StatsKit
+import ModuleKit
+
+internal class Popup: NSView {
+ public init() {
+ super.init(frame: NSRect(x: 0, y: 0, width: Constants.Popup.width, height: 0))
+ }
+
+ required init?(coder: NSCoder) {
+ fatalError("init(coder:) has not been implemented")
+ }
+
+ internal func infoCallback(_ value: GPUs) {
+ print(value)
+ }
+}
+
+private class GPUView: NSView {
+
+}
diff --git a/Modules/GPU/reader.swift b/Modules/GPU/reader.swift
index 879b7966..9a3c77cd 100644
--- a/Modules/GPU/reader.swift
+++ b/Modules/GPU/reader.swift
@@ -14,8 +14,94 @@ import StatsKit
import ModuleKit
import os.log
-internal class LoadReader: Reader {
+internal class InfoReader: Reader {
+ internal var smc: UnsafePointer? = nil
+ private var gpus: GPUs = GPUs()
+
public override func read() {
+ guard let devices = fetchIOService("IOPCIDevice") else {
+ return
+ }
+ let gpus = devices.filter{ $0.object(forKey: "IOName") as? String == "display" }
+ guard let acceletators = fetchIOService(kIOAcceleratorClassName) else {
+ return
+ }
+
+ acceletators.forEach { (accelerator: NSDictionary) in
+ guard let matchedGPU = gpus.first(where: { (gpu: NSDictionary) -> Bool in
+ guard let deviceID = gpu["device-id"] as? Data, let vendorID = gpu["vendor-id"] as? Data else {
+ return false
+ }
+
+ let pciMatch = "0x" + Data([deviceID[1], deviceID[0], vendorID[1], vendorID[0]]).map { String(format: "%02hhX", $0) }.joined()
+ let accMatch = accelerator["IOPCIMatch"] as? String ?? accelerator["IOPCIPrimaryMatch"] as? String ?? ""
+
+ return accMatch.range(of: pciMatch) != nil
+ }) else { return }
+
+ guard let agcInfo = accelerator["AGCInfo"] as? [String:Int] else {
+ return
+ }
+
+ guard let stats = accelerator["PerformanceStatistics"] as? [String:Any] else {
+ return
+ }
+
+ guard let model = matchedGPU.object(forKey: "model") as? Data else {
+ return
+ }
+ let modelName = String(data: model, encoding: .ascii)!.replacingOccurrences(of: "\0", with: "")
+
+ guard let IOClass = accelerator.object(forKey: "IOClass") as? String else {
+ return
+ }
+
+ if self.gpus.list.first(where: { $0.name == modelName }) == nil {
+ self.gpus.list.append(GPU_Info(name: modelName, IOclass: IOClass))
+ }
+
+ guard let idx = self.gpus.list.firstIndex(where: { $0.name == modelName }) else {
+ return
+ }
+
+ let utilization = stats["Device Utilization %"] as? Int ?? 0
+ let totalVram = accelerator["VRAM,totalMB"] as? Int ?? matchedGPU["VRAM,totalMB"] as? Int ?? 0
+ let freeVram = stats["vramFreeBytes"] as? Int ?? 0
+ let coreClock = stats["Core Clock(MHz)"] as? Int ?? 0
+ var power = stats["Total Power(W)"] as? Int ?? 0
+ var temperature = stats["Temperature(C)"] as? Int ?? 0
+
+ if IOClass == "IntelAccelerator" {
+ if temperature == 0 {
+ if let tmp = self.smc?.pointee.getValue("TCGC") {
+ temperature = Int(tmp)
+ } else if let tmp = self.smc?.pointee.getValue("TG0D") {
+ temperature = Int(tmp)
+ }
+ }
+
+ if power == 0 {
+ if let pwr = self.smc?.pointee.getValue("PCPG") {
+ power = Int(pwr)
+ } else if let pwr = self.smc?.pointee.getValue("PCGC") {
+ power = Int(pwr)
+ } else if let pwr = self.smc?.pointee.getValue("PCGM") {
+ power = Int(pwr)
+ }
+ }
+ }
+
+ self.gpus.list[idx].state = agcInfo["poweredOffByAGC"] == 0
+
+ self.gpus.list[idx].utilization = utilization == 0 ? 0 : Double(utilization)/100
+ self.gpus.list[idx].totalVram = totalVram
+ self.gpus.list[idx].freeVram = freeVram
+ self.gpus.list[idx].coreClock = coreClock
+ self.gpus.list[idx].power = power
+ self.gpus.list[idx].temperature = temperature
+ }
+
+ self.callback(self.gpus)
}
}
diff --git a/Modules/GPU/settings.swift b/Modules/GPU/settings.swift
new file mode 100644
index 00000000..4381afbc
--- /dev/null
+++ b/Modules/GPU/settings.swift
@@ -0,0 +1,126 @@
+//
+// settings.swift
+// GPU
+//
+// Created by Serhiy Mytrovtsiy on 17/08/2020.
+// Using Swift 5.0.
+// Running on macOS 10.15.
+//
+// Copyright © 2020 Serhiy Mytrovtsiy. All rights reserved.
+//
+
+import Cocoa
+import StatsKit
+import ModuleKit
+
+internal class Settings: NSView, Settings_v {
+ private var updateIntervalValue: String = "1"
+ private let listOfUpdateIntervals: [String] = ["1", "2", "3", "5", "10", "15", "30"]
+ private var selectedGPU: String
+
+ private let title: String
+ private let store: UnsafePointer
+
+ public var selectedGPUHandler: (String) -> Void = {_ in }
+ public var callback: (() -> Void) = {}
+ public var setInterval: ((_ value: Double) -> Void) = {_ in }
+
+ private var hyperthreadView: NSView? = nil
+
+ private var button: NSPopUpButton?
+
+ public init(_ title: String, store: UnsafePointer) {
+ self.title = title
+ self.store = store
+ self.selectedGPU = store.pointee.string(key: "\(self.title)_gpu", defaultValue: "")
+ self.updateIntervalValue = store.pointee.string(key: "\(self.title)_updateInterval", defaultValue: self.updateIntervalValue)
+
+ super.init(frame: CGRect(
+ x: 0,
+ y: 0,
+ width: Constants.Settings.width - (Constants.Settings.margin*2),
+ height: 0
+ ))
+
+ self.wantsLayer = true
+ self.canDrawConcurrently = true
+ }
+
+ required init?(coder: NSCoder) {
+ fatalError("init(coder:) has not been implemented")
+ }
+
+ public func load(widget: widget_t) {
+ self.subviews.forEach{ $0.removeFromSuperview() }
+
+ let rowHeight: CGFloat = 30
+ let num: CGFloat = 1
+
+ self.addSubview(SelectTitleRow(
+ frame: NSRect(x: Constants.Settings.margin, y: Constants.Settings.margin + (rowHeight + Constants.Settings.margin) * num, width: self.frame.width - (Constants.Settings.margin*2), height: rowHeight),
+ title: "Update interval",
+ action: #selector(changeUpdateInterval),
+ items: self.listOfUpdateIntervals.map{ "\($0) sec" },
+ selected: "\(self.updateIntervalValue) sec"
+ ))
+
+ self.addGPUSelector()
+
+ self.setFrameSize(NSSize(width: self.frame.width, height: (rowHeight*(num+1)) + (Constants.Settings.margin*(2+num))))
+ }
+
+ private func addGPUSelector() {
+ let view: NSView = NSView(frame: NSRect(
+ x: Constants.Settings.margin,
+ y: Constants.Settings.margin,
+ width: self.frame.width - Constants.Settings.margin*2,
+ height: 30
+ ))
+
+ let rowTitle: NSTextField = LabelField(frame: NSRect(x: 0, y: (view.frame.height - 16)/2, width: view.frame.width - 52, height: 17), "GPU to show")
+ rowTitle.font = NSFont.systemFont(ofSize: 13, weight: .light)
+ rowTitle.textColor = .textColor
+
+ self.button = NSPopUpButton(frame: NSRect(x: view.frame.width - 200, y: -1, width: 200, height: 30))
+ self.button!.target = self
+ self.button?.action = #selector(self.handleSelection)
+
+ view.addSubview(rowTitle)
+ view.addSubview(self.button!)
+
+ self.addSubview(view)
+ }
+
+ internal func setList(_ list: GPUs) {
+ let disks = list.active().map{ $0.name }
+ DispatchQueue.main.async(execute: {
+ if self.button?.itemTitles.count != disks.count {
+ self.button?.removeAllItems()
+ }
+
+ if disks != self.button?.itemTitles {
+ self.button?.addItems(withTitles: disks)
+ if self.selectedGPU != "" {
+ self.button?.selectItem(withTitle: self.selectedGPU)
+ }
+ }
+ })
+ }
+
+ @objc private func changeUpdateInterval(_ sender: NSMenuItem) {
+ let newUpdateInterval = sender.title.replacingOccurrences(of: " sec", with: "")
+ self.updateIntervalValue = newUpdateInterval
+ store.pointee.set(key: "\(self.title)_updateInterval", value: self.updateIntervalValue)
+
+ if let value = Double(self.updateIntervalValue) {
+ self.setInterval(value)
+ }
+ }
+
+ @objc private func handleSelection(_ sender: NSPopUpButton) {
+ guard let item = sender.selectedItem else { return }
+ self.selectedGPU = item.title
+ self.store.pointee.set(key: "\(self.title)_gpu", value: item.title)
+ self.selectedGPUHandler(item.title)
+ }
+}
diff --git a/Modules/Net/settings.swift b/Modules/Net/settings.swift
index 6132d7c2..2c4a20a6 100644
--- a/Modules/Net/settings.swift
+++ b/Modules/Net/settings.swift
@@ -58,13 +58,13 @@ internal class Settings: NSView, Settings_v {
}
private func addNetworkSelector() {
- let view: NSView = NSView(frame: NSRect(x: Constants.Settings.margin, y: Constants.Settings.margin, width: self.frame.width, height: 29))
+ let view: NSView = NSView(frame: NSRect(x: Constants.Settings.margin, y: Constants.Settings.margin, width: self.frame.width, height: 30))
let rowTitle: NSTextField = LabelField(frame: NSRect(x: 0, y: (view.frame.height - 16)/2, width: view.frame.width - 52, height: 17), "Network interface")
rowTitle.font = NSFont.systemFont(ofSize: 13, weight: .light)
rowTitle.textColor = .textColor
- self.button = NSPopUpButton(frame: NSRect(x: view.frame.width - 200 - Constants.Settings.margin*2, y: -1, width: 200, height: 30))
+ self.button = NSPopUpButton(frame: NSRect(x: view.frame.width - 200 - Constants.Settings.margin*2, y: 0, width: 200, height: 30))
self.button!.target = self
self.button?.action = #selector(self.handleSelection)
diff --git a/Modules/Sensors/values.swift b/Modules/Sensors/values.swift
index f84882a7..db418c2c 100644
--- a/Modules/Sensors/values.swift
+++ b/Modules/Sensors/values.swift
@@ -104,7 +104,7 @@ let SensorsList: [Sensor_t] = [
Sensor_t(key: "Th3H", name: "Heatpipe 4", group: SensorGroup.Sensor.rawValue, type: SensorType.Temperature.rawValue),
Sensor_t(key: "TZ0C", name: "Termal zone 1", group: SensorGroup.Sensor.rawValue, type: SensorType.Temperature.rawValue),
Sensor_t(key: "TZ1C", name: "Termal zone 2", group: SensorGroup.Sensor.rawValue, type: SensorType.Temperature.rawValue),
-
+
Sensor_t(key: "TC0E", name: "CPU 1", group: SensorGroup.CPU.rawValue, type: SensorType.Temperature.rawValue),
Sensor_t(key: "TC0F", name: "CPU 2", group: SensorGroup.CPU.rawValue, type: SensorType.Temperature.rawValue),
Sensor_t(key: "TC0D", name: "CPU die", group: SensorGroup.CPU.rawValue, type: SensorType.Temperature.rawValue),
@@ -112,7 +112,7 @@ let SensorsList: [Sensor_t] = [
Sensor_t(key: "TC0H", name: "CPU heatsink", group: SensorGroup.CPU.rawValue, type: SensorType.Temperature.rawValue),
Sensor_t(key: "TC0P", name: "CPU proximity", group: SensorGroup.CPU.rawValue, type: SensorType.Temperature.rawValue),
Sensor_t(key: "TCAD", name: "CPU package", group: SensorGroup.CPU.rawValue, type: SensorType.Temperature.rawValue),
-
+
Sensor_t(key: "TC0c", name: "CPU core 1", group: SensorGroup.CPU.rawValue, type: SensorType.Temperature.rawValue),
Sensor_t(key: "TC1c", name: "CPU core 2", group: SensorGroup.CPU.rawValue, type: SensorType.Temperature.rawValue),
Sensor_t(key: "TC2c", name: "CPU core 3", group: SensorGroup.CPU.rawValue, type: SensorType.Temperature.rawValue),
@@ -129,12 +129,12 @@ let SensorsList: [Sensor_t] = [
Sensor_t(key: "TC13c", name: "CPU core 14", group: SensorGroup.CPU.rawValue, type: SensorType.Temperature.rawValue),
Sensor_t(key: "TC14c", name: "CPU core 15", group: SensorGroup.CPU.rawValue, type: SensorType.Temperature.rawValue),
Sensor_t(key: "TC15c", name: "CPU core 16", group: SensorGroup.CPU.rawValue, type: SensorType.Temperature.rawValue),
-
+
Sensor_t(key: "TCGC", name: "GPU Intel Graphics", group: SensorGroup.GPU.rawValue, type: SensorType.Temperature.rawValue),
Sensor_t(key: "TG0D", name: "GPU die", group: SensorGroup.GPU.rawValue, type: SensorType.Temperature.rawValue),
Sensor_t(key: "TG0H", name: "GPU heatsink", group: SensorGroup.GPU.rawValue, type: SensorType.Temperature.rawValue),
Sensor_t(key: "TG0P", name: "GPU proximity", group: SensorGroup.GPU.rawValue, type: SensorType.Temperature.rawValue),
-
+
Sensor_t(key: "Tm0P", name: "Mainboard", group: SensorGroup.System.rawValue, type: SensorType.Temperature.rawValue),
Sensor_t(key: "Tp0P", name: "Powerboard", group: SensorGroup.System.rawValue, type: SensorType.Temperature.rawValue),
Sensor_t(key: "TB1T", name: "Battery", group: SensorGroup.System.rawValue, type: SensorType.Temperature.rawValue),
@@ -144,11 +144,11 @@ let SensorsList: [Sensor_t] = [
Sensor_t(key: "TI1P", name: "Thunderbold 2", group: SensorGroup.System.rawValue, type: SensorType.Temperature.rawValue),
Sensor_t(key: "TI2P", name: "Thunderbold 3", group: SensorGroup.System.rawValue, type: SensorType.Temperature.rawValue),
Sensor_t(key: "TI3P", name: "Thunderbold 4", group: SensorGroup.System.rawValue, type: SensorType.Temperature.rawValue),
-
+
Sensor_t(key: "TN0D", name: "Northbridge die", group: SensorGroup.System.rawValue, type: SensorType.Temperature.rawValue),
Sensor_t(key: "TN0H", name: "Northbridge heatsink", group: SensorGroup.System.rawValue, type: SensorType.Temperature.rawValue),
Sensor_t(key: "TN0P", name: "Northbridge proximity", group: SensorGroup.System.rawValue, type: SensorType.Temperature.rawValue),
-
+
/// Voltage
Sensor_t(key: "VCAC", name: "CPU IA", group: SensorGroup.CPU.rawValue, type: SensorType.Voltage.rawValue),
Sensor_t(key: "VCSC", name: "CPU System Agent", group: SensorGroup.CPU.rawValue, type: SensorType.Voltage.rawValue),
@@ -168,13 +168,13 @@ let SensorsList: [Sensor_t] = [
Sensor_t(key: "VC13C", name: "CPU Core 14", group: SensorGroup.CPU.rawValue, type: SensorType.Voltage.rawValue),
Sensor_t(key: "VC14C", name: "CPU Core 15", group: SensorGroup.CPU.rawValue, type: SensorType.Voltage.rawValue),
Sensor_t(key: "VC15C", name: "CPU Core 16", group: SensorGroup.CPU.rawValue, type: SensorType.Voltage.rawValue),
-
+
Sensor_t(key: "VCTC", name: "GPU Intel Graphics", group: SensorGroup.GPU.rawValue, type: SensorType.Voltage.rawValue),
Sensor_t(key: "VG0C", name: "GPU", group: SensorGroup.GPU.rawValue, type: SensorType.Voltage.rawValue),
-
+
Sensor_t(key: "VM0R", name: "Memory", group: SensorGroup.System.rawValue, type: SensorType.Voltage.rawValue),
Sensor_t(key: "Vb0R", name: "CMOS", group: SensorGroup.System.rawValue, type: SensorType.Voltage.rawValue),
-
+
Sensor_t(key: "VD0R", name: "DC In", group: SensorGroup.Sensor.rawValue, type: SensorType.Voltage.rawValue),
Sensor_t(key: "VP0R", name: "12V rail", group: SensorGroup.Sensor.rawValue, type: SensorType.Voltage.rawValue),
Sensor_t(key: "Vp0C", name: "12V vcc", group: SensorGroup.Sensor.rawValue, type: SensorType.Voltage.rawValue),
@@ -183,7 +183,7 @@ let SensorsList: [Sensor_t] = [
Sensor_t(key: "VV1S", name: "5V", group: SensorGroup.Sensor.rawValue, type: SensorType.Voltage.rawValue),
Sensor_t(key: "VV9S", name: "12V", group: SensorGroup.Sensor.rawValue, type: SensorType.Voltage.rawValue),
Sensor_t(key: "VeES", name: "PCI 12V", group: SensorGroup.Sensor.rawValue, type: SensorType.Voltage.rawValue),
-
+
/// Power
Sensor_t(key: "PC0C", name: "CPU Core", group: SensorGroup.CPU.rawValue, type: SensorType.Power.rawValue),
Sensor_t(key: "PCAM", name: "CPU Core (IMON)", group: SensorGroup.CPU.rawValue, type: SensorType.Power.rawValue),
@@ -193,7 +193,7 @@ let SensorsList: [Sensor_t] = [
Sensor_t(key: "PCPR", name: "CPU Package total (SMC)", group: SensorGroup.CPU.rawValue, type: SensorType.Power.rawValue),
Sensor_t(key: "PC0R", name: "CPU Computing high side", group: SensorGroup.CPU.rawValue, type: SensorType.Power.rawValue),
Sensor_t(key: "PC0G", name: "CPU GFX", group: SensorGroup.CPU.rawValue, type: SensorType.Power.rawValue),
-
+
Sensor_t(key: "PCPG", name: "GPU Intel Graphics", group: SensorGroup.GPU.rawValue, type: SensorType.Power.rawValue),
Sensor_t(key: "PG0R", name: "GPU", group: SensorGroup.GPU.rawValue, type: SensorType.Power.rawValue),
Sensor_t(key: "PCGC", name: "Intel GPU", group: SensorGroup.GPU.rawValue, type: SensorType.Power.rawValue),
@@ -203,7 +203,7 @@ let SensorsList: [Sensor_t] = [
Sensor_t(key: "PPBR", name: "Battery", group: SensorGroup.Sensor.rawValue, type: SensorType.Power.rawValue),
Sensor_t(key: "PDTR", name: "DC In", group: SensorGroup.Sensor.rawValue, type: SensorType.Power.rawValue),
Sensor_t(key: "PSTR", name: "System total", group: SensorGroup.Sensor.rawValue, type: SensorType.Power.rawValue),
-
+
/// Frequency
Sensor_t(key: "FRC0", name: "CPU 1", group: SensorGroup.CPU.rawValue, type: SensorType.Frequency.rawValue),
Sensor_t(key: "FRC1", name: "CPU 2", group: SensorGroup.CPU.rawValue, type: SensorType.Frequency.rawValue),
@@ -221,11 +221,11 @@ let SensorsList: [Sensor_t] = [
Sensor_t(key: "FRC13", name: "CPU 14", group: SensorGroup.CPU.rawValue, type: SensorType.Frequency.rawValue),
Sensor_t(key: "FRC14", name: "CPU 15", group: SensorGroup.CPU.rawValue, type: SensorType.Frequency.rawValue),
Sensor_t(key: "FRC15", name: "CPU 16", group: SensorGroup.CPU.rawValue, type: SensorType.Frequency.rawValue),
-
+
Sensor_t(key: "CG0C", name: "GPU", group: SensorGroup.GPU.rawValue, type: SensorType.Frequency.rawValue),
Sensor_t(key: "CG0S", name: "GPU shader", group: SensorGroup.GPU.rawValue, type: SensorType.Frequency.rawValue),
Sensor_t(key: "CG0M", name: "GPU memory", group: SensorGroup.GPU.rawValue, type: SensorType.Frequency.rawValue),
-
+
/// Battery
Sensor_t(key: "B0AV", name: "Voltage", group: SensorGroup.Sensor.rawValue, type: SensorType.Battery.rawValue),
Sensor_t(key: "B0AC", name: "Amperage", group: SensorGroup.Sensor.rawValue, type: SensorType.Battery.rawValue),
diff --git a/Stats.xcodeproj/project.pbxproj b/Stats.xcodeproj/project.pbxproj
index 5b1473d3..1cae54a4 100644
--- a/Stats.xcodeproj/project.pbxproj
+++ b/Stats.xcodeproj/project.pbxproj
@@ -37,6 +37,8 @@
9A3E17E8247AA8E100449CD1 /* Speed.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A3E17E7247AA8E100449CD1 /* Speed.swift */; };
9A3E17EA247B07BF00449CD1 /* popup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A3E17E9247B07BF00449CD1 /* popup.swift */; };
9A41530C24ABC3AF00A2BDA7 /* Memory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A41530B24ABC3AF00A2BDA7 /* Memory.swift */; };
+ 9A53EBF924EAFA5200648841 /* settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A53EBF824EAFA5200648841 /* settings.swift */; };
+ 9A53EBFB24EB041E00648841 /* popup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A53EBFA24EB041E00648841 /* popup.swift */; };
9A58DE9E24B363D800716A9F /* popup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A58DE9D24B363D800716A9F /* popup.swift */; };
9A58DEA024B363F300716A9F /* settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A58DE9F24B363F300716A9F /* settings.swift */; };
9A58DEA424B3647600716A9F /* settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A58DEA324B3647600716A9F /* settings.swift */; };
@@ -462,6 +464,8 @@
9A3E17E9247B07BF00449CD1 /* popup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = popup.swift; sourceTree = ""; };
9A41530B24ABC3AF00A2BDA7 /* Memory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Memory.swift; sourceTree = ""; };
9A5349CD23D8832E00C23824 /* Reachability.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Reachability.framework; path = Carthage/Build/Mac/Reachability.framework; sourceTree = ""; };
+ 9A53EBF824EAFA5200648841 /* settings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = settings.swift; sourceTree = ""; };
+ 9A53EBFA24EB041E00648841 /* popup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = popup.swift; sourceTree = ""; };
9A58DE9D24B363D800716A9F /* popup.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = popup.swift; sourceTree = ""; };
9A58DE9F24B363F300716A9F /* settings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = settings.swift; sourceTree = ""; };
9A58DEA324B3647600716A9F /* settings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = settings.swift; sourceTree = ""; };
@@ -777,6 +781,8 @@
children = (
9A90E19524EAD35F00471E9A /* main.swift */,
9A90E1A224EAD66600471E9A /* reader.swift */,
+ 9A53EBF824EAFA5200648841 /* settings.swift */,
+ 9A53EBFA24EB041E00648841 /* popup.swift */,
9A90E18C24EAD2BB00471E9A /* Info.plist */,
9A90E19724EAD3B000471E9A /* config.plist */,
);
@@ -1435,6 +1441,8 @@
files = (
9A90E1A324EAD66600471E9A /* reader.swift in Sources */,
9A90E19624EAD35F00471E9A /* main.swift in Sources */,
+ 9A53EBFB24EB041E00648841 /* popup.swift in Sources */,
+ 9A53EBF924EAFA5200648841 /* settings.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
diff --git a/StatsKit/SystemKit.swift b/StatsKit/SystemKit.swift
index dcc18f9b..7b4fd03c 100644
--- a/StatsKit/SystemKit.swift
+++ b/StatsKit/SystemKit.swift
@@ -382,4 +382,5 @@ let osDict: [Int: String] = [
13: "High Sierra",
14: "Mojave",
15: "Catalina",
+ 16: "Big Sur",
]
diff --git a/StatsKit/extensions.swift b/StatsKit/extensions.swift
index f2716b1d..94a8a8b8 100644
--- a/StatsKit/extensions.swift
+++ b/StatsKit/extensions.swift
@@ -876,6 +876,26 @@ public func getIOParent(_ obj: io_registry_entry_t) -> io_registry_entry_t? {
return parent
}
+public func fetchIOService(_ name: String) -> [NSDictionary]? {
+ var iterator: io_iterator_t = io_iterator_t()
+ var obj: io_registry_entry_t = 1
+ var list: [NSDictionary] = []
+
+ let result = IOServiceGetMatchingServices(kIOMasterPortDefault, IOServiceMatching(name), &iterator)
+ if result == kIOReturnSuccess {
+ while obj != 0 {
+ obj = IOIteratorNext(iterator)
+ if let props = getIOProperties(obj) {
+ list.append(props)
+ }
+ IOObjectRelease(obj)
+ }
+ IOObjectRelease(iterator)
+ }
+
+ return list.isEmpty ? nil : list
+}
+
public func getIOProperties(_ entry: io_registry_entry_t) -> NSDictionary? {
var properties: Unmanaged? = nil