← All projects
IoT · Personal

Plant IoT — a plant that waters itself

ESP32 firmware, a Django API and a Flutter app: soil moisture every five minutes, a pump that can be triggered from a phone or left on a schedule, and BLE provisioning so a new device never needs the Wi-Fi password hardcoded.

DjangoESP32FlutterIoT
Plant IoT — a plant that waters itself

Plant IoT

A soil moisture probe, an ESP32, a DRV8833 driving a small pump, and the two pieces of software that make them usable by someone who is not holding a laptop.

Provisioning without a rebuild

On first boot the ESP32 advertises over BLE. The app's Add Device flow sends it the Wi-Fi credentials and the server URL wirelessly, so credentials never live in the firmware image and a device can move to another network without being reflashed.

The loop

Once online the device reads moisture every five minutes and posts it. Commands go the other way by polling: the device asks for pending work every thirty seconds, executes it, and acknowledges it — which means no inbound connection, no broker, and no held socket on a device that would rather be asleep. Watering can be triggered by hand from the app or left to a schedule.

Two audiences, one API

The API is split by who is calling. The app's endpoints are JWT-authenticated and scoped to the user's devices; the device's own endpoints — register, post reading, fetch config, poll and acknowledge commands — are addressed by MAC, so the firmware carries no user credentials at all. The app shows a live gauge, the reading history, and the schedule editor.