2020-11-06 22:12:48 +01:00
|
|
|
#include "wled.h"
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Methods to handle saving and loading presets to/from the filesystem
|
|
|
|
*/
|
|
|
|
|
2021-11-12 23:33:10 +01:00
|
|
|
// called from: handleSet(), deserializeState(), applyMacro(), handlePlaylist(), checkCountdown(), checkTimers(), handleNightlight(), presetFallback()
|
|
|
|
// shortPressAction(), longPressAction(), doublePressAction(), handleSwitch(), onAlexaChange()
|
2021-07-09 18:42:52 +02:00
|
|
|
bool applyPreset(byte index, byte callMode)
|
2020-11-06 22:12:48 +01:00
|
|
|
{
|
2021-01-09 00:35:48 +01:00
|
|
|
if (index == 0) return false;
|
2021-10-04 20:22:04 +02:00
|
|
|
|
|
|
|
const char *filename = index < 255 ? "/presets.json" : "/tmp.json";
|
|
|
|
|
2021-12-11 23:17:47 +01:00
|
|
|
uint8_t core = 1;
|
|
|
|
//crude way to determine if this was called by a network request
|
|
|
|
#ifdef ARDUINO_ARCH_ESP32
|
|
|
|
core = xPortGetCoreID();
|
|
|
|
#endif
|
|
|
|
|
|
|
|
//only allow use of fileDoc from the core responsible for network requests
|
|
|
|
//do not use active network request doc from preset called by main loop (playlist, schedule, ...)
|
|
|
|
if (fileDoc && core) {
|
2021-10-04 20:22:04 +02:00
|
|
|
errorFlag = readObjectFromFileUsingId(filename, index, fileDoc) ? ERR_NONE : ERR_FS_PLOAD;
|
2020-11-09 00:50:13 +01:00
|
|
|
JsonObject fdo = fileDoc->as<JsonObject>();
|
|
|
|
if (fdo["ps"] == index) fdo.remove("ps"); //remove load request for same presets to prevent recursive crash
|
2020-11-06 22:12:48 +01:00
|
|
|
#ifdef WLED_DEBUG_FS
|
|
|
|
serializeJson(*fileDoc, Serial);
|
|
|
|
#endif
|
2021-07-09 18:42:52 +02:00
|
|
|
deserializeState(fdo, callMode, index);
|
2020-11-06 22:12:48 +01:00
|
|
|
} else {
|
2021-11-12 23:33:10 +01:00
|
|
|
DEBUG_PRINTLN(F("Apply preset JSON buffer requested."));
|
2021-11-14 16:56:34 +01:00
|
|
|
#ifdef WLED_USE_DYNAMIC_JSON
|
2021-11-07 11:58:16 +01:00
|
|
|
DynamicJsonDocument doc(JSON_BUFFER_SIZE);
|
2021-11-14 16:56:34 +01:00
|
|
|
#else
|
|
|
|
if (!requestJSONBufferLock(9)) return false;
|
|
|
|
#endif
|
2021-11-03 14:52:22 +01:00
|
|
|
errorFlag = readObjectFromFileUsingId(filename, index, &doc) ? ERR_NONE : ERR_FS_PLOAD;
|
|
|
|
JsonObject fdo = doc.as<JsonObject>();
|
2020-11-09 00:50:13 +01:00
|
|
|
if (fdo["ps"] == index) fdo.remove("ps");
|
2020-11-06 22:12:48 +01:00
|
|
|
#ifdef WLED_DEBUG_FS
|
2021-11-03 14:52:22 +01:00
|
|
|
serializeJson(doc, Serial);
|
2020-11-06 22:12:48 +01:00
|
|
|
#endif
|
2021-07-09 18:42:52 +02:00
|
|
|
deserializeState(fdo, callMode, index);
|
2021-11-12 23:33:10 +01:00
|
|
|
releaseJSONBufferLock();
|
2020-11-06 22:12:48 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!errorFlag) {
|
2021-10-04 20:22:04 +02:00
|
|
|
if (index < 255) currentPreset = index;
|
2020-11-06 22:12:48 +01:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void savePreset(byte index, bool persist, const char* pname, JsonObject saveobj)
|
|
|
|
{
|
2021-10-04 20:22:04 +02:00
|
|
|
if (index == 0 || (index > 250 && persist) || (index<255 && !persist)) return;
|
2020-11-06 22:12:48 +01:00
|
|
|
JsonObject sObj = saveobj;
|
|
|
|
|
2021-10-04 20:22:04 +02:00
|
|
|
const char *filename = persist ? "/presets.json" : "/tmp.json";
|
|
|
|
|
2021-11-03 14:52:22 +01:00
|
|
|
if (!fileDoc) {
|
2021-11-12 23:33:10 +01:00
|
|
|
DEBUG_PRINTLN(F("Save preset JSON buffer requested."));
|
2021-11-14 16:56:34 +01:00
|
|
|
#ifdef WLED_USE_DYNAMIC_JSON
|
2021-11-07 11:58:16 +01:00
|
|
|
DynamicJsonDocument doc(JSON_BUFFER_SIZE);
|
2021-11-14 16:56:34 +01:00
|
|
|
#else
|
|
|
|
if (!requestJSONBufferLock(10)) return;
|
|
|
|
#endif
|
2021-11-03 14:52:22 +01:00
|
|
|
sObj = doc.to<JsonObject>();
|
2020-11-06 22:12:48 +01:00
|
|
|
if (pname) sObj["n"] = pname;
|
2021-11-03 14:52:22 +01:00
|
|
|
|
2020-11-29 22:07:12 +01:00
|
|
|
DEBUGFS_PRINTLN(F("Save current state"));
|
|
|
|
serializeState(sObj, true);
|
2021-10-04 20:22:04 +02:00
|
|
|
if (persist) currentPreset = index;
|
2020-11-29 22:07:12 +01:00
|
|
|
|
2021-11-03 14:52:22 +01:00
|
|
|
writeObjectToFileUsingId(filename, index, &doc);
|
|
|
|
|
2021-11-12 23:33:10 +01:00
|
|
|
releaseJSONBufferLock();
|
2021-11-03 14:52:22 +01:00
|
|
|
} else { //from JSON API (fileDoc != nullptr)
|
2020-11-06 22:12:48 +01:00
|
|
|
DEBUGFS_PRINTLN(F("Reuse recv buffer"));
|
|
|
|
sObj.remove(F("psave"));
|
|
|
|
sObj.remove(F("v"));
|
|
|
|
|
2020-11-29 22:07:12 +01:00
|
|
|
if (!sObj["o"]) {
|
|
|
|
DEBUGFS_PRINTLN(F("Save current state"));
|
|
|
|
serializeState(sObj, true, sObj["ib"], sObj["sb"]);
|
2021-10-04 20:22:04 +02:00
|
|
|
if (persist) currentPreset = index;
|
2020-11-29 22:07:12 +01:00
|
|
|
}
|
|
|
|
sObj.remove("o");
|
|
|
|
sObj.remove("ib");
|
|
|
|
sObj.remove("sb");
|
|
|
|
sObj.remove(F("error"));
|
|
|
|
sObj.remove(F("time"));
|
2020-11-06 22:12:48 +01:00
|
|
|
|
2021-10-04 20:22:04 +02:00
|
|
|
writeObjectToFileUsingId(filename, index, fileDoc);
|
2020-11-29 22:07:12 +01:00
|
|
|
}
|
2021-10-04 20:22:04 +02:00
|
|
|
if (persist) presetsModifiedTime = toki.second(); //unix time
|
2020-11-06 22:12:48 +01:00
|
|
|
updateFSInfo();
|
|
|
|
}
|
|
|
|
|
|
|
|
void deletePreset(byte index) {
|
|
|
|
StaticJsonDocument<24> empty;
|
|
|
|
writeObjectToFileUsingId("/presets.json", index, &empty);
|
2021-05-25 09:59:19 +02:00
|
|
|
presetsModifiedTime = toki.second(); //unix time
|
2020-11-06 22:12:48 +01:00
|
|
|
updateFSInfo();
|
|
|
|
}
|