Project 03 06

WCS

An end-to-end sensor and weather platform, from the firmware on the microcontroller to the charts in the browser.

IoT platform
Django · Next.js · TimescaleDB · MQTT · ESP8266

WCS is a modular platform for collecting, storing, and visualising sensor and weather data. It spans the whole path a measurement takes: an ESP8266 reads its sensors and publishes over MQTT, an EMQX broker receives it, a Django backend ingests and stores it in PostgreSQL with TimescaleDB, and a Next.js frontend turns it into charts.

The stack, layer by layer

Sensor. Arduino firmware on an ESP8266, built through arduino-cli, publishing readings over MQTT rather than HTTP — fewer bytes per message, a persistent connection, and no request overhead on a device with very little to spare.

Backend. Django 5 and Django REST Framework over PostgreSQL with the TimescaleDB extension. Sensor readings are time-series data, and TimescaleDB’s hypertables handle the write volume and time-bucketed queries that a plain relational table struggles with once the history gets long.

Frontend. Next.js 14 and React 18 with Ant Design and MUI for the interface, Chart.js for the visualisations, and Zustand holding client state, all in TypeScript.

Deployment. The whole system ships as Docker Compose services behind Nginx: the WSGI and ASGI Django processes, the EMQX broker, and the database, each with its own environment file.

What I learned

Owning every layer is the part of this project I value most. When a reading looks wrong, the cause could be a loose sensor wire, a firmware rounding bug, a dropped MQTT message, a timezone in the ingest path, or a chart axis. Having to chase problems across all of those boundaries taught me more about system design than any single layer would have.

Time-series data also changed how I think about storage. My instinct was a normal table with a timestamp column, and it works right up until it doesn’t — queries that were instant over a week of data become unusable over a year. Learning to reach for hypertables, retention policies, and pre-aggregation was the moment “it’s just a database” stopped being true for me.

The protocol choice mattered more than I expected. Moving from HTTP requests to MQTT on a constrained device was not a micro-optimisation; it was the difference between a sensor that stays connected and one that spends its power budget on handshakes. Constraints at the edge of a system propagate back through everything behind them.

Finally, WCS is where I learned that deployment is part of the design. A system with four services that only runs on my machine isn’t finished. Getting it into Docker Compose with Nginx in front forced every implicit assumption about hosts, ports, and configuration into a file where it could be read.