A powerful ESP32-based home automation controller that provides WebSocket and REST API interfaces for controlling multiple relays. Perfect for smart home applications, lighting control, and IoT projects.
- Multi-Relay Control: Support for multiple relays with individual control
- WebSocket Interface: Real-time bidirectional communication
- REST API: Standard HTTP endpoints for easy integration
- JSON Protocol: Modern, structured command format
- mDNS Discovery: Automatic device discovery on local network
- Status Monitoring: Real-time relay status reporting
- CORS Enabled: Ready for web and mobile app integration
- Relay 1: GPIO 18 - "Living Light" (Living room main lighting)
- Relay 2: GPIO 19 - "Bedroom Light" (Master bedroom tube light)
- Status LED: GPIO 2 - Built-in LED for connection status
Update the credentials in main.cpp
:
const char *ssid = "Your-WiFi-SSID";
const char *password = "Your-WiFi-Password";
- PlatformIO IDE or CLI
- ESP32 development board
- Relay modules or LEDs for testing
- Clone or download this project
- Open in PlatformIO
- Update Wi-Fi credentials in
src/main.cpp
- Build and upload to ESP32
- Monitor serial output for IP address
Once uploaded and connected to Wi-Fi, the device will print its IP address. You can:
- Access web interface:
http://[ESP32_IP]/
- View device info:
http://[ESP32_IP]/info
- Connect WebSocket:
ws://[ESP32_IP]/ws
Connect to: ws://[ESP32_IP]/ws
All WebSocket commands use JSON format:
{
"relay_id": 1,
"action": "on"
}
Parameters:
relay_id
: Integer (1-N, where N is number of relays)action
: String - "on", "off", "toggle", "status"
Response:
{
"status": "success",
"relay_id": 1,
"action": "on",
"state": true
}
{
"action": "all_on"
}
Actions:
all_on
: Turn on all relaysall_off
: Turn off all relaysstatus
: Get status of all relays
Response:
{
"status": "success",
"action": "all_on",
"message": "All relays turned ON"
}
{
"action": "status"
}
Response:
{
"relays": [
{
"id": 1,
"name": "Living Light",
"description": "Living room main lighting",
"pin": 18,
"state": false
},
{
"id": 2,
"name": "Bedroom Light",
"description": "Master bedroom tube light",
"pin": 19,
"state": true
}
]
}
Base URL: http://[ESP32_IP]
Returns HTML interface with device status
Returns device information and relay status
Response:
{
"device_name": "ESP32 Controller",
"device_type": "home_automation",
"ip_address": "192.168.1.100",
"mac_address": "AA:BB:CC:DD:EE:FF",
"num_relays": 2,
"relays": [
{
"id": 1,
"name": "Living Light",
"description": "Living room main lighting",
"pin": 18,
"state": false
}
]
}
Get status of all relays
Response:
{
"relays": [
{
"id": 1,
"name": "Living Light",
"description": "Living room main lighting",
"pin": 18,
"state": false
},
{
"id": 2,
"name": "Bedroom Light",
"description": "Master bedroom tube light",
"pin": 19,
"state": true
}
]
}
Get status of specific relay
Parameters:
id
: Relay ID (1-N)
Response:
{
"id": 1,
"name": "Living Light",
"description": "Living room main lighting",
"pin": 18,
"state": false
}
Control individual relay
Parameters:
id
: Relay ID (1-N)action
: "on", "off", or "toggle"
Example:
POST /api/relay/control?id=1&action=on
Response:
{
"success": true,
"relay": 1,
"state": true
}
Control all relays
Parameters:
action
: "on" or "off"
Example:
POST /api/relays/all?action=on
Response:
{
"success": true,
"message": "All relays turned ON"
}
{
"status": "error",
"message": "Invalid relay_id. Must be between 1 and 2"
}
{
"error": "Invalid relay ID. Must be between 1 and 2"
}
Common Error Codes:
400
: Bad Request (invalid parameters)404
: Not Found (invalid endpoint)
// WebSocket connection
const ws = new WebSocket('ws://192.168.1.100/ws');
// Turn on relay 1
ws.send(JSON.stringify({
relay_id: 1,
action: "on"
}));
// Get status
ws.send(JSON.stringify({
action: "status"
}));
// Handle responses
ws.onmessage = function(event) {
const data = JSON.parse(event.data);
console.log('Response:', data);
};
import requests
import json
# Device IP
BASE_URL = "http://192.168.1.100"
# Turn on relay 1
response = requests.post(f"{BASE_URL}/api/relay/control",
params={"id": 1, "action": "on"})
print(response.json())
# Get all relay status
response = requests.get(f"{BASE_URL}/api/relays")
print(response.json())
# Turn off all relays
response = requests.post(f"{BASE_URL}/api/relays/all",
params={"action": "off"})
print(response.json())
# Get device info
curl http://192.168.1.100/info
# Turn on relay 1
curl -X POST "http://192.168.1.100/api/relay/control?id=1&action=on"
# Get relay status
curl http://192.168.1.100/api/relays
# Turn off all relays
curl -X POST "http://192.168.1.100/api/relays/all?action=off"
- Update
NUM_RELAYS
constant - Add relay configurations to the
relays[]
array:
const int NUM_RELAYS = 4;
Relay relays[NUM_RELAYS] = {
{18, false, "Living Light", "Living room main lighting"},
{19, false, "Bedroom Light", "Master bedroom tube light"},
{21, false, "Kitchen Light", "Kitchen lighting"},
{22, false, "Office Light", "Office lighting"},
};
const char *deviceName = "My ESP32 Controller";
Update the pin
values in the relay configuration array.
The device supports mDNS for automatic discovery:
- Device name:
ESP32_Controller.local
- Services: HTTP (port 80), WebSocket (port 80)
-
Device not connecting to Wi-Fi
- Check SSID and password
- Ensure 2.4GHz network (ESP32 doesn't support 5GHz)
- Check signal strength
-
Cannot access web interface
- Verify IP address from serial monitor
- Check firewall settings
- Ensure device and client on same network
-
WebSocket connection fails
- Verify WebSocket URL format:
ws://IP/ws
- Check for proxy or firewall blocking
- Use browser developer tools to debug
- Verify WebSocket URL format:
-
Relays not responding
- Check GPIO pin connections
- Verify relay module power supply
- Test with multimeter for voltage output
Enable serial monitoring (115200 baud) to see:
- Connection status
- Command processing
- Error messages
- System status updates
- WiFi (ESP32 core)
- AsyncTCP
- ESPAsyncWebServer
- ArduinoJson
- ESPmDNS
# Using PlatformIO CLI
pio run
# Upload to device
pio run --target upload
# Monitor serial output
pio device monitor
This project is licensed under the MIT License - see the LICENSE file for details.