diff --git a/ESPixelStick/ESPixelStick.ino b/ESPixelStick/ESPixelStick.ino index a603c7a2f..f0e12092a 100644 --- a/ESPixelStick/ESPixelStick.ino +++ b/ESPixelStick/ESPixelStick.ino @@ -98,7 +98,10 @@ bool ResetWiFi = false; bool IsBooting = true; // Configuration initialization flag time_t ConfigLoadNeeded = NO_CONFIG_NEEDED; bool ConfigSaveNeeded = false; +bool RestoredConfig = false; + uint32_t DiscardedRxData = 0; +const String RestoredConfigFileName = F("/RestoredConfig.json"); ///////////////////////////////////////////////////////// // @@ -171,6 +174,15 @@ void setup() // DEBUG_V(""); FileMgr.Begin(); + if(FileMgr.FlashFileExists (RestoredConfigFileName)) + { + // DEBUG_V("Setting Restored Config flag to true"); + RestoredConfig = true; + } + else + { + // DEBUG_V("Setting Restored Config flag to false"); + } // Load configuration from the File System and set Hostname // TestHeap(uint32_t(15)); // DEBUG_V(String("LoadConfig Heap: ") + String(ESP.getFreeHeap())); @@ -218,6 +230,14 @@ void setup() // Done with initialization IsBooting = false; + if(RestoredConfig) + { + // DEBUG_V("Delete Restored Config Flag file"); + FileMgr.DeleteFlashFile(RestoredConfigFileName); + ConfigSaveNeeded = true; + RestoredConfig = false; + } + // DEBUG_END; } // setup @@ -285,7 +305,7 @@ void SetConfig (const char * DataString) // of the data. Chance for 3rd party software to muck up the configuraton // if they send bad json data. - FileMgr.SaveConfigFile (ConfigFileName, DataString); + FileMgr.SaveFlashFile (ConfigFileName, DataString); ScheduleLoadConfig(); // DEBUG_END; @@ -388,7 +408,7 @@ void SaveConfig() GetConfig(JsonConfig); - FileMgr.SaveConfigFile(ConfigFileName, jsonConfigDoc); + FileMgr.SaveFlashFile(ConfigFileName, jsonConfigDoc); // DEBUG_END; } // SaveConfig @@ -405,7 +425,7 @@ void LoadConfig() String temp; // DEBUG_V (""); - FileMgr.LoadConfigFile (ConfigFileName, &deserializeCoreHandler); + FileMgr.LoadFlashFile (ConfigFileName, &deserializeCoreHandler); ConfigSaveNeeded |= !validateConfig (); @@ -415,7 +435,7 @@ void LoadConfig() void DeleteConfig () { // DEBUG_START; - FileMgr.DeleteConfigFile (ConfigFileName); + FileMgr.DeleteFlashFile (ConfigFileName); // DEBUG_END; @@ -487,7 +507,7 @@ void loop() /* if(millis() > HeapTime) { - DEBUG_V(String("Heap: ") + String(ESP.getFreeHeap())); + // DEBUG_V(String("Heap: ") + String(ESP.getFreeHeap())); HeapTime += 5000; } */ diff --git a/ESPixelStick/src/ESPixelStick.h b/ESPixelStick/src/ESPixelStick.h index 96e32fb1b..fec9b7f78 100644 --- a/ESPixelStick/src/ESPixelStick.h +++ b/ESPixelStick/src/ESPixelStick.h @@ -131,6 +131,8 @@ bool setFromJSON (T& OutValue, J& Json, N Name) extern config_t config; extern bool ConfigSaveNeeded; +extern bool RestoredConfig; + extern const uint8_t CurrentConfigVersion; #define LOAD_CONFIG_DELAY 4 // #define DEBUG_GPIO gpio_num_t::GPIO_NUM_25 diff --git a/ESPixelStick/src/FileMgr.cpp b/ESPixelStick/src/FileMgr.cpp index cd8547264..b94b9f01d 100644 --- a/ESPixelStick/src/FileMgr.cpp +++ b/ESPixelStick/src/FileMgr.cpp @@ -255,7 +255,7 @@ void c_FileMgr::ResetSdCard() } // ResetSdCard //----------------------------------------------------------------------------- -void c_FileMgr::DeleteConfigFile (const String& FileName) +void c_FileMgr::DeleteFlashFile (const String& FileName) { // DEBUG_START; @@ -309,7 +309,7 @@ void c_FileMgr::listDir (fs::FS& fs, String dirname, uint8_t levels) } // listDir //----------------------------------------------------------------------------- -bool c_FileMgr::LoadConfigFile (const String& FileName, DeserializationHandler Handler) +bool c_FileMgr::LoadFlashFile (const String& FileName, DeserializationHandler Handler) { // DEBUG_START; @@ -399,18 +399,18 @@ bool c_FileMgr::LoadConfigFile (const String& FileName, DeserializationHandler H } // LoadConfigFile //----------------------------------------------------------------------------- -bool c_FileMgr::SaveConfigFile (const String& FileName, String& FileData) +bool c_FileMgr::SaveFlashFile (const String& FileName, String& FileData) { // DEBUG_START; - bool Response = SaveConfigFile (FileName, FileData.c_str ()); + bool Response = SaveFlashFile (FileName, FileData.c_str ()); // DEBUG_END; return Response; } // SaveConfigFile //----------------------------------------------------------------------------- -bool c_FileMgr::SaveConfigFile (const String& FileName, const char * FileData) +bool c_FileMgr::SaveFlashFile (const String& FileName, const char * FileData) { // DEBUG_START; @@ -445,7 +445,7 @@ bool c_FileMgr::SaveConfigFile (const String& FileName, const char * FileData) } // SaveConfigFile //----------------------------------------------------------------------------- -bool c_FileMgr::SaveConfigFile(const String &FileName, JsonDocument &FileData) +bool c_FileMgr::SaveFlashFile(const String &FileName, JsonDocument &FileData) { // DEBUG_START; bool Response = false; @@ -488,7 +488,7 @@ bool c_FileMgr::SaveConfigFile(const String &FileName, JsonDocument &FileData) } // SaveConfigFile //----------------------------------------------------------------------------- -bool c_FileMgr::SaveConfigFile(const String FileName, uint32_t index, uint8_t *data, uint32_t len, bool final) +bool c_FileMgr::SaveFlashFile(const String FileName, uint32_t index, uint8_t *data, uint32_t len, bool final) { // DEBUG_START; bool Response = false; @@ -538,7 +538,7 @@ bool c_FileMgr::SaveConfigFile(const String FileName, uint32_t index, uint8_t *d } // SaveConfigFile //----------------------------------------------------------------------------- -bool c_FileMgr::ReadConfigFile (const String& FileName, String& FileData) +bool c_FileMgr::ReadFlashFile (const String& FileName, String& FileData) { // DEBUG_START; @@ -572,7 +572,7 @@ bool c_FileMgr::ReadConfigFile (const String& FileName, String& FileData) } // ReadConfigFile //----------------------------------------------------------------------------- -bool c_FileMgr::ReadConfigFile (const String& FileName, JsonDocument & FileData) +bool c_FileMgr::ReadFlashFile (const String& FileName, JsonDocument & FileData) { // DEBUG_START; bool GotFileData = false; @@ -580,7 +580,7 @@ bool c_FileMgr::ReadConfigFile (const String& FileName, JsonDocument & FileData) do // once { String RawFileData; - if (false == ReadConfigFile (FileName, RawFileData)) + if (false == ReadFlashFile (FileName, RawFileData)) { // DEBUG_V ("Failed to read file"); break; @@ -619,7 +619,7 @@ bool c_FileMgr::ReadConfigFile (const String& FileName, JsonDocument & FileData) } // ReadConfigFile //----------------------------------------------------------------------------- -bool c_FileMgr::ReadConfigFile (const String & FileName, byte * FileData, size_t maxlen) +bool c_FileMgr::ReadFlashFile (const String & FileName, byte * FileData, size_t maxlen) { // DEBUG_START; bool GotFileData = false; @@ -666,6 +666,13 @@ bool c_FileMgr::ReadConfigFile (const String & FileName, byte * FileData, size_t } // ReadConfigFile +//----------------------------------------------------------------------------- +bool c_FileMgr::FlashFileExists (const String & FileName) +{ + return LittleFS.exists (FileName.c_str ()); + +} // FlashFileExists + //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- diff --git a/ESPixelStick/src/FileMgr.hpp b/ESPixelStick/src/FileMgr.hpp index e2e7cf8a8..2a8368b56 100644 --- a/ESPixelStick/src/FileMgr.hpp +++ b/ESPixelStick/src/FileMgr.hpp @@ -68,16 +68,17 @@ class c_FileMgr FileAppend, } FileMode; - void DeleteConfigFile (const String & FileName); - bool SaveConfigFile (const String & FileName, String & FileData); - bool SaveConfigFile (const String & FileName, const char * FileData); - bool SaveConfigFile (const String & FileName, JsonDocument & FileData); - bool SaveConfigFile (const String filename, uint32_t index, uint8_t *data, uint32_t len, bool final); - - bool ReadConfigFile (const String & FileName, String & FileData); - bool ReadConfigFile (const String & FileName, JsonDocument & FileData); - bool ReadConfigFile (const String & FileName, byte * FileData, size_t maxlen); - bool LoadConfigFile (const String & FileName, DeserializationHandler Handler); + void DeleteFlashFile (const String & FileName); + bool SaveFlashFile (const String & FileName, String & FileData); + bool SaveFlashFile (const String & FileName, const char * FileData); + bool SaveFlashFile (const String & FileName, JsonDocument & FileData); + bool SaveFlashFile (const String filename, uint32_t index, uint8_t *data, uint32_t len, bool final); + + bool ReadFlashFile (const String & FileName, String & FileData); + bool ReadFlashFile (const String & FileName, JsonDocument & FileData); + bool ReadFlashFile (const String & FileName, byte * FileData, size_t maxlen); + bool LoadFlashFile (const String & FileName, DeserializationHandler Handler); + bool FlashFileExists (const String & FileName); bool SdCardIsInstalled () { return SdCardInstalled; } FileId CreateSdFileHandle (); diff --git a/ESPixelStick/src/WebMgr.cpp b/ESPixelStick/src/WebMgr.cpp index 689f07f59..3e9a8c721 100644 --- a/ESPixelStick/src/WebMgr.cpp +++ b/ESPixelStick/src/WebMgr.cpp @@ -329,6 +329,12 @@ void c_WebMgr::init () OutputMgr.ScheduleLoadConfig(); request->send (200, CN_textSLASHplain, String(F("XFER Complete"))); } + else if(UploadFileName.equals(F("RestoredConfig.json"))) + { + DEBUG_V("Received RestoredConfig message"); + request->send (200, CN_textSLASHplain, String(F("XFER Complete"))); + RequestReboot(700000); + } else { logcon(String(F("Unexpected Config File Name: ")) + UploadFileName); @@ -347,7 +353,7 @@ void c_WebMgr::init () // DEBUG_V(String(" file: ") + filename); // DEBUG_V(String("final: ") + String(final)); - if(FileMgr.SaveConfigFile(filename, index, data, len, final)) + if(FileMgr.SaveFlashFile(filename, index, data, len, final)) { // DEBUG_V("Save Chunk - Success"); } @@ -371,7 +377,7 @@ void c_WebMgr::init () // DEBUG_V(String(" file: ") + UploadFileName); // DEBUG_V(String("final: ") + String(total <= (index+len))); - if(FileMgr.SaveConfigFile(UploadFileName, index, data, len, total <= (index+len))) + if(FileMgr.SaveFlashFile(UploadFileName, index, data, len, total <= (index+len))) { // DEBUG_V("Save Chunk - Success"); } @@ -619,7 +625,7 @@ void c_WebMgr::CreateAdminInfoFile () #endif // write to json file - if (true == FileMgr.SaveConfigFile (F("/admininfo.json"), AdminJsonDoc)) + if (true == FileMgr.SaveFlashFile (F("/admininfo.json"), AdminJsonDoc)) { } // end we saved a config and it was good else diff --git a/ESPixelStick/src/input/InputMgr.cpp b/ESPixelStick/src/input/InputMgr.cpp index 3f1fdcf60..c71591456 100644 --- a/ESPixelStick/src/input/InputMgr.cpp +++ b/ESPixelStick/src/input/InputMgr.cpp @@ -128,11 +128,15 @@ void c_InputMgr::Begin (uint32_t BufferSize) } HasBeenInitialized = true; + if(RestoredConfig) + { + logcon("Merging Restored Input Config File"); + CreateNewConfig(); + } + // load up the configuration from the saved file. This also starts the drivers LoadConfig (); - // CreateNewConfig (); - // DEBUG_END; } // begin @@ -258,7 +262,19 @@ void c_InputMgr::CreateNewConfig () DynamicJsonDocument JsonConfigDoc(IM_JSON_SIZE); // DEBUG_V(""); - JsonObject JsonConfig = JsonConfigDoc.createNestedObject(CN_input_config); + // do we create a clean config or do we merge from a restored config? + if(RestoredConfig) + { + // DEBUG_V("Merge a Restored Config"); + // read the existing file and add to it as needed + FileMgr.ReadFlashFile(ConfigFileName, JsonConfigDoc); + } + + if(!JsonConfigDoc.containsKey(CN_input_config)) + { + JsonConfigDoc.createNestedObject(CN_input_config); + } + JsonObject JsonConfig = JsonConfigDoc[CN_input_config]; // DEBUG_V(""); JsonConfig[CN_cfgver] = CurrentConfigVersion; @@ -306,7 +322,7 @@ void c_InputMgr::GetConfig (byte * Response, uint32_t maxlen) { // DEBUGSTART; - FileMgr.ReadConfigFile (ConfigFileName, Response, maxlen); + FileMgr.ReadFlashFile (ConfigFileName, Response, maxlen); // DEBUGV (String ("TempConfigData: ") + TempConfigData); // DEBUGEND; @@ -616,7 +632,7 @@ void c_InputMgr::LoadConfig () ConfigLoadNeeded = NO_CONFIG_NEEDED; configInProgress = true; // try to load and process the config file - if (!FileMgr.LoadConfigFile (ConfigFileName, [this](DynamicJsonDocument & JsonConfigDoc) + if (!FileMgr.LoadFlashFile (ConfigFileName, [this](DynamicJsonDocument & JsonConfigDoc) { // DEBUG_V (""); JsonObject JsonConfig = JsonConfigDoc.as (); @@ -873,7 +889,7 @@ void c_InputMgr::SetConfig (const char * NewConfigData) { // DEBUG_START; - if (true == FileMgr.SaveConfigFile (ConfigFileName, NewConfigData)) + if (true == FileMgr.SaveFlashFile (ConfigFileName, NewConfigData)) { // DEBUG_V (String("NewConfigData: ") + NewConfigData); // FileMgr logs for us @@ -899,7 +915,7 @@ void c_InputMgr::SetConfig(JsonDocument & NewConfigData) { // DEBUG_START; - if (true == FileMgr.SaveConfigFile(ConfigFileName, NewConfigData)) + if (true == FileMgr.SaveFlashFile(ConfigFileName, NewConfigData)) { // FileMgr logs for us // logcon (CN_stars + String (F (" Saved Input Manager Config File. ")) + CN_stars); diff --git a/ESPixelStick/src/input/InputMgr.hpp b/ESPixelStick/src/input/InputMgr.hpp index 7ddbac765..8f1a18eaf 100644 --- a/ESPixelStick/src/input/InputMgr.hpp +++ b/ESPixelStick/src/input/InputMgr.hpp @@ -59,7 +59,7 @@ class c_InputMgr void SetBufferInfo (uint32_t BufferSize); void SetOperationalState (bool Active); void NetworkStateChanged (bool IsConnected); - void DeleteConfig () { FileMgr.DeleteConfigFile (ConfigFileName); } + void DeleteConfig () { FileMgr.DeleteFlashFile (ConfigFileName); } bool GetNetworkState () { return IsConnected; } void GetDriverName (String & Name) { Name = "InputMgr"; } void RestartBlankTimer (e_InputChannelIds Selector) { BlankEndTime[int(Selector)].StartTimer(config.BlankDelay * 1000); } diff --git a/ESPixelStick/src/output/OutputMgr.cpp b/ESPixelStick/src/output/OutputMgr.cpp index c02f7501b..4a6371d5a 100644 --- a/ESPixelStick/src/output/OutputMgr.cpp +++ b/ESPixelStick/src/output/OutputMgr.cpp @@ -267,13 +267,15 @@ void c_OutputMgr::Begin () // DEBUG_V(String("init index: ") + String(index) + " Done"); } - // CreateNewConfig (); + if(RestoredConfig) + { + // DEBUG_V("create a merged config"); + CreateNewConfig(); + } // DEBUG_V("load up the configuration from the saved file. This also starts the drivers"); LoadConfig(); - // CreateNewConfig (); - // Preset the output memory memset((void*)&OutputBuffer[0], 0x00, sizeof(OutputBuffer)); @@ -301,17 +303,12 @@ void c_OutputMgr::CreateJsonConfig (JsonObject& jsonConfig) // add the channels header JsonObject OutputMgrChannelsData; - if (true == jsonConfig.containsKey (CN_channels)) - { - // DEBUG_V (); - OutputMgrChannelsData = jsonConfig[CN_channels]; - } - else + if (!jsonConfig.containsKey (CN_channels)) { - // add our section header // DEBUG_V (); - OutputMgrChannelsData = jsonConfig.createNestedObject (CN_channels); + jsonConfig.createNestedObject (CN_channels); } + OutputMgrChannelsData = jsonConfig[CN_channels]; // add the channel configurations // DEBUG_V ("For Each Output Channel"); @@ -401,7 +398,19 @@ void c_OutputMgr::CreateNewConfig () DynamicJsonDocument JsonConfigDoc (OM_MAX_CONFIG_SIZE); // DEBUG_V (); - JsonObject JsonConfig = JsonConfigDoc.createNestedObject (CN_output_config); + // do we create a clean config or do we merge from a restored config? + if(RestoredConfig) + { + logcon("Merging Restored Output Config File"); + FileMgr.ReadFlashFile(ConfigFileName, JsonConfigDoc); + } + + if(!JsonConfigDoc.containsKey(CN_output_config)) + { + // DEBUG_V("Create a new output config area."); + JsonConfigDoc.createNestedObject (CN_output_config); + } + JsonObject JsonConfig = JsonConfigDoc[CN_output_config]; // DEBUG_V (); JsonConfig[CN_cfgver] = CurrentConfigVersion; @@ -471,7 +480,7 @@ void c_OutputMgr::GetConfig (String & Response) { // DEBUG_START; - FileMgr.ReadConfigFile (ConfigFileName, Response); + FileMgr.ReadFlashFile (ConfigFileName, Response); // DEBUG_END; @@ -482,7 +491,7 @@ void c_OutputMgr::GetConfig (byte * Response, uint32_t maxlen ) { // DEBUG_START; - FileMgr.ReadConfigFile (ConfigFileName, Response, maxlen); + FileMgr.ReadFlashFile (ConfigFileName, Response, maxlen); // DEBUG_END; @@ -1007,7 +1016,7 @@ void c_OutputMgr::LoadConfig () ConfigInProgress = true; // try to load and process the config file - if (!FileMgr.LoadConfigFile(ConfigFileName, [this](DynamicJsonDocument &JsonConfigDoc) + if (!FileMgr.LoadFlashFile(ConfigFileName, [this](DynamicJsonDocument &JsonConfigDoc) { // extern void PrettyPrint(DynamicJsonDocument & jsonStuff, String Name); // PrettyPrint(JsonConfigDoc, "OM Load Config"); @@ -1195,7 +1204,7 @@ void c_OutputMgr::SetConfig (const char * ConfigData) // DEBUG_V (String ("ConfigData: ") + ConfigData); - if (true == FileMgr.SaveConfigFile (ConfigFileName, ConfigData)) + if (true == FileMgr.SaveFlashFile (ConfigFileName, ConfigData)) { ScheduleLoadConfig(); } // end we got a config and it was good @@ -1224,7 +1233,7 @@ void c_OutputMgr::SetConfig(ArduinoJson::JsonDocument & ConfigData) // serializeJson(ConfigData, LOG_PORT); // DEBUG_V (); - if (true == FileMgr.SaveConfigFile(ConfigFileName, ConfigData)) + if (true == FileMgr.SaveFlashFile(ConfigFileName, ConfigData)) { ScheduleLoadConfig(); } // end we got a config and it was good diff --git a/ESPixelStick/src/output/OutputMgr.hpp b/ESPixelStick/src/output/OutputMgr.hpp index bfd180cc8..d583ba04a 100644 --- a/ESPixelStick/src/output/OutputMgr.hpp +++ b/ESPixelStick/src/output/OutputMgr.hpp @@ -55,7 +55,7 @@ class c_OutputMgr uint8_t* GetBufferAddress () { return OutputBuffer; } ///< Get the address of the buffer into which the E1.31 handler will stuff data uint32_t GetBufferUsedSize () { return UsedBufferSize; } ///< Get the size (in intensities) of the buffer into which the E1.31 handler will stuff data uint32_t GetBufferSize () { return sizeof(OutputBuffer); } ///< Get the size (in intensities) of the buffer into which the E1.31 handler will stuff data - void DeleteConfig () { FileMgr.DeleteConfigFile (ConfigFileName); } + void DeleteConfig () { FileMgr.DeleteFlashFile (ConfigFileName); } void PauseOutputs (bool NewState); void GetDriverName (String & Name) { Name = "OutputMgr"; } void WriteChannelData (uint32_t StartChannelId, uint32_t ChannelCount, uint8_t * pData); diff --git a/html/script.js b/html/script.js index 5e85d910c..7f0c5756c 100644 --- a/html/script.js +++ b/html/script.js @@ -73,7 +73,7 @@ class Semaphore { }); } } -} // Semaphore +} // callFunction const ServerAccess = new Semaphore(1); @@ -337,6 +337,7 @@ function ProcessLocalConfig(data) { ServerAccess.callFunction(SendConfigFileToServer, "config", {'system': ParsedLocalConfig.system}); ServerAccess.callFunction(SendConfigFileToServer, "output_config", {'output_config': ParsedLocalConfig.output}); ServerAccess.callFunction(SendConfigFileToServer, "input_config", {'input_config': ParsedLocalConfig.input}); + ServerAccess.callFunction(SendConfigFileToServer, "RestoredConfig", {'RestoredConfig': true}); } // ProcessLocalConfig