#include #include #include #include #include #include #include #include #include #include #include #include #include #include #define ONE_WIRE_BUS D1 // char wifiMultiSSID[30]; #include using namespace std; SoftwareSerial s(D3, D2); //RX.TX static char temperaturesJson[200]; static char rtcDate[10]; OneWire oneWire(ONE_WIRE_BUS); DallasTemperature sensors(&oneWire); const int SENSOR_RESOLUTION = 12; unsigned long lastTempRequest = 0; const unsigned int delayInMillisSensors = 750 / (1 << (12 - SENSOR_RESOLUTION)); ESP8266WiFiMulti wifiMulti; // Create an instance of the ESP8266WiFiMulti class, called 'wifiMulti' ESP8266WebServer server(300); // create a web server on port 80 WebSocketsServer webSocket(301); // create a websocket server on port 81 File fsUploadFile; // a File variable to temporarily store the received file const char *ssid = "ESP8266 Access Point"; // The name of the Wi-Fi network that will be created const char *password = "thereisnospoon"; // The password required to connect to it, leave blank for an open network const char *OTAName = "ESP8266"; // A name and a password for the OTA service const char *OTAPassword = "esp8266"; const size_t JSON_BUFFER_SIZE = JSON_ARRAY_SIZE(3) + JSON_OBJECT_SIZE(2) + 3 * JSON_OBJECT_SIZE(5) + 180; // #define LED_RED 15 // specify the pins with an RGB LED connected // #define LED_GREEN 12 // #define LED_BLUE 13 #define ARDUINO_TO_ESP_PIN D0 // #define ESP_TO_ARDUINO_PIN D2 byte currentArduinoState; byte previousArduinoState; const char *mdnsName = "esp8266"; // Domain name for the mDNS responder /*__________________________________________________________SETUP__________________________________________________________*/ void setup() { // pinMode(LED_RED, OUTPUT); // the pins with LEDs connected are outputs // pinMode(LED_GREEN, OUTPUT); // pinMode(LED_BLUE, OUTPUT); Serial.begin(115200); Log.begin(LOG_LEVEL_VERBOSE, &Serial); Log.setPrefix(printTimestamp); // Uncomment to get timestamps as prefix Log.setSuffix(printNewline); // Uncomment to get newline as suffix // Serial << "Starting up ESP light controller with log level = " << Log.getLevel(); // gdbstub_init(); Serial << "Hello" << endl; pinMode(ARDUINO_TO_ESP_PIN, INPUT); // pinMode(ESP_TO_ARDUINO_PIN, OUTPUT); // digitalWrite(ESP_TO_ARDUINO_PIN, 1); s.begin(9600); // Start the Serial communication to send messages to the computer delay(10); Serial.println("\r\n"); startWiFi(); // Start a Wi-Fi access point, and try to connect to some given access points. Then wait for either an AP or STA connection startOTA(); // Start the OTA service startSPIFFS(); // Start the SPIFFS and list all contents startWebSocket(); // Start a WebSocket server startMDNS(); // Start the mDNS responder startServer(); // Start a HTTP server with a file read handler and an upload handler Serial.println(); sensors.begin(); sensors.setWaitForConversion(false); sensors.requestTemperatures(); // delayInMillisSensors = 750 / (1 << (12 - SENSOR_RESOLUTION)); // delayInMillisSensors = 1000; lastTempRequest = millis(); } /*__________________________________________________________LOOP__________________________________________________________*/ bool rainbow = false; // The rainbow effect is turned off on startup //bool arduinoON = false; unsigned long prevMillis = millis(); int hue = 0; void loop() { // // digitalWrite(ESP_TO_ARDUINO_PIN, 0); // webSocket.loop(); // constantly check for websocket events server.handleClient(); // run the server ArduinoOTA.handle(); // listen for OTA events previousArduinoState = currentArduinoState; currentArduinoState = digitalRead(ARDUINO_TO_ESP_PIN); if (previousArduinoState == LOW && currentArduinoState == HIGH) { // Serial.println("Arduino turned on"); Log.notice("Arduino turned on"); //arduinoON = true; //combineSettings(); displayCombinedSettings(); Log.notice("Settings sent to arduino"); } // if (rainbow) // { // if the rainbow effect is turned on // if (millis() > prevMillis + 32) // { // if (++hue == 360) // Cycle through the color wheel (increment by one degree every 32 ms) // hue = 0; // setHue(hue); // Set the RGB LED to the right color // prevMillis = millis(); // } // } if (s.available() > 0) { // Serial << F("Received JSON from arduino") << endl; // Serial << F("Inside second if ") << endl; // StaticJsonBuffer<100> jsonBuffer; // Log.notice(F("Received JSON from arduino")); DynamicJsonBuffer jsonBuffer(100); // Serial << "S available = " << s.available(); JsonObject &root = jsonBuffer.parseObject(s); JsonArray &lcd_data = root["lcdData"]; // lcd_data[0]; // char a[10]; sprintf(rtcDate, lcd_data[1] | "N/A"); // root.printTo(Serial); // Serial << s.available() << endl; // s.flush(); // Serial << (char)s.read() << endl; // sensors.requestTemperatures(); // char str_temp[6]; // dtostrf(sensors.getTempCByIndex(0), 1, 1, str_temp); // sprintf(a, "%s", str_temp); // tft.drawString(str_temp, coordinates.x[3], coordinates.y[3], 2); // Serial.println(sensors.getTempCByIndex(0)); delay(50); } // sensors.requestTemperatures(); // Serial.println(sensors.getTempCByIndex(0)); // delay(1000); // Serial << F("Serial available = ") << s.available() << endl; // delay(50); // if (sensors.isConversionAvailable(0)) // { // // tft.drawString("25.5C", coordinates.x[3], coordinates.y[3], 2); // Serial << "Reading avaialable" << endl; // char b[10]; // char str_temp[6]; // dtostrf(sensors.getTempCByIndex(0), 1, 1, str_temp); // sprintf(b, "%s", str_temp); // tft.drawString(str_temp, coordinates.x[3], coordinates.y[3], 2); // Serial.println(sensors.getTempCByIndex(0)); // sensors.requestTemperatures(); // } if (millis() - lastTempRequest >= delayInMillisSensors) { // char b[10]; // char str_temp[6]; // saveTemperatureJson(); // StaticJsonBuffer<200> jsonBuffer; DynamicJsonBuffer jsonBuffer(100); JsonObject &root = jsonBuffer.createObject(); if (!root.success()) { Log.error("Error creating temperature json"); } JsonArray &temperatures = root.createNestedArray("temperatures"); // temperatures.add(sensors.getTempCByIndex(0)); // Serial << "Sensor" << endl; float temp1 = sensors.getTempCByIndex(0); // Serial << "Sensor" << endl; float temp2 = sensors.getTempCByIndex(1); temperatures.add(temp1); temperatures.add(temp2); // root.prettyPrintTo(Serial); root.prettyPrintTo(temperaturesJson); // dtostrf(sensors.getTempCByIndex(0), 1, 1, str_temp); // sprintf(b, "%s", str_temp); // tft.drawString(str_temp, coordinates.x[3], coordinates.y[3], 2); // Serial.println(sensors.getTempCByIndex(0)); // Serial << "Delay: " << delayInMillisSensors << endl; // Serial << "Requesting temperatures" << endl; sensors.requestTemperatures(); // delayInMillisSensors = 750 / (1 << (12 - SENSOR_RESOLUTION)); lastTempRequest = millis(); } } /*__________________________________________________________SETUP_FUNCTIONS__________________________________________________________*/ void startWiFi() { // Start a Wi-Fi access point, and try to connect to some given access points. Then wait for either an AP or STA connection WiFi.softAP(ssid, password); // Start the access point Serial.print("Access Point \""); Serial.print(ssid); Serial.println("\" started\r\n"); // wifiMulti.addAP(wifiMultiSSID, wifiMultiPassword); // #ifdef WIFI_SSID // const char *wifiMultiSSID = WIFI_SSID; // Serial << "Macro " << WIFI_SSID; // // wifiMulti.addAP(LC_WIFI_SSID, ""); // #else // const char *wifiMultiSSID = "ssid"; // #endif // #ifdef WIFI_PASS // const char *wifiMultiPassword = WIFI_PASS; // #else // const char *wifiMultiPassword = "password"; // #endif // wifiMulti.addAP(wifiMultiSSID, wifiMultiPassword); Serial.print(F("MAC: ")); Serial.println(WiFi.macAddress()); Serial.println("Connecting"); while (wifiMulti.run() != WL_CONNECTED && WiFi.softAPgetStationNum() < 1) { // Wait for the Wi-Fi to connect delay(250); Serial.print('.'); } Serial.println("\r\n"); if (WiFi.softAPgetStationNum() == 0) { // If the ESP is connected to an AP Serial.print("Connected to "); Serial.println(WiFi.SSID()); // Tell us what network we're connected to Serial.print("IP address:\t"); Serial.print(WiFi.localIP()); // Send the IP address of the ESP8266 to the computer } else { // If a station is connected to the ESP SoftAP Serial.print("Station connected to ESP8266 AP"); } Serial.println("\r\n"); } void startOTA() { // Start the OTA service ArduinoOTA.setHostname(OTAName); ArduinoOTA.setPassword(OTAPassword); ArduinoOTA.onStart([]() { Serial.println("Start"); // digitalWrite(LED_RED, 0); // turn off the LEDs // digitalWrite(LED_GREEN, 0); // digitalWrite(LED_BLUE, 0); }); ArduinoOTA.onEnd([]() { Serial.println("\r\nEnd"); }); ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) { Serial.printf("Progress: %u%%\r", (progress / (total / 100))); }); ArduinoOTA.onError([](ota_error_t error) { Serial.printf("Error[%u]: ", error); if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed"); else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed"); else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed"); else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed"); else if (error == OTA_END_ERROR) Serial.println("End Failed"); }); ArduinoOTA.begin(); Serial.println("OTA ready\r\n"); } void startSPIFFS() { // Start the SPIFFS and list all contents SPIFFS.begin(); // Start the SPI Flash File System (SPIFFS) Serial.println("SPIFFS started. Contents:"); { Dir dir = SPIFFS.openDir("/"); while (dir.next()) { // List the file system contents String fileName = dir.fileName(); size_t fileSize = dir.fileSize(); Serial.printf("\tFS File: %s, size: %s\r\n", fileName.c_str(), formatBytes(fileSize).c_str()); } Serial.printf("\n"); } } void startWebSocket() { // Start a WebSocket server webSocket.begin(); // start the websocket server webSocket.onEvent(webSocketEvent); // if there's an incomming websocket message, go to function 'webSocketEvent' Serial.println("WebSocket server started."); } void startMDNS() { // Start the mDNS responder MDNS.begin(mdnsName); // start the multicast domain name server Serial.print("mDNS responder started: http://"); Serial.print(mdnsName); Serial.println(".local"); } void startServer() { // Start a HTTP server with a file read handler and an upload handler server.on( "/edit.html", HTTP_POST, []() { // If a POST request is sent to the /edit.html address, // server.send(200, "text/plain", ""); server.send(200); }, handleFileUpload); // go to 'handleFileUpload' server.onNotFound(handleNotFound); // if someone requests any other file or page, go to function 'handleNotFound' // and check if the file exists server.on("/settings.html", HTTP_POST, handleSettings); server.on("/manualMode.html", HTTP_POST, handleManual); server.on("/api/get/temperatures", HTTP_GET, []() { sendCors(); server.send(200, "application/json", temperaturesJson); }); server.on("/api/get/date", HTTP_GET, []() { sendCors(); server.send(200, "text/plain", rtcDate); }); server.begin(); // start the HTTP server Serial.println("HTTP server started."); } /*__________________________________________________________SERVER_HANDLERS__________________________________________________________*/ void handleNotFound() { // if the requested file or page doesn't exist, return a 404 not found error if (!handleFileRead(server.uri())) { // check if the file exists in the flash memory (SPIFFS), if so, send it server.send(404, "application/json", "{\"status\":\"failed\",\"message\":\"Resource not found\"}"); } } bool handleFileRead(String path) { // send the right file to the client (if it exists) Serial.println("handleFileRead: " + path); if (path.endsWith("/")) path += "index.html"; // If a folder is requested, send the index file String contentType = getContentType(path); // Get the MIME type String pathWithGz = path + ".gz"; if (SPIFFS.exists(pathWithGz) || SPIFFS.exists(path)) { // If the file exists, either as a compressed archive, or normal if (SPIFFS.exists(pathWithGz)) // If there's a compressed version available path += ".gz"; // Use the compressed verion File file = SPIFFS.open(path, "r"); // Open the file size_t sent = server.streamFile(file, contentType); // Send it to the client file.close(); // Close the file again Serial.println(String("\tSent file: ") + path); return true; } Serial.println(String("\tFile Not Found: ") + path); // If the file doesn't exist, return false return false; } void sendCors() { server.sendHeader("Access-Control-Allow-Origin", "*"); server.sendHeader("Access-Control-Max-Age", "10000"); server.sendHeader("Access-Control-Allow-Methods", "PUT,POST,GET,OPTIONS"); server.sendHeader("Access-Control-Allow-Headers", "*"); } void saveTemperatureJson(DallasTemperature &sensors) { StaticJsonBuffer<200> jsonBuffer; JsonObject &root = jsonBuffer.createObject(); if (!root.success()) { Log.error("Error creating temperature json object"); } // JsonArray &data = root.createNestedArray("data"); // data.add(48); // data.add(2); JsonArray &temperatures = root.createNestedArray("temperatures"); float temp1 = sensors.getTempCByIndex(0); float temp2 = sensors.getTempCByIndex(1); temperatures.add(temp1); temperatures.add(temp2); temperatures.add(1); root.prettyPrintTo(Serial); root.prettyPrintTo(temperaturesJson); // if (SPIFFS.exists("/temperatures.txt")) // { // SPIFFS.remove("/temperatures.txt"); // Serial.println("Old settings file removed"); // } // File settingsFile = SPIFFS.open("/temperatures.txt", "w"); // if (!settingsFile) // Log.error("Error wriing json to file"); // root.prettyPrintTo(settingsFile); //Export and save JSON object to SPIFFS area // Serial.println("Json written to file"); // settingsFile.close(); } void saveSettings(ESP8266WebServer &server, int num) { Log.notice("Ballast num = %d", num); const int shour = server.arg("shour").toInt(); const int smin = server.arg("smin").toInt(); const int fadePeriod = server.arg("fadePeriod").toInt(); const int ehour = server.arg("ehour").toInt(); const int emin = server.arg("emin").toInt(); StaticJsonBuffer<200> jsonBuffer; JsonObject &root = jsonBuffer.createObject(); if (!root.success()) { Log.error("Error creating json"); return; } root["shour"] = shour; root["fadePeriod"] = fadePeriod; root["smin"] = smin; root["ehour"] = ehour; root["emin"] = emin; root.prettyPrintTo(Serial); char buf[40] = ""; sprintf(buf, "/settingsFile%d.txt", num); Log.verbose("Settings file chosen = %s", buf); if (SPIFFS.exists(buf)) { SPIFFS.remove(buf); Log.notice("Old settings file removed"); } File settingsFile = SPIFFS.open(buf, "w"); if (!settingsFile) Log.error("Error opening settings file - %d", num); root.prettyPrintTo(settingsFile); //Export and save JSON object to SPIFFS area Log.notice("Json written to file"); settingsFile.close(); // delete server; } void combineSettings() { File file1 = SPIFFS.open("/settingsFile1.txt", "r"); File file2 = SPIFFS.open("/settingsFile2.txt", "r"); File file3 = SPIFFS.open("/settingsFile3.txt", "r"); File file5 = SPIFFS.open("/manualMode.txt", "r"); // Serial.println("2"); if (SPIFFS.exists("/combinedSettingsFile.txt")) { SPIFFS.remove("/combinedSettingsFile.txt"); } File file4 = SPIFFS.open("/combinedSettingsFile.txt", "w"); size_t size1 = file1.size(), size2 = file2.size(), size3 = file3.size(), size5 = file5.size(); ; std::unique_ptr buf1(new char[size1]); std::unique_ptr buf2(new char[size2]); std::unique_ptr buf3(new char[size3]); std::unique_ptr buf5(new char[size5]); file1.readBytes(buf1.get(), size1); file2.readBytes(buf2.get(), size2); file3.readBytes(buf3.get(), size3); file5.readBytes(buf5.get(), size5); StaticJsonBuffer<100> jsonBuffer10; JsonObject &root1 = jsonBuffer10.parseObject(buf1.get()); if (root1 == JsonObject::invalid()) { Serial.println("Error1"); } StaticJsonBuffer<100> jsonBuffer11; JsonObject &root2 = jsonBuffer11.parseObject(buf2.get()); if (root2 == JsonObject::invalid()) { Serial.println("Error2"); } StaticJsonBuffer<100> jsonBuffer12; JsonObject &root3 = jsonBuffer12.parseObject(buf3.get()); if (root3 == JsonObject::invalid()) { Serial.println("Error3"); } StaticJsonBuffer<50> jsonBuffer16; JsonObject &root5 = jsonBuffer16.parseObject(buf5.get()); /*StaticJsonBuffer<300> jsonBuffer13; JsonObject& root4 = jsonBuffer13.createObject(); JsonObject& ballast1 = root4.createNestedObject(); root4["shour1"]=root1["shour1"]; root4["smin1"]=root1["smin1"]; root4["fadePeriod1"]=root1["fadePeriod1"]; root4["shour2"]=root2["shour2"]; root4["smin2"]=root2["smin2"]; root4["fadePeriod2"]=root2["fadePeriod2"]; root4["shour3"]=root3["shour3"]; root4["smin3"]=root3["smin3"]; root4["fadePeriod3"]=root3["fadePeriod3"];*/ DynamicJsonBuffer jsonBuffer(JSON_BUFFER_SIZE); JsonObject &root = jsonBuffer.createObject(); JsonArray &settings = root.createNestedArray("settings"); JsonObject &settings_0 = settings.createNestedObject(); settings_0["shour"] = root1["shour"]; settings_0["fadePeriod"] = root1["fadePeriod"]; settings_0["smin"] = root1["smin"]; settings_0["ehour"] = root1["ehour"]; settings_0["emin"] = root1["emin"]; JsonObject &settings_1 = settings.createNestedObject(); settings_1["shour"] = root2["shour"]; settings_1["fadePeriod"] = root2["fadePeriod"]; settings_1["smin"] = root2["smin"]; settings_1["ehour"] = root2["ehour"]; settings_1["emin"] = root2["emin"]; JsonObject &settings_2 = settings.createNestedObject(); settings_2["shour"] = root3["shour"]; settings_2["fadePeriod"] = root3["fadePeriod"]; settings_2["smin"] = root3["smin"]; settings_2["ehour"] = root3["ehour"]; settings_2["emin"] = root3["emin"]; root["manual"] = root5["manual"]; /*root1.printTo(file4); root1.printTo(Serial); root2.printTo(file4); root2.printTo(Serial); root3.printTo(file4); root3.printTo(Serial);*/ root.prettyPrintTo(Serial); root.prettyPrintTo(file4); // Serial.println("3"); file1.close(); file2.close(); file3.close(); file4.close(); file5.close(); } void combineSettings_new() { const File file1 = SPIFFS.open("/settingsFile1.txt", "r"); const File file2 = SPIFFS.open("/settingsFile2.txt", "r"); const File file3 = SPIFFS.open("/settingsFile3.txt", "r"); File file5 = SPIFFS.open("/manualMode.txt", "r"); if (SPIFFS.exists("/combinedSettingsFile.txt")) { SPIFFS.remove("/combinedSettingsFile.txt"); } File file_arr[] = {file1, file2, file3}; File file4 = SPIFFS.open("/combinedSettingsFile.txt", "w"); StaticJsonBuffer jsonBuffer; JsonObject &root = jsonBuffer.createObject(); JsonArray &settings = root.createNestedArray("settings"); StaticJsonBuffer<50> jsonBufferManual; size_t size_manual = file5.size(); unique_ptr buf_manual(new char[size_manual]); file5.readBytes(buf_manual.get(), size_manual); JsonObject &root_manual = jsonBufferManual.parseObject(buf_manual.get()); for (int i = 0; i < 3; i++) { const size_t file_size = file_arr[i].size(); const unique_ptr buf(new char[file_size]); file_arr[i].readBytes(buf.get(), file_size); StaticJsonBuffer<(JSON_BUFFER_SIZE / 3) + 50> jsonBuffer; JsonObject &root_i = jsonBuffer.parseObject(buf.get()); if (!root_i.success()) { Log.error(F("Error creating json for file %d"), i + 1); } else { JsonObject &settings_i = settings.createNestedObject(); settings_i["shour"] = root_i["shour"]; settings_i["fadePeriod"] = root_i["fadePeriod"]; settings_i["smin"] = root_i["smin"]; settings_i["ehour"] = root_i["ehour"]; settings_i["emin"] = root_i["emin"]; // Log.notice("inside array temp"); // char buf[JSON_BUFFER_SIZE / 3]; // root_i.prettyPrintTo(buf); // Log.trace("%s", buf); Log.trace("Printing settings %d", i + 1); // settings_i.prettyPrintTo(Serial); // root.prettyPrintTo(Serial); // settings.prettyPrintTo(Serial); file_arr[i].close(); } } root["manual"] = root_manual["manual"]; Log.trace("Printing final root"); root.prettyPrintTo(Serial); root.prettyPrintTo(file4); file4.close(); file5.close(); } /*void displaySettings() { File file = SPIFFS.open("/settingsFile.txt", "r"); if (!file){ Log.error("Error reading settings file or file does not exist"); } else { size_t size = file.size(); if ( size == 0 ) { Serial.println("Settings file is empty"); } else { std::unique_ptr buf (new char[size]); file.readBytes(buf.get(), size); StaticJsonBuffer<200> jsonBuffer2; JsonObject& root = jsonBuffer2.parseObject(buf.get()); if (!root.success()) { Log.error("Error reading settings file"); } else { Serial.println("Settings file loaded"); root.prettyPrintTo(Serial); root.printTo(s); Serial.println("Settings sent to arduino"); } } file.close(); } }*/ void displayCombinedSettings() { File file = SPIFFS.open("/combinedSettingsFile.txt", "r"); if (!file) { Log.error("Error reading combined settings file or file does not exist"); } else { Log.notice("Settings file exists"); size_t size = file.size(); if (size == 0) { Log.notice("Settings file is empty"); } else { std::unique_ptr buf5(new char[size]); file.readBytes(buf5.get(), size); // StaticJsonBuffer<300> jsonBuffer; DynamicJsonBuffer jsonBuffer(JSON_BUFFER_SIZE); JsonObject &root5 = jsonBuffer.parseObject(buf5.get()); if (!root5.success()) { Log.error("Error reading combined settings file"); } else { Log.notice("Settings file loaded"); root5.prettyPrintTo(Serial); // digitalWrite(ESP_TO_ARDUINO_PIN,0); // analogWrite(ESP_TO_ARDUINO_PIN,255); root5.printTo(s); // digitalWrite(ESP_TO_ARDUINO_PIN,1); } } file.close(); } } void handleManual() { File file = SPIFFS.open("/manualMode.txt", "w"); StaticJsonBuffer<50> jsonBufferManual; JsonObject &root = jsonBufferManual.createObject(); if (server.arg("manual") == "True") { root["manual"] = "True"; } else { root["manual"] = "False"; } root.prettyPrintTo(file); file.close(); combineSettings(); // digitalWrite(ESP_TO_ARDUINO_PIN, 1); displayCombinedSettings(); // digitalWrite(ESP_TO_ARDUINO_PIN,1); // server.sendHeader("Location", "/manualMode.html"); // Redirect the client to the success page // server.send(303); server.send(200); } void handleSettings() { // if (server.arg("ballast").toInt() == 1) // handleSettings1(); // else if (server.arg("ballast").toInt() == 2) // handleSettings2(); // else if (server.arg("ballast").toInt() == 3) // handleSettings3(); // displayCombinedSettings(); // server.sendHeader("Location", "/settings.html"); // Redirect the client to the success page const int ballast_num = server.arg("ballast").toInt(); Log.notice("Chosen num = %d", ballast_num); saveSettings(server, ballast_num); combineSettings(); displayCombinedSettings(); server.send(200); } void handleFileUpload() { // upload a new file to the SPIFFS HTTPUpload &upload = server.upload(); String path; if (upload.status == UPLOAD_FILE_START) { path = upload.filename; if (!path.startsWith("/")) path = "/" + path; if (!path.endsWith(".gz")) { // The file server always prefers a compressed version of a file String pathWithGz = path + ".gz"; // So if an uploaded file is not compressed, the existing compressed if (SPIFFS.exists(pathWithGz)) // version of that file must be deleted (if it exists) SPIFFS.remove(pathWithGz); } Serial.print("handleFileUpload Name: "); Serial.println(path); fsUploadFile = SPIFFS.open(path, "w"); // Open the file for writing in SPIFFS (create if it doesn't exist) path = String(); } else if (upload.status == UPLOAD_FILE_WRITE) { if (fsUploadFile) fsUploadFile.write(upload.buf, upload.currentSize); // Write the received bytes to the file } else if (upload.status == UPLOAD_FILE_END) { if (fsUploadFile) { // If the file was successfully created fsUploadFile.close(); // Close the file again Serial.print("handleFileUpload Size: "); Serial.println(upload.totalSize); // server.sendHeader("Location", "/success.html"); // Redirect the client to the success page server.send(201, "application/json", "{\"status\":\"success\",\"message\":\"File created successfully\"}"); } else { server.send(500, "application/json", "{\"status\":\"failed\",\"message\":\"Could not create file\"}"); } } } // const char *text = R"( // { " " // ;'' // } // qegqeg // qegq // )"; void webSocketEvent(uint8_t num, WStype_t type, uint8_t *payload, size_t lenght) { // When a WebSocket message is received switch (type) { case WStype_DISCONNECTED: // if the websocket is disconnected Serial.printf("[%u] Disconnected!\n", num); break; case WStype_CONNECTED: { // if a new websocket connection is established IPAddress ip = webSocket.remoteIP(num); Serial.printf("[%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload); rainbow = false; // Turn rainbow off when a new connection is established } break; case WStype_TEXT: // if new text data is received Serial.printf("[%u] get Text: %s\n", num, payload); if (payload[0] == '#') { // we get RGB data uint32_t rgb = (uint32_t)strtol((const char *)&payload[1], NULL, 16); // decode rgb data int r = ((rgb >> 20) & 0x3FF); // 10 bits per color, so R: bits 20-29 int g = ((rgb >> 10) & 0x3FF); // G: bits 10-19 int b = rgb & 0x3FF; // B: bits 0-9 // analogWrite(LED_RED, r); // write it to the LED output pins // analogWrite(LED_GREEN, g); // analogWrite(LED_BLUE, b); } else if (payload[0] == 'R') { // the browser sends an R when the rainbow effect is enabled rainbow = true; } else if (payload[0] == 'N') { // the browser sends an N when the rainbow effect is disabled rainbow = false; } break; default: { Log.error("Unsupported operation - number %d", type); } } } /*__________________________________________________________HELPER_FUNCTIONS__________________________________________________________*/ String formatBytes(size_t bytes) { // convert sizes in bytes to KB and MB if (bytes < 1024) { return String(bytes) + "B"; } else if (bytes < (1024 * 1024)) { return String(bytes / 1024.0) + "KB"; } else if (bytes < (1024 * 1024 * 1024)) { return String(bytes / 1024.0 / 1024.0) + "MB"; } else return ""; } String getContentType(String filename) { // determine the filetype of a given filename, based on the extension if (filename.endsWith(".html")) return "text/html"; else if (filename.endsWith(".css")) return "text/css"; else if (filename.endsWith(".js")) return "application/javascript"; else if (filename.endsWith(".ico")) return "image/x-icon"; else if (filename.endsWith(".gz")) return "application/x-gzip"; return "text/plain"; } void setHue(int hue) { // Set the RGB LED to a given hue (color) (0° = Red, 120° = Green, 240° = Blue) hue %= 360; // hue is an angle between 0 and 359° float radH = hue * 3.142 / 180; // Convert degrees to radians float rf, gf, bf; if (hue >= 0 && hue < 120) { // Convert from HSI color space to RGB rf = cos(radH * 3 / 4); gf = sin(radH * 3 / 4); bf = 0; } else if (hue >= 120 && hue < 240) { radH -= 2.09439; gf = cos(radH * 3 / 4); bf = sin(radH * 3 / 4); rf = 0; } else if (hue >= 240 && hue < 360) { radH -= 4.188787; bf = cos(radH * 3 / 4); rf = sin(radH * 3 / 4); gf = 0; } int r = rf * rf * 1023; int g = gf * gf * 1023; int b = bf * bf * 1023; // analogWrite(LED_RED, r); // Write the right color to the LED output pins // analogWrite(LED_GREEN, g); // analogWrite(LED_BLUE, b); } void printTimestamp(Print *_logOutput) { char c[12]; int m = sprintf(c, "%10lu ", millis()); _logOutput->print(c); } void printNewline(Print *_logOutput) { _logOutput->print('\n'); }