Use "pd" JSON API call for direct preset apply (#2946)
This commit is contained in:
parent
6bb158786b
commit
f50c9e855c
@ -2194,12 +2194,12 @@ function setPreset(i)
|
|||||||
{
|
{
|
||||||
var obj = {"ps":i};
|
var obj = {"ps":i};
|
||||||
if (pJson && pJson[i] && (!pJson[i].win || pJson[i].win.indexOf("Please") <= 0)) {
|
if (pJson && pJson[i] && (!pJson[i].win || pJson[i].win.indexOf("Please") <= 0)) {
|
||||||
// we will send complete preset content as to avoid delay introduced by
|
// we will send the complete preset content as to avoid delay introduced by
|
||||||
// async nature of applyPreset(). json.cpp has to decide wether to call applyPreset()
|
// async nature of applyPreset() and having to read the preset from file system.
|
||||||
// or not (by looking at the JSON content, if "ps" only)
|
obj = {"pd":i}; // use "pd" instead of "ps" to indicate that we are sending the preset content directly
|
||||||
Object.assign(obj, pJson[i]);
|
Object.assign(obj, pJson[i]);
|
||||||
delete obj.ql; // no need for quick load
|
delete obj.ql; // no need for quick load
|
||||||
delete obj.n; // no need for name
|
delete obj.n; // no need for name
|
||||||
}
|
}
|
||||||
if (isPlaylist(i)) obj.on = true; // force on
|
if (isPlaylist(i)) obj.on = true; // force on
|
||||||
showToast("Loading preset " + pName(i) +" (" + i + ")");
|
showToast("Loading preset " + pName(i) +" (" + i + ")");
|
||||||
|
3817
wled00/html_ui.h
3817
wled00/html_ui.h
File diff suppressed because it is too large
Load Diff
@ -394,29 +394,22 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId)
|
|||||||
handleSet(nullptr, apireq, false); // may set stateChanged
|
handleSet(nullptr, apireq, false); // may set stateChanged
|
||||||
}
|
}
|
||||||
|
|
||||||
// applying preset (2 cases: a) API call includes all preset values, b) API only specifies preset ID)
|
// applying preset (2 cases: a) API call includes all preset values ("pd"), b) API only specifies preset ID ("ps"))
|
||||||
if (!root["ps"].isNull()) {
|
byte presetToRestore = 0;
|
||||||
|
// a) already applied preset content (requires "seg" or "win" but will ignore the rest)
|
||||||
|
if (!root["pd"].isNull() && stateChanged) {
|
||||||
|
currentPreset = root[F("pd")] | currentPreset;
|
||||||
|
if (root["win"].isNull()) presetCycCurr = currentPreset;
|
||||||
|
presetToRestore = currentPreset; // stateUpdated() will clear the preset, so we need to restore it after
|
||||||
|
//unloadPlaylist(); // applying a preset unloads the playlist, may be needed here too?
|
||||||
|
} else if (!root["ps"].isNull()) {
|
||||||
ps = presetCycCurr;
|
ps = presetCycCurr;
|
||||||
if (stateChanged) {
|
if (root["win"].isNull() && getVal(root["ps"], &ps, 0, 0) && ps > 0 && ps < 251 && ps != currentPreset) {
|
||||||
// a) already applied preset content (requires "seg" or "win" but will ignore the rest)
|
|
||||||
currentPreset = root["ps"] | currentPreset;
|
|
||||||
// if preset contains HTTP API call do not change presetCycCurr
|
|
||||||
if (root["win"].isNull()) presetCycCurr = currentPreset;
|
|
||||||
stateChanged = false; // cancel state change update (preset was set directly by applying values stored in UI JSON array)
|
|
||||||
notify(callMode);
|
|
||||||
} else if (root["win"].isNull() && getVal(root["ps"], &ps, 0, 0) && ps > 0 && ps < 251 && ps != currentPreset) {
|
|
||||||
// b) preset ID only or preset that does not change state (use embedded cycling limits if they exist in getVal())
|
// b) preset ID only or preset that does not change state (use embedded cycling limits if they exist in getVal())
|
||||||
presetCycCurr = ps;
|
presetCycCurr = ps;
|
||||||
presetId = ps;
|
unloadPlaylist(); // applying a preset unloads the playlist
|
||||||
root.remove("v"); // may be added in UI call
|
applyPreset(ps, callMode); // async load from file system (only preset ID was specified)
|
||||||
root.remove("time"); // may be added in UI call
|
return stateResponse;
|
||||||
root.remove("ps");
|
|
||||||
root.remove("on"); // some external calls add "on" to "ps" call
|
|
||||||
if (root.size() == 0) {
|
|
||||||
unloadPlaylist(); // we need to unload playlist
|
|
||||||
applyPreset(ps, callMode); // async load (only preset ID was specified)
|
|
||||||
return stateResponse;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -428,6 +421,7 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId)
|
|||||||
}
|
}
|
||||||
|
|
||||||
stateUpdated(callMode);
|
stateUpdated(callMode);
|
||||||
|
if (presetToRestore) currentPreset = presetToRestore;
|
||||||
|
|
||||||
return stateResponse;
|
return stateResponse;
|
||||||
}
|
}
|
||||||
|
@ -16,15 +16,15 @@ static char quickLoad[9];
|
|||||||
static char saveName[33];
|
static char saveName[33];
|
||||||
static bool includeBri = true, segBounds = true, selectedOnly = false, playlistSave = false;;
|
static bool includeBri = true, segBounds = true, selectedOnly = false, playlistSave = false;;
|
||||||
|
|
||||||
static const char *getName(bool persist = true) {
|
static const char *getFileName(bool persist = true) {
|
||||||
return persist ? "/presets.json" : "/tmp.json";
|
return persist ? "/presets.json" : "/tmp.json";
|
||||||
}
|
}
|
||||||
|
|
||||||
static void doSaveState() {
|
static void doSaveState() {
|
||||||
bool persist = (presetToSave < 251);
|
bool persist = (presetToSave < 251);
|
||||||
const char *filename = getName(persist);
|
const char *filename = getFileName(persist);
|
||||||
|
|
||||||
if (!requestJSONBufferLock(10)) return; // will set fileDoc
|
if (!requestJSONBufferLock(10)) return; // will set fileDoc
|
||||||
|
|
||||||
initPresetsFile(); // just in case if someone deleted presets.json using /edit
|
initPresetsFile(); // just in case if someone deleted presets.json using /edit
|
||||||
JsonObject sObj = doc.to<JsonObject>();
|
JsonObject sObj = doc.to<JsonObject>();
|
||||||
@ -83,7 +83,7 @@ bool getPresetName(byte index, String& name)
|
|||||||
{
|
{
|
||||||
if (!requestJSONBufferLock(9)) return false;
|
if (!requestJSONBufferLock(9)) return false;
|
||||||
bool presetExists = false;
|
bool presetExists = false;
|
||||||
if (readObjectFromFileUsingId(getName(), index, &doc))
|
if (readObjectFromFileUsingId(getFileName(), index, &doc))
|
||||||
{
|
{
|
||||||
JsonObject fdo = doc.as<JsonObject>();
|
JsonObject fdo = doc.as<JsonObject>();
|
||||||
if (fdo["n"]) {
|
if (fdo["n"]) {
|
||||||
@ -97,12 +97,12 @@ bool getPresetName(byte index, String& name)
|
|||||||
|
|
||||||
void initPresetsFile()
|
void initPresetsFile()
|
||||||
{
|
{
|
||||||
if (WLED_FS.exists(getName())) return;
|
if (WLED_FS.exists(getFileName())) return;
|
||||||
|
|
||||||
StaticJsonDocument<64> doc;
|
StaticJsonDocument<64> doc;
|
||||||
JsonObject sObj = doc.to<JsonObject>();
|
JsonObject sObj = doc.to<JsonObject>();
|
||||||
sObj.createNestedObject("0");
|
sObj.createNestedObject("0");
|
||||||
File f = WLED_FS.open(getName(), "w");
|
File f = WLED_FS.open(getFileName(), "w");
|
||||||
if (!f) {
|
if (!f) {
|
||||||
errorFlag = ERR_FS_GENERAL;
|
errorFlag = ERR_FS_GENERAL;
|
||||||
return;
|
return;
|
||||||
@ -127,14 +127,14 @@ void handlePresets()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (presetToApply == 0 || fileDoc) return; // no preset waiting to apply, or JSON buffer is already allocated, return to loop until free
|
||||||
|
|
||||||
bool changePreset = false;
|
bool changePreset = false;
|
||||||
uint8_t tmpPreset = presetToApply; // store temporary since deserializeState() may call applyPreset()
|
uint8_t tmpPreset = presetToApply; // store temporary since deserializeState() may call applyPreset()
|
||||||
uint8_t tmpMode = callModeToApply;
|
uint8_t tmpMode = callModeToApply;
|
||||||
|
|
||||||
if (tmpPreset == 0 || (fileDoc /*&& !force*/)) return; // JSON buffer already allocated and not force apply or no preset waiting
|
|
||||||
|
|
||||||
JsonObject fdo;
|
JsonObject fdo;
|
||||||
const char *filename = getName(tmpPreset < 255);
|
const char *filename = getFileName(tmpPreset < 255);
|
||||||
|
|
||||||
// allocate buffer
|
// allocate buffer
|
||||||
if (!requestJSONBufferLock(9)) return; // will also assign fileDoc
|
if (!requestJSONBufferLock(9)) return; // will also assign fileDoc
|
||||||
@ -201,30 +201,28 @@ void savePreset(byte index, const char* pname, JsonObject sObj)
|
|||||||
presetToSave = index;
|
presetToSave = index;
|
||||||
playlistSave = false;
|
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
|
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
|
||||||
sObj.remove("v");
|
|
||||||
sObj.remove("time");
|
if (sObj["o"].isNull()) { // no "o" means not a playlist or custom API call, saving of state is async (not immediately)
|
||||||
sObj.remove(F("error"));
|
|
||||||
sObj.remove(F("psave"));
|
|
||||||
if (sObj["o"].isNull()) { // "o" marks a playlist or manually entered API
|
|
||||||
includeBri = sObj["ib"].as<bool>() || index==255; // temporary preset needs brightness
|
includeBri = sObj["ib"].as<bool>() || index==255; // temporary preset needs brightness
|
||||||
segBounds = sObj["sb"].as<bool>() || index==255; // temporary preset needs bounds
|
segBounds = sObj["sb"].as<bool>() || index==255; // temporary preset needs bounds
|
||||||
selectedOnly = sObj[F("sc")].as<bool>();
|
selectedOnly = sObj[F("sc")].as<bool>();
|
||||||
saveLedmap = sObj[F("ledmap")] | -1;
|
saveLedmap = sObj[F("ledmap")] | -1;
|
||||||
sObj.remove("ib");
|
|
||||||
sObj.remove("sb");
|
|
||||||
sObj.remove(F("sc"));
|
|
||||||
} else {
|
} else {
|
||||||
// this is a playlist or API
|
// this is a playlist or API call
|
||||||
sObj.remove("o");
|
|
||||||
if (sObj[F("playlist")].isNull()) {
|
if (sObj[F("playlist")].isNull()) {
|
||||||
presetToSave = 0; // we will save API immediately
|
// we will save API call immediately
|
||||||
if (index < 251 && fileDoc) {
|
presetToSave = 0;
|
||||||
if (sObj["n"].isNull()) sObj["n"] = saveName;
|
if (index > 250 || !fileDoc) return; // cannot save API calls to temporary preset (255)
|
||||||
initPresetsFile(); // just in case if someone deleted presets.json using /edit
|
sObj.remove("o");
|
||||||
writeObjectToFileUsingId(getName(index), index, fileDoc);
|
sObj.remove("v");
|
||||||
presetsModifiedTime = toki.second(); //unix time
|
sObj.remove("time");
|
||||||
updateFSInfo();
|
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(getFileName(index), index, fileDoc);
|
||||||
|
presetsModifiedTime = toki.second(); //unix time
|
||||||
|
updateFSInfo();
|
||||||
} else {
|
} else {
|
||||||
// store playlist
|
// store playlist
|
||||||
includeBri = true; // !sObj["on"].isNull();
|
includeBri = true; // !sObj["on"].isNull();
|
||||||
@ -235,7 +233,7 @@ void savePreset(byte index, const char* pname, JsonObject sObj)
|
|||||||
|
|
||||||
void deletePreset(byte index) {
|
void deletePreset(byte index) {
|
||||||
StaticJsonDocument<24> empty;
|
StaticJsonDocument<24> empty;
|
||||||
writeObjectToFileUsingId(getName(), index, &empty);
|
writeObjectToFileUsingId(getFileName(), index, &empty);
|
||||||
presetsModifiedTime = toki.second(); //unix time
|
presetsModifiedTime = toki.second(); //unix time
|
||||||
updateFSInfo();
|
updateFSInfo();
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user