Skip to content

Instantly share code, notes, and snippets.

@brennanMKE
Created January 15, 2024 07:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save brennanMKE/460f95912311442f6fbb13e668a8a7ba to your computer and use it in GitHub Desktop.
Save brennanMKE/460f95912311442f6fbb13e668a8a7ba to your computer and use it in GitHub Desktop.
ESP32 controller for lights

ESP32 controller for lights

A lot can be done with an ESP32. This code will announce a network name and add a service for handling lights. It then runs a web server with a few endpoints to get version and get and set the lights mode. Once the code is built and running on an ESP32 on your network you can run the commands below.

This was done in Arduino IDE and it uses a library named AutomaticNetworking which was placed in the libraries folder where Arduino looks when building. Update the code to include any Access Points you will be using which can include a password or not.

dns-sd -B _mylights._tcp local

curl http://mylights.local/version

curl http://mylights.local/light-mode

curl -X POST http://mylights.local/light-mode \
     -H "Content-Type: application/json" \
     -d '{"color": "#FF0000", "mode": "static"}'

You can run multiple ESP32s with this code so that you can name each one and use it control LED lights. A web page or even an app could interact with this REST API to get the version and current light mode for each of the discovered controllers.

What it does not do is any security so anyone on the WiFi network can reach and interact with it. It could be set up with a self-signed certificate to run with SSL/TSL on port 443 and control access by some system that the controller syncs with to authorize access. This code is just a proof of concept as a starting point.

#include "AutomaticNetworking.h"
#define ATTEMPT_MAX 10
#define ATTEMPT_DELAY 500
AutomaticNetworking::AutomaticNetworking() {
// Constructor - You can initialize variables here if needed
}
bool AutomaticNetworking::connect() {
wifiMulti.addAP("PaddysPub", "Charlie"); // Home WiFi
wifiMulti.addAP("ParkingLot", NULL); // Open WiFi
// Attempt to connect to the WiFi network
Serial.println("Connecting to WiFi...");
int attempts = 0;
while (wifiMulti.run() != WL_CONNECTED && attempts < ATTEMPT_MAX) {
delay(ATTEMPT_DELAY);
Serial.print(".");
attempts++;
}
if (wifiMulti.run() != WL_CONNECTED) {
Serial.println("Failed to connect to WiFi");
return false;
}
Serial.println("");
Serial.println("Connected to WiFi");
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());
return true;
}
String AutomaticNetworking::startMDNS(String hostname) {
int attempt = 0;
while (attempt < 100) { // Limiting the number of attempts to 100
String attemptedName = attempt == 0 ? hostname : hostname + String(attempt);
if (MDNS.begin(attemptedName.c_str())) {
return attemptedName; // Successfully started mDNS with this hostname
} else {
Serial.println("Conflict with hostname: " + attemptedName);
attempt++;
MDNS.end(); // End the previous mDNS session before starting a new one
}
}
return String(); // Return a null String if failed to start mDNS
}
#ifndef AutomaticNetworking_h
#define AutomaticNetworking_h
#include "Arduino.h"
#include <WiFi.h>
#include <WiFiMulti.h>
#include <ESPmDNS.h>
class AutomaticNetworking {
public:
AutomaticNetworking();
bool connect();
String startMDNS(String hostname);
private:
WiFiMulti wifiMulti;
};
#endif
#include <AutomaticNetworking.h>
#include <WebServer.h>
AutomaticNetworking autoNet;
bool connected = false;
WebServer server(80);
void setup() {
Serial.begin(115200);
connected = autoNet.connect();
if (connected) {
Serial.println("Connected and Ready");
String mdnsHostname = autoNet.startMDNS("mylights");
if (mdnsHostname.length() > 0) {
Serial.println("mDNS started with hostname: " + mdnsHostname + ".local");
} else {
Serial.println("Failed to start mDNS after multiple attempts.");
}
}
setupWebServer();
MDNS.addService("mylights", "tcp", 80);
}
void loop() {
if (!connected) {
return;
}
server.handleClient();
}
void setupWebServer() {
server.on("/version", HTTP_GET, handleVersion);
server.on("/light-mode", HTTP_GET, handleGetLightMode);
server.on("/light-mode", HTTP_POST, handlePostLightMode);
server.begin();
}
void handleVersion() {
Serial.println("Changing lights version");
server.send(200, "application/json", "{\"lights-version\": \"1.0\"}");
}
void handleGetLightMode() {
// Example response: {"color": "#FF0000", "mode": "static"}
// Replace this with the actual logic to get the current light mode
Serial.println("Returning lights mode");
server.send(200, "application/json", "{\"color\": \"#FF0000\", \"mode\": \"static\"}");
}
void handlePostLightMode() {
if (server.hasArg("plain") == false) {
server.send(400, "application/json", "{\"success\": false, \"message\": \"Bad Request\"}");
return;
}
// Get the JSON payload from the request body
String payload = server.arg("plain");
// Here, you should parse the JSON payload and use it to set the light mode.
// For simplicity, the parsing part is not shown here.
// You can use the ArduinoJson library for parsing.
Serial.println("Changing lights mode");
// Assuming the light mode is set successfully
server.send(200, "application/json", "{\"success\": true}");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment