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 (!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<JsonObject>();
// 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<customMappingSize; i++) {
if (!(i%Segment::maxWidth)) DEBUGFX_PRINTLN();
DEBUG_PRINTF_P(PSTR("%4d,"), customMappingTable[i]);
}
DEBUG_PRINTLN();
#endif
/*
JsonArray map = root[F("map")];
if (!map.isNull() && map.size()) { // not an empty map
customMappingSize = min((unsigned)map.size(), (unsigned)getLengthTotal());
for (unsigned i=0; i<customMappingSize; i++) customMappingTable[i] = (uint16_t) (map[i]<0 ? 0xFFFFU : map[i]);
currentLedmap = n;
}
*/
} else {
DEBUG_PRINTLN(F("ERROR LED map allocation error."));
}
resume();
releaseJSONBufferLock();
return (customMappingSize > 0);
}

View File

@ -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();

View File

@ -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);