A few more PROGMEM optimisations
This commit is contained in:
		
							
								
								
									
										4
									
								
								wled00/cfg.cpp
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							
							
						
						
									
										4
									
								
								wled00/cfg.cpp
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							| @@ -1052,7 +1052,7 @@ void serializeConfig() { | ||||
|   JsonObject usermods_settings = root.createNestedObject("um"); | ||||
|   usermods.addToConfig(usermods_settings); | ||||
|  | ||||
|   File f = WLED_FS.open("/cfg.json", "w"); | ||||
|   File f = WLED_FS.open(SET_F("/cfg.json"), "w"); | ||||
|   if (f) serializeJson(root, f); | ||||
|   f.close(); | ||||
|   releaseJSONBufferLock(); | ||||
| @@ -1066,7 +1066,7 @@ bool deserializeConfigSec() { | ||||
|  | ||||
|   if (!requestJSONBufferLock(3)) return false; | ||||
|  | ||||
|   bool success = readObjectFromFile("/wsec.json", nullptr, pDoc); | ||||
|   bool success = readObjectFromFile(PSTR("/wsec.json"), nullptr, pDoc); | ||||
|   if (!success) { | ||||
|     releaseJSONBufferLock(); | ||||
|     return false; | ||||
|   | ||||
| @@ -272,8 +272,8 @@ bool writeObjectToFile(const char* file, const char* key, JsonDocument* content) | ||||
|   #endif | ||||
|  | ||||
|   size_t pos = 0; | ||||
|   f = WLED_FS.open(file, "r+"); | ||||
|   if (!f && !WLED_FS.exists(file)) f = WLED_FS.open(file, "w+"); | ||||
|   char fileName[129]; strncpy_P(fileName, file, 128); fileName[128] = 0; //use PROGMEM safe copy as FS.open() does not | ||||
|   f = WLED_FS.open(fileName, WLED_FS.exists(fileName) ? "r+" : "w+"); | ||||
|   if (!f) { | ||||
|     DEBUGFS_PRINTLN(F("Failed to open!")); | ||||
|     return false; | ||||
| @@ -340,7 +340,8 @@ bool readObjectFromFile(const char* file, const char* key, JsonDocument* dest) | ||||
|     DEBUGFS_PRINTF("Read from %s with key %s >>>\n", file, (key==nullptr)?"nullptr":key); | ||||
|     uint32_t s = millis(); | ||||
|   #endif | ||||
|   f = WLED_FS.open(file, "r"); | ||||
|   char fileName[129]; strncpy_P(fileName, file, 128); fileName[128] = 0; //use PROGMEM safe copy as FS.open() does not | ||||
|   f = WLED_FS.open(fileName, "r"); | ||||
|   if (!f) return false; | ||||
|  | ||||
|   if (key != nullptr && !bufferedFind(key)) //key does not exist in file | ||||
|   | ||||
| @@ -631,6 +631,7 @@ Sample: | ||||
| void decodeIRJson(uint32_t code) | ||||
| { | ||||
|   char objKey[10]; | ||||
|   char fileName[16]; | ||||
|   String cmdStr; | ||||
|   JsonObject fdo; | ||||
|   JsonObject jsonCmdObj; | ||||
| @@ -638,17 +639,18 @@ void decodeIRJson(uint32_t code) | ||||
|   if (!requestJSONBufferLock(13)) return; | ||||
|  | ||||
|   sprintf_P(objKey, PSTR("\"0x%lX\":"), (unsigned long)code); | ||||
|   strcpy_P(fileName, PSTR("/ir.json")); // for FS.exists() | ||||
|  | ||||
|   // attempt to read command from ir.json | ||||
|   // this may fail for two reasons: ir.json does not exist or IR code not found | ||||
|   // if the IR code is not found readObjectFromFile() will clean() doc JSON document | ||||
|   // so we can differentiate between the two | ||||
|   readObjectFromFile("/ir.json", objKey, pDoc); | ||||
|   readObjectFromFile(fileName, objKey, pDoc); | ||||
|   fdo = pDoc->as<JsonObject>(); | ||||
|   lastValidCode = 0; | ||||
|   if (fdo.isNull()) { | ||||
|     //the received code does not exist | ||||
|     if (!WLED_FS.exists("/ir.json")) errorFlag = ERR_FS_IRLOAD; //warn if IR file itself doesn't exist | ||||
|     if (!WLED_FS.exists(fileName)) errorFlag = ERR_FS_IRLOAD; //warn if IR file itself doesn't exist | ||||
|     releaseJSONBufferLock(); | ||||
|     return; | ||||
|   } | ||||
|   | ||||
| @@ -12,8 +12,8 @@ static volatile byte presetToApply = 0; | ||||
| static volatile byte callModeToApply = 0; | ||||
| static volatile byte presetToSave = 0; | ||||
| static volatile int8_t saveLedmap = -1; | ||||
| static char quickLoad[9]; | ||||
| static char saveName[33]; | ||||
| static char *quickLoad = nullptr; | ||||
| static char *saveName = nullptr; | ||||
| static bool includeBri = true, segBounds = true, selectedOnly = false, playlistSave = false;; | ||||
|  | ||||
| static const char presets_json[] PROGMEM = "/presets.json"; | ||||
| @@ -39,8 +39,9 @@ static void doSaveState() { | ||||
|   } else { | ||||
|     serializeState(sObj, true, includeBri, segBounds, selectedOnly); | ||||
|   } | ||||
|   sObj["n"] = saveName; | ||||
|   if (quickLoad[0]) sObj[F("ql")] = quickLoad; | ||||
|   if (saveName) sObj["n"] = saveName; | ||||
|   else          sObj["n"] = F("Unkonwn preset"); // should not happen, but just in case... | ||||
|   if (quickLoad && quickLoad[0]) sObj[F("ql")] = quickLoad; | ||||
|   if (saveLedmap >= 0) sObj[F("ledmap")] = saveLedmap; | ||||
| /* | ||||
|   #ifdef WLED_DEBUG | ||||
| @@ -64,11 +65,11 @@ static void doSaveState() { | ||||
|     if (tmpRAMbuffer!=nullptr) { | ||||
|       serializeJson(*fileDoc, tmpRAMbuffer, len); | ||||
|     } else { | ||||
|       writeObjectToFileUsingId(FPSTR(getPresetsFileName(persist)), presetToSave, fileDoc); | ||||
|       writeObjectToFileUsingId(getPresetsFileName(persist), presetToSave, fileDoc); | ||||
|     } | ||||
|   } else | ||||
|   #endif | ||||
|   writeObjectToFileUsingId(FPSTR(getPresetsFileName(persist)), presetToSave, fileDoc); | ||||
|   writeObjectToFileUsingId(getPresetsFileName(persist), presetToSave, fileDoc); | ||||
|  | ||||
|   if (persist) presetsModifiedTime = toki.second(); //unix time | ||||
|   releaseJSONBufferLock(); | ||||
| @@ -77,8 +78,10 @@ static void doSaveState() { | ||||
|   // clean up | ||||
|   saveLedmap   = -1; | ||||
|   presetToSave = 0; | ||||
|   saveName[0]  = '\0'; | ||||
|   quickLoad[0] = '\0'; | ||||
|   delete[] saveName; | ||||
|   delete[] quickLoad; | ||||
|   saveName = nullptr; | ||||
|   quickLoad = nullptr; | ||||
|   playlistSave = false; | ||||
| } | ||||
|  | ||||
| @@ -86,7 +89,7 @@ bool getPresetName(byte index, String& name) | ||||
| { | ||||
|   if (!requestJSONBufferLock(19)) return false; | ||||
|   bool presetExists = false; | ||||
|   if (readObjectFromFileUsingId(FPSTR(getPresetsFileName()), index, pDoc)) { | ||||
|   if (readObjectFromFileUsingId(getPresetsFileName(), index, pDoc)) { | ||||
|     JsonObject fdo = pDoc->as<JsonObject>(); | ||||
|     if (fdo["n"]) { | ||||
|       name = (const char*)(fdo["n"]); | ||||
| @@ -99,12 +102,13 @@ bool getPresetName(byte index, String& name) | ||||
|  | ||||
| void initPresetsFile() | ||||
| { | ||||
|   if (WLED_FS.exists(FPSTR(getPresetsFileName()))) return; | ||||
|   char fileName[33]; strncpy_P(fileName, getPresetsFileName(), 32); fileName[32] = 0; //use PROGMEM safe copy as FS.open() does not | ||||
|   if (WLED_FS.exists(fileName)) return; | ||||
|  | ||||
|   StaticJsonDocument<64> doc; | ||||
|   JsonObject sObj = doc.to<JsonObject>(); | ||||
|   sObj.createNestedObject("0"); | ||||
|   File f = WLED_FS.open(FPSTR(getPresetsFileName()), "w"); | ||||
|   File f = WLED_FS.open(fileName, "w"); | ||||
|   if (!f) { | ||||
|     errorFlag = ERR_FS_GENERAL; | ||||
|     return; | ||||
| @@ -164,7 +168,7 @@ void handlePresets() | ||||
|   } else | ||||
|   #endif | ||||
|   { | ||||
|   errorFlag = readObjectFromFileUsingId(FPSTR(getPresetsFileName(tmpPreset < 255)), tmpPreset, fileDoc) ? ERR_NONE : ERR_FS_PLOAD; | ||||
|   errorFlag = readObjectFromFileUsingId(getPresetsFileName(tmpPreset < 255), tmpPreset, fileDoc) ? ERR_NONE : ERR_FS_PLOAD; | ||||
|   } | ||||
|   fdo = fileDoc->as<JsonObject>(); | ||||
|  | ||||
| @@ -202,6 +206,10 @@ void handlePresets() | ||||
| //called from handleSet(PS=) [network callback (fileDoc==nullptr), IR (irrational), deserializeState, UDP] and deserializeState() [network callback (filedoc!=nullptr)] | ||||
| void savePreset(byte index, const char* pname, JsonObject sObj) | ||||
| { | ||||
|   if (!saveName) saveName = new char[33]; | ||||
|   if (!quickLoad) quickLoad = new char[9]; | ||||
|   if (!saveName || !quickLoad) return; | ||||
|  | ||||
|   if (index == 0 || (index > 250 && index < 255)) return; | ||||
|   if (pname) strlcpy(saveName, pname, 33); | ||||
|   else { | ||||
| @@ -214,6 +222,7 @@ void savePreset(byte index, const char* pname, JsonObject sObj) | ||||
|   presetToSave = index; | ||||
|   playlistSave = false; | ||||
|   if (sObj[F("ql")].is<const char*>()) strlcpy(quickLoad, sObj[F("ql")].as<const char*>(), 9); // client limits QL to 2 chars, buffer for 8 bytes to allow unicode | ||||
|   else quickLoad[0] = 0; | ||||
|  | ||||
|   if (sObj.size()==0 || sObj["o"].isNull()) { // no "o" means not a playlist or custom API call, saving of state is async (not immediately) | ||||
|     includeBri   = sObj["ib"].as<bool>() || sObj.size()==0 || index==255; // temporary preset needs brightness | ||||
| @@ -225,17 +234,22 @@ void savePreset(byte index, const char* pname, JsonObject sObj) | ||||
|     if (sObj[F("playlist")].isNull()) { | ||||
|       // we will save API call immediately (often causes presets.json corruption) | ||||
|       presetToSave = 0; | ||||
|       if (index > 250 || !fileDoc) return; // cannot save API calls to temporary preset (255) | ||||
|       sObj.remove("o"); | ||||
|       sObj.remove("v"); | ||||
|       sObj.remove("time"); | ||||
|       sObj.remove(F("error")); | ||||
|       sObj.remove(F("psave")); | ||||
|       if (sObj["n"].isNull()) sObj["n"] = saveName; | ||||
|       initPresetsFile(); // just in case if someone deleted presets.json using /edit | ||||
|       writeObjectToFileUsingId(FPSTR(getPresetsFileName()), index, fileDoc); | ||||
|       presetsModifiedTime = toki.second(); //unix time | ||||
|       updateFSInfo(); | ||||
|       if (index <= 250 && fileDoc) { // cannot save API calls to temporary preset (255) | ||||
|         sObj.remove("o"); | ||||
|         sObj.remove("v"); | ||||
|         sObj.remove("time"); | ||||
|         sObj.remove(F("error")); | ||||
|         sObj.remove(F("psave")); | ||||
|         if (sObj["n"].isNull()) sObj["n"] = saveName; | ||||
|         initPresetsFile(); // just in case if someone deleted presets.json using /edit | ||||
|         writeObjectToFileUsingId(getPresetsFileName(), index, fileDoc); | ||||
|         presetsModifiedTime = toki.second(); //unix time | ||||
|         updateFSInfo(); | ||||
|       } | ||||
|       delete[] saveName; | ||||
|       delete[] quickLoad; | ||||
|       saveName = nullptr; | ||||
|       quickLoad = nullptr; | ||||
|     } else { | ||||
|       // store playlist | ||||
|       // WARNING: playlist will be loaded in json.cpp after this call and will have repeat counter increased by 1 | ||||
| @@ -247,7 +261,7 @@ void savePreset(byte index, const char* pname, JsonObject sObj) | ||||
|  | ||||
| void deletePreset(byte index) { | ||||
|   StaticJsonDocument<24> empty; | ||||
|   writeObjectToFileUsingId(FPSTR(getPresetsFileName()), index, &empty); | ||||
|   writeObjectToFileUsingId(getPresetsFileName(), index, &empty); | ||||
|   presetsModifiedTime = toki.second(); //unix time | ||||
|   updateFSInfo(); | ||||
| } | ||||
| @@ -123,7 +123,7 @@ static bool remoteJson(int button) | ||||
|   sprintf_P(objKey, PSTR("\"%d\":"), button); | ||||
|  | ||||
|   // attempt to read command from remote.json | ||||
|   readObjectFromFile("/remote.json", objKey, pDoc); | ||||
|   readObjectFromFile(PSTR("/remote.json"), objKey, pDoc); | ||||
|   JsonObject fdo = pDoc->as<JsonObject>(); | ||||
|   if (fdo.isNull()) { | ||||
|     // the received button does not exist | ||||
|   | ||||
| @@ -8,7 +8,7 @@ | ||||
|  */ | ||||
|  | ||||
| // version code in format yymmddb (b = daily build) | ||||
| #define VERSION 2402250 | ||||
| #define VERSION 2402290 | ||||
|  | ||||
| //uncomment this if you have a "my_config.h" file you'd like to use | ||||
| //#define WLED_USE_MY_CONFIG | ||||
| @@ -567,7 +567,7 @@ WLED_GLOBAL byte bri                 _INIT(briS);          // global brightness | ||||
| WLED_GLOBAL byte briOld              _INIT(0);             // global brightness while in transition loop (previous iteration) | ||||
| WLED_GLOBAL byte briT                _INIT(0);             // global brightness during transition | ||||
| WLED_GLOBAL byte briLast             _INIT(128);           // brightness before turned off. Used for toggle function | ||||
| WLED_GLOBAL byte whiteLast           _INIT(128);           // white channel before turned off. Used for toggle function | ||||
| WLED_GLOBAL byte whiteLast           _INIT(128);           // white channel before turned off. Used for toggle function in ir.cpp | ||||
|  | ||||
| // button | ||||
| WLED_GLOBAL bool buttonPublishMqtt                            _INIT(false); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Blaz Kristan
					Blaz Kristan