Large ledmap support

- add filtering support for readObjectFromFile()
This commit is contained in:
Blaž Kristan 2024-11-09 11:22:38 +01:00
parent 271a07a7d6
commit 9fa53ccf05
3 changed files with 52 additions and 9 deletions

View File

@ -1820,12 +1820,18 @@ bool WS2812FX::deserializeMap(uint8_t n) {
if (!isFile || !requestJSONBufferLock(7)) return false; 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); DEBUG_PRINT(F("ERROR Invalid ledmap in ")); DEBUG_PRINTLN(fileName);
releaseJSONBufferLock(); releaseJSONBufferLock();
return false; // if file does not load properly then exit return false; // if file does not load properly then exit
} }
suspend();
JsonObject root = pDoc->as<JsonObject>(); JsonObject root = pDoc->as<JsonObject>();
// if we are loading default ledmap (at boot) set matrix width and height from the ledmap (compatible with WLED MM ledmaps) // 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())) { if (isMatrix && n == 0 && (!root[F("width")].isNull() || !root[F("height")].isNull())) {
@ -1838,16 +1844,52 @@ bool WS2812FX::deserializeMap(uint8_t n) {
if (customMappingTable) { if (customMappingTable) {
DEBUG_PRINT(F("Reading LED map from ")); DEBUG_PRINTLN(fileName); 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<customMappingSize; i++) {
if (!(i%Segment::maxWidth)) DEBUGFX_PRINTLN();
DEBUG_PRINTF_P(PSTR("%4d,"), customMappingTable[i]);
}
DEBUG_PRINTLN();
#endif
/*
JsonArray map = root[F("map")]; JsonArray map = root[F("map")];
if (!map.isNull() && map.size()) { // not an empty map if (!map.isNull() && map.size()) { // not an empty map
customMappingSize = min((unsigned)map.size(), (unsigned)getLengthTotal()); customMappingSize = min((unsigned)map.size(), (unsigned)getLengthTotal());
for (unsigned i=0; i<customMappingSize; i++) customMappingTable[i] = (uint16_t) (map[i]<0 ? 0xFFFFU : map[i]); for (unsigned i=0; i<customMappingSize; i++) customMappingTable[i] = (uint16_t) (map[i]<0 ? 0xFFFFU : map[i]);
currentLedmap = n; currentLedmap = n;
} }
*/
} else { } else {
DEBUG_PRINTLN(F("ERROR LED map allocation error.")); DEBUG_PRINTLN(F("ERROR LED map allocation error."));
} }
resume();
releaseJSONBufferLock(); releaseJSONBufferLock();
return (customMappingSize > 0); return (customMappingSize > 0);
} }

View File

@ -109,14 +109,14 @@ void sendArtnetPollReply(ArtPollReply* reply, IPAddress ipAddress, uint16_t port
bool handleFileRead(AsyncWebServerRequest*, String path); bool handleFileRead(AsyncWebServerRequest*, String path);
bool writeObjectToFileUsingId(const char* file, uint16_t id, JsonDocument* content); bool writeObjectToFileUsingId(const char* file, uint16_t id, JsonDocument* content);
bool writeObjectToFile(const char* file, const char* key, JsonDocument* content); bool writeObjectToFile(const char* file, const char* key, JsonDocument* content);
bool readObjectFromFileUsingId(const char* file, uint16_t id, 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); bool readObjectFromFile(const char* file, const char* key, JsonDocument* dest, JsonDocument* filter = nullptr);
void updateFSInfo(); void updateFSInfo();
void closeFile(); void closeFile();
inline bool writeObjectToFileUsingId(const String &file, uint16_t id, JsonDocument* content) { return writeObjectToFileUsingId(file.c_str(), id, content); }; 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 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 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) { return readObjectFromFile(file.c_str(), key, dest); }; inline bool readObjectFromFile(const String &file, const char* key, JsonDocument* dest, JsonDocument* filter = nullptr) { return readObjectFromFile(file.c_str(), key, dest); };
//hue.cpp //hue.cpp
void handleHue(); void handleHue();

View File

@ -325,15 +325,15 @@ bool writeObjectToFile(const char* file, const char* key, JsonDocument* content)
return true; 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]; char objKey[10];
sprintf(objKey, "\"%d\":", id); sprintf(objKey, "\"%d\":", id);
return readObjectFromFile(file, objKey, dest); return readObjectFromFile(file, objKey, dest, filter);
} }
//if the key is a nullptr, deserialize entire object //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(); if (doCloseFile) closeFile();
#ifdef WLED_DEBUG_FS #ifdef WLED_DEBUG_FS
@ -352,7 +352,8 @@ bool readObjectFromFile(const char* file, const char* key, JsonDocument* dest)
return false; return false;
} }
deserializeJson(*dest, f); if (filter) deserializeJson(*dest, f, DeserializationOption::Filter(*filter));
else deserializeJson(*dest, f);
f.close(); f.close();
DEBUGFS_PRINTF("Read, took %d ms\n", millis() - s); DEBUGFS_PRINTF("Read, took %d ms\n", millis() - s);