Initial pump monitor with Coolify deployment

This commit is contained in:
2026-09-06 10:37:34 +02:00
commit 9d7179308f
16 changed files with 1539 additions and 0 deletions
+95
View File
@@ -0,0 +1,95 @@
# Tapo P110 pump-cycle monitor
A small, private monitor for a domestic waterworks pump connected through a Tapo P110. It reads power locally, records the first and last threshold crossing for every run, and presents the results in a phone-friendly dashboard.
## What it records
- Start and stop time for every pump cycle
- Duration, average power, peak power, and estimated energy per cycle
- A rolling 24-hour power trace
- Daily cycle count, total runtime, average duration, and longest duration
- Partial-cycle markers after restarts or communication gaps
- CSV export of completed cycles
With the default two-second polling interval, event times have approximately two-second resolution. Two consecutive readings confirm a transition, but the saved event time is the first threshold crossing.
## Run locally with Docker
1. Open the local `.env` file in this directory.
2. Enter `TAPO_USERNAME` and `TAPO_PASSWORD` using the account from the Tapo app.
3. Run `docker compose up --detach --build` from this directory.
4. Open [http://localhost:8000](http://localhost:8000).
The dashboard is bound to `127.0.0.1`, so it is only available on this computer. Recorded data is stored in a named Docker volume and survives container rebuilds.
Required variables:
| Variable | Value |
| --- | --- |
| `TAPO_HOST` | The plug's reserved LAN address, for example `192.168.1.50` |
| `TAPO_USERNAME` | The email address used for the Tapo account |
| `TAPO_PASSWORD` | The Tapo account password; keep it only in the ignored local `.env` file |
| `DASHBOARD_PASSWORD` | Optional locally; use a long password if the dashboard is ever exposed beyond localhost |
Useful defaults already included in `compose.yaml`:
| Variable | Default | Meaning |
| --- | ---: | --- |
| `TZ` | `Europe/Prague` | Boundary used for daily totals |
| `POLL_INTERVAL_SECONDS` | `2` | Time between readings |
| `START_WATTS` | `100` | Two readings at or above this start a cycle |
| `STOP_WATTS` | `30` | Two readings at or below this stop a cycle |
| `CONFIRM_SAMPLES` | `2` | Consecutive readings required |
| `MAX_GAP_SECONDS` | `20` | Longer data gaps split and mark partial cycles |
| `SAMPLE_RETENTION_DAYS` | `30` | Raw chart history retention; cycle records remain |
| `DASHBOARD_PORT` | `8000` | Local dashboard port |
| `DASHBOARD_USERNAME` | `water-monitor` | Dashboard login name when a password is configured |
Do not paste real credentials into `.env.example`, `compose.yaml`, Git, or application logs. The `.env` file is excluded by `.gitignore` and `.dockerignore`.
## Deploy with Coolify and Gitea
Use `compose.coolify.yaml` for the Coolify deployment. It exposes container port 8000 to Coolify's proxy without publishing a host port and stores SQLite data in the persistent `tapo-pump-monitor-data` Docker volume.
1. Create an application in Coolify from this Gitea repository.
2. Select Docker Compose and set the compose file to `/compose.coolify.yaml`.
3. Add `TAPO_HOST`, `TAPO_USERNAME`, `TAPO_PASSWORD`, and `DASHBOARD_PASSWORD` as Coolify environment variables. Do not save their real values in Git.
4. Add a domain in Coolify and route it to the `pump-monitor` service on port 8000.
5. Deploy and confirm that the service becomes healthy and can reach the plug on the home LAN.
Keep only one instance running. Stop the local Docker deployment at cutover so the same pump cycle is not recorded twice. The local SQLite history can be copied into the Coolify volume before the first server start if it needs to be preserved.
## Before starting
- Reserve the plug's LAN address in the router so DHCP does not change it.
- In the Tapo app, enable **Me > Third-Party Services > Third-Party Compatibility**. Newer P110 firmware otherwise advertises the unsupported TPAP-only local protocol.
- Keep exactly one instance of this service. Multiple instances would record duplicate cycles.
Docker's normal bridge network can initiate connections to devices on the home LAN, so host networking is not required.
## Calibrate the thresholds
The defaults are intentionally conservative. After deployment:
1. Watch the live wattage while the pump is idle.
2. Open a tap and note the stable running wattage.
3. Set `START_WATTS` comfortably below the running value but above all idle noise.
4. Set `STOP_WATTS` above idle consumption and below `START_WATTS`.
For example, if idle is 1 W and the pump is around 750 W, the defaults of 100 W to start and 30 W to stop are suitable.
## Useful commands
```bash
docker compose up --detach --build # build and start
docker compose ps # show health and port
docker compose logs --follow # watch connection and cycle events
docker compose restart # restart without deleting data
docker compose down # stop; recorded data remains
```
Do not add `--volumes` to `docker compose down` unless you intentionally want to erase all recorded history.
## Interpreting likely problems
Once a normal baseline is established, useful warning signals include unusually short repeated cycles, a run much longer than normal, a sharp increase in cycles per hour, or a meaningful change in average running wattage. The dashboard records the evidence first; alert rules can be added after several days of normal data show appropriate limits.