diff --git a/src/DisplayManager.cpp b/src/DisplayManager.cpp index a3ef09d6..135dcc2e 100644 --- a/src/DisplayManager.cpp +++ b/src/DisplayManager.cpp @@ -489,15 +489,7 @@ bool DisplayManager_::generateCustomPage(const String &name, JsonObject doc, boo customApp.progress = doc.containsKey("progress") ? doc["progress"].as() : -1; - if (doc.containsKey("background")) - { - auto background = doc["background"]; - customApp.background = getColorFromJsonVariant(background, 0); - } - else - { - customApp.background = 0; - } + customApp.background = getColorField(doc, "background", 0); if (doc.containsKey("save") && preventSave == false) { @@ -524,86 +516,11 @@ bool DisplayManager_::generateCustomPage(const String &name, JsonObject doc, boo } } - if (doc.containsKey("progressC")) - { - auto progressC = doc["progressC"]; - customApp.pColor = getColorFromJsonVariant(progressC, 0x00FF00); - } - else - { - customApp.pColor = 0x00FF00; - } + customApp.pColor = getColorField(doc, "progressC", 0x00FF00); + customApp.pbColor = getColorField(doc, "progressBC", 0xFFFFFF); - if (doc.containsKey("progressBC")) - { - auto progressBC = doc["progressBC"]; - customApp.pbColor = getColorFromJsonVariant(progressBC, 0xFFFFFF); - } - else - { - customApp.pbColor = 0xFFFFFF; - } - - bool autoscale = true; - if (doc.containsKey("autoscale")) - { - autoscale = doc["autoscale"].as(); - } - - // Handling for "bar" and "line" as they have similar structures - const char *dataKeys[] = {"bar", "line"}; - int *dataArrays[] = {customApp.barData, customApp.lineData}; - int *dataSizeArrays[] = {&customApp.barSize, &customApp.lineSize}; - - for (int i = 0; i < 2; i++) - { - const char *key = dataKeys[i]; - int *dataArray = dataArrays[i]; - int *dataSize = dataSizeArrays[i]; - - if (doc.containsKey(key)) - { - if (doc.containsKey("barBC")) - { - auto color = doc["barBC"]; - customApp.barBG = getColorFromJsonVariant(color, 0); - } - else - { - customApp.barBG = 0; - } - JsonArray data = doc[key]; - int index = 0; - int maximum = 0; - for (JsonVariant v : data) - { - if (index >= 16) - { - break; - } - int d = v.as(); - if (d > maximum) - { - maximum = d; - } - dataArray[index] = d; - index++; - } - *dataSize = index; - - if (autoscale) - { - for (int j = 0; j < *dataSize; j++) - { - dataArray[j] = map(dataArray[j], 0, maximum, 0, 8); - } - } - } - else - { - *dataSize = 0; - } - } + bool autoscale = doc.containsKey("autoscale") ? doc["autoscale"].as() : true; + parseBarLineData(doc, customApp.barData, customApp.barSize, customApp.lineData, customApp.lineSize, customApp.barBG, autoscale); if (doc.containsKey("draw")) { @@ -683,21 +600,7 @@ bool DisplayManager_::generateCustomPage(const String &name, JsonObject doc, boo customApp.currentFrame = 0; } - customApp.gradient[0] = -1; - customApp.gradient[1] = -1; - - if (doc.containsKey("gradient")) - { - JsonArray arr = doc["gradient"].as(); - if (arr.size() == 2) - { - auto color1 = arr[0]; - auto color2 = arr[1]; - - customApp.gradient[0] = getColorFromJsonVariant(color1, TEXTCOLOR_888); - customApp.gradient[1] = getColorFromJsonVariant(color2, TEXTCOLOR_888); - } - } + parseGradient(doc, customApp.gradient); if (doc.containsKey("color")) { @@ -766,35 +669,9 @@ bool DisplayManager_::generateNotification(uint8_t source, const char *json) newNotification.progress = doc.containsKey("progress") ? doc["progress"].as() : -1; - if (doc.containsKey("progressC")) - { - auto progressC = doc["progressC"]; - newNotification.pColor = getColorFromJsonVariant(progressC, 0x00FF00); - } - else - { - newNotification.pColor = 0x00FF00; - } - - if (doc.containsKey("progressBC")) - { - auto progressBC = doc["progressBC"]; - newNotification.pbColor = getColorFromJsonVariant(progressBC, 0xFFFFFF); - } - else - { - newNotification.pbColor = 0xFFFFFF; - } - - if (doc.containsKey("background")) - { - auto background = doc["background"]; - newNotification.background = getColorFromJsonVariant(background, 0); - } - else - { - newNotification.background = 0x000000; - } + newNotification.pColor = getColorField(doc.as(), "progressC", 0x00FF00); + newNotification.pbColor = getColorField(doc.as(), "progressBC", 0xFFFFFF); + newNotification.background = getColorField(doc.as(), "background", 0); if (doc.containsKey("draw")) { @@ -844,88 +721,12 @@ bool DisplayManager_::generateNotification(uint8_t source, const char *json) newNotification.iconPosition = 0; newNotification.scrollDelay = 0; - newNotification.gradient[0] = -1; - newNotification.gradient[1] = -1; - if (doc.containsKey("gradient")) - { - JsonArray arr = doc["gradient"].as(); - if (arr.size() == 2) - { - auto color1 = arr[0]; - auto color2 = arr[1]; - - newNotification.gradient[0] = getColorFromJsonVariant(color1, TEXTCOLOR_888); - newNotification.gradient[1] = getColorFromJsonVariant(color2, TEXTCOLOR_888); - } - } - - bool autoscale = true; - if (doc.containsKey("autoscale")) - { - autoscale = doc["autoscale"].as(); - } - - // Handling for "bar" and "line" as they have similar structures - const char *dataKeys[] = {"bar", "line"}; - int *dataArrays[] = {newNotification.barData, newNotification.lineData}; - int *dataSizeArrays[] = {&newNotification.barSize, &newNotification.lineSize}; - - for (int i = 0; i < 2; i++) - { - const char *key = dataKeys[i]; - int *dataArray = dataArrays[i]; - int *dataSize = dataSizeArrays[i]; - - if (doc.containsKey(key)) - { - - if (doc.containsKey("barBC")) - { - auto color = doc["barBC"]; - newNotification.barBG = getColorFromJsonVariant(color, 0); - } - JsonArray data = doc[key]; - int index = 0; - int maximum = 0; - for (JsonVariant v : data) - { - if (index >= 16) - { - break; - } - int d = v.as(); - if (d > maximum) - { - maximum = d; - } - dataArray[index] = d; - index++; - } - *dataSize = index; + parseGradient(doc.as(), newNotification.gradient); - if (autoscale) - { - for (int j = 0; j < *dataSize; j++) - { - dataArray[j] = map(dataArray[j], 0, maximum, 0, 8); - } - } - } - else - { - *dataSize = 0; - } - } + bool autoscale = doc.containsKey("autoscale") ? doc["autoscale"].as() : true; + parseBarLineData(doc.as(), newNotification.barData, newNotification.barSize, newNotification.lineData, newNotification.lineSize, newNotification.barBG, autoscale); - if (doc.containsKey("color")) - { - auto color = doc["color"]; - newNotification.color = getColorFromJsonVariant(color, TEXTCOLOR_888); - } - else - { - newNotification.color = TEXTCOLOR_888; - } + newNotification.color = getColorField(doc.as(), "color", TEXTCOLOR_888); if (doc.containsKey("text") && doc["text"].is()) { @@ -2139,55 +1940,15 @@ void DisplayManager_::setNewSettings(const char *json) PeripheryManager.setVolume(SOUND_VOLUME); } - if (doc.containsKey("CCORRECTION")) + if (parseCRGB(doc.as(), "CCORRECTION", COLOR_CORRECTION)) { - auto colorValue = doc["CCORRECTION"]; - if (colorValue.is()) - { - String hexColor = colorValue.as(); - uint32_t rgbColor = strtoul(hexColor.c_str(), NULL, 16); - uint8_t r = (rgbColor >> 16) & 0xFF; - uint8_t g = (rgbColor >> 8) & 0xFF; - uint8_t b = rgbColor & 0xFF; - COLOR_CORRECTION.setRGB(r, g, b); - } - else if (colorValue.is() && colorValue.size() == 3) - { - uint8_t r = colorValue[0]; - uint8_t g = colorValue[1]; - uint8_t b = colorValue[2]; - COLOR_CORRECTION.setRGB(r, g, b); - } - if (COLOR_CORRECTION) - { FastLED.setCorrection(COLOR_CORRECTION); - } } - if (doc.containsKey("CTEMP")) + if (parseCRGB(doc.as(), "CTEMP", COLOR_TEMPERATURE)) { - auto colorValue = doc["CTEMP"]; - if (colorValue.is()) - { - String hexColor = colorValue.as(); - uint32_t rgbColor = strtoul(hexColor.c_str(), NULL, 16); - uint8_t r = (rgbColor >> 16) & 0xFF; - uint8_t g = (rgbColor >> 8) & 0xFF; - uint8_t b = rgbColor & 0xFF; - COLOR_TEMPERATURE.setRGB(r, g, b); - } - else if (colorValue.is() && colorValue.size() == 3) - { - uint8_t r = colorValue[0]; - uint8_t g = colorValue[1]; - uint8_t b = colorValue[2]; - COLOR_TEMPERATURE.setRGB(r, g, b); - } - if (COLOR_TEMPERATURE) - { FastLED.setTemperature(COLOR_TEMPERATURE); - } } if (doc.containsKey("WDCA")) { diff --git a/src/Functions.cpp b/src/Functions.cpp index e58cc80c..f2c7a6d4 100644 --- a/src/Functions.cpp +++ b/src/Functions.cpp @@ -249,6 +249,111 @@ String utf8ascii(String s) return r; } +// Reads a color value from a JSON object by key. +// Supports hex strings ("#RRGGBB") and RGB arrays ([r, g, b]). +// Returns defaultColor if the key is missing. +uint32_t getColorField(JsonObject doc, const char *key, uint32_t defaultColor) +{ + if (doc.containsKey(key)) + { + return getColorFromJsonVariant(doc[key], defaultColor); + } + return defaultColor; +} + +// Parses a two-color gradient from the "gradient" JSON field. +// Each color can be a hex string or RGB array. +// Sets both elements to -1 if the field is missing or malformed. +void parseGradient(JsonObject doc, int gradient[2]) +{ + gradient[0] = -1; + gradient[1] = -1; + if (doc.containsKey("gradient")) + { + JsonArray arr = doc["gradient"].as(); + if (arr.size() == 2) + { + gradient[0] = getColorFromJsonVariant(arr[0], TEXTCOLOR_888); + gradient[1] = getColorFromJsonVariant(arr[1], TEXTCOLOR_888); + } + } +} + +// Parses "bar" and "line" chart data arrays (max 16 elements each) from a JSON object. +// Reads the optional "barBC" field for bar background color. +// When autoscale is true, values are mapped to the 0-8 range relative to the maximum. +void parseBarLineData(JsonObject doc, int barData[16], int &barSize, int lineData[16], int &lineSize, uint32_t &barBG, bool autoscale) +{ + const char *dataKeys[] = {"bar", "line"}; + int *dataArrays[] = {barData, lineData}; + int *dataSizeArrays[] = {&barSize, &lineSize}; + + for (int i = 0; i < 2; i++) + { + const char *key = dataKeys[i]; + int *dataArray = dataArrays[i]; + int *dataSize = dataSizeArrays[i]; + + if (doc.containsKey(key)) + { + barBG = getColorField(doc, "barBC", 0); + JsonArray data = doc[key]; + int index = 0; + int maximum = 0; + for (JsonVariant v : data) + { + if (index >= 16) + { + break; + } + int d = v.as(); + if (d > maximum) + { + maximum = d; + } + dataArray[index] = d; + index++; + } + *dataSize = index; + + if (autoscale) + { + for (int j = 0; j < *dataSize; j++) + { + dataArray[j] = map(dataArray[j], 0, maximum, 0, 8); + } + } + } + else + { + *dataSize = 0; + } + } +} + +// Parses a CRGB color from a JSON object by key. +// Accepts a hex string ("RRGGBB") or an RGB array ([r, g, b]). +// Returns true and sets `out` if the key exists and has a valid format, false otherwise. +bool parseCRGB(JsonObject doc, const char *key, CRGB &out) +{ + if (!doc.containsKey(key)) + return false; + auto colorValue = doc[key]; + if (colorValue.is()) + { + String hexColor = colorValue.as(); + uint32_t rgbColor = strtoul(hexColor.c_str(), NULL, 16); + out.setRGB((rgbColor >> 16) & 0xFF, (rgbColor >> 8) & 0xFF, rgbColor & 0xFF); + return true; + } + else if (colorValue.is() && colorValue.size() == 3) + { + out.setRGB((uint8_t)colorValue[0], (uint8_t)colorValue[1], (uint8_t)colorValue[2]); + return true; + } + return false; +} + uint32_t fadeColor(uint32_t color, uint32_t interval) { float phase = (sin(2 * PI * millis() / float(interval)) + 1) * 0.5; diff --git a/src/Functions.h b/src/Functions.h index 321cb1a5..ce83c9a5 100644 --- a/src/Functions.h +++ b/src/Functions.h @@ -27,4 +27,12 @@ uint32_t TextEffect(uint32_t color, uint32_t fade, uint32_t blink); uint32_t fadeColor(uint32_t color, uint32_t interval); +uint32_t getColorField(JsonObject doc, const char *key, uint32_t defaultColor); + +void parseGradient(JsonObject doc, int gradient[2]); + +void parseBarLineData(JsonObject doc, int barData[16], int &barSize, int lineData[16], int &lineSize, uint32_t &barBG, bool autoscale); + +bool parseCRGB(JsonObject doc, const char *key, CRGB &out); + #endif \ No newline at end of file