Battery Tracker

Battery Tracker

Stop losing track of your batteries.

A fast, self-hosted web app that tells you exactly where every rechargeable battery is,
how healthy it is, and when it was last charged — all from any device on your network.

--- ## Why Battery Tracker? Rechargeable batteries are everywhere — remotes, flashlights, sensors, toys, tools. Without a system, you end up guessing which batteries are dead, buying new ones you didn't need, and finding half-charged stragglers rattling around a drawer. Battery Tracker gives you a single source of truth: - **Know where every battery is.** Each battery is assigned to a device or a storage location. No more mystery batteries. - **Track health over time.** Log capacity tests and see a trend chart. Spot batteries that are degrading before they let you down. - **Never forget to charge.** Log charge events, track charge cycles, and see at a glance which batteries are running low. - **Works with Home Assistant.** If you already have smart battery sensors, Battery Tracker will pull the live percentage automatically — no manual updates needed. - **Runs on a Pi.** Lightweight enough for a Raspberry Pi Zero. No cloud, no subscription, no data leaving your home. --- ## Features ### Batteries - Add batteries in bulk (auto-generated labels like "Eneloop 001", "Eneloop 002") - Track status: **Available**, **Installed**, **Retired** - Store metadata: size (AA/AAA/18650/…), chemistry (NiMH/Li-ion/…), capacity, tested capacity, charge cycles, purchase date, storage location, notes - Visual health indicator when tested capacity is recorded (good / warn / bad) - Battery percentage — set manually or synced live from Home Assistant; resets to 100% when a charge is logged - Retire and unretire batteries > **Tip — measuring tested capacity:** The Panasonic BQ-CC65 charger (AA/AAA) can > measure the actual capacity of a cell during a charge cycle. Use the reading it > reports as the "Tested capacity" value when logging a capacity test. ### Devices - Add devices with a name, battery slot count, type (Remote Control, Flashlight, Sensor, …), and notes - Install batteries into devices — by brand/quantity or by picking specific batteries - Bulk install multiple batteries at once from the dashboard - Mixed-brand warning when batteries from different brands share a device - Link a device to a Home Assistant battery sensor for automatic live percentage tracking ### Dashboard - Overview stats (total / available / installed / retired) + **Low Battery** count when any battery is below 20% - Charge summary: total charge events and events in the last year - Full battery table with client-side filtering by status, brand, size, storage location, and free-text search - Column picker (Chemistry, Capacity, Storage, Purchase Date, Cycles, Battery %) stored in localStorage - Quick-assign available batteries to a device without leaving the page - Bulk actions: Unassign, Retire, Delete, Set Field (storage location or brand), Install in Device ### History & Charts - **Capacity history** — track tested capacity over time with a trend chart; full log in a modal with year filter and pagination - **Charge history** — log every charge event; full log in a modal with year filter and pagination - **Percentage history** — see a live chart of battery percentage over time; full log in a modal ### Home Assistant Integration (optional) - Link any device to a Home Assistant entity (e.g. `sensor.tv_remote_battery`) - Background poller fetches the current percentage on a configurable interval (default 5 min) and updates all installed batteries in that device - Low-battery warning badge (< 20%) on the dashboard, device detail, and battery detail pages - Fully optional — when `HOMEASSISTANT_URL` is not set the app works exactly as before ### UI - **PWA** — installable on Android, iOS, and desktop; works as a home screen app - **Mobile-friendly** — card-style table rows on small screens, full-width filter controls, stacked form buttons - **Dark mode** — follows OS system preference automatically (`prefers-color-scheme`) - No JavaScript framework — vanilla JS only --- ## Tech Stack | Layer | Technology | |---|---| | Web framework | Flask 3.x | | ORM | SQLAlchemy 2.x (raw session, no Flask-SQLAlchemy) | | Database | SQLite (dev) / MariaDB (prod) | | WSGI server | Waitress | | Process manager | systemd user service | | Tests | pytest (80 acceptance tests) | --- ## Setup ### Prerequisites - Python 3.10+ - `python3-venv` ### Install ```bash git clone cd battery-tracker-app python3 -m venv .venv source .venv/bin/activate pip install -r requirements.txt ``` ### Run (development) ```bash source .venv/bin/activate flask run # → http://127.0.0.1:5000 ``` ### Run (production — systemd user service) ```bash bash sbin/install-service.sh # prompts for host/port + optional HA config, installs and enables the service systemctl --user start battery-tracker systemctl --user status battery-tracker journalctl --user -u battery-tracker -f ``` ### Database SQLite is used by default (`batteries.db` in the project root). To switch to MariaDB, set the environment variable before starting: ```bash export DATABASE_URL="mysql+pymysql://user:pass@host/dbname" ``` See `MIGRATION.md` for migrating an existing SQLite database to MariaDB, and for the schema migration commands needed when upgrading an existing database. ### Home Assistant integration Set these environment variables before starting (or enter them when running `install-service.sh`): ```bash export HOMEASSISTANT_URL="http://homeassistant.local:8123" export HOMEASSISTANT_API_KEY="" export HOMEASSISTANT_POLL_INTERVAL="300" # seconds, default 300 ``` Then link a device to its HA sensor entity ID on the device's edit page (e.g. `sensor.tv_remote_battery`). The app will poll HA every interval and update the battery percentage for all installed batteries in that device. ### Seed data (optional) ```bash source .venv/bin/activate python seed.py ``` --- ## Running Tests ```bash source .venv/bin/activate pytest tests/ -v ``` Tests use a fresh temporary SQLite database per test and exercise the full HTTP stack. --- ## Project Structure ``` app.py Flask app factory + all routes models.py SQLAlchemy models (Battery, Device) config.py Database URL + HA config ha_client.py Home Assistant REST API wrapper ha_poller.py Background thread — polls HA, updates battery_percentage seed.py Optional seed data script migrate_to_mariadb.py SQLite → MariaDB migration script MIGRATION.md Schema migration instructions + MariaDB procedure requirements.txt sbin/ install-service.sh systemd user service installer (prompts for HA config) static/ icon-192.png PWA icon (192×192) icon-512.png PWA icon (512×512) favicon.ico Browser favicon manifest.json PWA manifest sw.js Service worker templates/ base.html Layout, CSS variables, dark mode, nav dashboard.html Battery list with filters, bulk actions, HA% column battery_add.html Add batteries form battery_detail.html Battery detail + history charts + modals battery_delete.html Delete confirmation assign.html Assign battery to device device_list.html Device list with type filter device_add.html Add device form device_detail.html Device detail + install + edit tests/ conftest.py pytest fixtures test_acceptance.py acceptance tests test_ha_integration.py HA integration tests ```