Skip to content
XDGFXPublic

About

Mac power draw, battery and thermals in the menu bar at near-zero cost (SwiftBar streaming plugin)

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

7 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 

Repository files navigation

PowerBar

A SwiftBar plugin that puts your Mac's power draw, battery and thermals in the menu bar — for effectively nothing, so the monitor isn't a meaningful part of what it measures.

Apple silicon only. No root, no sudoers, no kernel extension.

What it shows

  • Menu bar — live system draw in watts (⚡ 24 W), on mains and on battery alike.
  • Power — system and package watts, with the package split across CPU, GPU, Neural Engine and RAM. Utilisation and clock speed per cluster (efficiency and performance cores separately), GPU frequency, RAM and swap use, and a stacked bar showing where the package power is going.
  • Battery — charge and state, watts into or out of the pack, time to full or empty, health against design capacity, cycle count, cell temperature, voltage and current, and the connected charger's name and wattage.
  • Thermals — CPU, GPU and battery temperatures, fan speeds, and a warning if macOS is throttling the scheduler.
  • Top processes by CPU, and a shortcut to Activity Monitor.
  • Graphs — the last hour of system power, battery charge and CPU temperature, with min / avg / max. Drawn in the style of Battery Settings: a translucent area under a connected polyline, dotted rules quartering the plot, a solid axis along the bottom, and the periods spent charging tinted behind the charge trace. History persists across restarts.
  • Its own cost — the last row shows how much CPU the plugin itself used for the current sample.

Data rows are set on a fixed character grid, so a value never shifts when it changes width. That needs a monospaced font — the system font's digits are not tabular, and SwiftBar's only other column tool is a tab stop hardcoded every 100 pt. Monaco at 12 pt is the narrowest fixed-pitch face that also sits right: a menu row's text area is 16 pt and a shorter line is set at the top of it rather than the middle, so anything shorter rides high, and Monaco 12 sets exactly 16 pt. The charts are drawn as wide as the widest row, so they span the menu rather than stopping short.

The battery rows open the Battery settings pane and the process rows open Activity Monitor. Nothing else is clickable: Activity Monitor opens on whichever tab you last used and offers no way to choose one, and macOS has no thermal UI at all, so a link from the power or thermal rows would only ever land somewhere irrelevant. Every row still highlights under the pointer regardless — SwiftBar attaches an action to any row carrying a colour, purely so macOS draws it enabled, and going without the colour to suppress that fades the text too much to be worth it.

How it's kept cheap

Most menu bar monitors are a script that SwiftBar re-runs every few seconds. That is fine for a runner status, but power sampling has a fixed setup cost: macmon spends about 0.2 CPU-seconds enumerating IOReport channels and sensors every time it starts, and the first version of this plugin — a shell script spawning macmon, ioreg, ps and a handful of python processes per refresh — cost about 0.6 CPU-seconds every 10 seconds, roughly 6% of a core.

PowerBar is instead a SwiftBar streaming plugin: one Python process that SwiftBar starts once and that stays resident. It holds a single macmon pipe open for its lifetime, so the setup cost is paid once, and each sample is one line read from that pipe, one ioreg dump, one ps listing and three small PNGs drawn in-process with the standard library (no ImageMagick, no pip packages). The charts are antialiased analytically — each pixel's coverage comes from where the trace falls inside it, rather than from supersampling — and the area's pixels come out of small lookup tables, so all four images together cost about a millisecond. Measured on an M4 Pro:

CPU per 10 s sample
PowerBar process + ioreg + ps ~30–60 ms (0.3–0.6% of one core)
macmon, steady state not measurable above zero
macmon, one-off at launch ~0.2 s

At the low clocks an efficiency core idles at, that is on the order of milliwatts against a system that draws tens of watts. The sampling interval is SAMPLE_S at the top of the script; 30 s cuts the cost by a further two-thirds if you want it.

Requirements

  • macOS on Apple silicon with SwiftBar (brew install --cask swiftbar)
  • macmon (brew install macmon) for package power, temperatures and fans — it reads IOReport without root. Without it the plugin still runs and shows battery data only.
  • python3 — the one Xcode Command Line Tools or Homebrew provides.

Install

git clone https://github.com/XDGFX/powerbar.git
cd powerbar && bash install.sh

The script installs SwiftBar and macmon if they're missing, wires the plugin in and sets SwiftBar to start at login. There is no configuration.

The plugin is symlinked into a dedicated SwiftBar plugin folder (~/.config/swiftbar, or whichever folder SwiftBar already uses), so git pull updates it in place — restart SwiftBar afterwards to pick the change up. The clone itself is deliberately not used as the plugin folder: SwiftBar runs every executable file in that folder, so it would try to run LICENSE and README.md as plugins as well.

Where the numbers come from

  • Battery and charger: IOKit's AppleSmartBattery service via ioreg. Health is raw full-charge capacity over design capacity, which is what System Settings shows too. Watts into or out of the pack are pack voltage times instantaneous current.
  • Package power, per-block power, clocks, utilisation, temperatures and fans: macmon, which reads the same IOReport energy counters powermetrics does, minus the root requirement. "System" power is the whole machine including display and peripherals; "package" is the SoC.
  • Per-process figures are CPU share from ps. Per-process energy impact (what Activity Monitor's Energy tab shows) is only available to root via powermetrics --samplers tasks, so it's not here.
  • Throttling: pmset -g therm's CPU scheduler limit.

Notes

  • SwiftBar starts a streaming plugin once and does not restart it on Refresh all. After editing the script, disable and re-enable the plugin in SwiftBar's preferences, or restart SwiftBar.
  • SwiftBar's own footer rows (About, Run in Terminal, and friends) are hidden via the plugin's metadata; to also hide SwiftBar's app icon from the menu bar, untick it in SwiftBar's preferences.

Support

PowerBar is free and open source. If it saved you some time, you can sponsor me on GitHub.

Licence

MIT.

About

Mac power draw, battery and thermals in the menu bar at near-zero cost (SwiftBar streaming plugin)

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Sponsor this project

Packages

Contributors

Languages