From b1acf6088fead5d450ad4753e3cfc260dfc8be56 Mon Sep 17 00:00:00 2001 From: cschwinne Date: Wed, 9 Sep 2020 09:51:04 +0200 Subject: [PATCH] Presets in FS function --- wled00/const.h | 7 +++++++ wled00/fcn_declare.h | 4 ++-- wled00/file.cpp | 45 ++++++++++++++++++++++------------------- wled00/json.cpp | 8 ++++---- wled00/wled.cpp | 1 + wled00/wled.h | 46 ++++++++++++++++++++++++++---------------- wled00/wled_eeprom.cpp | 10 +++++---- wled00/wled_server.cpp | 4 ++-- 8 files changed, 75 insertions(+), 50 deletions(-) diff --git a/wled00/const.h b/wled00/const.h index 9fac43396..e25520599 100644 --- a/wled00/const.h +++ b/wled00/const.h @@ -126,4 +126,11 @@ #define ABL_MILLIAMPS_DEFAULT 850; // auto lower brightness to stay close to milliampere limit +// WLED Error modes +#define ERR_NONE 0 // All good :) +#define ERR_FS_BEGIN 10 // Could not init filesystem (no partition?) +#define ERR_FS_QUOTA 11 // The FS is full or the maximum file size is reached +#define ERR_FS_PLOAD 12 // It was attempted to load a preset that does not exist +#define ERR_FS_GENERAL 19 // A general unspecified filesystem error occured + #endif diff --git a/wled00/fcn_declare.h b/wled00/fcn_declare.h index 80ef9492d..bc5926fc2 100644 --- a/wled00/fcn_declare.h +++ b/wled00/fcn_declare.h @@ -88,7 +88,7 @@ void handleIR(); void deserializeSegment(JsonObject elem, byte it); bool deserializeState(JsonObject root); -void serializeSegment(JsonObject& root, WS2812FX::Segment& seg, byte id); +void serializeSegment(JsonObject& root, WS2812FX::Segment& seg, byte id, bool forPreset = false); void serializeState(JsonObject root, bool forPreset = false); void serializeInfo(JsonObject root); void serveJson(AsyncWebServerRequest* request); @@ -195,7 +195,7 @@ void saveSettingsToEEPROM(); void loadSettingsFromEEPROM(bool first); void savedToPresets(); bool applyPreset(byte index, bool loadBri = true); -void savePreset(byte index, bool persist = true); +void savePreset(byte index, bool persist = true, const char* pname = nullptr, byte prio = 50); void loadMacro(byte index, char* m); void applyMacro(byte index); void saveMacro(byte index, String mc, bool persist = true); //only commit on single save, not in settings diff --git a/wled00/file.cpp b/wled00/file.cpp index 57ef1e308..56b9a1006 100644 --- a/wled00/file.cpp +++ b/wled00/file.cpp @@ -27,6 +27,7 @@ bool bufferedFind(const char *target, File f) { byte c; uint16_t bufsize = 0, count = 0; byte buf[256]; + f.seek(0); while (f.position() < f.size() -1) { //c = f.read(); @@ -54,21 +55,26 @@ bool bufferedFind(const char *target, File f) { bool bufferedFindSpace(uint16_t targetLen, File f) { Serial.print("bfs "); if (!f || !f.size()) return false; + Serial.print(targetLen); uint16_t index = 0; uint16_t bufsize = 0, count = 0; byte buf[256]; + f.seek(0); while (f.position() < f.size() -1) { bufsize = f.read(buf, 256); count = 0; while (count < bufsize) { + Serial.print(count); + Serial.write(' '); + Serial.println(index); if(buf[count] != ' ') index = 0; // reset index if not space if(buf[count] == ' ') { if(++index >= targetLen) { // return true if space long enough - f.seek(f.position() - targetLen); - Serial.print("SPAAAACE!"); + f.seek((f.position() - bufsize) + count +1 - targetLen); + Serial.print("SPAAAACE!"); return true; } } @@ -88,10 +94,10 @@ bool writeObjectToFileUsingId(const char* file, uint16_t id, JsonDocument* conte bool writeObjectToFile(const char* file, const char* key, JsonDocument* content) { uint32_t pos = 0; - File f = SPIFFS.open(file, "r+"); - if (!f) f = SPIFFS.open(file,"w"); + File f = WLED_FS.open(file, "r+"); + if (!f) f = WLED_FS.open(file, "w"); if (!f) return false; - //f.setTimeout(1); + f.seek(0, SeekSet); Serial.print("Writing to "); @@ -116,6 +122,7 @@ bool writeObjectToFile(const char* file, const char* key, JsonDocument* content) StaticJsonDocument<1024> doc; deserializeJson(doc, f); uint32_t pos2 = f.position(); + uint32_t oldLen = pos2 - pos; Serial.print("Old obj len: "); Serial.print(oldLen); @@ -135,7 +142,7 @@ bool writeObjectToFile(const char* file, const char* key, JsonDocument* content) } else { //delete Serial.println("delete"); pos -= strlen(key); - oldLen = pos2 - pos; + if (pos > 3) pos--; //also delete leading comma if not first object f.seek(pos); for (uint32_t i = pos; i < pos2; i++) { f.write(' '); @@ -149,8 +156,8 @@ bool appendObjectToFile(const char* file, const char* key, JsonDocument* content { Serial.println("Append"); uint32_t pos = 0; - File f = (input) ? input : SPIFFS.open(file, "r+"); - if (!f) f = SPIFFS.open(file,"w"); + File f = (input) ? input : WLED_FS.open(file, "r+"); + if (!f) f = WLED_FS.open(file,"w"); if (!f) return false; if (f.size() < 3) f.print("{}"); @@ -159,7 +166,7 @@ bool appendObjectToFile(const char* file, const char* key, JsonDocument* content Serial.print("clen"); Serial.println(contentLen); if (bufferedFindSpace(contentLen + strlen(key) + 1, f)) { Serial.println("space"); - f.write(","); + if (f.position() > 2) f.write(","); //add comma if not first object f.print(key); serializeJson(*content, f); return true; @@ -187,13 +194,12 @@ bool appendObjectToFile(const char* file, const char* key, JsonDocument* content f.write('{'); //start JSON } - //f.print("\""); f.print(key); - //f.print("\":"); + //Append object serializeJson(*content, f); - f.write('}'); + f.close(); } @@ -206,13 +212,10 @@ bool readObjectFromFileUsingId(const char* file, uint16_t id, JsonDocument* dest bool readObjectFromFile(const char* file, const char* key, JsonDocument* dest) { - //if (id == playlistId) return true; - //playlist is already loaded, but we can't be sure that file hasn't changed since loading - - File f = SPIFFS.open(file, "r"); + File f = WLED_FS.open(file, "r"); if (!f) return false; //f.setTimeout(0); - //Serial.println(key); + if (!bufferedFind(key, f)) //key does not exist in file { f.close(); @@ -251,12 +254,12 @@ bool handleFileRead(AsyncWebServerRequest* request, String path){ if(path.endsWith("/")) path += "index.htm"; String contentType = getContentType(request, path); /*String pathWithGz = path + ".gz"; - if(SPIFFS.exists(pathWithGz)){ - request->send(SPIFFS, pathWithGz, contentType); + if(WLED_FS.exists(pathWithGz)){ + request->send(WLED_FS, pathWithGz, contentType); return true; }*/ - if(SPIFFS.exists(path)) { - request->send(SPIFFS, path, contentType); + if(WLED_FS.exists(path)) { + request->send(WLED_FS, path, contentType); return true; } return false; diff --git a/wled00/json.cpp b/wled00/json.cpp index 160247df6..5bfbb4b03 100644 --- a/wled00/json.cpp +++ b/wled00/json.cpp @@ -225,17 +225,17 @@ bool deserializeState(JsonObject root) bool persistSaves = !(root["np"] | false); ps = root["psave"] | -1; - if (ps >= 0) savePreset(ps, persistSaves); + if (ps >= 0) savePreset(ps, persistSaves, root["n"], root["p"]); return stateResponse; } -void serializeSegment(JsonObject& root, WS2812FX::Segment& seg, byte id) +void serializeSegment(JsonObject& root, WS2812FX::Segment& seg, byte id, bool forPreset) { root["id"] = id; root["start"] = seg.start; root["stop"] = seg.stop; - root["len"] = seg.stop - seg.start; + if (!forPreset) root["len"] = seg.stop - seg.start; root["grp"] = seg.grouping; root["spc"] = seg.spacing; root["on"] = seg.getOption(SEG_OPTION_ON); @@ -317,7 +317,7 @@ void serializeState(JsonObject root, bool forPreset) if (sg.isActive()) { JsonObject seg0 = seg.createNestedObject(); - serializeSegment(seg0, sg, s); + serializeSegment(seg0, sg, s, forPreset); } } } diff --git a/wled00/wled.cpp b/wled00/wled.cpp index fab1df7fe..71e319509 100644 --- a/wled00/wled.cpp +++ b/wled00/wled.cpp @@ -24,6 +24,7 @@ void WLED::reset() setAllLeds(); DEBUG_PRINTLN("MODULE RESET"); ESP.restart(); + SPIFFS.begin(); } bool oappendi(int i) diff --git a/wled00/wled.h b/wled00/wled.h index f0338986f..ec5bb4e0a 100644 --- a/wled00/wled.h +++ b/wled00/wled.h @@ -10,9 +10,9 @@ // version code in format yymmddb (b = daily build) #define VERSION 2009070 -// ESP8266-01 (blue) got too little storage space to work with all features of WLED. To use it, you must use ESP8266 Arduino Core v2.4.2 and the setting 512K(No SPIFFS). +// ESP8266-01 (blue) got too little storage space to work with WLED. 0.10.2 is the last release supporting this unit. -// ESP8266-01 (black) has 1MB flash and can thus fit the whole program. Use 1M(64K SPIFFS). +// ESP8266-01 (black) has 1MB flash and can thus fit the whole program, although OTA update is not possible. Use 1M(128K SPIFFS). // Uncomment some of the following lines to disable features to compile for ESP8266-01 (max flash size 434kB): // Alternatively, with platformio pass your chosen flags to your custom build target in platformio.ini.override @@ -118,25 +118,14 @@ #include #endif +//Filesystem to use for preset and config files. SPIFFS or LittleFS on ESP8266, SPIFFS only on ESP32 +#define WLED_FS SPIFFS + // remove flicker because PWM signal of RGB channels can become out of phase (part of core as of Arduino core v2.7.0) //#if defined(WLED_USE_ANALOG_LEDS) && defined(ESP8266) // #include "src/dependencies/arduino/core_esp8266_waveform.h" //#endif -// enable additional debug output -#ifdef WLED_DEBUG - #ifndef ESP8266 - #include - #endif - #define DEBUG_PRINT(x) Serial.print(x) - #define DEBUG_PRINTLN(x) Serial.println(x) - #define DEBUG_PRINTF(x) Serial.printf(x) -#else - #define DEBUG_PRINT(x) - #define DEBUG_PRINTLN(x) - #define DEBUG_PRINTF(x) -#endif - // GLOBAL VARIABLES // both declared and defined in header (solution from http://www.keil.com/support/docs/1868.htm) // @@ -504,6 +493,30 @@ WLED_GLOBAL WS2812FX strip _INIT(WS2812FX()); // Usermod manager WLED_GLOBAL UsermodManager usermods _INIT(UsermodManager()); +// enable additional debug output +#ifdef WLED_DEBUG + #ifndef ESP8266 + #include + #endif + #define DEBUG_PRINT(x) Serial.print(x) + #define DEBUG_PRINTLN(x) Serial.println(x) + #define DEBUG_PRINTF(x) Serial.printf(x) +#else + #define DEBUG_PRINT(x) + #define DEBUG_PRINTLN(x) + #define DEBUG_PRINTF(x) +#endif + +#ifdef WLED_DEBUG_FS + #define DEBUGFS_PRINT(x) Serial.print(x) + #define DEBUGFS_PRINTLN(x) Serial.println(x) + #define DEBUGFS_PRINTF(x) Serial.printf(x) +#else + #define DEBUGFS_PRINT(x) + #define DEBUGFS_PRINTLN(x) + #define DEBUGFS_PRINTF(x) +#endif + // debug macro variable definitions #ifdef WLED_DEBUG WLED_GLOBAL unsigned long debugTime _INIT(0); @@ -512,7 +525,6 @@ WLED_GLOBAL UsermodManager usermods _INIT(UsermodManager()); WLED_GLOBAL int loops _INIT(0); #endif - #define WLED_CONNECTED (WiFi.status() == WL_CONNECTED) #define WLED_WIFI_CONFIGURED (strlen(clientSSID) >= 1 && strcmp(clientSSID, DEFAULT_CLIENT_SSID) != 0) #define WLED_MQTT_CONNECTED (mqtt != nullptr && mqtt->connected()) diff --git a/wled00/wled_eeprom.cpp b/wled00/wled_eeprom.cpp index 7599b374c..f23fdb170 100644 --- a/wled00/wled_eeprom.cpp +++ b/wled00/wled_eeprom.cpp @@ -33,7 +33,7 @@ void commit() { - if (!EEPROM.commit()) errorFlag = 2; + if (!EEPROM.commit()) errorFlag = ERR_EEP_COMMIT; } /* @@ -622,7 +622,7 @@ void savedToPresets() bool applyPreset(byte index, bool loadBri) { StaticJsonDocument<1024> temp; - errorFlag = !readObjectFromFileUsingId("/presets.json", index, &temp); + if (!readObjectFromFileUsingId("/presets.json", index, &temp)) errorFlag = ERR_FS_PLOAD; serializeJson(temp, Serial); deserializeState(temp.as()); //presetToApply = index; @@ -672,11 +672,13 @@ bool applyPreset(byte index, bool loadBri) return true; } -void savePreset(byte index, bool persist) +void savePreset(byte index, bool persist, const char* pname, byte priority) { StaticJsonDocument<1024> doc; serializeState(doc.to(), true); - doc["p"]=50; + doc["p"] = priority; + if (pname) doc["n"] = pname; + //serializeJson(doc, Serial); writeObjectToFileUsingId("/presets.json", index, &doc); return; diff --git a/wled00/wled_server.cpp b/wled00/wled_server.cpp index 6c981afb4..d3f20bfe5 100644 --- a/wled00/wled_server.cpp +++ b/wled00/wled_server.cpp @@ -157,13 +157,13 @@ void initServer() if (!otaLock){ #if !defined WLED_DISABLE_FILESYSTEM && defined WLED_ENABLE_FS_EDITOR #ifdef ARDUINO_ARCH_ESP32 - server.addHandler(new SPIFFSEditor(SPIFFS));//http_username,http_password)); + server.addHandler(new SPIFFSEditor(WLED_FS));//http_username,http_password)); #else server.addHandler(new SPIFFSEditor());//http_username,http_password)); #endif #else server.on("/edit", HTTP_GET, [](AsyncWebServerRequest *request){ - serveMessage(request, 501, "Not implemented", F("The SPIFFS editor is disabled in this build."), 254); + serveMessage(request, 501, "Not implemented", F("The FS editor is disabled in this build."), 254); }); #endif //init ota page