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.
Quick Start
uvx powermonitor
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:
qorESC- Quit applicationr- Force refresh datac- 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)
-
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)
-
StatsPanel (cyan) - Historical statistics
- Time range (earliest/latest)
- Average/min/max power
- Average battery percentage
- Based on last 100 readings
-
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:
-
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)
-
IORegCollector (fallback) - Subprocess-based
- Executes
ioreg -rw0 -c AppleSmartBattery -a - Parses plist output using Python's plistlib
- Works on all Macs without special permissions
- Executes
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_PATHenvironment variable removed (use config.toml instead)
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file powermonitor-0.0.8-py3-none-any.whl.
File metadata
- Download URL: powermonitor-0.0.8-py3-none-any.whl
- Upload date:
- Size: 35.2 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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
588ccf6ef39e3bbfa81cd61f8f425610fa7a6922e7fc9b47629ce2939b4f97bf
|
|
| MD5 |
f0a8876be2b9185c340d1a173e5d038b
|
|
| BLAKE2b-256 |
895ef7ceb7b1acb31032d06d2e6aae59b91d9196e8802f39d9f440127b5c7628
|