From 49f044ecde8119d03d78fe167f375e71eabf6150 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bla=C5=BE=20Kristan?= Date: Sun, 13 Oct 2024 10:43:56 +0200 Subject: [PATCH] Better fix for #4154 --- wled00/json.cpp | 19 ++++++++++++------- wled00/presets.cpp | 4 ++-- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/wled00/json.cpp b/wled00/json.cpp index c877d1f3b..06eb3015e 100644 --- a/wled00/json.cpp +++ b/wled00/json.cpp @@ -454,20 +454,25 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId) handleSet(nullptr, apireq, false); // may set stateChanged } - // applying preset (2 cases: a) API call includes all preset values ("pd"), b) API only specifies preset ID ("ps")) + // Applying preset from JSON API has 2 cases: a) "pd" AKA "preset direct" and b) "ps" AKA "preset select" + // a) "preset direct" can only be an integer value representing preset ID. "preset direct" assumes JSON API contains the rest of preset content (i.e. from UI call) + // "preset direct" JSON can contain "ps" API (i.e. call from UI to cycle presets) in such case stateChanged has to be false (i.e. no "win" or "seg" API) + // b) "preset select" can be cycling ("1~5~""), random ("r" or "1~5r"), ID, etc. value allowed from JSON API. This type of call assumes no state changing content in API call byte presetToRestore = 0; - // a) already applied preset content (requires "seg" or "win" but will ignore the rest) if (!root[F("pd")].isNull() && stateChanged) { + // a) already applied preset content (requires "seg" or "win" but will ignore the rest) currentPreset = root[F("pd")] | currentPreset; - if (root["win"].isNull()) presetCycCurr = currentPreset; // otherwise it was set in handleSet() [set.cpp] + if (root["win"].isNull()) presetCycCurr = currentPreset; // otherwise presetCycCurr was set in handleSet() [set.cpp] presetToRestore = currentPreset; // stateUpdated() will clear the preset, so we need to restore it after + DEBUG_PRINTF_P(PSTR("Preset direct: %d\n"), currentPreset); } else if (!root["ps"].isNull()) { - ps = presetCycCurr; - if (root["win"].isNull() && getVal(root["ps"], &ps, 0, 0) && ps > 0 && ps < 251 && ps != currentPreset) { + // we have "ps" call (i.e. from button or external API call) or "pd" that includes "ps" (i.e. from UI call) + if (root["win"].isNull() && getVal(root["ps"], &presetCycCurr, 0, 0) && presetCycCurr > 0 && presetCycCurr < 251 && presetCycCurr != currentPreset) { + DEBUG_PRINTF_P(PSTR("Preset select: %d\n"), presetCycCurr); // b) preset ID only or preset that does not change state (use embedded cycling limits if they exist in getVal()) - applyPreset(ps, callMode); // async load from file system (only preset ID was specified) + applyPreset(presetCycCurr, callMode); // async load from file system (only preset ID was specified) return stateResponse; - } + } else presetCycCurr = currentPreset; // restore presetCycCurr } JsonObject playlist = root[F("playlist")]; diff --git a/wled00/presets.cpp b/wled00/presets.cpp index 2749d4677..20edfd91e 100644 --- a/wled00/presets.cpp +++ b/wled00/presets.cpp @@ -118,7 +118,7 @@ void initPresetsFile() bool applyPresetFromPlaylist(byte index) { DEBUG_PRINTF_P(PSTR("Request to apply preset: %d\n"), index); - presetToApply = presetCycCurr = index; + presetToApply = index; callModeToApply = CALL_MODE_DIRECT_CHANGE; return true; } @@ -127,7 +127,7 @@ bool applyPreset(byte index, byte callMode) { unloadPlaylist(); // applying a preset unloads the playlist (#3827) DEBUG_PRINTF_P(PSTR("Request to apply preset: %u\n"), index); - presetToApply = presetCycCurr = index; + presetToApply = index; callModeToApply = callMode; return true; }