Files

5.2 KiB

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.

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

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.