Skip to main content

macOS power monitoring tool with auto-updating TUI

Project description

Power Monitor

macOS power monitoring tool with auto-updating TUI for real-time battery and charging status.

Features

  • ๐Ÿ–ฅ๏ธ Auto-updating TUI with 3-panel layout (Textual framework)
  • โšก Real-time monitoring - Updates every 2 seconds automatically
  • ๐Ÿ“Š Live power metrics - Voltage, amperage, wattage, battery %
  • ๐Ÿ“ˆ Historical visualization - Power chart and statistics
  • ๐Ÿ”‹ Battery tracking - Capacity, charging status, charger info
  • ๐Ÿ’พ SQLite persistence - Automatic background data logging with proper resource management
  • ๐ŸŽฏ IOKit/SMC access - Direct macOS API integration via ctypes
  • ๐Ÿ”„ Auto-fallback - Graceful fallback to subprocess-based collection
  • โš™๏ธ Configuration file - Optional TOML config with CLI override support
  • ๐Ÿ“ค Data export - Export to CSV/JSON formats
  • ๐Ÿงน Data cleanup - Remove old readings by age or clear all
  • ๐Ÿฅ Battery health - Track battery degradation over time

Installation

Install with uv (recommended)

uv tool install powermonitor

Install with pipx

pipx install powermonitor

Usage

Launch the TUI

# Launch auto-updating TUI with default settings
powermonitor

# Customize TUI settings
powermonitor --interval 1.0 --stats-limit 100 --chart-limit 60

# Enable debug logging
powermonitor --debug

TUI Options:

  • --interval / -i - Data collection interval in seconds (default: 1.0)
  • --stats-limit - Number of readings for statistics (default: 100)
  • --chart-limit - Number of readings in chart (default: 60)
  • --debug - Enable debug logging

The TUI displays:

โ”Œโ”€ powermonitor โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Real-Time Power                           โ”‚
โ”‚ โšก 45.2W / 67W    ๐Ÿ”‹ 72%    โšก Charging   โ”‚
โ”‚ 20.0V ร— 2.26A                             โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ Statistics (Last 100 readings)            โ”‚
โ”‚ Avg: 42.3W  Max: 55.1W  Min: 12.4W       โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ Power Chart (Last 60 readings)            โ”‚
โ”‚     55W โ”ค      โ•ญโ”€โ”€โ•ฎ                       โ”‚
โ”‚     45W โ”ค  โ•ญโ”€โ”€โ”€โ•ฏ  โ•ฐโ”€โ”€โ•ฎ                    โ”‚
โ”‚     35W โ”คโ”€โ”€โ•ฏ         โ•ฐโ”€                   โ”‚
โ”‚         โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€               โ”‚
โ”‚ [q] Quit  [r] Refresh  [c] Clear History โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Keyboard Controls:

  • q or ESC - Quit application
  • r - Force refresh data
  • c - Clear history (with confirmation)

Configuration File

powermonitor supports an optional configuration file at ~/.powermonitor/config.toml:

# powermonitor configuration file

[tui]
interval = 1.0           # Data collection interval in seconds
stats_limit = 100        # Number of readings for statistics
chart_limit = 60         # Number of readings to display in chart

[database]
path = "~/.powermonitor/powermonitor.db"  # Database file location

[cli]
default_history_limit = 20           # Default limit for history command
default_export_limit = 1000          # Default limit for export command

[logging]
level = "INFO"           # Logging level: DEBUG, INFO, WARNING, ERROR

Configuration Priority: CLI arguments > Config file > Defaults

If no config file exists, powermonitor uses sensible defaults. CLI arguments always override config file values.

Example: Set custom database path and collection interval:

[database]
path = "~/Documents/power-data.db"

[tui]
interval = 2.0

Then run: powermonitor (uses config) or powermonitor --interval 0.5 (overrides config)

CLI Commands

Export Data

Export power readings to CSV or JSON format:

# Export to CSV (auto-detected from extension)
powermonitor export data.csv

# Export to JSON
powermonitor export data.json

