From 9fa53ccf058b9e687d17d5350e4993a9dd72d1e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bla=C5=BE=20Kristan?= Date: Sat, 9 Nov 2024 11:22:38 +0100 Subject: [PATCH 1/3] Large ledmap support - add filtering support for readObjectFromFile() --- wled00/FX_fcn.cpp | 44 +++++++++++++++++++++++++++++++++++++++++++- wled00/fcn_declare.h | 8 ++++---- wled00/file.cpp | 9 +++++---- 3 files changed, 52 insertions(+), 9 deletions(-) diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index e706f2b43..12e9a80d4 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -1820,12 +1820,18 @@ bool WS2812FX::deserializeMap(uint8_t n) { if (!isFile || !requestJSONBufferLock(7)) return false; - if (!readObjectFromFile(fileName, nullptr, pDoc)) { + StaticJsonDocument<64> filter; + filter[F("width")] = true; + filter[F("height")] = true; + filter[F("name")] = true; + if (!readObjectFromFile(fileName, nullptr, pDoc, &filter)) { DEBUG_PRINT(F("ERROR Invalid ledmap in ")); DEBUG_PRINTLN(fileName); releaseJSONBufferLock(); return false; // if file does not load properly then exit } + suspend(); + JsonObject root = pDoc->as(); // if we are loading default ledmap (at boot) set matrix width and height from the ledmap (compatible with WLED MM ledmaps) if (isMatrix && n == 0 && (!root[F("width")].isNull() || !root[F("height")].isNull())) { @@ -1838,16 +1844,52 @@ bool WS2812FX::deserializeMap(uint8_t n) { if (customMappingTable) { DEBUG_PRINT(F("Reading LED map from ")); DEBUG_PRINTLN(fileName); + File f = WLED_FS.open(fileName, "r"); + f.find("\"map\":["); + while (f.available()) { // f.position() < f.size() - 1 + char number[32]; + size_t numRead = f.readBytesUntil(',', number, sizeof(number)-1); // read a single number (may include array terminating "]" but not number separator ',') + number[numRead] = 0; + if (numRead > 0) { + char *end = strchr(number,']'); // we encountered end of array so stop processing if no digit found + bool foundDigit = (end == nullptr); + int i = 0; + if (end != nullptr) do { + if (number[i] >= '0' && number[i] <= '9') foundDigit = true; + if (foundDigit || &number[i++] == end) break; + } while (i < 32); + if (!foundDigit) break; + int index = atoi(number); + if (index < 0 || index > 16384) index = 0xFFFF; + customMappingTable[customMappingSize++] = index; + if (customMappingSize > getLengthTotal()) break; + } else break; // there was nothing to read, stop + } + currentLedmap = n; + f.close(); + + #ifdef WLED_DEBUG + DEBUG_PRINT(F("Loaded ledmap:")); + for (unsigned i=0; i 0); } diff --git a/wled00/fcn_declare.h b/wled00/fcn_declare.h index 1855a8b63..311f71ef4 100644 --- a/wled00/fcn_declare.h +++ b/wled00/fcn_declare.h @@ -109,14 +109,14 @@ void sendArtnetPollReply(ArtPollReply* reply, IPAddress ipAddress, uint16_t port bool handleFileRead(AsyncWebServerRequest*, String path); bool writeObjectToFileUsingId(const char* file, uint16_t id, JsonDocument* content); bool writeObjectToFile(const char* file, const char* key, JsonDocument* content); -bool readObjectFromFileUsingId(const char* file, uint16_t id, JsonDocument* dest); -bool readObjectFromFile(const char* file, const char* key, JsonDocument* dest); +bool readObjectFromFileUsingId(const char* file, uint16_t id, JsonDocument* dest, JsonDocument* filter = nullptr); +bool readObjectFromFile(const char* file, const char* key, JsonDocument* dest, JsonDocument* filter = nullptr); void updateFSInfo(); void closeFile(); inline bool writeObjectToFileUsingId(const String &file, uint16_t id, JsonDocument* content) { return writeObjectToFileUsingId(file.c_str(), id, content); }; inline bool writeObjectToFile(const String &file, const char* key, JsonDocument* content) { return writeObjectToFile(file.c_str(), key, content); }; -inline bool readObjectFromFileUsingId(const String &file, uint16_t id, JsonDocument* dest) { return readObjectFromFileUsingId(file.c_str(), id, dest); }; -inline bool readObjectFromFile(const String &file, const char* key, JsonDocument* dest) { return readObjectFromFile(file.c_str(), key, dest); }; +inline bool readObjectFromFileUsingId(const String &file, uint16_t id, JsonDocument* dest, JsonDocument* filter = nullptr) { return readObjectFromFileUsingId(file.c_str(), id, dest); }; +inline bool readObjectFromFile(const String &file, const char* key, JsonDocument* dest, JsonDocument* filter = nullptr) { return readObjectFromFile(file.c_str(), key, dest); }; //hue.cpp void handleHue(); diff --git a/wled00/file.cpp b/wled00/file.cpp index bc3467202..f390bcc0c 100644 --- a/wled00/file.cpp +++ b/wled00/file.cpp @@ -325,15 +325,15 @@ bool writeObjectToFile(const char* file, const char* key, JsonDocument* content) return true; } -bool readObjectFromFileUsingId(const char* file, uint16_t id, JsonDocument* dest) +bool readObjectFromFileUsingId(const char* file, uint16_t id, JsonDocument* dest, JsonDocument* filter) { char objKey[10]; sprintf(objKey, "\"%d\":", id); - return readObjectFromFile(file, objKey, dest); + return readObjectFromFile(file, objKey, dest, filter); } //if the key is a nullptr, deserialize entire object -bool readObjectFromFile(const char* file, const char* key, JsonDocument* dest) +bool readObjectFromFile(const char* file, const char* key, JsonDocument* dest, JsonDocument* filter) { if (doCloseFile) closeFile(); #ifdef WLED_DEBUG_FS @@ -352,7 +352,8 @@ bool readObjectFromFile(const char* file, const char* key, JsonDocument* dest) return false; } - deserializeJson(*dest, f); + if (filter) deserializeJson(*dest, f, DeserializationOption::Filter(*filter)); + else deserializeJson(*dest, f); f.close(); DEBUGFS_PRINTF("Read, took %d ms\n", millis() - s); From ba5ec57e4d784f19ff50ec74ce6b1aeb62b68998 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bla=C5=BE=20Kristan?= Date: Sat, 9 Nov 2024 11:33:10 +0100 Subject: [PATCH 2/3] Enumeration support. --- wled00/FX_fcn.cpp | 1 - wled00/util.cpp | 4 +++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index 12e9a80d4..e213740ac 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -1823,7 +1823,6 @@ bool WS2812FX::deserializeMap(uint8_t n) { StaticJsonDocument<64> filter; filter[F("width")] = true; filter[F("height")] = true; - filter[F("name")] = true; if (!readObjectFromFile(fileName, nullptr, pDoc, &filter)) { DEBUG_PRINT(F("ERROR Invalid ledmap in ")); DEBUG_PRINTLN(fileName); releaseJSONBufferLock(); diff --git a/wled00/util.cpp b/wled00/util.cpp index 0b78a4646..d58084e8c 100644 --- a/wled00/util.cpp +++ b/wled00/util.cpp @@ -493,6 +493,8 @@ um_data_t* simulateSound(uint8_t simulationId) static const char s_ledmap_tmpl[] PROGMEM = "ledmap%d.json"; // enumerate all ledmapX.json files on FS and extract ledmap names if existing void enumerateLedmaps() { + StaticJsonDocument<64> filter; + filter["n"] = true; ledMaps = 1; for (size_t i=1; ias(); if (!root["n"].isNull()) { From ebc171d405f61d80c26de05ac069a9b601d08277 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bla=C5=BE=20Kristan?= Date: Mon, 20 Jan 2025 08:59:35 +0100 Subject: [PATCH 3/3] Const update - removed erroneous DEBUGFX --- wled00/FX_fcn.cpp | 6 +++--- wled00/fcn_declare.h | 16 ++++++++-------- wled00/file.cpp | 10 +++++----- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index e213740ac..4aa4f6d1d 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -528,7 +528,7 @@ Segment &Segment::setCCT(uint16_t k) { k = (k - 1900) >> 5; } if (cct != k) { - //DEBUGFX_PRINTF_P(PSTR("- Starting CCT transition: %d\n"), k); + //DEBUG_PRINTF_P(PSTR("- Starting CCT transition: %d\n"), k); startTransition(strip.getTransition()); // start transition prior to change cct = k; stateChanged = true; // send UDP/WS broadcast @@ -538,7 +538,7 @@ Segment &Segment::setCCT(uint16_t k) { Segment &Segment::setOpacity(uint8_t o) { if (opacity != o) { - //DEBUGFX_PRINTF_P(PSTR("- Starting opacity transition: %d\n"), o); + //DEBUG_PRINTF_P(PSTR("- Starting opacity transition: %d\n"), o); startTransition(strip.getTransition()); // start transition prior to change opacity = o; stateChanged = true; // send UDP/WS broadcast @@ -1870,7 +1870,7 @@ bool WS2812FX::deserializeMap(uint8_t n) { #ifdef WLED_DEBUG DEBUG_PRINT(F("Loaded ledmap:")); for (unsigned i=0; i