Battery Monitoring
Relevant source files
The following files were used as context for generating this wiki page:
The Battery Monitoring system in Buddi provides real-time tracking and visualization of the host device's power status. It integrates directly with macOS system services to monitor battery level, charging states, power source transitions, and low power mode status. This information is surfaced to the user through a dedicated notch component and detailed popover menus.
The system is architected using a layered approach: a low-level manager interfaces with the IOKit framework, a view model manages the application state, and SwiftUI components handle the visual representation and user interaction.
Architecture and Data Flow
The battery monitoring architecture follows a reactive pattern where hardware changes are propagated from the macOS kernel up to the User Interface.
The diagram shows the flow of battery data from system frameworks to the Buddi UI components.
Sources: buddi/managers/BatteryActivityManager.swift:4-15, buddi/models/BatteryStatusViewModel.swift:10-30
BatteryActivityManager
The BatteryActivityManager is a singleton class responsible for direct interaction with IOKit.ps. It creates a run loop source using IOPSNotificationCreateRunLoopSource to receive asynchronous callbacks when power source information changes.
- Key Functionality: It polls the system for
BatteryInfostructures and compares current values against apreviousBatteryInfocache to determine if aBatteryEventshould be dispatched. - Events Tracked:
powerSourceChanged: Transition between AC power and battery.batteryLevelChanged: Changes in current capacity percentage.lowPowerModeChanged: Toggle of macOS Low Power Mode.isChargingChanged: Status of active energy transfer.timeToFullChargeChanged: Estimated minutes remaining to 100%.
Sources: buddi/managers/BatteryActivityManager.swift:17-50, buddi/managers/BatteryActivityManager.swift:150-190
BatteryStatusViewModel
The BatteryStatusViewModel serves as the intermediary that translates raw battery events into a state suitable for SwiftUI. It subscribes to the manager's observer pattern and updates its @Published properties.
This sequence illustrates how a hardware change results in an animated UI update.
Sources: buddi/models/BatteryStatusViewModel.swift:50-100, buddi/managers/BatteryActivityManager.swift:75-110
Data Structures
Battery Information Models
The system relies on a standardized BatteryInfo struct to pass data between the manager and the view model.
| Field | Type | Description |
|---|---|---|
isPluggedIn | Bool | True if connected to AC power. |
isCharging | Bool | True if the battery is actively gaining charge. |
currentCapacity | Float | The current battery percentage (0-100). |
maxCapacity | Float | The maximum capacity the battery can currently hold. |
isInLowPowerMode | Bool | Status of the system-wide Low Power Mode. |
timeToFullCharge | Int | Estimated minutes until charge completion. |
Sources: buddi/managers/BatteryActivityManager.swift:233-240
UI Components
BuddiBatteryView
This is the primary container for battery information in the notch header. It conditionally displays the battery percentage and an icon representing the current state.
- Visual States: The battery color changes dynamically:
- Yellow: Low Power Mode is enabled.
- Red: Battery level ≤ 20% while not charging.
- Green: Charging, plugged in, or 100% capacity.
- White: Standard discharging state.
Sources: buddi/components/Live activities/BuddiBattery.swift:31-43
BatteryMenuView
A detailed popover triggered by clicking the battery icon. It provides a technical breakdown of the battery's health and current charging status. It also includes an "Open Battery Preferences" button that links directly to the macOS System Settings via the x-apple.systempreferences:com.apple.preference.battery URL scheme.
Sources: buddi/components/Live activities/BuddiBattery.swift:85-135
Configuration and Settings
The behavior of battery monitoring is controlled by several keys in the Defaults system.
| Preference Key | Type | Default | Description |
|---|---|---|---|
showBatteryIndicator | Bool | true | Toggles the visibility of the battery icon in the notch. |
showBatteryPercentage | Bool | true | Shows/hides the numerical percentage next to the icon. |
showPowerStatusIcons | Bool | true | Displays specific icons for "bolt" (charging) or "plug" (AC power). |
showPowerStatusNotifications | Bool | true | Enables system notifications for power status changes. |
Sources: buddi/models/Constants.swift:115-120, buddi/components/Settings/SettingsView.swift:425-450
Technical Implementation Details
IOKit Integration
The manager retrieves the battery description dictionary from the system using IOPSGetPowerSourceDescription. It specifically looks for standard keys such as kIOPSCurrentCapacityKey and kIOPSPowerSourceStateKey.
// Example of extracting power source state
if let powerSource = description[kIOPSPowerSourceStateKey] as? String {
let isPluggedIn = (powerSource == kIOPSACPowerValue)
}
Sources: buddi/managers/BatteryActivityManager.swift:180-210
Expanded View Coordination
When a significant battery event occurs (e.g., plugging in or entering low power mode), the BatteryStatusViewModel calls notifyImportanChangeStatus(). This interacts with the BuddiViewCoordinator to potentially expand the notch view to alert the user of the status change.
Sources: buddi/models/BatteryStatusViewModel.swift:130-136
Cleanup and Memory Management
The system ensures that hardware observers are properly deregistered when the application components are deinitialized. BatteryActivityManager stops the CFRunLoop source in its deinit, while the BatteryStatusViewModel removes its observer from the manager to prevent memory leaks.
Sources: buddi/managers/BatteryActivityManager.swift:70-73, buddi/models/BatteryStatusViewModel.swift:138-144