Skip to content

IoT · 3D Printing · Firmware

Server-Room Climate Monitor

One request, running in the server room about 14 hours later.
ESP32 + DHT11, a home-printed sliding-lid case, firmware that only serves an API.

2026 ESP32 + DHT11 PLA sliding lid HTTP JSON API
The finished server-room climate monitor, lid closed and powered

The real device, lid closed and running · background screen blurred

It started with one sentence

The server room needed a temperature and humidity sensor that could be read over the network. The scope was narrow from the start: measure only, no control of dehumidifiers or humidifiers; USB 5 V power; a case printed in PLA on the Ender‑3 at home.

The device only serves an API. Whether to alert and how long to keep data is decided by a separate polling service, so adding a sensor or changing a threshold never means reflashing.

I bought the parts, printed, wired and assembled it myself. AI implemented the wiring diagram, the CAD model, the firmware and the dashboard, each from a written brief with its scope and acceptance criteria.

From request to running

Four turns along the way: new hardware, an unknown board size, two swapped wires, and “alert on the device” becoming “measure only”.

01

Parts: whatever was actually bought

The plan was an ESP32‑C3 with an SHT31. The same day it became the ESP32 board and DHT11 an electronics shop had on the shelf. The BOM follows the real parts, with prices compared against equivalent items online.

02

Wiring: drawn from an existing parts library

Wokwi's open-source elements (MIT) were rendered in a headless browser, and every wire ends on the part's own pin coordinates. Three wires: 3V3, GND, GPIO4.

03

Model: a parametric OpenSCAD case

Body and lid print on one plate with no supports. The board came home in a bag, 30-pin or 38-pin unknown, so both versions were built, each with 15 automated checks.

04

Slicing: three rounds of G-code

Cura, PLA, 0.28 mm layers, about 6 hours per plate. The last round added a brim, a hotter bed and no fan for the first 3 layers, so the long, thin parts are less likely to warp.

05

Firmware: measure and serve

One sample every 5 seconds, about an hour kept in RAM; endpoints for latest, incremental history, health and Prometheus-format metrics. The core logic was tested on the host before it ever reached the board.

06

Closing the loop: two swapped white wires

The first flash read nothing. A diagnostic sketch found the data pin pulled to ground, which pointed to two same-colored wires swapped at the module. After swapping them back: 923 readings in a row on the dashboard, zero failures.

The sliding-lid case

A 45° dovetail lid slides out toward the USB end; vented walls, clear space over the antenna, and the cable and BOOT/EN buttons reachable without opening it.

Render of the case with the lid half open, showing the board, wiring and sensor bay

30-pin version, lid half open (the full write-up has a 3D model you can rotate and slide open)

~14h

request to running

923

readings · 0 failed

15

automated case checks

181+47

host-side tests

Key design decisions

The device measures; a service decides

The first firmware alerted on the device. That was taken out, leaving raw values and health counters. Thresholds, alert channels and retention change on the service side, with no reflash.

Mark what is uncertain, build both

Every dimension is labeled as official, third-party measured or estimated. With the board size unknown, a 30-pin and a 38-pin case were both built instead of treating a guess as settled.

Checks have to be able to fail

Both the case checks and the firmware tests were deliberately broken once to prove they catch errors; on-device acceptance had its own checklist.

The API stays on a trusted LAN

There is no login and only plain HTTP, so it is never exposed to the internet; reaching it from another network goes through a VPN. A Bearer token can be added later, and CORS already allows the Authorization header.

Tech

Hardware

ESP32 30-pin DOIT DevKit V1
DHT11 module
Jumper wires, no soldering

CAD / Print

OpenSCAD (Manifold)
Python interference checks
Cura 5.6 · layer-by-layer G-code review

Firmware

arduino-cli · ESP32 Arduino core
C++ host tests (ASan / UBSan)
NTP · Prometheus format

Dashboard

One HTML file calling the API
Displays only, never judges
Verified on the device with Playwright

The BOM and price comparison, wiring diagram, rotatable 3D model, G-code, API and closing evidence are in the full write-up (in Chinese).