# Export last 1000 readings
powermonitor export data.csv --limit 1000

# Manually specify format
powermonitor export backup.txt --format csv

Database Statistics

Show database information and statistics:

powermonitor stats

Output:

Database Statistics
โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”
Total readings       12,450
Earliest reading     2025-12-01 10:30:00
Latest reading       2026-01-06 15:22:00
Database size        2.4 MB
Database path        /Users/you/.powermonitor/powermonitor.db

View History

Display recent power readings in a formatted table:

# Show last 20 readings (default)
powermonitor history

# Show last 50 readings
powermonitor history --limit 50

Output shows time, power, battery %, voltage, current, and status.

Clean Up Data

Remove old readings to manage database size:

# Delete readings older than 30 days
powermonitor cleanup --days 30

# Delete all readings (requires confirmation)
powermonitor cleanup --all

Battery Health

Track battery degradation over time:

# Analyze last 30 days (default)
powermonitor health

# Analyze last 60 days
powermonitor health --days 60

Output:

Battery Health Analysis (30 days)
โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”
First reading        2025-12-06
First avg capacity   4,709 mAh
Last reading         2026-01-06
Last avg capacity    4,650 mAh
Change               -59 mAh (-1.25%)
Status               โš ๏ธ  Degrading (normal wear)
Days analyzed        30

Development Mode

# Run with verbose collector info
uv run python -c "from powermonitor.collector import default_collector; collector = default_collector(verbose=True); print(collector.collect())"

# Test data collection
uv run python -c "from powermonitor.collector import default_collector; print(default_collector().collect())"

Requirements

  • macOS: 12.0+ (Monterey or later)
  • Python: 3.13+ (uses modern type hints)
  • Dependencies: textual, rich, textual-plotext (auto-installed by uv)

Architecture

TUI Layout (3 Panels)

  1. LiveDataPanel (green) - Real-time power data

    • Status: โšก Charging / ๐Ÿ”Œ AC Power / ๐Ÿ”‹ On Battery
    • Power: watts_actual / watts_negotiated
    • Battery: percentage, capacity (mAh)
    • Electrical: voltage, amperage
    • Charger info (if available)
  2. StatsPanel (cyan) - Historical statistics

    • Time range (earliest/latest)
    • Average/min/max power
    • Average battery percentage
    • Based on last 100 readings
  3. ChartWidget (blue) - Power over time

    • Line chart with 60 data points
    • Shows actual power and max negotiated power
    • Auto-scales based on data

Data Collection

powermonitor uses two collectors with automatic fallback:

  1. IOKitCollector (preferred) - Direct IOKit/SMC API via ctypes

    • Reads 7 SMC sensors: PPBR, PDTR, PSTR, PHPC, PDBR, TB0T, CHCC
    • Most accurate power readings (PDTR sensor)
    • Zero overhead (no subprocess)
  2. IORegCollector (fallback) - Subprocess-based

    • Executes ioreg -rw0 -c AppleSmartBattery -a
    • Parses plist output using Python's plistlib
    • Works on all Macs without special permissions

Database

All readings automatically saved to SQLite with proper resource management:

Default location: ~/.powermonitor/powermonitor.db

Custom location (via config file):

[database]
path = "/path/to/custom.db"

Resource Management:

  • Automatic connection cleanup using context managers
  • No ResourceWarnings or connection leaks
  • Proper transaction handling for all write operations
  • Safe shutdown and cleanup in TUI mode

Schema:

CREATE TABLE power_readings (
    id INTEGER PRIMARY KEY,
    timestamp TEXT,
    watts_actual REAL,
    watts_negotiated INTEGER,
    voltage REAL,
    amperage REAL,
    current_capacity INTEGER,
    max_capacity INTEGER,
    battery_percent INTEGER,
    is_charging INTEGER,
    external_connected INTEGER,
    charger_name TEXT,
    charger_manufacturer TEXT
);

Project Structure

