{"id":22264833,"url":"https://github.com/xza85hrf/smartups","last_synced_at":"2026-04-29T11:02:11.463Z","repository":{"id":260364394,"uuid":"881087674","full_name":"Xza85hrf/SmartUPS","owner":"Xza85hrf","description":"Smart, real-time UPS monitoring solution for Raspberry Pi, providing detailed system insights and power management using the Waveshare UPS Module 3S.","archived":false,"fork":false,"pushed_at":"2026-04-25T00:39:38.000Z","size":61,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-04-25T02:37:01.863Z","etag":null,"topics":["battery-management","i2c","power-consumption","python","raspberry-pi","raspberry-pi-power-management","real-time-monitoring","ups","ups-monitoring","waveshare-ups-module-3s"],"latest_commit_sha":null,"homepage":"https://www.waveshare.com/wiki/UPS_Module_3S","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Xza85hrf.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-10-30T22:20:26.000Z","updated_at":"2026-04-25T00:39:41.000Z","dependencies_parsed_at":"2024-10-30T23:35:40.994Z","dependency_job_id":null,"html_url":"https://github.com/Xza85hrf/SmartUPS","commit_stats":null,"previous_names":["xza85hrf/smartups"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Xza85hrf/SmartUPS","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Xza85hrf%2FSmartUPS","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Xza85hrf%2FSmartUPS/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Xza85hrf%2FSmartUPS/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Xza85hrf%2FSmartUPS/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Xza85hrf","download_url":"https://codeload.github.com/Xza85hrf/SmartUPS/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Xza85hrf%2FSmartUPS/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32422532,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-29T06:29:02.080Z","status":"ssl_error","status_checked_at":"2026-04-29T06:29:00.631Z","response_time":110,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["battery-management","i2c","power-consumption","python","raspberry-pi","raspberry-pi-power-management","real-time-monitoring","ups","ups-monitoring","waveshare-ups-module-3s"],"created_at":"2024-12-03T10:12:18.684Z","updated_at":"2026-04-29T11:02:11.457Z","avatar_url":"https://github.com/Xza85hrf.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# SmartUPS - UPS Monitoring for Raspberry Pi\n\n**SmartUPS** is a real-time monitoring solution for the [Waveshare UPS Module 3S](https://www.waveshare.com/wiki/UPS_Module_3S) on a Raspberry Pi running Linux. It provides detailed insights into your UPS status, including battery voltage, power consumption, CPU metrics, and more.\n\n## Features\n\n- **Real-Time UPS Monitoring** — voltage, current, power, and battery percentage with smoothed display values\n- **Charging Detection** — automatically detects AC power vs battery with color-coded status\n- **Estimated Remaining Time** — dynamically calculated from actual power draw and battery level\n- **Graceful Shutdown** — safely powers down the Pi when battery gets critically low\n- **CSV Data Logging** — daily auto-rotated CSV files with configurable retention\n- **System Tray Icon** — optional battery indicator for desktop environments\n- **Optional Live Plot** — real-time graphs of voltage, current, and power\n- **Auto-Start on Boot** — systemd service with auto-restart on failure\n\n## Hardware Requirements\n\n- **Raspberry Pi** (tested on Raspberry Pi 4 and 5)\n- **Waveshare UPS Module 3S** (other INA219-based UPS modules work with `--i2c-address`)\n\n---\n\n## Quick Start (Automated)\n\nThe easiest way to get running — one command handles everything:\n\n```bash\ngit clone https://github.com/Xza85hrf/SmartUPS.git\ncd SmartUPS\nchmod +x setup.sh\n./setup.sh\n```\n\nThe setup script will:\n1. Check that Python 3 and I2C are available\n2. Create a virtual environment and install dependencies\n3. Optionally install a systemd service for auto-start on boot\n\nThat's it! Skip to [Usage](#usage) below.\n\n---\n\n## Manual Installation (Step by Step)\n\nIf you prefer to set things up yourself, follow these steps.\n\n### Step 1: Enable I2C on your Raspberry Pi\n\n```bash\nsudo raspi-config\n```\n\nNavigate to **Interface Options** → **I2C** → **Enable**, then reboot:\n\n```bash\nsudo reboot\n```\n\nAfter reboot, verify I2C is working:\n\n```bash\nls /dev/i2c-*          # should show /dev/i2c-1\nsudo i2cdetect -y 1    # should show your UPS at address 0x41\n```\n\n### Step 2: Install system packages\n\n```bash\nsudo apt update\nsudo apt install -y python3 python3-pip python3-venv git\n```\n\n### Step 3: Clone the repository\n\n```bash\ngit clone https://github.com/Xza85hrf/SmartUPS.git\ncd SmartUPS\n```\n\n### Step 4: Create a virtual environment\n\nA virtual environment keeps SmartUPS dependencies isolated from your system Python:\n\n```bash\npython3 -m venv venv\n```\n\n### Step 5: Activate the virtual environment\n\n```bash\nsource venv/bin/activate\n```\n\n\u003e **Note:** You need to activate the venv every time you open a new terminal.\n\u003e Your prompt will show `(venv)` when it's active.\n\n### Step 6: Install dependencies\n\n```bash\npip install -r requirements.txt\n```\n\n### Step 7: Run SmartUPS\n\n```bash\npython SmartUPS.py\n```\n\nTo deactivate the virtual environment when you're done:\n\n```bash\ndeactivate\n```\n\n---\n\n## Usage\n\n### Running SmartUPS\n\nIf you used `setup.sh`, the venv python is at `./venv/bin/python`:\n\n```bash\n# Basic monitoring\n./venv/bin/python SmartUPS.py\n\n# With live graphs (needs a display)\n./venv/bin/python SmartUPS.py --show-plot\n\n# Headless background mode\n./venv/bin/python SmartUPS.py --daemon\n\n# Different UPS board at address 0x40\n./venv/bin/python SmartUPS.py --i2c-address 0x40\n\n# Custom battery capacity (e.g. larger 18650 cells)\n./venv/bin/python SmartUPS.py --battery-capacity 35\n```\n\n### All Command-Line Options\n\n#### Hardware\n\n| Flag | Default | Description |\n|------|---------|-------------|\n| `--i2c-bus` | `1` | I2C bus number |\n| `--i2c-address` | `0x41` | INA219 I2C address (hex). Use `sudo i2cdetect -y 1` to find yours |\n| `--battery-capacity` | `30` | Battery capacity in Wh. Default fits 3× 18650 cells |\n\n#### Monitoring\n\n| Flag | Default | Description |\n|------|---------|-------------|\n| `--log-interval` | `2` | Sampling interval in seconds |\n| `--smoothing` | `5` | Rolling-average window for display. Raw values always go to CSV |\n| `--show-plot` | off | Show real-time voltage/current/power graphs |\n| `--daemon` | off | Background mode: no terminal output, log to file only |\n| `--tray` | off | Show system-tray battery icon (needs `pystray` + `Pillow`) |\n\n#### Shutdown Guard\n\n| Flag | Default | Description |\n|------|---------|-------------|\n| `--shutdown-threshold` | `20` | Battery % at which shutdown arms |\n| `--shutdown-consecutive` | `3` | Consecutive critical readings before shutdown fires |\n| `--no-shutdown` | off | Disable automatic shutdown (monitoring only) |\n\n#### Logging\n\n| Flag | Default | Description |\n|------|---------|-------------|\n| `--log-file` | `~/.local/share/smartups/smartups.log` | Text log path. Rotates at 5 MB, keeps 3 backups |\n| `--csv-file` | `./ina219_data_log.csv` | CSV base path. Date stamp is appended automatically |\n| `--csv-keep-days` | `30` | Auto-delete CSV files older than N days (0 = keep all) |\n| `--version` | — | Print version and exit |\n\n---\n\n## Example Output\n\n```\n=============================================\n  [2026-04-25 01:59:14]\n=============================================\n  Voltage:        12.368 V\n  Current:        0.0277 A (out)\n  Power:          0.344 W  [Low]\n  Battery:        93.6%  On Battery\n  CPU Temp:       64.8°C\n  CPU Usage:      51.4%\n  Memory:         15.2%\n  Remaining:      More than 24 hrs\n```\n\nThe display shows **smoothed** (rolling average) values for stable readings. Raw sensor values are always written to the CSV for accurate analysis.\n\n---\n\n## CSV Data Logging\n\nCSV files are automatically date-stamped and rotated daily:\n\n```\nina219_data_log_2026-04-25.csv\nina219_data_log_2026-04-26.csv\n...\n```\n\nFiles older than `--csv-keep-days` (default 30) are automatically pruned on startup. Set `--csv-keep-days 0` to keep everything.\n\n---\n\n## Graceful Shutdown\n\nWhen running on battery and the charge drops to the configured threshold for the configured number of consecutive samples, SmartUPS invokes `sudo shutdown -h now`. The consecutive-reading requirement means a single transient dip will never trigger a shutdown — the condition has to persist across `--shutdown-consecutive` samples (default 3, so 6 seconds at the default 2s interval).\n\nFor the shutdown command to succeed non-interactively:\n\n- **Option A (recommended):** Use the systemd service — it has `CAP_SYS_BOOT` built in.\n- **Option B:** Add a passwordless sudoers entry:\n  ```bash\n  echo \"$(whoami) ALL=(ALL) NOPASSWD: /sbin/shutdown\" | sudo tee /etc/sudoers.d/smartups\n  ```\n\nUse `--no-shutdown` for monitoring only (no automated shutdown).\n\n---\n\n## System Tray Icon\n\nWith `--tray`, SmartUPS shows a battery icon in your system tray:\n\n| Color | Meaning |\n|-------|---------|\n| Blue | Charging / plugged in |\n| Green | On battery, healthy (\u003e50%) |\n| Amber | On battery, low (21–50%) |\n| Red | On battery, critical (≤20%) |\n\nInstall the optional dependencies:\n```bash\n./venv/bin/pip install pystray pillow\n```\n\n---\n\n## Auto-Start on Boot (systemd)\n\n### Option A: Use the setup script (recommended)\n\n```bash\n./setup.sh\n```\n\nThis automatically generates a service file with your username and paths.\n\n### Option B: Manual installation\n\n```bash\n# 1. Create log directory\nsudo mkdir -p /var/log/smartups\nsudo chown \"$(whoami):$(whoami)\" /var/log/smartups\n\n# 2. Copy and edit the service file\nsudo cp systemd/smartups.service /etc/systemd/system/\n# Edit User= and paths to match your setup:\nsudo nano /etc/systemd/system/smartups.service\n\n# 3. Enable and start\nsudo systemctl daemon-reload\nsudo systemctl enable --now smartups.service\n\n# 4. Check status\nsystemctl status smartups.service\njournalctl -u smartups.service -f\n```\n\n### Managing the service\n\n```bash\nsudo systemctl status smartups.service     # check status\nsudo systemctl restart smartups.service    # restart after config change\nsudo systemctl stop smartups.service       # stop temporarily\njournalctl -u smartups.service -f          # watch live logs\n```\n\n### Desktop tray icon (KDE/GNOME)\n\nFor the tray icon in a desktop session, install the user service:\n\n```bash\nmkdir -p ~/.config/systemd/user\ncp systemd/smartups-tray.service ~/.config/systemd/user/\n# Edit WorkingDirectory if your clone isn't at ~/SmartUPS\nsystemctl --user daemon-reload\nsystemctl --user enable --now smartups-tray.service\n```\n\n---\n\n## Troubleshooting\n\n### \"No such file or directory: /dev/i2c-1\"\nI2C is not enabled. Run `sudo raspi-config` → Interface Options → I2C → Enable, then reboot.\n\n### \"Permission denied\" on I2C\nAdd your user to the `i2c` group:\n```bash\nsudo usermod -aG i2c $(whoami)\n```\nThen log out and back in.\n\n### Current reads as 0.0 A\nMake sure you're using the correct I2C address. Check with:\n```bash\nsudo i2cdetect -y 1\n```\nThen pass the address: `python SmartUPS.py --i2c-address 0x41`\n\n### \"ModuleNotFoundError: No module named 'smbus2'\"\nYou need to activate the virtual environment first:\n```bash\nsource venv/bin/activate\npython SmartUPS.py\n```\nOr run directly with the venv python:\n```bash\n./venv/bin/python SmartUPS.py\n```\n\n### Service fails to start\nCheck the logs:\n```bash\njournalctl -u smartups.service --no-pager -n 50\n```\n\n---\n\n## Extending SmartUPS\n\nSmartUPS works with any INA219-based UPS module. If you're using different hardware:\n\n- **I2C Address** — use `--i2c-address` (e.g. `--i2c-address 0x40`)\n- **I2C Bus** — use `--i2c-bus` (e.g. `--i2c-bus 0`)\n- **Battery Capacity** — use `--battery-capacity` (in watt-hours)\n\n## License\n\nSmartUPS is licensed under the MIT License. See `LICENSE` for details.\n\n## Contributions\n\nFeel free to open issues or submit pull requests!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxza85hrf%2Fsmartups","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fxza85hrf%2Fsmartups","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxza85hrf%2Fsmartups/lists"}