Battery Manager API
Relevant source files
The following files were used as context for generating this wiki page:
The Battery Manager API serves as the primary entry point for the battery crate, providing a cross-platform interface to discover and monitor notebook batteries. Its main purpose is to abstract away OS-specific interfaces (such as Linux SysFS, macOS IOKit, or Windows IOCTLs) into a unified, type-safe API that returns information in SI measurement units.
The API is designed around a central Manager struct that facilitates the discovery of available batteries through an iterator and allows for in-place updates of battery telemetry. This architecture ensures that users can write platform-independent code while the library handles the underlying complexity of various kernel drivers and legacy hardware cases.
Sources: src/lib.rs:1-10, README.md:21-25, src/types/manager.rs:11-15
Architecture and Core Components
The Battery Manager API is structured into three main layers: the public-facing Manager type, the platform-specific implementations, and the shared traits that define the required behavior for any supported operating system.
The Manager Type
The Manager struct is the high-level orchestrator. It holds an Arc reference to a PlatformManager, ensuring that the underlying system resources can be shared and safely managed across the application.
The diagram above shows the relationship between the public Manager and the internal platform-specific implementation.
Sources: src/types/manager.rs:25-54, src/platform/traits.rs:16-22
Platform Traits
For a platform to be supported, it must implement a set of internal traits that the Manager interacts with. This decouple the public API from the hardware-specific fetching logic.
| Trait | Responsibility | Key Methods |
|---|---|---|
BatteryManager | System-level initialization and refreshing individual devices. | new(), refresh() |
BatteryIterator | Enumerating discovered hardware devices. | new(), next() |
BatteryDevice | Providing specific telemetry (voltage, energy, state). | energy(), state(), voltage() |
Sources: src/platform/traits.rs:16-55
Battery Discovery and Iteration
Discovery is handled through the batteries() method, which returns a Batteries iterator. This iterator yields Result<Battery> objects, allowing the application to handle potential IO errors during discovery on a per-device basis.
This flowchart illustrates the standard workflow for discovering batteries using the Manager API.
Sources: examples/simple.rs:9-25, src/types/manager.rs:43-48
Data Refresh and Telemetry
The API supports in-place updates via the refresh method. Instead of recreating a battery object, users can pass a mutable reference to an existing Battery to the Manager. This is more efficient as it allows the underlying platform implementation to reuse file descriptors or handles.
Refresh Logic
- The
Managerdelegates the refresh call to thePlatformManager. - The platform implementation (e.g.,
SysFsDeviceon Linux) validates that the device source still exists. - Updated values (Energy, Power, State) are fetched and recalculated into SI units.
Telemetry Recalculation
The API provides default implementations for complex values like "Time to Full" or "Time to Empty" within the BatteryDevice trait if the hardware does not provide them directly. These are calculated based on the current energy_rate and energy levels.
Sources: src/platform/traits.rs:77-117
Usage Example
The following example demonstrates the typical lifecycle: initializing the manager, discovering a battery, and entering a refresh loop.
fn main() -> battery::Result<()> {
// 1. Initialize the system-specific manager
let manager = battery::Manager::new()?;
// 2. Discover batteries
if let Some(Ok(mut battery)) = manager.batteries()?.next() {
loop {
// 3. Access SI-unit typed data
println!("Voltage: {:?}", battery.voltage());
// 4. Update the object in-place
manager.refresh(&mut battery)?;
}
}
Ok(())
}
Sources: examples/simple.rs:9-29, src/types/manager.rs:16-23
Summary
The Battery Manager API provides a robust abstraction layer for battery telemetry. By utilizing a trait-based architecture and a central Manager type, it ensures that developers can access sophisticated battery metrics (energy, state of health, charge rates) consistently across Linux, Windows, and BSD platforms without dealing with the idiosyncrasies of different kernel interfaces.