I had an old fan sitting in my room since childhood — perfectly functional, but completely dumb. No remote, no timer, nothing. So I decided to fix that and turn it into a Wi-Fi controlled fan I can toggle from my phone without getting off the couch.
Parts list
- ESP8266 (NodeMCU or Wemos D1 Mini)
- 5V relay module
- Old USB charger (for 5V power supply)
- Old fan
- Soldering iron + solder
- Wire, heat shrink or cable housing
Disassembly — the hard part
Opening the fan was the first challenge. Three screws came out easily, but two were completely stripped — some kind of tamper-resistant head I had never seen before. My solution: mark the screw center with a marker, heat the soldering iron, and melt just enough plastic around it to grip and turn it out. Not elegant, and definitely not something to do in a closed room — melting plastic fumes are not your friend. Open a window, or better yet, do it outside.
Schematic and wiring
The plan is straightforward: the ESP8266 needs 5V to run, and so does the relay module. I sourced that 5V from an old USB phone charger — its live and neutral wires connect to mains, and the 5V output feeds the ESP and relay. The relay's normally-open contact sits in series with the fan's neutral wire. When the relay closes, the fan runs. When it opens, the fan stops.
- USB charger → mains live & neutral → 5V out to ESP8266 VIN & relay VCC
- ESP8266 GPIO pin → relay IN
- Relay NO contact → fan neutral wire (in series)
After soldering everything together and insulating the connections with cable housing, I tested the 5V supply with a multimeter before touching anything else.
The sketch
The ESP8266 connects to the home Wi-Fi router and starts a small HTTP server. One route — /toggle — flips the relay state each time it is called. That's all it needs to do.
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
const char* ssid = "YOUR_SSID";
const char* password = "YOUR_PASSWORD";
const int RELAY = D1;
ESP8266WebServer server(80);
bool fanOn = false;
void handleToggle() {
fanOn = !fanOn;
digitalWrite(RELAY, fanOn ? HIGH : LOW);
server.send(200, "text/plain", fanOn ? "ON" : "OFF");
}
void setup() {
pinMode(RELAY, OUTPUT);
digitalWrite(RELAY, LOW);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) delay(500);
server.on("/toggle", handleToggle);
server.begin();
}
void loop() {
server.handleClient();
}
Full source code is on GitHub: github.com/viktoriabuilds/ventilator
Phone UI
A plain HTTP endpoint works, but typing an IP address into the browser every time is annoying. I asked an AI to generate a minimal HTML page with a single toggle button that calls the /toggle route. Saved it as an HTML file, opened it on my phone — done. One tap to turn the fan on or off from anywhere on the home network.
Final result
After reassembling the fan and running a final test, everything worked. The fan responds instantly to the button, the ESP8266 stays connected reliably, and I didn't have to buy a new smart fan. Total cost: basically zero, since all the parts came from the parts bin. Now I can be even lazier when summer hits.