3. ESP32 Web Server for Remote Device Control
Project Overview
Create a custom web interface hosted on ESP32 to control devices from any browser on your network.
Key Features
- Responsive web interface
- Real-time control
- No internet dependency (local network)
- Customizable UI
- API support
Components Required
- ESP32 DevKit
- LEDs/Relays for testing
- Smartphone/Computer
- Router for Wi-Fi
Diagram.json:
{
"version": 1,
"author": "ESP32 Web Server Control",
"editor": "wokwi",
"parts": [
{ "type": "wokwi-esp32-devkit-v1", "id": "esp", "top": 0, "left": 0, "attrs": {} },
{
"type": "wokwi-led",
"id": "led1",
"top": -124.8,
"left": 230.4,
"attrs": { "color": "yellow", "lightColor": "yellow", "label": "Living Room" }
},
{
"type": "wokwi-resistor",
"id": "r1",
"top": -67.2,
"left": 230.4,
"rotate": 90,
"attrs": { "value": "220" }
},
{
"type": "wokwi-led",
"id": "led2",
"top": -124.8,
"left": 307.2,
"attrs": { "color": "white", "lightColor": "white", "label": "Bedroom" }
},
{
"type": "wokwi-resistor",
"id": "r2",
"top": -67.2,
"left": 307.2,
"rotate": 90,
"attrs": { "value": "220" }
},
{
"type": "wokwi-led",
"id": "led3",
"top": -124.8,
"left": 384,
"attrs": { "color": "blue", "lightColor": "blue", "label": "Fan" }
},
{
"type": "wokwi-resistor",
"id": "r3",
"top": -67.2,
"left": 384,
"rotate": 90,
"attrs": { "value": "220" }
},
{
"type": "wokwi-led",
"id": "led4",
"top": -124.8,
"left": 460.8,
"attrs": { "color": "red", "lightColor": "orange", "label": "Heater" }
},
{
"type": "wokwi-resistor",
"id": "r4",
"top": -67.2,
"left": 460.8,
"rotate": 90,
"attrs": { "value": "220" }
},
{
"type": "wokwi-led",
"id": "led5",
"top": -124.8,
"left": 537.6,
"attrs": { "color": "green", "lightColor": "green", "label": "Door Lock" }
},
{
"type": "wokwi-resistor",
"id": "r5",
"top": -67.2,
"left": 537.6,
"rotate": 90,
"attrs": { "value": "220" }
},
{
"type": "wokwi-dht22",
"id": "dht1",
"top": -86.4,
"left": 105.6,
"attrs": { "temperature": "25", "humidity": "55" }
},
{
"type": "wokwi-ssd1306",
"id": "oled1",
"top": 141.1,
"left": 289.9,
"attrs": { "i2cAddress": "0x3C" }
},
{
"type": "wokwi-buzzer",
"id": "bz1",
"top": 96,
"left": 518.4,
"attrs": { "volume": "0.3" }
}
],
"connections": [
[ "esp:TX0", "$serialMonitor:RX", "", [] ],
[ "esp:RX0", "$serialMonitor:TX", "", [] ],
[ "led1:A", "esp:D26", "yellow", [ "v0" ] ],
[ "led1:C", "r1:1", "yellow", [ "v0" ] ],
[ "r1:2", "esp:GND.1", "black", [ "v0" ] ],
[ "led2:A", "esp:D27", "white", [ "v0" ] ],
[ "led2:C", "r2:1", "white", [ "v0" ] ],
[ "r2:2", "esp:GND.1", "black", [ "v0" ] ],
[ "led3:A", "esp:D14", "blue", [ "v0" ] ],
[ "led3:C", "r3:1", "blue", [ "v0" ] ],
[ "r3:2", "esp:GND.1", "black", [ "v0" ] ],
[ "led4:A", "esp:D12", "red", [ "v0" ] ],
[ "led4:C", "r4:1", "red", [ "v0" ] ],
[ "r4:2", "esp:GND.1", "black", [ "v0" ] ],
[ "led5:A", "esp:D13", "green", [ "v0" ] ],
[ "led5:C", "r5:1", "green", [ "v0" ] ],
[ "r5:2", "esp:GND.1", "black", [ "v0" ] ],
[ "dht1:VCC", "esp:3V3", "red", [ "v0" ] ],
[ "dht1:GND", "esp:GND.1", "black", [ "v0" ] ],
[ "dht1:SDA", "esp:D15", "green", [ "v0" ] ],
[ "oled1:VCC", "esp:3V3", "red", [ "h0" ] ],
[ "oled1:GND", "esp:GND.2", "black", [ "h0" ] ],
[ "oled1:SDA", "esp:D21", "blue", [ "h0" ] ],
[ "oled1:SCL", "esp:D22", "yellow", [ "h0" ] ],
[ "bz1:1", "esp:D25", "purple", [ "v0" ] ],
[ "bz1:2", "esp:GND.2", "black", [ "v0" ] ]
],
"dependencies": {}
}
Applications
- Laboratory equipment control
- Workshop automation
- Smart office systems
- Educational demonstrations
Difficulty Level
Beginner - Great starting project
Code:
/*
* ESP32 Web Server for Remote Device Control
*
* Features:
* - Control 4 different devices (Lights, Fan, Door Lock, Heater)
* - Real-time status updates
* - Beautiful responsive web interface
* - Slider controls for dimmable devices
* - Toggle switches for on/off devices
* - Scheduling support
* - Password protection
* - Mobile-friendly design
* - OLED display for status
* - Temperature monitoring
*/
#include <WiFi.h>
#include <WebServer.h>
#include <DHT.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// WiFi Credentials
const char* ssid = "Wokwi-GUEST";
const char* password = "";
// Web Server
WebServer server(80);
// Authentication
const char* webUsername = "admin";
const char* webPassword = "1234";
bool isAuthenticated = false;
// Pin Definitions
#define LED1_PIN 26 // Living Room Light
#define LED2_PIN 27 // Bedroom Light
#define FAN_PIN 14 // Fan (PWM)
#define HEATER_PIN 12 // Heater
#define DOOR_LOCK_PIN 13 // Door Lock Servo/Relay
#define DHT_PIN 15 // Temperature Sensor
#define BUZZER_PIN 25 // Alert Buzzer
// PWM Settings
#define PWM_FREQ 5000
#define PWM_RESOLUTION 8
// DHT Sensor
#define DHT_TYPE DHT22
DHT dht(DHT_PIN, DHT_TYPE);
// OLED Display
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// Device States
struct DeviceState {
bool livingRoomLight;
bool bedroomLight;
bool doorLock;
bool heater;
int fanSpeed; // 0-100
float temperature;
float humidity;
unsigned long lastUpdate;
};
DeviceState devices;
// Schedule Structure
struct Schedule {
bool enabled;
int hour;
int minute;
String device;
bool action;
};
Schedule schedules[5];
int scheduleCount = 0;
// Timing
unsigned long lastSensorRead = 0;
const long sensorInterval = 2000;
void setup() {
Serial.begin(115200);
// Initialize pins
pinMode(LED1_PIN, OUTPUT);
pinMode(LED2_PIN, OUTPUT);
pinMode(HEATER_PIN, OUTPUT);
pinMode(DOOR_LOCK_PIN, OUTPUT);
pinMode(BUZZER_PIN, OUTPUT);
// Setup PWM for fan (compatible with ESP32 Arduino Core 3.x)
ledcAttach(FAN_PIN, PWM_FREQ, PWM_RESOLUTION);
// Initialize DHT
dht.begin();
// Initialize OLED
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
} else {
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println("Remote Control");
display.println("Starting...");
display.display();
delay(2000);
}
// Initialize device states
devices.livingRoomLight = false;
devices.bedroomLight = false;
devices.doorLock = true; // Locked by default
devices.heater = false;
devices.fanSpeed = 0;
devices.temperature = 0;
devices.humidity = 0;
// Apply initial states
applyDeviceStates();
// Connect to WiFi
WiFi.begin(ssid, password);
Serial.print("Connecting to WiFi");
display.clearDisplay();
display.setCursor(0, 0);
display.println("Connecting WiFi...");
display.display();
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nWiFi connected");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
// Setup web server routes
server.on("/", handleRoot);
server.on("/login", handleLogin);
server.on("/logout", handleLogout);
server.on("/control", handleControl);
server.on("/status", handleStatus);
server.on("/living-room/on", []() { handleDeviceControl("living-room", true); });
server.on("/living-room/off", []() { handleDeviceControl("living-room", false); });
server.on("/bedroom/on", []() { handleDeviceControl("bedroom", true); });
server.on("/bedroom/off", []() { handleDeviceControl("bedroom", false); });
server.on("/fan/set", handleFanControl);
server.on("/heater/on", []() { handleDeviceControl("heater", true); });
server.on("/heater/off", []() { handleDeviceControl("heater", false); });
server.on("/door/lock", []() { handleDoorControl(true); });
server.on("/door/unlock", []() { handleDoorControl(false); });
server.on("/all/on", handleAllOn);
server.on("/all/off", handleAllOff);
server.begin();
Serial.println("HTTP server started");
Serial.println("\n=== Remote Control System Ready ===");
Serial.println("Access the control panel at:");
Serial.print("http://");
Serial.println(WiFi.localIP());
Serial.println("Username: admin");
Serial.println("Password: 1234");
Serial.println("=====================================\n");
updateDisplay();
playStartupSound();
}
void loop() {
server.handleClient();
// Read sensors periodically
unsigned long currentMillis = millis();
if (currentMillis - lastSensorRead >= sensorInterval) {
lastSensorRead = currentMillis;
readSensors();
updateDisplay();
}
}
void readSensors() {
devices.temperature = dht.readTemperature();
devices.humidity = dht.readHumidity();
if (isnan(devices.temperature) || isnan(devices.humidity)) {
devices.temperature = 0;
devices.humidity = 0;
}
devices.lastUpdate = millis();
}
void applyDeviceStates() {
digitalWrite(LED1_PIN, devices.livingRoomLight ? HIGH : LOW);
digitalWrite(LED2_PIN, devices.bedroomLight ? HIGH : LOW);
digitalWrite(HEATER_PIN, devices.heater ? HIGH : LOW);
digitalWrite(DOOR_LOCK_PIN, devices.doorLock ? HIGH : LOW);
ledcWrite(FAN_PIN, map(devices.fanSpeed, 0, 100, 0, 255));
}
void updateDisplay() {
display.clearDisplay();
display.setTextSize(1);
display.setCursor(0, 0);
display.println("SMART HOME");
display.drawLine(0, 9, 128, 9, SSD1306_WHITE);
// Temperature
display.setCursor(0, 12);
display.print("Temp: ");
display.print(devices.temperature, 1);
display.println("C");
// Device Status
display.setCursor(0, 22);
display.print("Living: ");
display.println(devices.livingRoomLight ? "ON" : "OFF");
display.setCursor(0, 32);
display.print("Bedroom: ");
display.println(devices.bedroomLight ? "ON" : "OFF");
display.setCursor(0, 42);
display.print("Fan: ");
display.print(devices.fanSpeed);
display.println("%");
display.setCursor(0, 52);
display.print("Door: ");
display.println(devices.doorLock ? "LOCKED" : "UNLOCKED");
display.display();
}
void playStartupSound() {
tone(BUZZER_PIN, 1000, 100);
delay(150);
tone(BUZZER_PIN, 1500, 100);
}
void playClickSound() {
tone(BUZZER_PIN, 800, 50);
}
// Web Server Handlers
void handleRoot() {
// Check authentication
if (!server.authenticate(webUsername, webPassword)) {
return server.requestAuthentication();
}
String html = generateHTML();
server.send(200, "text/html", html);
}
String generateHTML() {
String html = "<!DOCTYPE html><html><head>";
html += "<meta name='viewport' content='width=device-width, initial-scale=1.0'>";
html += "<title>Smart Home Control</title>";
html += "<style>";
html += "* { margin: 0; padding: 0; box-sizing: border-box; }";
html += "body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; ";
html += "background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); ";
html += "min-height: 100vh; padding: 20px; color: white; }";
html += ".container { max-width: 1200px; margin: 0 auto; }";
html += "h1 { text-align: center; font-size: 2.5em; margin-bottom: 10px; text-shadow: 2px 2px 4px rgba(0,0,0,0.3); }";
html += ".subtitle { text-align: center; font-size: 1em; margin-bottom: 30px; opacity: 0.9; }";
html += ".stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 15px; margin-bottom: 30px; }";
html += ".stat-card { background: rgba(255,255,255,0.2); padding: 15px; border-radius: 10px; text-align: center; backdrop-filter: blur(10px); }";
html += ".stat-value { font-size: 2em; font-weight: bold; }";
html += ".stat-label { font-size: 0.9em; opacity: 0.8; margin-top: 5px; }";
html += ".devices-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 20px; margin-bottom: 20px; }";
html += ".device-card { background: rgba(255,255,255,0.15); backdrop-filter: blur(10px); ";
html += "padding: 25px; border-radius: 15px; box-shadow: 0 8px 32px rgba(0,0,0,0.1); border: 1px solid rgba(255,255,255,0.18); }";
html += ".device-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; }";
html += ".device-icon { font-size: 2.5em; }";
html += ".device-name { font-size: 1.3em; font-weight: bold; }";
html += ".device-status { font-size: 0.9em; opacity: 0.8; margin-bottom: 15px; }";
html += ".controls { display: flex; gap: 10px; flex-wrap: wrap; }";
html += ".btn { padding: 12px 24px; border: none; border-radius: 8px; cursor: pointer; ";
html += "font-size: 1em; font-weight: 600; transition: all 0.3s; text-decoration: none; display: inline-block; color: white; }";
html += ".btn-on { background: #4CAF50; }";
html += ".btn-on:hover { background: #45a049; transform: translateY(-2px); box-shadow: 0 4px 8px rgba(0,0,0,0.2); }";
html += ".btn-off { background: #f44336; }";
html += ".btn-off:hover { background: #da190b; transform: translateY(-2px); box-shadow: 0 4px 8px rgba(0,0,0,0.2); }";
html += ".btn-action { background: #2196F3; }";
html += ".btn-action:hover { background: #0b7dda; transform: translateY(-2px); }";
html += ".btn-warning { background: #ff9800; }";
html += ".slider-container { margin: 15px 0; }";
html += ".slider { width: 100%; height: 8px; border-radius: 5px; background: rgba(255,255,255,0.3); ";
html += "outline: none; -webkit-appearance: none; }";
html += ".slider::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; ";
html += "width: 20px; height: 20px; border-radius: 50%; background: white; cursor: pointer; }";
html += ".slider::-moz-range-thumb { width: 20px; height: 20px; border-radius: 50%; background: white; cursor: pointer; border: none; }";
html += ".slider-value { text-align: center; font-size: 1.2em; margin-top: 10px; font-weight: bold; }";
html += ".quick-actions { background: rgba(255,255,255,0.2); padding: 20px; border-radius: 15px; margin-top: 20px; }";
html += ".quick-actions h3 { margin-bottom: 15px; }";
html += ".status-indicator { display: inline-block; width: 12px; height: 12px; border-radius: 50%; margin-right: 8px; }";
html += ".status-on { background: #4CAF50; box-shadow: 0 0 10px #4CAF50; }";
html += ".status-off { background: #666; }";
html += "@media (max-width: 768px) { .devices-grid { grid-template-columns: 1fr; } }";
html += "</style>";
html += "<script>";
html += "function updateSlider(val) { document.getElementById('fanValue').innerHTML = val + '%'; }";
html += "function setFan() { var speed = document.getElementById('fanSlider').value; ";
html += "fetch('/fan/set?speed=' + speed).then(() => location.reload()); }";
html += "setInterval(() => fetch('/status').then(r => r.json()).then(data => {";
html += "document.getElementById('temp').innerHTML = data.temperature.toFixed(1);";
html += "document.getElementById('humid').innerHTML = data.humidity.toFixed(1);";
html += "}), 3000);";
html += "</script>";
html += "</head><body>";
html += "<div class='container'>";
// Header
html += "<h1>🏠 Smart Home Control Panel</h1>";
html += "<div class='subtitle'>Remote Device Management System</div>";
// Environment Stats
html += "<div class='stats'>";
html += "<div class='stat-card'>";
html += "<div class='stat-value' id='temp'>" + String(devices.temperature, 1) + "</div>";
html += "<div class='stat-label'>Temperature °C</div>";
html += "</div>";
html += "<div class='stat-card'>";
html += "<div class='stat-value' id='humid'>" + String(devices.humidity, 1) + "</div>";
html += "<div class='stat-label'>Humidity %</div>";
html += "</div>";
html += "<div class='stat-card'>";
html += "<div class='stat-value'>" + String(WiFi.RSSI()) + "</div>";
html += "<div class='stat-label'>WiFi Signal dBm</div>";
html += "</div>";
html += "</div>";
// Devices Grid
html += "<div class='devices-grid'>";
// Living Room Light
html += "<div class='device-card'>";
html += "<div class='device-header'>";
html += "<div><div class='device-icon'>💡</div><div class='device-name'>Living Room</div></div>";
html += "</div>";
html += "<div class='device-status'>";
html += "<span class='status-indicator " + String(devices.livingRoomLight ? "status-on" : "status-off") + "'></span>";
html += String(devices.livingRoomLight ? "Currently ON" : "Currently OFF");
html += "</div>";
html += "<div class='controls'>";
html += "<a href='/living-room/on' class='btn btn-on'>Turn ON</a>";
html += "<a href='/living-room/off' class='btn btn-off'>Turn OFF</a>";
html += "</div>";
html += "</div>";
// Bedroom Light
html += "<div class='device-card'>";
html += "<div class='device-header'>";
html += "<div><div class='device-icon'>🛏️</div><div class='device-name'>Bedroom</div></div>";
html += "</div>";
html += "<div class='device-status'>";
html += "<span class='status-indicator " + String(devices.bedroomLight ? "status-on" : "status-off") + "'></span>";
html += String(devices.bedroomLight ? "Currently ON" : "Currently OFF");
html += "</div>";
html += "<div class='controls'>";
html += "<a href='/bedroom/on' class='btn btn-on'>Turn ON</a>";
html += "<a href='/bedroom/off' class='btn btn-off'>Turn OFF</a>";
html += "</div>";
html += "</div>";
// Fan with Speed Control
html += "<div class='device-card'>";
html += "<div class='device-header'>";
html += "<div><div class='device-icon'>🌀</div><div class='device-name'>Ceiling Fan</div></div>";
html += "</div>";
html += "<div class='device-status'>";
html += "<span class='status-indicator " + String(devices.fanSpeed > 0 ? "status-on" : "status-off") + "'></span>";
html += "Speed: " + String(devices.fanSpeed) + "%";
html += "</div>";
html += "<div class='slider-container'>";
html += "<input type='range' min='0' max='100' value='" + String(devices.fanSpeed) + "' ";
html += "class='slider' id='fanSlider' oninput='updateSlider(this.value)'>";
html += "<div class='slider-value' id='fanValue'>" + String(devices.fanSpeed) + "%</div>";
html += "</div>";
html += "<div class='controls'>";
html += "<button onclick='setFan()' class='btn btn-action'>Apply Speed</button>";
html += "</div>";
html += "</div>";
// Heater
html += "<div class='device-card'>";
html += "<div class='device-header'>";
html += "<div><div class='device-icon'>🔥</div><div class='device-name'>Heater</div></div>";
html += "</div>";
html += "<div class='device-status'>";
html += "<span class='status-indicator " + String(devices.heater ? "status-on" : "status-off") + "'></span>";
html += String(devices.heater ? "Currently ON" : "Currently OFF");
html += "</div>";
html += "<div class='controls'>";
html += "<a href='/heater/on' class='btn btn-on'>Turn ON</a>";
html += "<a href='/heater/off' class='btn btn-off'>Turn OFF</a>";
html += "</div>";
html += "</div>";
// Door Lock
html += "<div class='device-card'>";
html += "<div class='device-header'>";
html += "<div><div class='device-icon'>🚪</div><div class='device-name'>Door Lock</div></div>";
html += "</div>";
html += "<div class='device-status'>";
html += "<span class='status-indicator " + String(devices.doorLock ? "status-on" : "status-off") + "'></span>";
html += String(devices.doorLock ? "🔒 LOCKED" : "🔓 UNLOCKED");
html += "</div>";
html += "<div class='controls'>";
html += "<a href='/door/lock' class='btn btn-warning'>🔒 Lock</a>";
html += "<a href='/door/unlock' class='btn btn-off'>🔓 Unlock</a>";
html += "</div>";
html += "</div>";
html += "</div>"; // End devices grid
// Quick Actions
html += "<div class='quick-actions'>";
html += "<h3>⚡ Quick Actions</h3>";
html += "<div class='controls'>";
html += "<a href='/all/on' class='btn btn-on'>Turn All Lights ON</a>";
html += "<a href='/all/off' class='btn btn-off'>Turn All Lights OFF</a>";
html += "<a href='/logout' class='btn btn-action'>Logout</a>";
html += "</div>";
html += "</div>";
html += "<div style='text-align: center; margin-top: 30px; opacity: 0.7; font-size: 0.9em;'>";
html += "IP: " + WiFi.localIP().toString() + " | Uptime: " + String(millis()/1000) + "s";
html += "</div>";
html += "</div></body></html>";
return html;
}
void handleLogin() {
server.send(200, "text/html", "Login handled by HTTP Basic Auth");
}
void handleLogout() {
server.send(401, "text/html", "Logged out. Please refresh the page.");
}
void handleDeviceControl(String device, bool state) {
if (!server.authenticate(webUsername, webPassword)) {
return server.requestAuthentication();
}
if (device == "living-room") {
devices.livingRoomLight = state;
} else if (device == "bedroom") {
devices.bedroomLight = state;
} else if (device == "heater") {
devices.heater = state;
}
applyDeviceStates();
playClickSound();
Serial.print(device);
Serial.print(" turned ");
Serial.println(state ? "ON" : "OFF");
server.sendHeader("Location", "/");
server.send(303);
}
void handleFanControl() {
if (!server.authenticate(webUsername, webPassword)) {
return server.requestAuthentication();
}
if (server.hasArg("speed")) {
devices.fanSpeed = server.arg("speed").toInt();
devices.fanSpeed = constrain(devices.fanSpeed, 0, 100);
applyDeviceStates();
playClickSound();
Serial.print("Fan speed set to: ");
Serial.println(devices.fanSpeed);
}
server.sendHeader("Location", "/");
server.send(303);
}
void handleDoorControl(bool lock) {
if (!server.authenticate(webUsername, webPassword)) {
return server.requestAuthentication();
}
devices.doorLock = lock;
applyDeviceStates();
// Play different sound for door
if (lock) {
tone(BUZZER_PIN, 1200, 100);
delay(150);
tone(BUZZER_PIN, 1000, 100);
} else {
tone(BUZZER_PIN, 800, 100);
delay(150);
tone(BUZZER_PIN, 600, 100);
}
Serial.print("Door ");
Serial.println(lock ? "LOCKED" : "UNLOCKED");
server.sendHeader("Location", "/");
server.send(303);
}
void handleAllOn() {
if (!server.authenticate(webUsername, webPassword)) {
return server.requestAuthentication();
}
devices.livingRoomLight = true;
devices.bedroomLight = true;
applyDeviceStates();
playClickSound();
Serial.println("All lights turned ON");
server.sendHeader("Location", "/");
server.send(303);
}
void handleAllOff() {
if (!server.authenticate(webUsername, webPassword)) {
return server.requestAuthentication();
}
devices.livingRoomLight = false;
devices.bedroomLight = false;
devices.heater = false;
devices.fanSpeed = 0;
applyDeviceStates();
playClickSound();
Serial.println("All devices turned OFF");
server.sendHeader("Location", "/");
server.send(303);
}
void handleControl() {
if (!server.authenticate(webUsername, webPassword)) {
return server.requestAuthentication();
}
String html = "<h1>Control Panel</h1>";
server.send(200, "text/html", html);
}
void handleStatus() {
String json = "{";
json += "\"livingRoomLight\":" + String(devices.livingRoomLight ? "true" : "false") + ",";
json += "\"bedroomLight\":" + String(devices.bedroomLight ? "true" : "false") + ",";
json += "\"fanSpeed\":" + String(devices.fanSpeed) + ",";
json += "\"heater\":" + String(devices.heater ? "true" : "false") + ",";
json += "\"doorLock\":" + String(devices.doorLock ? "true" : "false") + ",";
json += "\"temperature\":" + String(devices.temperature, 2) + ",";
json += "\"humidity\":" + String(devices.humidity, 2) + ",";
json += "\"uptime\":" + String(millis() / 1000);
json += "}";
server.send(200, "application/json", json);
}

Comments
Post a Comment