mirror of
https://github.com/wled/WLED.git
synced 2025-04-19 12:27:17 +00:00
Merge pull request #4609 from willmmiles/usermod-cfg-live
Use live cfg json instead of file for usermod settings page
This commit is contained in:
commit
e979c58c98
@ -671,7 +671,7 @@ void deserializeConfigFromFS() {
|
||||
// call readFromConfig() with an empty object so that usermods can initialize to defaults prior to saving
|
||||
JsonObject empty = JsonObject();
|
||||
UsermodManager::readFromConfig(empty);
|
||||
serializeConfig();
|
||||
serializeConfigToFS();
|
||||
// init Ethernet (in case default type is set at compile time)
|
||||
#if defined(ARDUINO_ARCH_ESP32) && defined(WLED_USE_ETHERNET)
|
||||
initEthernet();
|
||||
@ -685,10 +685,10 @@ void deserializeConfigFromFS() {
|
||||
bool needsSave = deserializeConfig(root, true);
|
||||
releaseJSONBufferLock();
|
||||
|
||||
if (needsSave) serializeConfig(); // usermods required new parameters
|
||||
if (needsSave) serializeConfigToFS(); // usermods required new parameters
|
||||
}
|
||||
|
||||
void serializeConfig() {
|
||||
void serializeConfigToFS() {
|
||||
serializeConfigSec();
|
||||
|
||||
DEBUG_PRINTLN(F("Writing settings to /cfg.json..."));
|
||||
@ -697,6 +697,17 @@ void serializeConfig() {
|
||||
|
||||
JsonObject root = pDoc->to<JsonObject>();
|
||||
|
||||
serializeConfig(root);
|
||||
|
||||
File f = WLED_FS.open(FPSTR(s_cfg_json), "w");
|
||||
if (f) serializeJson(root, f);
|
||||
f.close();
|
||||
releaseJSONBufferLock();
|
||||
|
||||
configNeedsWrite = false;
|
||||
}
|
||||
|
||||
void serializeConfig(JsonObject root) {
|
||||
JsonArray rev = root.createNestedArray("rev");
|
||||
rev.add(1); //major settings revision
|
||||
rev.add(0); //minor settings revision
|
||||
@ -1111,13 +1122,6 @@ void serializeConfig() {
|
||||
|
||||
JsonObject usermods_settings = root.createNestedObject("um");
|
||||
UsermodManager::addToConfig(usermods_settings);
|
||||
|
||||
File f = WLED_FS.open(FPSTR(s_cfg_json), "w");
|
||||
if (f) serializeJson(root, f);
|
||||
f.close();
|
||||
releaseJSONBufferLock();
|
||||
|
||||
doSerializeConfig = false;
|
||||
}
|
||||
|
||||
|
||||
|
@ -13,7 +13,7 @@
|
||||
function S() {
|
||||
getLoc();
|
||||
// load settings and insert values into DOM
|
||||
fetch(getURL('/cfg.json'), {
|
||||
fetch(getURL('/json/cfg'), {
|
||||
method: 'get'
|
||||
})
|
||||
.then(res => {
|
||||
|
@ -22,7 +22,7 @@ void rdmPersonalityChangedCb(dmx_port_t dmxPort, const rdm_header_t *header,
|
||||
if (header->cc == RDM_CC_SET_COMMAND_RESPONSE) {
|
||||
const uint8_t personality = dmx_get_current_personality(dmx->inputPortNum);
|
||||
DMXMode = std::min(DMX_MODE_PRESET, std::max(DMX_MODE_SINGLE_RGB, int(personality)));
|
||||
doSerializeConfig = true;
|
||||
configNeedsWrite = true;
|
||||
DEBUG_PRINTF("DMX personality changed to to: %d\n", DMXMode);
|
||||
}
|
||||
}
|
||||
@ -40,7 +40,7 @@ void rdmAddressChangedCb(dmx_port_t dmxPort, const rdm_header_t *header,
|
||||
if (header->cc == RDM_CC_SET_COMMAND_RESPONSE) {
|
||||
const uint16_t addr = dmx_get_start_address(dmx->inputPortNum);
|
||||
DMXAddress = std::min(512, int(addr));
|
||||
doSerializeConfig = true;
|
||||
configNeedsWrite = true;
|
||||
DEBUG_PRINTF("DMX start addr changed to: %d\n", DMXAddress);
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,8 @@ void IRAM_ATTR touchButtonISR();
|
||||
bool deserializeConfig(JsonObject doc, bool fromFS = false);
|
||||
void deserializeConfigFromFS();
|
||||
bool deserializeConfigSec();
|
||||
void serializeConfig();
|
||||
void serializeConfig(JsonObject doc);
|
||||
void serializeConfigToFS();
|
||||
void serializeConfigSec();
|
||||
|
||||
template<typename DestType>
|
||||
|
@ -272,5 +272,5 @@ void parseWiFiCommand(char* rpcData) {
|
||||
improvActive = 2;
|
||||
|
||||
forceReconnect = true;
|
||||
serializeConfig();
|
||||
serializeConfigToFS();
|
||||
}
|
@ -2,15 +2,6 @@
|
||||
|
||||
#include "palettes.h"
|
||||
|
||||
#define JSON_PATH_STATE 1
|
||||
#define JSON_PATH_INFO 2
|
||||
#define JSON_PATH_STATE_INFO 3
|
||||
#define JSON_PATH_NODES 4
|
||||
#define JSON_PATH_PALETTES 5
|
||||
#define JSON_PATH_FXDATA 6
|
||||
#define JSON_PATH_NETWORKS 7
|
||||
#define JSON_PATH_EFFECTS 8
|
||||
|
||||
/*
|
||||
* JSON API (De)serialization
|
||||
*/
|
||||
@ -1036,16 +1027,21 @@ class LockedJsonResponse: public AsyncJsonResponse {
|
||||
|
||||
void serveJson(AsyncWebServerRequest* request)
|
||||
{
|
||||
byte subJson = 0;
|
||||
enum class json_target {
|
||||
all, state, info, state_info, nodes, effects, palettes, fxdata, networks, config
|
||||
};
|
||||
json_target subJson = json_target::all;
|
||||
|
||||
const String& url = request->url();
|
||||
if (url.indexOf("state") > 0) subJson = JSON_PATH_STATE;
|
||||
else if (url.indexOf("info") > 0) subJson = JSON_PATH_INFO;
|
||||
else if (url.indexOf("si") > 0) subJson = JSON_PATH_STATE_INFO;
|
||||
else if (url.indexOf(F("nodes")) > 0) subJson = JSON_PATH_NODES;
|
||||
else if (url.indexOf(F("eff")) > 0) subJson = JSON_PATH_EFFECTS;
|
||||
else if (url.indexOf(F("palx")) > 0) subJson = JSON_PATH_PALETTES;
|
||||
else if (url.indexOf(F("fxda")) > 0) subJson = JSON_PATH_FXDATA;
|
||||
else if (url.indexOf(F("net")) > 0) subJson = JSON_PATH_NETWORKS;
|
||||
if (url.indexOf("state") > 0) subJson = json_target::state;
|
||||
else if (url.indexOf("info") > 0) subJson = json_target::info;
|
||||
else if (url.indexOf("si") > 0) subJson = json_target::state_info;
|
||||
else if (url.indexOf(F("nodes")) > 0) subJson = json_target::nodes;
|
||||
else if (url.indexOf(F("eff")) > 0) subJson = json_target::effects;
|
||||
else if (url.indexOf(F("palx")) > 0) subJson = json_target::palettes;
|
||||
else if (url.indexOf(F("fxda")) > 0) subJson = json_target::fxdata;
|
||||
else if (url.indexOf(F("net")) > 0) subJson = json_target::networks;
|
||||
else if (url.indexOf(F("cfg")) > 0) subJson = json_target::config;
|
||||
#ifdef WLED_ENABLE_JSONLIVE
|
||||
else if (url.indexOf("live") > 0) {
|
||||
serveLiveLeds(request);
|
||||
@ -1056,9 +1052,6 @@ void serveJson(AsyncWebServerRequest* request)
|
||||
request->send_P(200, FPSTR(CONTENT_TYPE_JSON), JSON_palette_names);
|
||||
return;
|
||||
}
|
||||
else if (url.indexOf(F("cfg")) > 0 && handleFileRead(request, F("/cfg.json"))) {
|
||||
return;
|
||||
}
|
||||
else if (url.length() > 6) { //not just /json
|
||||
serveJsonError(request, 501, ERR_NOT_IMPL);
|
||||
return;
|
||||
@ -1070,32 +1063,35 @@ void serveJson(AsyncWebServerRequest* request)
|
||||
}
|
||||
// releaseJSONBufferLock() will be called when "response" is destroyed (from AsyncWebServer)
|
||||
// make sure you delete "response" if no "request->send(response);" is made
|
||||
LockedJsonResponse *response = new LockedJsonResponse(pDoc, subJson==JSON_PATH_FXDATA || subJson==JSON_PATH_EFFECTS); // will clear and convert JsonDocument into JsonArray if necessary
|
||||
LockedJsonResponse *response = new LockedJsonResponse(pDoc, subJson==json_target::fxdata || subJson==json_target::effects); // will clear and convert JsonDocument into JsonArray if necessary
|
||||
|
||||
JsonVariant lDoc = response->getRoot();
|
||||
|
||||
switch (subJson)
|
||||
{
|
||||
case JSON_PATH_STATE:
|
||||
case json_target::state:
|
||||
serializeState(lDoc); break;
|
||||
case JSON_PATH_INFO:
|
||||
case json_target::info:
|
||||
serializeInfo(lDoc); break;
|
||||
case JSON_PATH_NODES:
|
||||
case json_target::nodes:
|
||||
serializeNodes(lDoc); break;
|
||||
case JSON_PATH_PALETTES:
|
||||
case json_target::palettes:
|
||||
serializePalettes(lDoc, request->hasParam(F("page")) ? request->getParam(F("page"))->value().toInt() : 0); break;
|
||||
case JSON_PATH_EFFECTS:
|
||||
case json_target::effects:
|
||||
serializeModeNames(lDoc); break;
|
||||
case JSON_PATH_FXDATA:
|
||||
case json_target::fxdata:
|
||||
serializeModeData(lDoc); break;
|
||||
case JSON_PATH_NETWORKS:
|
||||
case json_target::networks:
|
||||
serializeNetworks(lDoc); break;
|
||||
default: //all
|
||||
case json_target::config:
|
||||
serializeConfig(lDoc); break;
|
||||
case json_target::state_info:
|
||||
case json_target::all:
|
||||
JsonObject state = lDoc.createNestedObject("state");
|
||||
serializeState(state);
|
||||
JsonObject info = lDoc.createNestedObject("info");
|
||||
serializeInfo(info);
|
||||
if (subJson != JSON_PATH_STATE_INFO)
|
||||
if (subJson == json_target::all)
|
||||
{
|
||||
JsonArray effects = lDoc.createNestedArray(F("effects"));
|
||||
serializeModeNames(effects); // remove WLED-SR extensions from effect names
|
||||
|
@ -242,7 +242,7 @@ void savePreset(byte index, const char* pname, JsonObject sObj)
|
||||
if (!sObj[FPSTR(bootPS)].isNull()) {
|
||||
bootPreset = sObj[FPSTR(bootPS)] | bootPreset;
|
||||
sObj.remove(FPSTR(bootPS));
|
||||
doSerializeConfig = true;
|
||||
configNeedsWrite = true;
|
||||
}
|
||||
|
||||
if (sObj.size()==0 || sObj["o"].isNull()) { // no "o" means not a playlist or custom API call, saving of state is async (not immediately)
|
||||
|
@ -805,8 +805,8 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
||||
|
||||
lastEditTime = millis();
|
||||
// do not save if factory reset or LED settings (which are saved after LED re-init)
|
||||
doSerializeConfig = subPage != SUBPAGE_LEDS && !(subPage == SUBPAGE_SEC && doReboot);
|
||||
if (subPage == SUBPAGE_UM) doReboot = request->hasArg(F("RBT")); // prevent race condition on dual core system (set reboot here, after doSerializeConfig has been set)
|
||||
configNeedsWrite = subPage != SUBPAGE_LEDS && !(subPage == SUBPAGE_SEC && doReboot);
|
||||
if (subPage == SUBPAGE_UM) doReboot = request->hasArg(F("RBT")); // prevent race condition on dual core system (set reboot here, after configNeedsWrite has been set)
|
||||
#ifndef WLED_DISABLE_ALEXA
|
||||
if (subPage == SUBPAGE_SYNC) alexaInit();
|
||||
#endif
|
||||
|
@ -193,14 +193,14 @@ void WLED::loop()
|
||||
if (aligned) strip.makeAutoSegments();
|
||||
else strip.fixInvalidSegments();
|
||||
BusManager::setBrightness(bri); // fix re-initialised bus' brightness
|
||||
doSerializeConfig = true;
|
||||
configNeedsWrite = true;
|
||||
}
|
||||
if (loadLedmap >= 0) {
|
||||
strip.deserializeMap(loadLedmap);
|
||||
loadLedmap = -1;
|
||||
}
|
||||
yield();
|
||||
if (doSerializeConfig) serializeConfig();
|
||||
if (configNeedsWrite) serializeConfigToFS();
|
||||
|
||||
yield();
|
||||
handleWs();
|
||||
@ -223,7 +223,7 @@ void WLED::loop()
|
||||
}
|
||||
#endif
|
||||
|
||||
if (doReboot && (!doInitBusses || !doSerializeConfig)) // if busses have to be inited & saved, wait until next iteration
|
||||
if (doReboot && (!doInitBusses || !configNeedsWrite)) // if busses have to be inited & saved, wait until next iteration
|
||||
reset();
|
||||
|
||||
// DEBUG serial logging (every 30s)
|
||||
|
@ -877,7 +877,7 @@ WLED_GLOBAL byte errorFlag _INIT(0);
|
||||
WLED_GLOBAL String messageHead, messageSub;
|
||||
WLED_GLOBAL byte optionType;
|
||||
|
||||
WLED_GLOBAL bool doSerializeConfig _INIT(false); // flag to initiate saving of config
|
||||
WLED_GLOBAL bool configNeedsWrite _INIT(false); // flag to initiate saving of config
|
||||
WLED_GLOBAL bool doReboot _INIT(false); // flag to initiate reboot from async handlers
|
||||
|
||||
WLED_GLOBAL bool psramSafe _INIT(true); // is it safe to use PSRAM (on ESP32 rev.1; compiler fix used "-mfix-esp32-psram-cache-issue")
|
||||
|
@ -328,7 +328,7 @@ void initServer()
|
||||
interfaceUpdateCallMode = CALL_MODE_WS_SEND; // schedule WS update
|
||||
serveJson(request); return; //if JSON contains "v"
|
||||
} else {
|
||||
doSerializeConfig = true; //serializeConfig(); //Save new settings to FS
|
||||
configNeedsWrite = true; //Save new settings to FS
|
||||
}
|
||||
}
|
||||
request->send(200, CONTENT_TYPE_JSON, F("{\"success\":true}"));
|
||||
|
Loading…
x
Reference in New Issue
Block a user