SmartIoT
ESP32 firmware, an MQTT bridge, a React dashboard and a Flutter app — running real hardware in real houses: water tanks, irrigation valves, an air conditioner, a solar changeover.
- 9
- device firmwares
- 4
- clients: web, mobile, local HTTP, MQTT
- 0
- cloud dependencies for local control
- ESP32
- PlatformIO
- FastAPI
- PostgreSQL
- EMQX / MQTT
- Flutter
- React
- Docker
The problem
Consumer smart-home gear dies the moment its vendor's cloud goes away, and in Lahore the internet and the power both go away regularly. I wanted devices that keep their schedules and their relays working on their own, but that I can still reach from anywhere when the connection is up.
My role
Everything: the hardware, the firmware, the backend, both frontends, the broker, the deployment and the security review.
What I built
- 01
Each device is a standalone PlatformIO project built from a shared blueprint — local HTTP control, its own schedules in flash, and MQTT only as an extra path. If the broker vanishes, the valve still opens on time.
- 02
A FastAPI backend bridges MQTT to the apps, holds users, devices and history in PostgreSQL, and serves OTA firmware so I don't climb on a roof to reflash a tank sensor.
- 03
A React dashboard for day-to-day control plus an admin side, and a Flutter app that replaced the old React Native one.
- 04
Hardened the whole thing in one pass: Postgres bound to localhost, API and broker dashboard behind nginx, every device given a login that may only touch its own MQTT topics, and scoped API keys for the automations that talk to it.
- 05
Single sign-on added in front of my own services, with a deliberate carve-out so device OTA and the mobile app never meet a login page.
Outcome
Tank levels, irrigation timers, the AC and a solar grid changeover have run on this for over a year, through outages that took the internet down for hours.
Adding a new device is a copy of the template plus a pinout — the platform side needs no changes.
The security pass turned a hobby setup into something I'd be comfortable deploying for someone else.