diff --git a/docs/api.md b/docs/api.md index adc99f58..ab971864 100644 --- a/docs/api.md +++ b/docs/api.md @@ -176,23 +176,6 @@ Here's an example JSON object to draw a red circle, a blue rectangle, and the te {"dt": [0, 0, "Hello", "#00FF00"]} ]} ``` - -### Send multiple custompage at once -This allows you to send multiple custompage at once. Instead of a single custompage object, you can send an array of objects. like - -**Topic:** -/custom/test - -```json -`[{"text":"1"},{"text":"2"}]` -``` -Internally the appname gets a suffix like test0, test1 and so on. -You can update each app like before, or you can update all apps at once. -While removing apps, awtrix doesnt search for the exact name, but uses the app that starts with the given name. -So if you want to delete all apps just send empty payload to /custom/test. This will remove test0, test1 and so on. -you can also remove one app by removing /custom/test1. -Please keep in mind that if you delete only one app, you cant get the correct Order again because all apps in the loop move, since there can be no placeholder. - ### Display a text in colored fragments You can display a text where you allowed to colorize fragments of the text. diff --git a/lib/webserver/esp-fs-webserver.cpp b/lib/webserver/esp-fs-webserver.cpp index 6831328d..5f4b9b2f 100644 --- a/lib/webserver/esp-fs-webserver.cpp +++ b/lib/webserver/esp-fs-webserver.cpp @@ -115,7 +115,7 @@ bool FSWebServer::begin(const char *path) // OTA update via webbrowser m_httpUpdater.setup(webserver); - + webserver->enableCORS(true); @@ -899,8 +899,8 @@ void FSWebServer::handleStatus() totalBytes = fs_info.totalBytes; usedBytes = fs_info.usedBytes; #elif defined(ESP32) - // totalBytes = m_filesystem->totalBytes(); - // usedBytes = m_filesystem->usedBytes(); + totalBytes = LittleFS.totalBytes(); + usedBytes = LittleFS.usedBytes(); #endif String json; diff --git a/src/DisplayManager.cpp b/src/DisplayManager.cpp index ab730a88..38db210c 100644 --- a/src/DisplayManager.cpp +++ b/src/DisplayManager.cpp @@ -334,24 +334,14 @@ void removeCustomAppFromApps(const String &name, bool setApps) deleteCustomAppFile(name); } -bool parseFragmentsText(const String &jsonText, std::vector &colors, std::vector &fragments, uint16_t standardColor) +bool parseFragmentsText(const JsonArray &fragmentArray, std::vector &colors, std::vector &fragments, uint16_t standardColor) { colors.clear(); fragments.clear(); - DynamicJsonDocument doc(4096); - DeserializationError error = deserializeJson(doc, jsonText); - if (error) - { - DEBUG_PRINTLN(error.c_str()); - doc.clear(); - return false; - } - - JsonArray fragmentArray = doc.as(); for (JsonObject fragmentObj : fragmentArray) { - String textFragment = fragmentObj["t"].as(); + String textFragment = utf8ascii(fragmentObj["t"].as()); uint16_t color; if (fragmentObj.containsKey("c")) { @@ -366,46 +356,9 @@ bool parseFragmentsText(const String &jsonText, std::vector &colors, s fragments.push_back(textFragment); colors.push_back(color); } - doc.clear(); return true; } -bool DisplayManager_::parseCustomPage(const String &name, const char *json) -{ - if ((strcmp(json, "") == 0) || (strcmp(json, "{}") == 0)) - { - removeCustomAppFromApps(name, true); - return true; - } - DynamicJsonDocument doc(4096); - DeserializationError error = deserializeJson(doc, json); - if (error) - { - DEBUG_PRINTLN(error.c_str()); - doc.clear(); - return false; - } - - if (doc.is()) - { - return generateCustomPage(name, json, false); - } - else if (doc.is()) - { - JsonArray customPagesArray = doc.as(); - int cpIndex = 0; - for (JsonVariant customPage : customPagesArray) - { - JsonObject customPageObject = customPage.as(); - String customPageJson; - serializeJson(customPageObject, customPageJson); - generateCustomPage(name + String(cpIndex), customPageJson.c_str(), false); - ++cpIndex; - } - } - doc.clear(); - return true; -} bool DisplayManager_::generateCustomPage(const String &name, const char *json, bool preventSave) { @@ -491,74 +444,51 @@ bool DisplayManager_::generateCustomPage(const String &name, const char *json, b autoscale = doc["autoscale"].as(); } - if (doc.containsKey("bar")) - { - JsonArray barData = doc["bar"]; - int i = 0; - int maximum = 0; - for (JsonVariant v : barData) - { - if (i >= 16) - { - break; - } - int d = v.as(); - if (d > maximum) - { - maximum = d; - } - customApp.barData[i] = d; - i++; - } - customApp.barSize = i; + // 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}; - if (autoscale) - { - for (int j = 0; j < customApp.barSize; j++) - { - customApp.barData[j] = map(customApp.barData[j], 0, maximum, 0, 8); - } - } - } - else + for (int i = 0; i < 2; i++) { - customApp.barSize = 0; - } + const char* key = dataKeys[i]; + int* dataArray = dataArrays[i]; + int* dataSize = dataSizeArrays[i]; - if (doc.containsKey("line")) - { - JsonArray lineData = doc["line"]; - int i = 0; - int maximum = 0; - for (JsonVariant v : lineData) + if (doc.containsKey(key)) { - if (i >= 16) + JsonArray data = doc[key]; + int index = 0; + int maximum = 0; + for (JsonVariant v : data) { - break; + if (index >= 16) + { + break; + } + int d = v.as(); + if (d > maximum) + { + maximum = d; + } + dataArray[index] = d; + index++; } - int d = v.as(); - if (d > maximum) + *dataSize = index; + + if (autoscale) { - maximum = d; + for (int j = 0; j < *dataSize; j++) + { + dataArray[j] = map(dataArray[j], 0, maximum, 0, 8); + } } - customApp.lineData[i] = d; - i++; } - customApp.lineSize = i; - - // Autoscaling - if (autoscale) + else { - for (int j = 0; j < customApp.lineSize; j++) - { - customApp.lineData[j] = map(customApp.lineData[j], 0, maximum, 0, 8); - } + *dataSize = 0; } } - else - { - customApp.lineSize = 0; - } if (doc.containsKey("draw")) { @@ -601,11 +531,15 @@ bool DisplayManager_::generateCustomPage(const String &name, const char *json, b customApp.color = TEXTCOLOR_565; } - if (doc.containsKey("text")) + if (doc.containsKey("text") && doc["text"].is()) { - String text = utf8ascii(doc["text"].as()); - parseFragmentsText(text, customApp.colors, customApp.fragments, customApp.color); - customApp.text = text; + JsonArray textArray = doc["text"].as(); + parseFragmentsText(textArray, customApp.colors, customApp.fragments, customApp.color); + // Der Code zur Zuweisung von customApp.text könnte hier angepasst werden, je nachdem, wie Sie die Textinformationen verwenden möchten. + } + else if (doc.containsKey("text") && doc["text"].is()) + { + customApp.text = utf8ascii(doc["text"].as()); } else { @@ -747,80 +681,57 @@ bool DisplayManager_::generateNotification(uint8_t source, const char *json) newNotification.iconPosition = 0; newNotification.scrollDelay = 0; - bool autoscale = true; + bool autoscale = true; if (doc.containsKey("autoscale")) { autoscale = doc["autoscale"].as(); } - if (doc.containsKey("bar")) - { - JsonArray barData = doc["bar"]; - int i = 0; - int maximum = 0; - for (JsonVariant v : barData) - { - if (i >= 16) - { - break; - } - int d = v.as(); - if (d > maximum) - { - maximum = d; - } - newNotification.barData[i] = d; - i++; - } - newNotification.barSize = i; + // 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}; - if (autoscale) - { - for (int j = 0; j < newNotification.barSize; j++) - { - newNotification.barData[j] = map(newNotification.barData[j], 0, maximum, 0, 8); - } - } - } - else + for (int i = 0; i < 2; i++) { - newNotification.barSize = 0; - } + const char* key = dataKeys[i]; + int* dataArray = dataArrays[i]; + int* dataSize = dataSizeArrays[i]; - if (doc.containsKey("line")) - { - JsonArray lineData = doc["line"]; - int i = 0; - int maximum = 0; - for (JsonVariant v : lineData) + if (doc.containsKey(key)) { - if (i >= 16) + JsonArray data = doc[key]; + int index = 0; + int maximum = 0; + for (JsonVariant v : data) { - break; + if (index >= 16) + { + break; + } + int d = v.as(); + if (d > maximum) + { + maximum = d; + } + dataArray[index] = d; + index++; } - int d = v.as(); - if (d > maximum) + *dataSize = index; + + if (autoscale) { - maximum = d; + for (int j = 0; j < *dataSize; j++) + { + dataArray[j] = map(dataArray[j], 0, maximum, 0, 8); + } } - newNotification.lineData[i] = d; - i++; } - newNotification.lineSize = i; - - // Autoscaling - if (autoscale) + else { - for (int j = 0; j < newNotification.lineSize; j++) - { - newNotification.lineData[j] = map(newNotification.lineData[j], 0, maximum, 0, 8); - } + *dataSize = 0; } } - else - { - newNotification.lineSize = 0; - } if (doc.containsKey("color")) { @@ -832,11 +743,15 @@ bool DisplayManager_::generateNotification(uint8_t source, const char *json) newNotification.color = TEXTCOLOR_565; } - if (doc.containsKey("text")) + if (doc.containsKey("text") && doc["text"].is()) { - String text = utf8ascii(doc["text"].as()); - parseFragmentsText(text, newNotification.colors, newNotification.fragments, newNotification.color); - newNotification.text = text; + JsonArray textArray = doc["text"].as(); + parseFragmentsText(textArray, newNotification.colors, newNotification.fragments, newNotification.color); + // Der Code zur Zuweisung von customApp.text könnte hier angepasst werden, je nachdem, wie Sie die Textinformationen verwenden möchten. + } + else if (doc["text"].is()) + { + newNotification.text = doc["text"].as(); } else { @@ -1521,7 +1436,7 @@ String DisplayManager_::getStats() doc[BatKey] = BATTERY_PERCENT; doc[BatRawKey] = BATTERY_RAW; doc[F("type")] = 0; -#else +#else doc[F("type")] = 1; #endif @@ -1785,8 +1700,10 @@ bool DisplayManager_::indicatorParser(uint8_t indicator, const char *json) float logMap(float x, float in_min, float in_max, float out_min, float out_max, float mid_point_out) { - if (xin_max) return out_max; + if (x < in_min) + return out_min; + if (x > in_max) + return out_max; float scale = (mid_point_out - out_min) / log(in_max - in_min + 1); if (x <= (in_max + in_min) / 2.0) { @@ -1817,7 +1734,7 @@ void DisplayManager_::sendAppLoop() String DisplayManager_::getSettings() { StaticJsonDocument<1024> doc; - doc["MATP"] = !MATRIX_OFF; + doc["MATP"] = !MATRIX_OFF; doc["ABRI"] = AUTO_BRIGHTNESS; doc["BRI"] = BRIGHTNESS; doc["ATRANS"] = AUTO_TRANSITION; @@ -1890,7 +1807,7 @@ void DisplayManager_::setNewSettings(const char *json) SCROLL_SPEED = doc.containsKey("SSPEED") ? doc["SSPEED"] : SCROLL_SPEED; IS_CELSIUS = doc.containsKey("CEL") ? doc["CEL"] : IS_CELSIUS; START_ON_MONDAY = doc.containsKey("SOM") ? doc["SOM"].as() : START_ON_MONDAY; - MATRIX_OFF = doc.containsKey("MATP") ? !doc["MATP"].as() : MATRIX_OFF; + MATRIX_OFF = doc.containsKey("MATP") ? !doc["MATP"].as() : MATRIX_OFF; TIME_FORMAT = doc.containsKey("TFORMAT") ? doc["TFORMAT"].as() : TIME_FORMAT; GAMMA = doc.containsKey("GAMMA") ? doc["GAMMA"].as() : GAMMA; DATE_FORMAT = doc.containsKey("DFORMAT") ? doc["DFORMAT"].as() : DATE_FORMAT; diff --git a/src/Globals.cpp b/src/Globals.cpp index d139f11c..37defcff 100644 --- a/src/Globals.cpp +++ b/src/Globals.cpp @@ -273,7 +273,7 @@ IPAddress gateway; IPAddress subnet; IPAddress primaryDNS; IPAddress secondaryDNS; -const char *VERSION = "0.76"; +const char *VERSION = "0.77"; String MQTT_HOST = ""; uint16_t MQTT_PORT = 1883; @@ -302,7 +302,6 @@ int TIME_PER_TRANSITION = 400; String NTP_SERVER = "de.pool.ntp.org"; String NTP_TZ = "CET-1CEST,M3.5.0,M10.5.0/3"; bool HA_DISCOVERY = false; - String HA_PREFIX = "homeassistant"; // Periphery String CURRENT_APP; diff --git a/src/MQTTManager.cpp b/src/MQTTManager.cpp index 6597312a..5e9ea88b 100644 --- a/src/MQTTManager.cpp +++ b/src/MQTTManager.cpp @@ -317,7 +317,7 @@ void onMqttMessage(const char *topic, const uint8_t *payload, uint16_t length) if (topic_str.startsWith(prefix)) { topic_str = topic_str.substring(prefix.length()); - DisplayManager.parseCustomPage(topic_str, payloadCopy); + DisplayManager.generateCustomPage(topic_str, payloadCopy,false); } delete[] payloadCopy; diff --git a/src/ServerManager.cpp b/src/ServerManager.cpp index 1f5319d5..cf31bf23 100644 --- a/src/ServerManager.cpp +++ b/src/ServerManager.cpp @@ -113,7 +113,7 @@ void addHandler() { mws.webserver->send_P(200, "application/json", DisplayManager.getSettings().c_str()); }); mws.addHandler("/api/custom", HTTP_POST, []() { - if (DisplayManager.parseCustomPage(mws.webserver->arg("name"),mws.webserver->arg("plain").c_str())){ + if (DisplayManager.generateCustomPage(mws.webserver->arg("name"),mws.webserver->arg("plain").c_str(),false)){ mws.webserver->send(200,F("text/plain"),F("OK")); }else{ mws.webserver->send(500,F("text/plain"),F("ErrorParsingJson"));