powermonitor/
โ”œโ”€โ”€ pyproject.toml              # uv project config
โ”œโ”€โ”€ uv.lock                     # Dependency lock file
โ”œโ”€โ”€ src/
โ”‚   โ””โ”€โ”€ powermonitor/
โ”‚       โ”œโ”€โ”€ cli.py              # Entry point
โ”‚       โ”œโ”€โ”€ models.py           # PowerReading dataclass
โ”‚       โ”œโ”€โ”€ database.py         # SQLite operations
โ”‚       โ”œโ”€โ”€ config.py           # PowerMonitorConfig dataclass
โ”‚       โ”œโ”€โ”€ config_loader.py    # TOML config file loader
โ”‚       โ”œโ”€โ”€ logger.py           # Logging configuration
โ”‚       โ”œโ”€โ”€ collector/          # Data collection
โ”‚       โ”‚   โ”œโ”€โ”€ base.py         # PowerCollector protocol
โ”‚       โ”‚   โ”œโ”€โ”€ ioreg.py        # Subprocess collector
โ”‚       โ”‚   โ”œโ”€โ”€ factory.py      # Auto-fallback logic
โ”‚       โ”‚   โ””โ”€โ”€ iokit/          # IOKit/SMC FFI
โ”‚       โ”‚       โ”œโ”€โ”€ bindings.py # ctypes bindings
โ”‚       โ”‚       โ”œโ”€โ”€ structures.py # SMC data structures
โ”‚       โ”‚       โ”œโ”€โ”€ parser.py   # Binary parsing
โ”‚       โ”‚       โ”œโ”€โ”€ connection.py # SMCConnection
โ”‚       โ”‚       โ””โ”€โ”€ collector.py # IOKitCollector
โ”‚       โ””โ”€โ”€ tui/                # Textual TUI
โ”‚           โ”œโ”€โ”€ app.py          # PowerMonitorApp
โ”‚           โ””โ”€โ”€ widgets.py      # Custom widgets
โ””โ”€โ”€ tests/
    โ””โ”€โ”€ fixtures/               # Test data

Development

Code Quality

# Type checking
uv run ty check .

# Linting
uv run ruff check src/

# Auto-formatting
uv run ruff format src/

# Run all checks
uv run ty check . && uv run ruff check src/ && uv run ruff format src/

Testing

# Run tests (when available)
uv run pytest

# Manual testing
uv run powermonitor

Performance

  • Memory: <50MB RAM
  • CPU: <1% when idle
  • Update interval: 2 seconds (configurable)
  • Database: Indexed for fast queries

Recent Improvements

  • โœ… Resource Management: Proper SQLite connection cleanup eliminates ResourceWarnings
  • โœ… Configuration System: TOML-based config with 3-layer priority (CLI > Config > Defaults)
  • โœ… CLI Commands: Export, stats, history, cleanup, and battery health tracking
  • โœ… Code Quality: Clean test infrastructure with proper fixture cleanup
  • โœ… Database Operations: Context manager pattern for all database operations

Migration Notes

  • To: Python TUI with unified auto-updating interface
  • Reason: Better rapid development, easier maintenance, similar performance for 2s intervals
  • Preserved: All data collection logic, database schema, SMC sensor access (via ctypes)
  • Breaking Change: POWERMONITOR_DB_PATH environment variable removed (use config.toml instead)

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

powermonitor-0.0.6-py3-none-any.whl (35.0 kB view details)

Uploaded Python 3

File details

Details for the file powermonitor-0.0.6-py3-none-any.whl.

File metadata

  • Download URL: powermonitor-0.0.6-py3-none-any.whl
  • Upload date:
  • Size: 35.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.22 {"installer":{"name":"uv","version":"0.9.22","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for powermonitor-0.0.6-py3-none-any.whl
Algorithm Hash digest
SHA256 6472277e0b599a132c7525e375ecf9b3d257f89c7743764503c64ab7b6621b3b
MD5 92a898b00cf93c22b479d5b196445453
BLAKE2b-256 1ea635030c9bba3c5d3abe89823604ff2894072e414ac95ba05c942a89421868

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page