A complete IoT solution for remote relay control, consisting of ESP32 firmware and an example web server. The ESP32 device polls a server for commands via HTTP GET requests and sends acknowledgments via HTTP POST, enabling reliable remote control of relays over the internet.
-
ESP32 Firmware
- WiFi Station mode with automatic reconnection
- HTTP polling mechanism (every 2 seconds)
- Embedded web server for local control
- UART command interface
- JSON-based command protocol
- Automatic relay timer (duration-based control)
- Command acknowledgment (ACK) via HTTP POST
- Persistent storage (NVS) for WiFi credentials and server URL
- LED status indicator for WiFi connection
-
Example Server (Blazor)
- Modern web interface for relay control
- RESTful API endpoints for ESP32 communication
- Command queuing and acknowledgment tracking
- Real-time state updates
- Responsive UI with dark theme
- Architecture
- Quick Start
- Project Structure
- Components
- API Documentation
- JSON Protocol
- Hardware Requirements
- Documentation
- License
- Contributing
βββββββββββββββββββ
β Web Browser β
β (Blazor UI) β
ββββββββββ¬βββββββββ
β HTTP
βΌ
βββββββββββββββββββ HTTP GET (poll every 2s) βββββββββββββββ
β Example Server β ββββββββββββββββββββββββββββββββββ β ESP32 β
β (Blazor/.NET) β β Firmware β
ββββββββββ¬βββββββββ HTTP POST (ACK) ββββββββ¬ββββββββ
β β
β Queue Commands β GPIO
β βΌ
β βββββββββββββββ
β β Relays β
β β (GPIO 16/17)β
β βββββββββββββββ
β
ββββ Command Acknowledgment βββββ
- User Action: User clicks a button in the web interface
- Command Queue: Server queues the command with a unique
command_id - ESP32 Polling: ESP32 polls
/api/relayevery 2 seconds via HTTP GET - Command Delivery: Server returns the queued command as JSON
- Command Execution: ESP32 parses JSON and controls relays via GPIO
- Acknowledgment: ESP32 sends ACK via HTTP POST with
command_id - State Update: Server updates UI state upon receiving ACK
For ESP32 Firmware:
- ESP-IDF v5.0 or later
- Python 3.6+
- CMake 3.16+
- ESP32 development board
For Example Server:
- .NET 10.0 SDK or later
- Visual Studio 2022 / VS Code / Rider (optional)
-
Build and flash the firmware:
cd ESP32/firmware idf.py build idf.py -p COM3 flash monitor -
Configure WiFi via UART (115200 baud):
SSID=YourWiFiNetwork WIFIPASS=YourPassword -
Get IP address:
IP? -
Configure server URL:
URL=http://your-server-ip:5000/api/relay
For detailed instructions, see ESP32 Firmware README.
-
Navigate to server directory:
cd ExampleServer/WebRelay.Server.Example.Blazor -
Run the server:
dotnet run
-
Access the web interface:
- Open browser:
http://localhost:5000(or the port shown in console)
- Open browser:
-
Configure ESP32:
- Set the ESP32 URL to:
http://<your-computer-ip>:5000/api/relay - Ensure ESP32 and server are on the same network (or use port forwarding)
- Set the ESP32 URL to:
web-relay/
βββ ESP32/
β βββ firmware/ # ESP32 firmware source code
β βββ main/
β β βββ inc/ # Header files
β β βββ src/ # Source files
β βββ CMakeLists.txt
β βββ sdkconfig
β βββ README.md # Detailed ESP32 documentation
β
βββ ExampleServer/
β βββ WebRelay.Server.Example.Blazor/ # Example Blazor server
β βββ Components/ # Blazor components
β βββ Endpoints/ # API endpoints
β βββ Services/ # Business logic
β βββ Program.cs # Application entry point
β
βββ LICENSE
βββ README.md # This file
The ESP32 firmware provides:
- WiFi Management: Connection, reconnection, credential storage
- HTTP Client: Polling server for commands, sending ACKs
- Web Server: Local web interface for direct control
- UART Interface: Serial command interface for configuration
- Relay Control: GPIO control for 2 relays
- JSON Parser: Processes server commands
Key Files:
main.c: Application entry point and main loophttp.c: HTTP client implementationwebserver.c: Embedded HTTP serverserver.c: JSON parsing and command executionwifi.c: WiFi connection managementrelay.c: GPIO relay control
See ESP32 Firmware README for complete documentation.
A .NET 10.0 Blazor Server application that demonstrates:
- Command queuing for ESP32 polling
- RESTful API endpoints
- Real-time web interface
- Command acknowledgment tracking
Key Components:
RelayEndpoints.cs: API endpoints (/api/relay)RelayCommandService.cs: Command queue and state managementHome.razor: Web UI for relay control
API Endpoints:
GET /api/relay: Returns queued command (polled by ESP32)POST /api/relay: Receives acknowledgment from ESP32GET /: Web interface for relay control
Returns the next queued command for ESP32.
Response:
- 200 OK with JSON command (if command queued)
- 200 OK with
{}(if no command queued)
Example Response:
{
"command_id": "abc12345",
"relay1": {
"state": 1,
"duration": 5000
}
}Receives acknowledgment from ESP32.
Request Body:
{
"command_id": "abc12345",
"status": "received"
}Response:
- 200 OK: Acknowledgment received
The ESP32 also runs a local web server (port 80):
GET /: Main control pageGET /relay1/on: Turn Relay 1 ONGET /relay1/off: Turn Relay 1 OFFGET /relay2/on: Turn Relay 2 ONGET /relay2/off: Turn Relay 2 OFFPOST /seturl: Set server URL
Commands sent from server to ESP32:
{
"command_id": "unique-id-8-chars",
"relay1": {
"state": 1,
"duration": 5000
},
"relay2": {
"state": 0
}
}Fields:
command_id(string, optional): Unique identifier for acknowledgmentrelay1(object, optional): Command for Relay 1relay2(object, optional): Command for Relay 2
Relay Object:
state(integer, required):1= ON,0= OFFduration(integer, optional): Auto-off duration in milliseconds (only whenstateis1)
ACK sent from ESP32 to server:
{
"command_id": "unique-id-8-chars",
"status": "received"
}Turn Relay 1 ON for 5 seconds:
{
"command_id": "cmd001",
"relay1": {
"state": 1,
"duration": 5000
}
}Turn Relay 2 OFF:
{
"command_id": "cmd002",
"relay2": {
"state": 0
}
}No command (empty response):
{}- ESP32-WROOM-32 or compatible
- USB cable for programming
- Power supply (5V via USB or external)
- 2 relay modules (active HIGH or LOW compatible)
- Connected to:
- Relay 1: GPIO 16
- Relay 2: GPIO 17
- LED for WiFi status indication
- Breadboard and jumper wires
| Function | GPIO Pin |
|---|---|
| Relay 1 | GPIO 16 |
| Relay 2 | GPIO 17 |
| UART TX | GPIO 1 |
| UART RX | GPIO 3 |
- ESP32 Firmware README: Complete ESP32 firmware documentation
- Building instructions
- Programming guide
- UART commands
- Web server API
- JSON protocol details
- Troubleshooting
cd ESP32/firmware
idf.py buildcd ExampleServer/WebRelay.Server.Example.Blazor
dotnet run- Modify ESP32 firmware: Edit files in
ESP32/firmware/main/src/ - Build and flash:
idf.py build flash monitor - Modify server: Edit files in
ExampleServer/ - Test: Use web interface or API directly
- Connect ESP32 to serial monitor
- Use UART commands:
relay1 on relay2 off IP?
# Get command (should return {})
curl http://localhost:5000/api/relay
# Send ACK
curl -X POST http://localhost:5000/api/relay \
-H "Content-Type: application/json" \
-d '{"command_id":"test123","status":"received"}'- Start the example server
- Configure ESP32 with server URL
- Click buttons in web interface
- Monitor ESP32 serial output for command execution
- Verify relay states update in web UI after ACK
- WiFi not connecting: Check SSID/password, verify 2.4 GHz network
- HTTP polling not working: Verify URL is set, check server accessibility
- Relays not responding: Check GPIO connections, verify relay module power
See ESP32 Firmware README - Troubleshooting for detailed solutions.
- Port already in use: Change port in
appsettings.jsonorlaunchSettings.json - ESP32 can't reach server: Ensure same network or configure port forwarding
- Commands not executing: Check ESP32 serial monitor for errors
ESP32 accepts commands via UART (115200 baud):
Relay Control:
relay1 on/relay1 offrelay2 on/relay2 offled on/led off
WiFi Configuration:
SSID=<ssid>- Set WiFi SSIDSSID?- Query SSIDWIFIPASS=<password>- Set passwordWIFIPASS?- Query password (masked)
Server Configuration:
URL=<url>- Set server URLURL?- Query URLIP?- Query current IP address
- The example server is for development/demo purposes only
- For production use:
- Implement authentication/authorization
- Use HTTPS (TLS) for all communications
- Secure WiFi credentials storage
- Add rate limiting to API endpoints
- Validate and sanitize all inputs
- Use secure password storage
See LICENSE file for details.
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Make your changes
- Test thoroughly
- Submit a pull request
- ESP32: Follow ESP-IDF coding standards
- C#: Follow C# coding conventions
- Include appropriate error handling and logging
- Add comments for complex logic
- ESP-IDF framework by Espressif
- .NET and Blazor by Microsoft
- cJSON library for JSON parsing
- Issues: GitHub Issues
- Documentation: See ESP32 Firmware README
Made with β€οΈ for the IoT community