# How Omarchy Handles Battery and Power Profile Management: Event-Driven UPower Integration

> Discover how Omarchy manages battery and power profiles with event-driven UPower integration. Get low-battery warnings and automatic profile switching for seamless power management.

- Repository: [Omacom/omarchy](https://github.com/omacom/omarchy)
- Tags: deep-dive
- Published: 2026-09-10

---

**Omarchy implements battery and power profile management as first-class Quickshell services that monitor the UPower daemon, emit low-battery warnings at a configurable 10% threshold, and automatically switch power profiles between AC and battery states using dedicated CLI wrappers.**

The omacom/omarchy repository treats power management as an integrated system rather than an afterthought, leveraging the Quickshell environment to bridge Linux UPower events with reactive UI components. By combining QML-based services with lightweight shell utilities, Omarchy delivers real-time battery monitoring and dynamic profile switching that keeps desktop widgets synchronized with hardware state.

## Core Battery Service Architecture

At the center of Omarchy's power management stack is the **Battery service** located at `shell/plugins/services/battery/Service.qml`. This QML component establishes a persistent connection to the Linux UPower daemon and orchestrates all battery-related state changes throughout the desktop environment.

The service delegates calculation logic to [`shell/plugins/services/battery/BatteryModel.js`](https://github.com/omacom/omarchy/blob/main/shell/plugins/services/battery/BatteryModel.js), a JavaScript helper that computes battery percentage, detects discharging states, and evaluates low-battery conditions. This separation allows the QML service to focus on process management and state propagation while the model handles data transformation.

### UPower Integration and Event Polling

Unlike simple polling mechanisms, the Battery service uses a hybrid approach combining UPower signals with conservative timers. A `Timer` with a 30-second interval triggers `checkBattery()` to validate the current charge level against the `batteryThreshold` value of 10 percent. This ensures the system detects critical battery states even if UPower signals are missed.

## Battery Health and Low-Battery Warnings

Omarchy's low-battery detection prevents notification spam through persistent state tracking. When `BatteryModel.shouldWarnLowBattery` returns true—indicating the battery has fallen below the threshold and is discharging—the service executes `omarchy-battery-low <level>` through a transient `Process` named `warningProcess`.

### Persistent Warning State

The service uses a `PersistentProperties` block to store `notifiedLowBattery`, ensuring the warning fires exactly once per low-battery event rather than on every timer tick. This state persists across Quickshell restarts, preventing duplicate alerts for the same discharge cycle.

```bash

# Check current battery status from terminal

omarchy-battery-status --shell

# Output format: percentage\t51%\nstate\tdischarging\nrate\t10.8W

```

## Dynamic Power Profile Switching

When UPower reports a source change via `UPower.onBattery`, the service immediately invokes `applyPowerProfile()` to synchronize the system's power profile with the physical power source. This function records the pending state in `pendingPowerSource`—either `"battery"` or `"ac"`—and spawns `powerProfileProcess` to execute `omarchy-powerprofiles-set <source>`.

### Rapid Change Handling and Profile Refresh

The implementation accounts for rapid AC/battery transitions by re-applying pending profiles in the `onExited` handler. After the set operation completes, the service launches `powerProfileReadProcess` running `powerprofilesctl get` to populate the `activePowerProfile` property.

A secondary `Timer` with a 2000-millisecond interval repeatedly calls `refreshPowerProfile()`, guaranteeing that widgets and wallpaper components always reflect the current profile without requiring UI interaction.

```bash

# Manually set power-saver profile while on battery

omarchy-powerprofiles-set battery power-saver

```

## CLI Utilities and Integration Points

Omarchy exposes its power management functionality through two primary CLI tools used by both the service and UI components. The `bin/omarchy-battery-status` utility wraps UPower device data for shell consumption, while `bin/omarchy-powerprofiles-set` serves as the command-line interface for profile switching.

### Power Panel UI Binding

The power panel at `shell/plugins/panels/power/Panel.qml` consumes the Battery service's computed properties—including `batteryInfo`, `batteryFraction`, and `batteryIcon`—through the shared `Model` object. The panel also invokes `omarchy-powerprofiles-set` directly when users manually select profiles from the UI.

### Power Saver State Exposure

The service exposes `powerSaverOnBattery`, a computed boolean that evaluates to `true` only when the system is on battery power **and** the active profile equals `"power-saver"`. UI components bind to this flag to trigger visual changes like wallpaper dimming:

```qml
Text {
    text: "Active profile: " + root.activePowerProfile
    color: root.powerSaverOnBattery ? "orange" : "white"
}

```

## Summary

- **Event-Driven Architecture**: The Battery service in `shell/plugins/services/battery/Service.qml` listens to UPower signals and uses 30-second polling to detect battery state changes reliably.
- **Smart Notifications**: Low-battery warnings trigger at a 10% threshold via `omarchy-battery-low`, with `PersistentProperties` ensuring single-notification semantics per discharge event.
- **Automatic Profile Switching**: The `applyPowerProfile()` function synchronizes power profiles with AC/battery state, using a 2000ms refresh timer to keep UI components updated.
- **Unified CLI Interface**: Both the service and UI rely on `omarchy-powerprofiles-set` and `omarchy-battery-status`, ensuring consistent behavior across scripted and interactive workflows.

## Frequently Asked Questions

### How does Omarchy prevent duplicate low-battery notifications?

The Battery service maintains `notifiedLowBattery` in a `PersistentProperties` block within `shell/plugins/services/battery/Service.qml`. This flag tracks whether a warning has already been emitted for the current discharge cycle, ensuring `omarchy-battery-low` executes only once when crossing the 10% threshold.

### What triggers automatic power profile changes in Omarchy?

The `UPower.onBattery` signal triggers `applyPowerProfile()`, which detects transitions between AC and battery power. The service records the new source in `pendingPowerSource` and executes `omarchy-powerprofiles-set` to apply the appropriate profile, subsequently refreshing the active state via `powerprofilesctl get`.

### Can I query Omarchy's battery status from a shell script?

Yes, the `bin/omarchy-battery-status` utility provides machine-readable output when passed the `--shell` flag, emitting tab-separated values for percentage, state, rate, size, and remaining time that scripts can parse directly.

### How does the UI know when to enter power-saver mode?

The Battery service exposes the `powerSaverOnBattery` computed property, which evaluates to `true` when `activePowerProfile` equals `"power-saver"` and the system is discharging. Panels and wallpapers bind to this boolean to adjust their appearance accordingly.