mirror of
https://github.com/wled/WLED.git
synced 2025-07-23 18:56:41 +00:00
Implement JSON buffer in PSRAM to free up DRAM.
This commit is contained in:
parent
4e105492ca
commit
1f81fb9284
@ -94,12 +94,12 @@ void WS2812FX::setUpMatrix() {
|
|||||||
DEBUG_PRINT(F("Reading LED gap from "));
|
DEBUG_PRINT(F("Reading LED gap from "));
|
||||||
DEBUG_PRINTLN(fileName);
|
DEBUG_PRINTLN(fileName);
|
||||||
// read the array into global JSON buffer
|
// read the array into global JSON buffer
|
||||||
if (readObjectFromFile(fileName, nullptr, &doc)) {
|
if (readObjectFromFile(fileName, nullptr, pDoc)) {
|
||||||
// the array is similar to ledmap, except it has only 3 values:
|
// the array is similar to ledmap, except it has only 3 values:
|
||||||
// -1 ... missing pixel (do not increase pixel count)
|
// -1 ... missing pixel (do not increase pixel count)
|
||||||
// 0 ... inactive pixel (it does count, but should be mapped out (-1))
|
// 0 ... inactive pixel (it does count, but should be mapped out (-1))
|
||||||
// 1 ... active pixel (it will count and will be mapped)
|
// 1 ... active pixel (it will count and will be mapped)
|
||||||
JsonArray map = doc.as<JsonArray>();
|
JsonArray map = pDoc->as<JsonArray>();
|
||||||
gapSize = map.size();
|
gapSize = map.size();
|
||||||
if (!map.isNull() && gapSize >= customMappingSize) { // not an empty map
|
if (!map.isNull() && gapSize >= customMappingSize) { // not an empty map
|
||||||
gapTable = new int8_t[gapSize];
|
gapTable = new int8_t[gapSize];
|
||||||
|
@ -1670,7 +1670,7 @@ bool WS2812FX::deserializeMap(uint8_t n) {
|
|||||||
|
|
||||||
if (!requestJSONBufferLock(7)) return false;
|
if (!requestJSONBufferLock(7)) return false;
|
||||||
|
|
||||||
if (!readObjectFromFile(fileName, nullptr, &doc)) {
|
if (!readObjectFromFile(fileName, nullptr, pDoc)) {
|
||||||
releaseJSONBufferLock();
|
releaseJSONBufferLock();
|
||||||
return false; //if file does not exist just exit
|
return false; //if file does not exist just exit
|
||||||
}
|
}
|
||||||
@ -1685,7 +1685,8 @@ bool WS2812FX::deserializeMap(uint8_t n) {
|
|||||||
customMappingTable = nullptr;
|
customMappingTable = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonArray map = doc[F("map")];
|
JsonObject root = pDoc->as<JsonObject>();
|
||||||
|
JsonArray map = root[F("map")];
|
||||||
if (!map.isNull() && map.size()) { // not an empty map
|
if (!map.isNull() && map.size()) { // not an empty map
|
||||||
customMappingSize = map.size();
|
customMappingSize = map.size();
|
||||||
customMappingTable = new uint16_t[customMappingSize];
|
customMappingTable = new uint16_t[customMappingSize];
|
||||||
|
@ -609,7 +609,7 @@ void deserializeConfigFromFS() {
|
|||||||
|
|
||||||
DEBUG_PRINTLN(F("Reading settings from /cfg.json..."));
|
DEBUG_PRINTLN(F("Reading settings from /cfg.json..."));
|
||||||
|
|
||||||
success = readObjectFromFile("/cfg.json", nullptr, &doc);
|
success = readObjectFromFile("/cfg.json", nullptr, pDoc);
|
||||||
if (!success) { // if file does not exist, optionally try reading from EEPROM and then save defaults to FS
|
if (!success) { // if file does not exist, optionally try reading from EEPROM and then save defaults to FS
|
||||||
releaseJSONBufferLock();
|
releaseJSONBufferLock();
|
||||||
#ifdef WLED_ADD_EEPROM_SUPPORT
|
#ifdef WLED_ADD_EEPROM_SUPPORT
|
||||||
@ -630,7 +630,8 @@ void deserializeConfigFromFS() {
|
|||||||
|
|
||||||
// NOTE: This routine deserializes *and* applies the configuration
|
// NOTE: This routine deserializes *and* applies the configuration
|
||||||
// Therefore, must also initialize ethernet from this function
|
// Therefore, must also initialize ethernet from this function
|
||||||
bool needsSave = deserializeConfig(doc.as<JsonObject>(), true);
|
JsonObject root = pDoc->as<JsonObject>();
|
||||||
|
bool needsSave = deserializeConfig(root, true);
|
||||||
releaseJSONBufferLock();
|
releaseJSONBufferLock();
|
||||||
|
|
||||||
if (needsSave) serializeConfig(); // usermods required new parameters
|
if (needsSave) serializeConfig(); // usermods required new parameters
|
||||||
@ -643,19 +644,21 @@ void serializeConfig() {
|
|||||||
|
|
||||||
if (!requestJSONBufferLock(2)) return;
|
if (!requestJSONBufferLock(2)) return;
|
||||||
|
|
||||||
JsonArray rev = doc.createNestedArray("rev");
|
JsonObject root = pDoc->as<JsonObject>();
|
||||||
|
|
||||||
|
JsonArray rev = root.createNestedArray("rev");
|
||||||
rev.add(1); //major settings revision
|
rev.add(1); //major settings revision
|
||||||
rev.add(0); //minor settings revision
|
rev.add(0); //minor settings revision
|
||||||
|
|
||||||
doc[F("vid")] = VERSION;
|
root[F("vid")] = VERSION;
|
||||||
|
|
||||||
JsonObject id = doc.createNestedObject("id");
|
JsonObject id = root.createNestedObject("id");
|
||||||
id[F("mdns")] = cmDNS;
|
id[F("mdns")] = cmDNS;
|
||||||
id[F("name")] = serverDescription;
|
id[F("name")] = serverDescription;
|
||||||
id[F("inv")] = alexaInvocationName;
|
id[F("inv")] = alexaInvocationName;
|
||||||
id[F("sui")] = simplifiedUI;
|
id[F("sui")] = simplifiedUI;
|
||||||
|
|
||||||
JsonObject nw = doc.createNestedObject("nw");
|
JsonObject nw = root.createNestedObject("nw");
|
||||||
#ifndef WLED_DISABLE_ESPNOW
|
#ifndef WLED_DISABLE_ESPNOW
|
||||||
nw[F("espnow")] = enableESPNow;
|
nw[F("espnow")] = enableESPNow;
|
||||||
nw[F("linked_remote")] = linked_remote;
|
nw[F("linked_remote")] = linked_remote;
|
||||||
@ -677,7 +680,7 @@ void serializeConfig() {
|
|||||||
nw_ins_0_sn.add(staticSubnet[i]);
|
nw_ins_0_sn.add(staticSubnet[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonObject ap = doc.createNestedObject("ap");
|
JsonObject ap = root.createNestedObject("ap");
|
||||||
ap[F("ssid")] = apSSID;
|
ap[F("ssid")] = apSSID;
|
||||||
ap[F("pskl")] = strlen(apPass);
|
ap[F("pskl")] = strlen(apPass);
|
||||||
ap[F("chan")] = apChannel;
|
ap[F("chan")] = apChannel;
|
||||||
@ -690,12 +693,12 @@ void serializeConfig() {
|
|||||||
ap_ip.add(2);
|
ap_ip.add(2);
|
||||||
ap_ip.add(1);
|
ap_ip.add(1);
|
||||||
|
|
||||||
JsonObject wifi = doc.createNestedObject("wifi");
|
JsonObject wifi = root.createNestedObject("wifi");
|
||||||
wifi[F("sleep")] = !noWifiSleep;
|
wifi[F("sleep")] = !noWifiSleep;
|
||||||
//wifi[F("phy")] = 1;
|
//wifi[F("phy")] = 1;
|
||||||
|
|
||||||
#ifdef WLED_USE_ETHERNET
|
#ifdef WLED_USE_ETHERNET
|
||||||
JsonObject ethernet = doc.createNestedObject("eth");
|
JsonObject ethernet = root.createNestedObject("eth");
|
||||||
ethernet["type"] = ethernetType;
|
ethernet["type"] = ethernetType;
|
||||||
if (ethernetType != WLED_ETH_NONE && ethernetType < WLED_NUM_ETH_TYPES) {
|
if (ethernetType != WLED_ETH_NONE && ethernetType < WLED_NUM_ETH_TYPES) {
|
||||||
JsonArray pins = ethernet.createNestedArray("pin");
|
JsonArray pins = ethernet.createNestedArray("pin");
|
||||||
@ -718,7 +721,7 @@ void serializeConfig() {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
JsonObject hw = doc.createNestedObject("hw");
|
JsonObject hw = root.createNestedObject("hw");
|
||||||
|
|
||||||
JsonObject hw_led = hw.createNestedObject("led");
|
JsonObject hw_led = hw.createNestedObject("led");
|
||||||
hw_led[F("total")] = strip.getLengthTotal(); //provided for compatibility on downgrade and per-output ABL
|
hw_led[F("total")] = strip.getLengthTotal(); //provided for compatibility on downgrade and per-output ABL
|
||||||
@ -830,7 +833,7 @@ void serializeConfig() {
|
|||||||
//JsonObject hw_status = hw.createNestedObject("status");
|
//JsonObject hw_status = hw.createNestedObject("status");
|
||||||
//hw_status["pin"] = -1;
|
//hw_status["pin"] = -1;
|
||||||
|
|
||||||
JsonObject light = doc.createNestedObject(F("light"));
|
JsonObject light = root.createNestedObject(F("light"));
|
||||||
light[F("scale-bri")] = briMultiplier;
|
light[F("scale-bri")] = briMultiplier;
|
||||||
light[F("pal-mode")] = strip.paletteBlend;
|
light[F("pal-mode")] = strip.paletteBlend;
|
||||||
light[F("aseg")] = autoSegments;
|
light[F("aseg")] = autoSegments;
|
||||||
@ -853,12 +856,12 @@ void serializeConfig() {
|
|||||||
light_nl[F("tbri")] = nightlightTargetBri;
|
light_nl[F("tbri")] = nightlightTargetBri;
|
||||||
light_nl["macro"] = macroNl;
|
light_nl["macro"] = macroNl;
|
||||||
|
|
||||||
JsonObject def = doc.createNestedObject("def");
|
JsonObject def = root.createNestedObject("def");
|
||||||
def["ps"] = bootPreset;
|
def["ps"] = bootPreset;
|
||||||
def["on"] = turnOnAtBoot;
|
def["on"] = turnOnAtBoot;
|
||||||
def["bri"] = briS;
|
def["bri"] = briS;
|
||||||
|
|
||||||
JsonObject interfaces = doc.createNestedObject("if");
|
JsonObject interfaces = root.createNestedObject("if");
|
||||||
|
|
||||||
JsonObject if_sync = interfaces.createNestedObject("sync");
|
JsonObject if_sync = interfaces.createNestedObject("sync");
|
||||||
if_sync[F("port0")] = udpPort;
|
if_sync[F("port0")] = udpPort;
|
||||||
@ -961,7 +964,7 @@ void serializeConfig() {
|
|||||||
if_ntp[F("ln")] = longitude;
|
if_ntp[F("ln")] = longitude;
|
||||||
if_ntp[F("lt")] = latitude;
|
if_ntp[F("lt")] = latitude;
|
||||||
|
|
||||||
JsonObject ol = doc.createNestedObject("ol");
|
JsonObject ol = root.createNestedObject("ol");
|
||||||
ol[F("clock")] = overlayCurrent;
|
ol[F("clock")] = overlayCurrent;
|
||||||
ol[F("cntdwn")] = countdownMode;
|
ol[F("cntdwn")] = countdownMode;
|
||||||
|
|
||||||
@ -971,7 +974,7 @@ void serializeConfig() {
|
|||||||
ol[F("o5m")] = analogClock5MinuteMarks;
|
ol[F("o5m")] = analogClock5MinuteMarks;
|
||||||
ol[F("osec")] = analogClockSecondsTrail;
|
ol[F("osec")] = analogClockSecondsTrail;
|
||||||
|
|
||||||
JsonObject timers = doc.createNestedObject(F("timers"));
|
JsonObject timers = root.createNestedObject(F("timers"));
|
||||||
|
|
||||||
JsonObject cntdwn = timers.createNestedObject(F("cntdwn"));
|
JsonObject cntdwn = timers.createNestedObject(F("cntdwn"));
|
||||||
JsonArray goal = cntdwn.createNestedArray(F("goal"));
|
JsonArray goal = cntdwn.createNestedArray(F("goal"));
|
||||||
@ -999,14 +1002,14 @@ void serializeConfig() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonObject ota = doc.createNestedObject("ota");
|
JsonObject ota = root.createNestedObject("ota");
|
||||||
ota[F("lock")] = otaLock;
|
ota[F("lock")] = otaLock;
|
||||||
ota[F("lock-wifi")] = wifiLock;
|
ota[F("lock-wifi")] = wifiLock;
|
||||||
ota[F("pskl")] = strlen(otaPass);
|
ota[F("pskl")] = strlen(otaPass);
|
||||||
ota[F("aota")] = aOtaEnabled;
|
ota[F("aota")] = aOtaEnabled;
|
||||||
|
|
||||||
#ifdef WLED_ENABLE_DMX
|
#ifdef WLED_ENABLE_DMX
|
||||||
JsonObject dmx = doc.createNestedObject("dmx");
|
JsonObject dmx = root.createNestedObject("dmx");
|
||||||
dmx[F("chan")] = DMXChannels;
|
dmx[F("chan")] = DMXChannels;
|
||||||
dmx[F("gap")] = DMXGap;
|
dmx[F("gap")] = DMXGap;
|
||||||
dmx["start"] = DMXStart;
|
dmx["start"] = DMXStart;
|
||||||
@ -1020,11 +1023,11 @@ void serializeConfig() {
|
|||||||
dmx[F("e131proxy")] = e131ProxyUniverse;
|
dmx[F("e131proxy")] = e131ProxyUniverse;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
JsonObject usermods_settings = doc.createNestedObject("um");
|
JsonObject usermods_settings = root.createNestedObject("um");
|
||||||
usermods.addToConfig(usermods_settings);
|
usermods.addToConfig(usermods_settings);
|
||||||
|
|
||||||
File f = WLED_FS.open("/cfg.json", "w");
|
File f = WLED_FS.open("/cfg.json", "w");
|
||||||
if (f) serializeJson(doc, f);
|
if (f) serializeJson(*pDoc, f);
|
||||||
f.close();
|
f.close();
|
||||||
releaseJSONBufferLock();
|
releaseJSONBufferLock();
|
||||||
|
|
||||||
@ -1037,19 +1040,21 @@ bool deserializeConfigSec() {
|
|||||||
|
|
||||||
if (!requestJSONBufferLock(3)) return false;
|
if (!requestJSONBufferLock(3)) return false;
|
||||||
|
|
||||||
bool success = readObjectFromFile("/wsec.json", nullptr, &doc);
|
bool success = readObjectFromFile("/wsec.json", nullptr, pDoc);
|
||||||
if (!success) {
|
if (!success) {
|
||||||
releaseJSONBufferLock();
|
releaseJSONBufferLock();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonObject nw_ins_0 = doc["nw"]["ins"][0];
|
JsonObject root = pDoc->as<JsonObject>();
|
||||||
|
|
||||||
|
JsonObject nw_ins_0 = root["nw"]["ins"][0];
|
||||||
getStringFromJson(clientPass, nw_ins_0["psk"], 65);
|
getStringFromJson(clientPass, nw_ins_0["psk"], 65);
|
||||||
|
|
||||||
JsonObject ap = doc["ap"];
|
JsonObject ap = root["ap"];
|
||||||
getStringFromJson(apPass, ap["psk"] , 65);
|
getStringFromJson(apPass, ap["psk"] , 65);
|
||||||
|
|
||||||
[[maybe_unused]] JsonObject interfaces = doc["if"];
|
[[maybe_unused]] JsonObject interfaces = root["if"];
|
||||||
|
|
||||||
#ifdef WLED_ENABLE_MQTT
|
#ifdef WLED_ENABLE_MQTT
|
||||||
JsonObject if_mqtt = interfaces["mqtt"];
|
JsonObject if_mqtt = interfaces["mqtt"];
|
||||||
@ -1060,10 +1065,10 @@ bool deserializeConfigSec() {
|
|||||||
getStringFromJson(hueApiKey, interfaces["hue"][F("key")], 47);
|
getStringFromJson(hueApiKey, interfaces["hue"][F("key")], 47);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
getStringFromJson(settingsPIN, doc["pin"], 5);
|
getStringFromJson(settingsPIN, root["pin"], 5);
|
||||||
correctPIN = !strlen(settingsPIN);
|
correctPIN = !strlen(settingsPIN);
|
||||||
|
|
||||||
JsonObject ota = doc["ota"];
|
JsonObject ota = root["ota"];
|
||||||
getStringFromJson(otaPass, ota[F("pwd")], 33);
|
getStringFromJson(otaPass, ota[F("pwd")], 33);
|
||||||
CJSON(otaLock, ota[F("lock")]);
|
CJSON(otaLock, ota[F("lock")]);
|
||||||
CJSON(wifiLock, ota[F("lock-wifi")]);
|
CJSON(wifiLock, ota[F("lock-wifi")]);
|
||||||
@ -1078,17 +1083,19 @@ void serializeConfigSec() {
|
|||||||
|
|
||||||
if (!requestJSONBufferLock(4)) return;
|
if (!requestJSONBufferLock(4)) return;
|
||||||
|
|
||||||
JsonObject nw = doc.createNestedObject("nw");
|
JsonObject root = pDoc->as<JsonObject>();
|
||||||
|
|
||||||
|
JsonObject nw = root.createNestedObject("nw");
|
||||||
|
|
||||||
JsonArray nw_ins = nw.createNestedArray("ins");
|
JsonArray nw_ins = nw.createNestedArray("ins");
|
||||||
|
|
||||||
JsonObject nw_ins_0 = nw_ins.createNestedObject();
|
JsonObject nw_ins_0 = nw_ins.createNestedObject();
|
||||||
nw_ins_0["psk"] = clientPass;
|
nw_ins_0["psk"] = clientPass;
|
||||||
|
|
||||||
JsonObject ap = doc.createNestedObject("ap");
|
JsonObject ap = root.createNestedObject("ap");
|
||||||
ap["psk"] = apPass;
|
ap["psk"] = apPass;
|
||||||
|
|
||||||
[[maybe_unused]] JsonObject interfaces = doc.createNestedObject("if");
|
[[maybe_unused]] JsonObject interfaces = root.createNestedObject("if");
|
||||||
#ifdef WLED_ENABLE_MQTT
|
#ifdef WLED_ENABLE_MQTT
|
||||||
JsonObject if_mqtt = interfaces.createNestedObject("mqtt");
|
JsonObject if_mqtt = interfaces.createNestedObject("mqtt");
|
||||||
if_mqtt["psk"] = mqttPass;
|
if_mqtt["psk"] = mqttPass;
|
||||||
@ -1098,16 +1105,16 @@ void serializeConfigSec() {
|
|||||||
if_hue[F("key")] = hueApiKey;
|
if_hue[F("key")] = hueApiKey;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
doc["pin"] = settingsPIN;
|
root["pin"] = settingsPIN;
|
||||||
|
|
||||||
JsonObject ota = doc.createNestedObject("ota");
|
JsonObject ota = root.createNestedObject("ota");
|
||||||
ota[F("pwd")] = otaPass;
|
ota[F("pwd")] = otaPass;
|
||||||
ota[F("lock")] = otaLock;
|
ota[F("lock")] = otaLock;
|
||||||
ota[F("lock-wifi")] = wifiLock;
|
ota[F("lock-wifi")] = wifiLock;
|
||||||
ota[F("aota")] = aOtaEnabled;
|
ota[F("aota")] = aOtaEnabled;
|
||||||
|
|
||||||
File f = WLED_FS.open("/wsec.json", "w");
|
File f = WLED_FS.open("/wsec.json", "w");
|
||||||
if (f) serializeJson(doc, f);
|
if (f) serializeJson(*pDoc, f);
|
||||||
f.close();
|
f.close();
|
||||||
releaseJSONBufferLock();
|
releaseJSONBufferLock();
|
||||||
}
|
}
|
||||||
|
@ -643,8 +643,8 @@ void decodeIRJson(uint32_t code)
|
|||||||
// this may fail for two reasons: ir.json does not exist or IR code not found
|
// this may fail for two reasons: ir.json does not exist or IR code not found
|
||||||
// if the IR code is not found readObjectFromFile() will clean() doc JSON document
|
// if the IR code is not found readObjectFromFile() will clean() doc JSON document
|
||||||
// so we can differentiate between the two
|
// so we can differentiate between the two
|
||||||
readObjectFromFile("/ir.json", objKey, &doc);
|
readObjectFromFile("/ir.json", objKey, pDoc);
|
||||||
fdo = doc.as<JsonObject>();
|
fdo = pDoc->as<JsonObject>();
|
||||||
lastValidCode = 0;
|
lastValidCode = 0;
|
||||||
if (fdo.isNull()) {
|
if (fdo.isNull()) {
|
||||||
//the received code does not exist
|
//the received code does not exist
|
||||||
|
@ -1055,7 +1055,7 @@ void serveJson(AsyncWebServerRequest* request)
|
|||||||
servingClient = false;
|
servingClient = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
AsyncJsonResponse *response = new AsyncJsonResponse(&doc, subJson==JSON_PATH_FXDATA || subJson==JSON_PATH_EFFECTS); // will clear and convert JsonDocument into JsonArray if necessary
|
AsyncJsonResponse *response = new AsyncJsonResponse(pDoc, subJson==JSON_PATH_FXDATA || subJson==JSON_PATH_EFFECTS); // will clear and convert JsonDocument into JsonArray if necessary
|
||||||
|
|
||||||
JsonVariant lDoc = response->getRoot();
|
JsonVariant lDoc = response->getRoot();
|
||||||
|
|
||||||
|
@ -109,8 +109,8 @@ void onMqttMessage(char* topic, char* payload, AsyncMqttClientMessageProperties
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (payloadStr[0] == '{') { //JSON API
|
if (payloadStr[0] == '{') { //JSON API
|
||||||
deserializeJson(doc, payloadStr);
|
deserializeJson(*pDoc, payloadStr);
|
||||||
deserializeState(doc.as<JsonObject>());
|
deserializeState(pDoc->as<JsonObject>());
|
||||||
} else { //HTTP API
|
} else { //HTTP API
|
||||||
String apireq = "win"; apireq += '&'; // reduce flash string usage
|
String apireq = "win"; apireq += '&'; // reduce flash string usage
|
||||||
apireq += payloadStr;
|
apireq += payloadStr;
|
||||||
|
@ -238,7 +238,7 @@ bool PinManagerClass::isPinAllocated(byte gpio, PinOwner tag)
|
|||||||
// Check if supplied GPIO is ok to use
|
// Check if supplied GPIO is ok to use
|
||||||
bool PinManagerClass::isPinOk(byte gpio, bool output)
|
bool PinManagerClass::isPinOk(byte gpio, bool output)
|
||||||
{
|
{
|
||||||
#ifdef ESP32
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
if (digitalPinIsValid(gpio)) {
|
if (digitalPinIsValid(gpio)) {
|
||||||
#if defined(CONFIG_IDF_TARGET_ESP32C3)
|
#if defined(CONFIG_IDF_TARGET_ESP32C3)
|
||||||
// strapping pins: 2, 8, & 9
|
// strapping pins: 2, 8, & 9
|
||||||
@ -257,6 +257,9 @@ bool PinManagerClass::isPinOk(byte gpio, bool output)
|
|||||||
// GPIO46 is input only and pulled down
|
// GPIO46 is input only and pulled down
|
||||||
#else
|
#else
|
||||||
if (gpio > 5 && gpio < 12) return false; //SPI flash pins
|
if (gpio > 5 && gpio < 12) return false; //SPI flash pins
|
||||||
|
#ifdef BOARD_HAS_PSRAM
|
||||||
|
if (gpio == 16 || gpio == 17) return false; //PSRAM pins
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
if (output) return digitalPinCanOutput(gpio);
|
if (output) return digitalPinCanOutput(gpio);
|
||||||
else return true;
|
else return true;
|
||||||
|
@ -27,7 +27,7 @@ static void doSaveState() {
|
|||||||
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 = pDoc->to<JsonObject>();
|
||||||
|
|
||||||
DEBUG_PRINTLN(F("Serialize current state"));
|
DEBUG_PRINTLN(F("Serialize current state"));
|
||||||
if (playlistSave) {
|
if (playlistSave) {
|
||||||
@ -42,7 +42,7 @@ static void doSaveState() {
|
|||||||
/*
|
/*
|
||||||
#ifdef WLED_DEBUG
|
#ifdef WLED_DEBUG
|
||||||
DEBUG_PRINTLN(F("Serialized preset"));
|
DEBUG_PRINTLN(F("Serialized preset"));
|
||||||
serializeJson(doc,Serial);
|
serializeJson(*pDoc,Serial);
|
||||||
DEBUG_PRINTLN();
|
DEBUG_PRINTLN();
|
||||||
#endif
|
#endif
|
||||||
*/
|
*/
|
||||||
@ -83,9 +83,9 @@ bool getPresetName(byte index, String& name)
|
|||||||
{
|
{
|
||||||
if (!requestJSONBufferLock(9)) return false;
|
if (!requestJSONBufferLock(9)) return false;
|
||||||
bool presetExists = false;
|
bool presetExists = false;
|
||||||
if (readObjectFromFileUsingId(getFileName(), index, &doc))
|
if (readObjectFromFileUsingId(getFileName(), index, pDoc))
|
||||||
{
|
{
|
||||||
JsonObject fdo = doc.as<JsonObject>();
|
JsonObject fdo = pDoc->as<JsonObject>();
|
||||||
if (fdo["n"]) {
|
if (fdo["n"]) {
|
||||||
name = (const char*)(fdo["n"]);
|
name = (const char*)(fdo["n"]);
|
||||||
presetExists = true;
|
presetExists = true;
|
||||||
|
@ -123,8 +123,8 @@ static bool remoteJson(int button)
|
|||||||
sprintf_P(objKey, PSTR("\"%d\":"), button);
|
sprintf_P(objKey, PSTR("\"%d\":"), button);
|
||||||
|
|
||||||
// attempt to read command from remote.json
|
// attempt to read command from remote.json
|
||||||
readObjectFromFile("/remote.json", objKey, &doc);
|
readObjectFromFile("/remote.json", objKey, pDoc);
|
||||||
JsonObject fdo = doc.as<JsonObject>();
|
JsonObject fdo = pDoc->as<JsonObject>();
|
||||||
if (fdo.isNull()) {
|
if (fdo.isNull()) {
|
||||||
// the received button does not exist
|
// the received button does not exist
|
||||||
if (!WLED_FS.exists("/remote.json")) errorFlag = ERR_FS_RMLOAD; //warn if file itself doesn't exist
|
if (!WLED_FS.exists("/remote.json")) errorFlag = ERR_FS_RMLOAD; //warn if file itself doesn't exist
|
||||||
|
@ -625,7 +625,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonObject um = doc.createNestedObject("um");
|
JsonObject um = pDoc->createNestedObject("um");
|
||||||
|
|
||||||
size_t args = request->args();
|
size_t args = request->args();
|
||||||
uint16_t j=0;
|
uint16_t j=0;
|
||||||
|
@ -664,8 +664,8 @@ void handleNotifications()
|
|||||||
apireq += (char*)udpIn;
|
apireq += (char*)udpIn;
|
||||||
handleSet(nullptr, apireq);
|
handleSet(nullptr, apireq);
|
||||||
} else if (udpIn[0] == '{') { //JSON API
|
} else if (udpIn[0] == '{') { //JSON API
|
||||||
DeserializationError error = deserializeJson(doc, udpIn);
|
DeserializationError error = deserializeJson(*pDoc, udpIn);
|
||||||
JsonObject root = doc.as<JsonObject>();
|
JsonObject root = pDoc->as<JsonObject>();
|
||||||
if (!error && !root.isNull()) deserializeState(root);
|
if (!error && !root.isNull()) deserializeState(root);
|
||||||
}
|
}
|
||||||
releaseJSONBufferLock();
|
releaseJSONBufferLock();
|
||||||
|
@ -209,6 +209,10 @@ bool isAsterisksOnly(const char* str, byte maxLen)
|
|||||||
//threading/network callback details: https://github.com/Aircoookie/WLED/pull/2336#discussion_r762276994
|
//threading/network callback details: https://github.com/Aircoookie/WLED/pull/2336#discussion_r762276994
|
||||||
bool requestJSONBufferLock(uint8_t module)
|
bool requestJSONBufferLock(uint8_t module)
|
||||||
{
|
{
|
||||||
|
if (pDoc == nullptr) {
|
||||||
|
DEBUG_PRINTLN(F("ERROR: JSON buffer not allocated!"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
unsigned long now = millis();
|
unsigned long now = millis();
|
||||||
|
|
||||||
while (jsonBufferLock && millis()-now < 1000) delay(1); // wait for a second for buffer lock
|
while (jsonBufferLock && millis()-now < 1000) delay(1); // wait for a second for buffer lock
|
||||||
@ -224,8 +228,8 @@ bool requestJSONBufferLock(uint8_t module)
|
|||||||
DEBUG_PRINT(F("JSON buffer locked. ("));
|
DEBUG_PRINT(F("JSON buffer locked. ("));
|
||||||
DEBUG_PRINT(jsonBufferLock);
|
DEBUG_PRINT(jsonBufferLock);
|
||||||
DEBUG_PRINTLN(")");
|
DEBUG_PRINTLN(")");
|
||||||
fileDoc = &doc; // used for applying presets (presets.cpp)
|
fileDoc = pDoc; // used for applying presets (presets.cpp)
|
||||||
doc.clear();
|
pDoc->clear();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -556,11 +560,12 @@ void enumerateLedmaps() {
|
|||||||
|
|
||||||
#ifndef ESP8266
|
#ifndef ESP8266
|
||||||
if (requestJSONBufferLock(21)) {
|
if (requestJSONBufferLock(21)) {
|
||||||
if (readObjectFromFile(fileName, nullptr, &doc)) {
|
if (readObjectFromFile(fileName, nullptr, pDoc)) {
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
if (!doc["n"].isNull()) {
|
JsonObject root = pDoc->as<JsonObject>();
|
||||||
|
if (!root["n"].isNull()) {
|
||||||
// name field exists
|
// name field exists
|
||||||
const char *name = doc["n"].as<const char*>();
|
const char *name = root["n"].as<const char*>();
|
||||||
if (name != nullptr) len = strlen(name);
|
if (name != nullptr) len = strlen(name);
|
||||||
if (len > 0 && len < 33) {
|
if (len > 0 && len < 33) {
|
||||||
ledmapNames[i-1] = new char[len+1];
|
ledmapNames[i-1] = new char[len+1];
|
||||||
|
@ -346,6 +346,11 @@ void WLED::setup()
|
|||||||
DEBUG_PRINT(F("heap ")); DEBUG_PRINTLN(ESP.getFreeHeap());
|
DEBUG_PRINT(F("heap ")); DEBUG_PRINTLN(ESP.getFreeHeap());
|
||||||
|
|
||||||
#if defined(ARDUINO_ARCH_ESP32) && defined(BOARD_HAS_PSRAM)
|
#if defined(ARDUINO_ARCH_ESP32) && defined(BOARD_HAS_PSRAM)
|
||||||
|
/*
|
||||||
|
* The following code is obsolete as PinManager::isPinOK() will return false for reserved GPIO.
|
||||||
|
* Additionally xml.cpp will inform UI about reserved GPIO.
|
||||||
|
*
|
||||||
|
|
||||||
#if defined(CONFIG_IDF_TARGET_ESP32S3)
|
#if defined(CONFIG_IDF_TARGET_ESP32S3)
|
||||||
// S3: reserve GPIO 33-37 for "octal" PSRAM
|
// S3: reserve GPIO 33-37 for "octal" PSRAM
|
||||||
managed_pin_type pins[] = { {33, true}, {34, true}, {35, true}, {36, true}, {37, true} };
|
managed_pin_type pins[] = { {33, true}, {34, true}, {35, true}, {36, true}, {37, true} };
|
||||||
@ -363,12 +368,17 @@ void WLED::setup()
|
|||||||
managed_pin_type pins[] = { {16, true}, {17, true} };
|
managed_pin_type pins[] = { {16, true}, {17, true} };
|
||||||
pinManager.allocateMultiplePins(pins, sizeof(pins)/sizeof(managed_pin_type), PinOwner::SPI_RAM);
|
pinManager.allocateMultiplePins(pins, sizeof(pins)/sizeof(managed_pin_type), PinOwner::SPI_RAM);
|
||||||
#endif
|
#endif
|
||||||
|
*/
|
||||||
#if defined(WLED_USE_PSRAM)
|
#if defined(WLED_USE_PSRAM)
|
||||||
|
pDoc = new PSRAMDynamicJsonDocument(2*JSON_BUFFER_SIZE);
|
||||||
|
if (!pDoc) pDoc = new PSRAMDynamicJsonDocument(JSON_BUFFER_SIZE); // falback if double sized buffer could not be allocated
|
||||||
|
// if the above still fails requestJsonBufferLock() will always return false preventing crashes
|
||||||
if (psramFound()) {
|
if (psramFound()) {
|
||||||
DEBUG_PRINT(F("Total PSRAM: ")); DEBUG_PRINT(ESP.getPsramSize()/1024); DEBUG_PRINTLN("kB");
|
DEBUG_PRINT(F("Total PSRAM: ")); DEBUG_PRINT(ESP.getPsramSize()/1024); DEBUG_PRINTLN("kB");
|
||||||
DEBUG_PRINT(F("Free PSRAM : ")); DEBUG_PRINT(ESP.getFreePsram()/1024); DEBUG_PRINTLN("kB");
|
DEBUG_PRINT(F("Free PSRAM : ")); DEBUG_PRINT(ESP.getFreePsram()/1024); DEBUG_PRINTLN("kB");
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
if (!pDoc) pDoc = &gDoc; // just in case ... (it should be globally assigned)
|
||||||
DEBUG_PRINTLN(F("PSRAM not used."));
|
DEBUG_PRINTLN(F("PSRAM not used."));
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// version code in format yymmddb (b = daily build)
|
// version code in format yymmddb (b = daily build)
|
||||||
#define VERSION 2312190
|
#define VERSION 2312210
|
||||||
|
|
||||||
//uncomment this if you have a "my_config.h" file you'd like to use
|
//uncomment this if you have a "my_config.h" file you'd like to use
|
||||||
//#define WLED_USE_MY_CONFIG
|
//#define WLED_USE_MY_CONFIG
|
||||||
@ -758,7 +758,12 @@ WLED_GLOBAL int8_t spi_sclk _INIT(SPISCLKPIN);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// global ArduinoJson buffer
|
// global ArduinoJson buffer
|
||||||
WLED_GLOBAL StaticJsonDocument<JSON_BUFFER_SIZE> doc;
|
#if defined(ARDUINO_ARCH_ESP32) && defined(BOARD_HAS_PSRAM) && defined(WLED_USE_PSRAM)
|
||||||
|
WLED_GLOBAL JsonDocument *pDoc _INIT(nullptr);
|
||||||
|
#else
|
||||||
|
WLED_GLOBAL StaticJsonDocument<JSON_BUFFER_SIZE> gDoc;
|
||||||
|
WLED_GLOBAL JsonDocument *pDoc _INIT(&gDoc);
|
||||||
|
#endif
|
||||||
WLED_GLOBAL volatile uint8_t jsonBufferLock _INIT(0);
|
WLED_GLOBAL volatile uint8_t jsonBufferLock _INIT(0);
|
||||||
|
|
||||||
// enable additional debug output
|
// enable additional debug output
|
||||||
|
@ -371,7 +371,7 @@ void deEEP() {
|
|||||||
DEBUGFS_PRINTLN(F("Allocating saving buffer for dEEP"));
|
DEBUGFS_PRINTLN(F("Allocating saving buffer for dEEP"));
|
||||||
if (!requestJSONBufferLock(8)) return;
|
if (!requestJSONBufferLock(8)) return;
|
||||||
|
|
||||||
JsonObject sObj = doc.to<JsonObject>();
|
JsonObject sObj = pDoc->to<JsonObject>();
|
||||||
sObj.createNestedObject("0");
|
sObj.createNestedObject("0");
|
||||||
|
|
||||||
EEPROM.begin(EEPSIZE);
|
EEPROM.begin(EEPSIZE);
|
||||||
@ -448,7 +448,7 @@ void deEEP() {
|
|||||||
releaseJSONBufferLock();
|
releaseJSONBufferLock();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
serializeJson(doc, f);
|
serializeJson(*pDoc, f);
|
||||||
f.close();
|
f.close();
|
||||||
|
|
||||||
releaseJSONBufferLock();
|
releaseJSONBufferLock();
|
||||||
|
@ -115,21 +115,21 @@ void handleSerial()
|
|||||||
bool verboseResponse = false;
|
bool verboseResponse = false;
|
||||||
if (!requestJSONBufferLock(16)) return;
|
if (!requestJSONBufferLock(16)) return;
|
||||||
Serial.setTimeout(100);
|
Serial.setTimeout(100);
|
||||||
DeserializationError error = deserializeJson(doc, Serial);
|
DeserializationError error = deserializeJson(*pDoc, Serial);
|
||||||
if (error) {
|
if (error) {
|
||||||
releaseJSONBufferLock();
|
releaseJSONBufferLock();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
verboseResponse = deserializeState(doc.as<JsonObject>());
|
verboseResponse = deserializeState(pDoc->as<JsonObject>());
|
||||||
//only send response if TX pin is unused for other purposes
|
//only send response if TX pin is unused for other purposes
|
||||||
if (verboseResponse && (!pinManager.isPinAllocated(hardwareTX) || pinManager.getPinOwner(hardwareTX) == PinOwner::DebugOut)) {
|
if (verboseResponse && (!pinManager.isPinAllocated(hardwareTX) || pinManager.getPinOwner(hardwareTX) == PinOwner::DebugOut)) {
|
||||||
doc.clear();
|
pDoc->clear();
|
||||||
JsonObject state = doc.createNestedObject("state");
|
JsonObject state = pDoc->createNestedObject("state");
|
||||||
serializeState(state);
|
serializeState(state);
|
||||||
JsonObject info = doc.createNestedObject("info");
|
JsonObject info = pDoc->createNestedObject("info");
|
||||||
serializeInfo(info);
|
serializeInfo(info);
|
||||||
|
|
||||||
serializeJson(doc, Serial);
|
serializeJson(*pDoc, Serial);
|
||||||
Serial.println();
|
Serial.println();
|
||||||
}
|
}
|
||||||
releaseJSONBufferLock();
|
releaseJSONBufferLock();
|
||||||
|
@ -180,8 +180,8 @@ void initServer()
|
|||||||
|
|
||||||
if (!requestJSONBufferLock(14)) return;
|
if (!requestJSONBufferLock(14)) return;
|
||||||
|
|
||||||
DeserializationError error = deserializeJson(doc, (uint8_t*)(request->_tempObject));
|
DeserializationError error = deserializeJson(*pDoc, (uint8_t*)(request->_tempObject));
|
||||||
JsonObject root = doc.as<JsonObject>();
|
JsonObject root = pDoc->as<JsonObject>();
|
||||||
if (error || root.isNull()) {
|
if (error || root.isNull()) {
|
||||||
releaseJSONBufferLock();
|
releaseJSONBufferLock();
|
||||||
serveJsonError(request, 400, ERR_JSON);
|
serveJsonError(request, 400, ERR_JSON);
|
||||||
|
@ -38,8 +38,8 @@ void wsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventTyp
|
|||||||
bool verboseResponse = false;
|
bool verboseResponse = false;
|
||||||
if (!requestJSONBufferLock(11)) return;
|
if (!requestJSONBufferLock(11)) return;
|
||||||
|
|
||||||
DeserializationError error = deserializeJson(doc, data, len);
|
DeserializationError error = deserializeJson(*pDoc, data, len);
|
||||||
JsonObject root = doc.as<JsonObject>();
|
JsonObject root = pDoc->as<JsonObject>();
|
||||||
if (error || root.isNull()) {
|
if (error || root.isNull()) {
|
||||||
releaseJSONBufferLock();
|
releaseJSONBufferLock();
|
||||||
return;
|
return;
|
||||||
@ -103,13 +103,13 @@ void sendDataWs(AsyncWebSocketClient * client)
|
|||||||
|
|
||||||
if (!requestJSONBufferLock(12)) return;
|
if (!requestJSONBufferLock(12)) return;
|
||||||
|
|
||||||
JsonObject state = doc.createNestedObject("state");
|
JsonObject state = pDoc->createNestedObject("state");
|
||||||
serializeState(state);
|
serializeState(state);
|
||||||
JsonObject info = doc.createNestedObject("info");
|
JsonObject info = pDoc->createNestedObject("info");
|
||||||
serializeInfo(info);
|
serializeInfo(info);
|
||||||
|
|
||||||
size_t len = measureJson(doc);
|
size_t len = measureJson(*pDoc);
|
||||||
DEBUG_PRINTF("JSON buffer size: %u for WS request (%u).\n", doc.memoryUsage(), len);
|
DEBUG_PRINTF("JSON buffer size: %u for WS request (%u).\n", pDoc->memoryUsage(), len);
|
||||||
|
|
||||||
size_t heap1 = ESP.getFreeHeap();
|
size_t heap1 = ESP.getFreeHeap();
|
||||||
DEBUG_PRINT(F("heap ")); DEBUG_PRINTLN(ESP.getFreeHeap());
|
DEBUG_PRINT(F("heap ")); DEBUG_PRINTLN(ESP.getFreeHeap());
|
||||||
@ -136,7 +136,7 @@ void sendDataWs(AsyncWebSocketClient * client)
|
|||||||
}
|
}
|
||||||
|
|
||||||
buffer->lock();
|
buffer->lock();
|
||||||
serializeJson(doc, (char *)buffer->get(), len);
|
serializeJson(*pDoc, (char *)buffer->get(), len);
|
||||||
|
|
||||||
DEBUG_PRINT(F("Sending WS data "));
|
DEBUG_PRINT(F("Sending WS data "));
|
||||||
if (client) {
|
if (client) {
|
||||||
|
@ -133,7 +133,7 @@ void appendGPIOinfo() {
|
|||||||
// usermod pin reservations will become unnecessary when settings pages will read cfg.json directly
|
// usermod pin reservations will become unnecessary when settings pages will read cfg.json directly
|
||||||
if (requestJSONBufferLock(6)) {
|
if (requestJSONBufferLock(6)) {
|
||||||
// if we can't allocate JSON buffer ignore usermod pins
|
// if we can't allocate JSON buffer ignore usermod pins
|
||||||
JsonObject mods = doc.createNestedObject(F("um"));
|
JsonObject mods = pDoc->createNestedObject(F("um"));
|
||||||
usermods.addToConfig(mods);
|
usermods.addToConfig(mods);
|
||||||
if (!mods.isNull()) fillUMPins(mods);
|
if (!mods.isNull()) fillUMPins(mods);
|
||||||
releaseJSONBufferLock();
|
releaseJSONBufferLock();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user