Files
battery-tracker-app/README.md
T

193 lines
7.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<div align="center">
<img src="static/icon-512.png" alt="Battery Tracker" width="160">
<h1>Battery Tracker</h1>
<p><strong>Stop losing track of your batteries.</strong></p>
<p>A fast, self-hosted web app that tells you exactly where every rechargeable battery is,<br>
how healthy it is, and when it was last charged — all from any device on your network.</p>
</div>
---
## 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
### 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 <repo-url>
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="<long-lived access token>"
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
```