#include <WiFi.h>
#include <WebServer.h>
// ── WiFi credentials (Wokwi simulated network) ──
const char* ssid = "Wokwi-GUEST";
const char* password = "";
// ── Pins ────────────────────────────────────────
#define LED_LIGHT 26
#define LED_FAN 27
#define LED_AC 14
WebServer server(80);
bool lightOn = false;
bool fanOn = false;
bool acOn = false;
// ── HTML Dashboard ───────────────────────────────
String buildPage() {
String html = "<!DOCTYPE html><html><head>";
html += "<meta name='viewport' content='width=device-width, initial-scale=1'>";
html += "<title>Voice Home Control</title>";
html += "<style>body{font-family:Arial;text-align:center;background:#1a1a2e;color:white;padding:20px;}";
html += "h1{color:#e94560;} .btn{padding:14px 28px;margin:10px;border:none;border-radius:8px;font-size:16px;cursor:pointer;}";
html += ".on{background:#27ae60;} .off{background:#c0392b;} .card{background:#16213e;padding:20px;border-radius:12px;margin:10px auto;max-width:400px;}";
html += "</style></head><body>";
html += "<h1>🏠 Voice Home Control</h1><p>Control via IFTTT Webhooks or buttons below</p>";
html += "<div class='card'>";
html += "<h2>💡 Light — " + String(lightOn ? "ON" : "OFF") + "</h2>";
html += "<a href='/light/on'><button class='btn on'>Turn ON</button></a>";
html += "<a href='/light/off'><button class='btn off'>Turn OFF</button></a></div>";
html += "<div class='card'>";
html += "<h2>🌀 Fan — " + String(fanOn ? "ON" : "OFF") + "</h2>";
html += "<a href='/fan/on'><button class='btn on'>Turn ON</button></a>";
html += "<a href='/fan/off'><button class='btn off'>Turn OFF</button></a></div>";
html += "<div class='card'>";
html += "<h2>❄️ AC — " + String(acOn ? "ON" : "OFF") + "</h2>";
html += "<a href='/ac/on'><button class='btn on'>Turn ON</button></a>";
html += "<a href='/ac/off'><button class='btn off'>Turn OFF</button></a></div>";
html += "<div class='card'><h3>IFTTT Webhook URLs:</h3>";
html += "<p>GET http://<IP>/light/on → Turn light on</p>";
html += "<p>GET http://<IP>/fan/on → Turn fan on</p>";
html += "<p>GET http://<IP>/ac/on → Turn AC on</p></div>";
html += "</body></html>";
return html;
}
void handleRoot() { server.send(200, "text/html", buildPage()); }
void handleNotFound() { server.send(404, "text/plain", "Not found"); }
void setDevice(bool &state, int pin, bool val, const char* name) {
state = val;
digitalWrite(pin, val ? HIGH : LOW);
Serial.print("[VOICE] "); Serial.print(name);
Serial.println(val ? " → ON" : " → OFF");
server.send(200, "text/html", buildPage());
}
void setup() {
Serial.begin(115200);
pinMode(LED_LIGHT, OUTPUT);
pinMode(LED_FAN, OUTPUT);
pinMode(LED_AC, OUTPUT);
digitalWrite(LED_LIGHT, LOW);
digitalWrite(LED_FAN, LOW);
digitalWrite(LED_AC, LOW);
Serial.println("=================================");
Serial.println(" Voice Control via IFTTT/Google");
Serial.println(" ESP32 WebServer");
Serial.println("=================================");
WiFi.begin(ssid, password);
Serial.print("Connecting to WiFi");
while (WiFi.status() != WL_CONNECTED) {
delay(500); Serial.print(".");
}
Serial.println("\n[OK] WiFi connected!");
Serial.print("[IP] http://");
Serial.println(WiFi.localIP());
Serial.println("\nIFTTT Webhook Routes:");
Serial.println(" GET /light/on or /light/off");
Serial.println(" GET /fan/on or /fan/off");
Serial.println(" GET /ac/on or /ac/off");
server.on("/", handleRoot);
server.on("/light/on", []() { setDevice(lightOn, LED_LIGHT, true, "Light"); });
server.on("/light/off", []() { setDevice(lightOn, LED_LIGHT, false, "Light"); });
server.on("/fan/on", []() { setDevice(fanOn, LED_FAN, true, "Fan"); });
server.on("/fan/off", []() { setDevice(fanOn, LED_FAN, false, "Fan"); });
server.on("/ac/on", []() { setDevice(acOn, LED_AC, true, "AC"); });
server.on("/ac/off", []() { setDevice(acOn, LED_AC, false, "AC"); });
server.onNotFound(handleNotFound);
server.begin();
Serial.println("[OK] Web server started.\n");
}
void loop() {
server.handleClient();
}