#include #include #include #include #include #include #include "FS.h" #include const char *ssid = "ESP8266-WS2812"; const char *password = ""; #define DATA_PIN 5 #define NUM_LEDS 256 CRGB leds[NUM_LEDS]; static size_t ledsSize; ESP8266WebServer server(80); WebSocketsServer ws = WebSocketsServer(8080); void ws_handle(uint8_t client, WStype_t type, uint8_t *payload, size_t length) { static char buffer[32]; switch(type) { case WStype_CONNECTED: break; case WStype_BIN: { if (length > ledsSize) { length = ledsSize; } memcpy(leds, payload, length); FastLED.show(); break; } } } const char* wifi_ssid; const char* wifi_psk; bool loadConfig() { File configFile = SPIFFS.open("/config.json", "r"); if (!configFile) { Serial.println("Failed to open config file"); return false; } size_t size = configFile.size(); if (size > 1024) { Serial.println("Config file size is too large"); return false; } std::unique_ptr buf(new char[size]); configFile.readBytes(buf.get(), size); StaticJsonDocument<1024> doc; DeserializationError error = deserializeJson(doc, buf.get()); if (error) { Serial.print("Failed to parse config file. Error: "); Serial.println(error.c_str()); return false; } wifi_ssid = doc["ssid"]; wifi_psk = doc["psk"]; Serial.print("wifi_ssid: "); Serial.println(wifi_ssid); Serial.print("wifi_psk: "); Serial.println(wifi_psk); return true; } void ap_start() { Serial.println("Configuring access point..."); WiFi.softAP(ssid, password); IPAddress ip = WiFi.softAPIP(); Serial.print("AP IP address: "); Serial.println(ip); } void setup() { pinMode(5, OUTPUT); Serial.begin(115200); Serial.println(); Serial.println("WS2812 " __DATE__ " " __TIME__); delay(1000); Serial.println("Mounting FS..."); if (!SPIFFS.begin()) { Serial.println("Failed to mount file system"); return; } if (!loadConfig()) { Serial.println("Failed to load config"); ap_start(); } else { Serial.println("Config loaded"); Serial.print("Connecting to "); Serial.println(ssid); WiFi.mode(WIFI_STA); WiFi.begin(wifi_ssid, wifi_psk); int i = 10; while (WiFi.status() != WL_CONNECTED) { delay(1000); i--; if (i <= 0) break; Serial.print("."); } if (WiFi.status() == WL_CONNECTED) { Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); } else { Serial.println("WiFi connection failed"); ap_start(); } } // start webSocket server ws.begin(); ws.onEvent(ws_handle); server.on("/", HTTP_GET, []() { server.send(200, "text/html", "" "" "" ""); }); server.on("/info", HTTP_GET, []() { server.send(200, "application/json", "{ \"name\": \"WS2812\", \"websocket_port\": 8080 }"); }); server.on("/config", HTTP_GET, []() { server.send(200, "application/json", "{}"); }); server.on("/config/edit", HTTP_GET, []() { server.send(200, "text/html", "" "" "" ""); }); server.on("/config", HTTP_POST, []() { if (server.hasArg("ssid")) { wifi_ssid = server.arg("ssid").c_str(); } if (server.hasArg("psk")) { wifi_psk = server.arg("psk").c_str(); } StaticJsonDocument<1024> doc; doc["ssid"] = wifi_ssid; doc["psk"] = wifi_psk; File configFile = SPIFFS.open("/config.json", "w"); if (configFile) { serializeJson(doc, configFile); server.send(200); } else { Serial.println("Failed to open config file for writing"); server.send(500); } }); server.on("/", HTTP_POST, []() { }); server.begin(); Serial.println("HTTP server started"); FastLED.addLeds(leds, NUM_LEDS); ledsSize = sizeof(leds) / sizeof(leds[0]); Serial.println("FastLED initialized"); } void loop() { ws.loop(); server.handleClient(); }