mirror of
https://github.com/morgan9e/macos-stats
synced 2026-04-14 00:04:15 +09:00
feat: added notifications for the Sensors module (#1124)
This commit is contained in:
@@ -13,9 +13,10 @@ import Cocoa
|
||||
import Kit
|
||||
|
||||
public class Sensors: Module {
|
||||
private var sensorsReader: SensorsReader
|
||||
private let sensorsReader: SensorsReader
|
||||
private let popupView: Popup
|
||||
private var settingsView: Settings
|
||||
private let settingsView: Settings
|
||||
private let notificationsView: Notifications
|
||||
|
||||
private var fanValueState: FanValue {
|
||||
FanValue(rawValue: Store.shared.string(key: "\(self.config.name)_fanValue", defaultValue: "percentage")) ?? .percentage
|
||||
@@ -25,14 +26,17 @@ public class Sensors: Module {
|
||||
self.sensorsReader = SensorsReader()
|
||||
self.settingsView = Settings("Sensors", list: self.sensorsReader.list.sensors)
|
||||
self.popupView = Popup()
|
||||
self.notificationsView = Notifications(.sensors)
|
||||
|
||||
super.init(
|
||||
popup: self.popupView,
|
||||
settings: self.settingsView
|
||||
settings: self.settingsView,
|
||||
notifications: self.notificationsView
|
||||
)
|
||||
guard self.available else { return }
|
||||
|
||||
self.popupView.setup(self.sensorsReader.list.sensors)
|
||||
self.notificationsView.setup(self.sensorsReader.list.sensors)
|
||||
|
||||
self.settingsView.callback = { [weak self] in
|
||||
self?.sensorsReader.read()
|
||||
@@ -46,6 +50,7 @@ public class Sensors: Module {
|
||||
DispatchQueue.main.async {
|
||||
self?.popupView.setup(self?.sensorsReader.list.sensors)
|
||||
self?.settingsView.setList(list: self?.sensorsReader.list.sensors ?? [])
|
||||
self?.notificationsView.setup(self?.sensorsReader.list.sensors)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -55,6 +60,7 @@ public class Sensors: Module {
|
||||
DispatchQueue.main.async {
|
||||
self?.popupView.setup(self?.sensorsReader.list.sensors)
|
||||
self?.settingsView.setList(list: self?.sensorsReader.list.sensors ?? [])
|
||||
self?.notificationsView.setup(self?.sensorsReader.list.sensors)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -111,6 +117,7 @@ public class Sensors: Module {
|
||||
}
|
||||
|
||||
self.popupView.usageCallback(value.sensors)
|
||||
self.notificationsView.usageCallback(value.sensors)
|
||||
|
||||
self.menuBar.widgets.filter{ $0.isActive }.forEach { (w: Widget) in
|
||||
switch w.item {
|
||||
|
||||
120
Modules/Sensors/notifications.swift
Normal file
120
Modules/Sensors/notifications.swift
Normal file
@@ -0,0 +1,120 @@
|
||||
//
|
||||
// notifications.swift
|
||||
// Sensors
|
||||
//
|
||||
// Created by Serhiy Mytrovtsiy on 05/12/2023
|
||||
// Using Swift 5.0
|
||||
// Running on macOS 14.1
|
||||
//
|
||||
// Copyright © 2023 Serhiy Mytrovtsiy. All rights reserved.
|
||||
//
|
||||
|
||||
import Cocoa
|
||||
import Kit
|
||||
|
||||
class Notifications: NotificationsWrapper {
|
||||
private var unknownSensorsState: Bool {
|
||||
Store.shared.bool(key: "Sensors_unknown", defaultValue: false)
|
||||
}
|
||||
|
||||
private var temperatureLevels: [KeyValue_t] = [
|
||||
KeyValue_t(key: "", value: "Disabled")
|
||||
]
|
||||
private let temperatureList: [String] = ["30", "35", "40", "45", "50", "55", "60", "65", "70", "75", "80", "85", "90", "96", "100", "105", "110"]
|
||||
|
||||
public init(_ module: ModuleType) {
|
||||
super.init(module)
|
||||
for p in self.temperatureList {
|
||||
if let v = Double(p) {
|
||||
self.temperatureLevels.append(KeyValue_t(key: p, value: temperature(v)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
internal func setup(_ values: [Sensor_p]? = nil) {
|
||||
guard var values = values else { return }
|
||||
values = values.filter({ $0.type == .fan || $0.type == .temperature })
|
||||
if !self.unknownSensorsState {
|
||||
values = values.filter({ $0.group != .unknown })
|
||||
}
|
||||
self.subviews.forEach({ $0.removeFromSuperview() })
|
||||
self.initIDs(values.map{$0.key})
|
||||
|
||||
var types: [SensorType] = []
|
||||
values.forEach { (s: Sensor_p) in
|
||||
if !types.contains(s.type) {
|
||||
types.append(s.type)
|
||||
}
|
||||
}
|
||||
|
||||
types.forEach { (typ: SensorType) in
|
||||
let filtered = values.filter{ $0.type == typ }
|
||||
var groups: [SensorGroup] = []
|
||||
filtered.forEach { (s: Sensor_p) in
|
||||
if !groups.contains(s.group) {
|
||||
groups.append(s.group)
|
||||
}
|
||||
}
|
||||
|
||||
let header = NSStackView()
|
||||
header.heightAnchor.constraint(equalToConstant: Constants.Settings.row).isActive = true
|
||||
header.spacing = 0
|
||||
|
||||
let titleField: NSTextField = LabelField(frame: NSRect(x: 0, y: 0, width: 0, height: 0), localizedString(typ.rawValue))
|
||||
titleField.font = NSFont.systemFont(ofSize: 13, weight: .medium)
|
||||
titleField.textColor = .labelColor
|
||||
|
||||
header.addArrangedSubview(titleField)
|
||||
header.addArrangedSubview(NSView())
|
||||
|
||||
self.addArrangedSubview(header)
|
||||
|
||||
let container = NSStackView()
|
||||
container.orientation = .vertical
|
||||
container.edgeInsets = NSEdgeInsets(top: 0, left: Constants.Settings.margin, bottom: 0, right: Constants.Settings.margin)
|
||||
container.spacing = 0
|
||||
|
||||
groups.forEach { (group: SensorGroup) in
|
||||
filtered.filter{ $0.group == group }.forEach { (s: Sensor_p) in
|
||||
var items = notificationLevels
|
||||
if s.type == .temperature {
|
||||
items = temperatureLevels
|
||||
}
|
||||
let row: NSView = selectSettingsRow(
|
||||
title: localizedString(s.name),
|
||||
action: #selector(self.changeSensorNotificaion),
|
||||
items: items,
|
||||
selected: s.notificationThreshold
|
||||
)
|
||||
row.subviews.filter{ $0 is NSControl }.forEach { (control: NSView) in
|
||||
control.identifier = NSUserInterfaceItemIdentifier(rawValue: s.key)
|
||||
}
|
||||
container.addArrangedSubview(row)
|
||||
}
|
||||
}
|
||||
|
||||
self.addArrangedSubview(container)
|
||||
}
|
||||
}
|
||||
|
||||
internal func usageCallback(_ values: [Sensor_p]) {
|
||||
let sensors = values.filter({ !$0.notificationThreshold.isEmpty })
|
||||
let title = localizedString("Sensor threshold")
|
||||
|
||||
for s in sensors {
|
||||
if let threshold = Double(s.notificationThreshold) {
|
||||
let subtitle = localizedString("\(localizedString(s.name)): \(s.formattedPopupValue)")
|
||||
self.checkDouble(id: s.key, value: s.value, threshold: threshold, title: title, subtitle: subtitle)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@objc private func changeSensorNotificaion(_ sender: NSMenuItem) {
|
||||
guard let id = sender.identifier, let key = sender.representedObject as? String else { return }
|
||||
Store.shared.set(key: "sensor_\(id.rawValue)_notification", value: key)
|
||||
}
|
||||
}
|
||||
@@ -36,6 +36,7 @@ public protocol Sensor_p {
|
||||
var value: Double { get set }
|
||||
var state: Bool { get }
|
||||
var popupState: Bool { get }
|
||||
var notificationThreshold: String { get }
|
||||
|
||||
var group: SensorGroup { get }
|
||||
var type: SensorType { get }
|
||||
@@ -211,6 +212,9 @@ public struct Sensor: Sensor_p, Codable {
|
||||
public var popupState: Bool {
|
||||
Store.shared.bool(key: "sensor_\(self.key)_popup", defaultValue: true)
|
||||
}
|
||||
public var notificationThreshold: String {
|
||||
Store.shared.string(key: "sensor_\(self.key)_notification", defaultValue: "")
|
||||
}
|
||||
|
||||
public func copy() -> Sensor {
|
||||
Sensor(
|
||||
@@ -265,6 +269,9 @@ public struct Fan: Sensor_p, Codable {
|
||||
public var popupState: Bool {
|
||||
Store.shared.bool(key: "sensor_\(self.key)_popup", defaultValue: true)
|
||||
}
|
||||
public var notificationThreshold: String {
|
||||
Store.shared.string(key: "sensor_\(self.key)_notification", defaultValue: "")
|
||||
}
|
||||
|
||||
public var customSpeed: Int? {
|
||||
get {
|
||||
|
||||
Reference in New Issue
Block a user