From d76c8a73c0b4b838d49e6c0db48ff3745cd7c830 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20M=C3=BChl?= <31169771+Blueforcer@users.noreply.github.com> Date: Wed, 13 Sep 2023 22:43:23 +0200 Subject: [PATCH] v0.86 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ### ✨ Features - 🎵 Adds `/rtttl` API to play a rtttl melody string directly - 🖥️ Adds HTTP fullscreen liveview at `/fullscreen` ### 🐛 Bug Fixes - 🎨 Fixes Matrix color for HA entity. Closes #314 - 🌈 Fixes moodlight bug. Closes #311 - 📆 Fixes drawing coordinates for time calendar icon. Closes #312 - 🔡 Fixes a bug with the free pixel between icon and text - 🟠 Fixes circle drawing - 📝 Fixes a bug while using textOffset and pushIcon. Closes #305 ### 🔥 Removals - ❌ Removes reset after X failed WiFi reconnect attempts, because some users disables WiFi over night. Closes #310 --- docs/api.md | 10 ++++- lib/webserver/esp-fs-webserver.cpp | 15 ------- src/Apps.h | 26 ++++++------ src/DisplayManager.cpp | 63 +++++++++++++++++------------- src/DisplayManager.h | 2 + src/GifPlayer.h | 7 ++-- src/Globals.cpp | 2 +- src/MQTTManager.cpp | 29 ++++++++------ src/MatrixDisplayUi.cpp | 8 ++-- src/MatrixDisplayUi.h | 1 - src/ServerManager.cpp | 5 +++ src/htmls.h | 12 ++---- 12 files changed, 91 insertions(+), 89 deletions(-) diff --git a/docs/api.md b/docs/api.md index 3bc4c517..014a60b7 100644 --- a/docs/api.md +++ b/docs/api.md @@ -28,8 +28,9 @@ Retrieve the current matrix screen as an array of 24bit colors: When triggering the MQTT API, AWTRIX sends the array to `[PREFIX]/screen`. **Extras:** -- Access a live view of the screen in your browser: `http://[IP]/screen`. +- Access a live view of the screen in your browser: `http://[IP]/screen`. - Options to download a screenshot or generate a GIF from the current display content. +- `http://[IP]/fullscreen` gives you a fullscreen liveview. Here you can optionally set the `fps` as parameter (standard 30) ## Power Control @@ -48,6 +49,13 @@ Play a RTTTL sound from the MELODIES folder: | ----------------- | ---------------------------- | ------------------- | ----------- | | `[PREFIX]/sound` | `http://[IP]/api/sound` | `{"sound":"alarm"}` | POST | +Play a RTTTL sound from a given RTTTL string: + +| MQTT Topic | HTTP URL | Payload/Body | HTTP Method | +| ----------------- | ---------------------------- | ------------------- | ----------- | +| `[PREFIX]/rtttl` | `http://[IP]/api/rtttl` | `rttl string` | POST | + + ## Mood Lighting Set the entire matrix to a custom color or temperature: diff --git a/lib/webserver/esp-fs-webserver.cpp b/lib/webserver/esp-fs-webserver.cpp index b57d03d9..7bf16ad3 100644 --- a/lib/webserver/esp-fs-webserver.cpp +++ b/lib/webserver/esp-fs-webserver.cpp @@ -19,27 +19,12 @@ void FSWebServer::run() m_dnsServer.processNextRequest(); unsigned long currentMillis = millis(); - // if WiFi is down, try reconnecting if ((WiFi.status() != WL_CONNECTED) && (currentMillis - previousMillis >= interval) && !m_apmode) { Serial.println("Reconnecting to WiFi..."); WiFi.disconnect(); WiFi.reconnect(); previousMillis = currentMillis; - if (WiFi.status() != WL_CONNECTED) - { - failedAttempts++; - if (failedAttempts >= 60) - { - Serial.println("60 failed attempts to connect. Restarting ESP..."); - ESP.restart(); - } - } - else - { - Serial.println("Reconnected!"); - failedAttempts = 0; - } } } diff --git a/src/Apps.h b/src/Apps.h index 03e32fbc..a45feb5e 100644 --- a/src/Apps.h +++ b/src/Apps.h @@ -26,6 +26,7 @@ String WEATHER_HUM; struct CustomApp { + bool hasCustomColor = false; uint32_t currentFrame = 0; String iconName; String iconFile; @@ -37,7 +38,6 @@ struct CustomApp uint32_t color; File icon; bool isGif; - bool iconSearched = false; bool rainbow; bool center; int fade = 0; @@ -222,23 +222,23 @@ void TimeApp(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, strftime(t, sizeof(t), timeformat, localtime(&now)); } - uint8_t wdPosY; - uint8_t timePosY; + int16_t wdPosY; + int16_t timePosY; if (TIME_MODE == 1 || TIME_MODE == 2) { wdPosY = TIME_MODE == 1 ? 7 : 0; timePosY = TIME_MODE == 1 ? 6 : 7; DisplayManager.printText(12 + x, timePosY + y, t, false, 2); - DisplayManager.drawFilledRect(0 + x, 0 + y, 9 + x, 2 + y, CALENDAR_HEADER_COLOR); - DisplayManager.drawFilledRect(0 + x, 2 + y, 9 + x, 7 + y, CALENDAR_BODY_COLOR); + DisplayManager.drawFilledRect(x, y, 9, 8, CALENDAR_BODY_COLOR); + DisplayManager.drawFilledRect(0 + x, 0 + y, 9, 2, CALENDAR_HEADER_COLOR); } else if (TIME_MODE == 3 || TIME_MODE == 4) { wdPosY = TIME_MODE == 3 ? 7 : 0; timePosY = TIME_MODE == 3 ? 6 : 7; DisplayManager.printText(12 + x, timePosY + y, t, false, 2); - DisplayManager.drawFilledRect(0 + x, 0 + y, 9 + x, 8 + y, CALENDAR_BODY_COLOR); + DisplayManager.drawFilledRect(0 + x, 0 + y, 9, 8, CALENDAR_BODY_COLOR); DisplayManager.drawLine(1, 0, 2, 0, 0x000000); DisplayManager.drawLine(6, 0, 7, 0, 0x000000); } @@ -263,8 +263,8 @@ void TimeApp(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, DisplayManager.setCursor(1 + x, 7 + y); } DisplayManager.matrixPrint(day_str); - uint8_t wdPosY = TIME_MODE > 0 ? 0 : 8; - uint8_t timePosY = TIME_MODE > 0 ? 6 : 0; + int16_t wdPosY = TIME_MODE > 0 ? 0 : 8; + int16_t timePosY = TIME_MODE > 0 ? 6 : 0; } if (!SHOW_WEEKDAY) @@ -507,7 +507,6 @@ void ShowCustomApp(String name, FastLED_NeoMatrix *matrix, MatrixDisplayUiState { ca->isGif = isGifFlags[i]; ca->icon = LittleFS.open(filePath); - ca->currentFrame=0; break; // Exit loop if icon was found } } @@ -557,7 +556,7 @@ void ShowCustomApp(String name, FastLED_NeoMatrix *matrix, MatrixDisplayUiState } if (ca->isGif) { - iconWidth = gifPlayer->playGif(x + ca->iconPosition + ca->iconOffset, y, &ca->icon,ca->currentFrame); + iconWidth = gifPlayer->playGif(x + ca->iconPosition + ca->iconOffset, y, &ca->icon, ca->currentFrame); ca->currentFrame = gifPlayer->getFrame(); } else @@ -608,9 +607,8 @@ void ShowCustomApp(String name, FastLED_NeoMatrix *matrix, MatrixDisplayUiState if (textWidth > availableWidth && !(state->appState == IN_TRANSITION)) { - if (ca->scrollposition <= (-textWidth - ca->textOffset)) + if (ca->scrollposition + ca->textOffset <= (-textWidth)) { - if (ca->iconWasPushed && ca->pushIcon == 2) { ca->iconWasPushed = false; @@ -634,7 +632,7 @@ void ShowCustomApp(String name, FastLED_NeoMatrix *matrix, MatrixDisplayUiState } if (!noScrolling) { - if ((ca->scrollDelay > MATRIX_FPS * 1.2) || ((hasIcon ? ca->textOffset + 9 : ca->textOffset) > 31)) + if ((ca->scrollDelay > MATRIX_FPS ) || ((hasIcon ? ca->textOffset + 9 : ca->textOffset) > 31)) { if (state->appState == FIXED && !ca->noScrolling) { @@ -898,7 +896,7 @@ void NotifyOverlay(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, GifPl } // Check if text needs to be scrolled - if (textWidth > availableWidth && notifications[0].scrollposition <= -textWidth) + if (textWidth > availableWidth && notifications[0].scrollposition + notifications[0].textOffset <= (-textWidth)) { // Reset scroll position and icon position if needed notifications[0].scrollDelay = 0; diff --git a/src/DisplayManager.cpp b/src/DisplayManager.cpp index 28b795ef..123ee2de 100644 --- a/src/DisplayManager.cpp +++ b/src/DisplayManager.cpp @@ -386,7 +386,7 @@ bool parseFragmentsText(const JsonArray &fragmentArray, std::vector &c for (JsonObject fragmentObj : fragmentArray) { - String textFragment = utf8ascii(fragmentObj["t"].as()); + String textFragment = fragmentObj["t"]; uint32_t color; if (fragmentObj.containsKey("c")) { @@ -398,7 +398,7 @@ bool parseFragmentsText(const JsonArray &fragmentArray, std::vector &c color = standardColor; } - fragments.push_back(textFragment); + fragments.push_back(utf8ascii(textFragment)); colors.push_back(color); } return true; @@ -610,16 +610,14 @@ bool DisplayManager_::generateCustomPage(const String &name, JsonObject doc, boo { customApp.iconName = newIconName; customApp.icon.close(); - customApp.currentFrame = 0; - customApp.iconSearched = false; + customApp.iconPosition = 0; } } else { customApp.icon.close(); - customApp.currentFrame = 0; - customApp.iconSearched = false; customApp.iconName = ""; + customApp.iconPosition = 0; } customApp.gradient[0] = -1; @@ -640,11 +638,13 @@ bool DisplayManager_::generateCustomPage(const String &name, JsonObject doc, boo if (doc.containsKey("color")) { + customApp.hasCustomColor = true; auto color = doc["color"]; customApp.color = getColorFromJsonVariant(color, TEXTCOLOR_888); } else { + customApp.hasCustomColor = false; customApp.color = TEXTCOLOR_888; } @@ -656,7 +656,8 @@ bool DisplayManager_::generateCustomPage(const String &name, JsonObject doc, boo } else if (doc.containsKey("text") && doc["text"].is()) { - customApp.text = utf8ascii(doc["text"].as()); + String text = doc["text"]; + customApp.text = utf8ascii(text); } else { @@ -858,7 +859,8 @@ bool DisplayManager_::generateNotification(uint8_t source, const char *json) } else if (doc["text"].is()) { - newNotification.text = utf8ascii(doc["text"].as()); + String text = doc["text"]; + newNotification.text = utf8ascii(text); } else { @@ -1072,7 +1074,6 @@ void ResetCustomApps() app.iconPosition = 0; app.scrollDelay = 0; app.currentRepeat = 0; - app.iconSearched = false; app.icon.close(); app.currentFrame = 0; } @@ -1081,7 +1082,6 @@ void ResetCustomApps() void checkLifetime(uint8_t pos) { - if (customApps.empty()) { return; @@ -2036,14 +2036,7 @@ void DisplayManager_::setNewSettings(const char *json) { auto TCOL = doc["TCOL"]; uint32_t TempColor = getColorFromJsonVariant(TCOL, 0xFFFFFF); - for (auto it = customApps.begin(); it != customApps.end(); ++it) - { - CustomApp &app = it->second; - if (app.color == TEXTCOLOR_888) - { - app.color = TempColor; - } - } + setCustomAppColors(TempColor); TEXTCOLOR_888 = TempColor; } @@ -2079,6 +2072,18 @@ void DisplayManager_::setNewSettings(const char *json) DEBUG_PRINTLN("Settings loaded"); } +void DisplayManager_::setCustomAppColors(uint32_t color) +{ + for (auto it = customApps.begin(); it != customApps.end(); ++it) + { + CustomApp &app = it->second; + if (!app.hasCustomColor) + { + app.color = color; + } + } +} + String DisplayManager_::ledsAsJson() { StaticJsonDocument jsonDoc; @@ -2191,7 +2196,7 @@ void DisplayManager_::processDrawInstructions(int16_t xOffset, int16_t yOffset, int y1 = params[3].as(); auto color2 = params[4]; uint32_t color = getColorFromJsonVariant(color2, TEXTCOLOR_888); - DisplayManager.drawLine(x0 + xOffset, y0 + yOffset, x1 + xOffset, y1 + yOffset, color); + drawLine(x0 + xOffset, y0 + yOffset, x1 + xOffset, y1 + yOffset, color); } else if (command == "dr") { @@ -2201,7 +2206,7 @@ void DisplayManager_::processDrawInstructions(int16_t xOffset, int16_t yOffset, int h = params[3].as(); auto color3 = params[4]; uint32_t color = getColorFromJsonVariant(color3, TEXTCOLOR_888); - DisplayManager.drawRect(x + xOffset, y + yOffset, w, h, color); + drawRect(x + xOffset, y + yOffset, w, h, color); } else if (command == "df") { @@ -2211,7 +2216,7 @@ void DisplayManager_::processDrawInstructions(int16_t xOffset, int16_t yOffset, int h = params[3].as(); auto color4 = params[4]; uint32_t color = getColorFromJsonVariant(color4, TEXTCOLOR_888); - DisplayManager.drawFilledRect(x + xOffset, y + yOffset, w, h, color); + drawFilledRect(x + xOffset, y + yOffset, w, h, color); } else if (command == "dc") { @@ -2220,7 +2225,7 @@ void DisplayManager_::processDrawInstructions(int16_t xOffset, int16_t yOffset, int r = params[2].as(); auto color5 = params[3]; uint32_t color = getColorFromJsonVariant(color5, TEXTCOLOR_888); - matrix->drawCircle(x + xOffset, y + yOffset, r, color); + drawCircle(x + xOffset, y + yOffset, r, color); } else if (command == "dfc") { @@ -2229,7 +2234,7 @@ void DisplayManager_::processDrawInstructions(int16_t xOffset, int16_t yOffset, double r = params[2].as(); auto color6 = params[3]; uint32_t color = getColorFromJsonVariant(color6, TEXTCOLOR_888); - matrix->fillCircle(x + xOffset, y + yOffset, r, color); + fillCircle(x + xOffset, y + yOffset, r, color); } else if (command == "dt") { @@ -2301,7 +2306,7 @@ bool DisplayManager_::moodlight(const char *json) { auto c = doc["color"]; uint32_t color888 = getColorFromJsonVariant(c, TEXTCOLOR_888); - matrix->fillScreen(color888); + drawFilledRect(0, 0, 32, 8, color888); } else { @@ -2367,14 +2372,16 @@ void DisplayManager_::drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint3 } } +void DisplayManager_::drawFastVLine(int16_t x, int16_t y, int16_t h, uint32_t color) +{ + drawLine(x, y, x, y + h - 1, color); +} + void DisplayManager_::drawFilledRect(int16_t x, int16_t y, int16_t w, int16_t h, uint32_t color) { for (int16_t i = x; i < x + w; i++) { - for (int16_t j = y; j < y + h; j++) - { - matrix->drawPixel(i, j, color); - } + drawFastVLine(i, y, h, color); } } diff --git a/src/DisplayManager.h b/src/DisplayManager.h index 37d85134..5e625878 100644 --- a/src/DisplayManager.h +++ b/src/DisplayManager.h @@ -88,6 +88,7 @@ class DisplayManager_ void drawRGBBitmap(int16_t x, int16_t y, uint32_t *bitmap, int16_t w, int16_t h); void drawCircle(int16_t x0, int16_t y0, int16_t r, uint32_t color); void fillCircle(int16_t x0, int16_t y0, int16_t r, uint32_t color); + void drawFastVLine(int16_t x, int16_t y, int16_t h, uint32_t color); void matrixPrint(const char *str); void matrixPrint(char c); void matrixPrint(String str); @@ -96,6 +97,7 @@ class DisplayManager_ void setCursor(int16_t x, int16_t y); void setTextColor(uint32_t color); void matrixPrint(double number, uint8_t digits); + void setCustomAppColors(uint32_t color); }; extern DisplayManager_ &DisplayManager; diff --git a/src/GifPlayer.h b/src/GifPlayer.h index aa9be7bc..f7becc59 100644 --- a/src/GifPlayer.h +++ b/src/GifPlayer.h @@ -238,7 +238,7 @@ class GifPlayer if ((prevDisposalMethod != DISPOSAL_NONE) && (prevDisposalMethod != DISPOSAL_LEAVE)) { - //mtx->fillRect(offsetX, offsetY, lsdWidth, lsdHeight, 0); + memset(FrameBuffer, 0, sizeof(FrameBuffer)); } if (prevDisposalMethod == DISPOSAL_BACKGROUND) @@ -546,7 +546,7 @@ class GifPlayer if (imageFile->name() == file.name()) { drawFrame(); - return tbiWidth; + return lsdWidth; } else { @@ -580,7 +580,7 @@ class GifPlayer drawFrame(); } } - return tbiWidth; + return lsdWidth; } boolean parseGifHeader() @@ -665,6 +665,7 @@ class GifPlayer { done = true; file.seek(0); + currentFrame = 0; parseGifHeader(); parseLogicalScreenDescriptor(); parseGlobalColorTable(); diff --git a/src/Globals.cpp b/src/Globals.cpp index 0ac30f40..06c82e26 100644 --- a/src/Globals.cpp +++ b/src/Globals.cpp @@ -297,7 +297,7 @@ IPAddress gateway; IPAddress subnet; IPAddress primaryDNS; IPAddress secondaryDNS; -const char *VERSION = "0.86"; +const char *VERSION = "0.85"; String MQTT_HOST = ""; uint16_t MQTT_PORT = 1883; diff --git a/src/MQTTManager.cpp b/src/MQTTManager.cpp index 481af9c4..46050f2a 100644 --- a/src/MQTTManager.cpp +++ b/src/MQTTManager.cpp @@ -94,6 +94,7 @@ void onRGBColorCommand(HALight::RGBColor color, HALight *sender) if (sender == Matrix) { TEXTCOLOR_888 = (color.red << 16) | (color.green << 8) | color.blue; + DisplayManager.setCustomAppColors(TEXTCOLOR_888); saveSettings(); } else if (sender == Indikator1) @@ -246,6 +247,13 @@ void onMqttMessage(const char *topic, const uint8_t *payload, uint16_t length) return; } + if (strTopic.equals(MQTT_PREFIX + "/rtttl")) + { + PeripheryManager.playRTTTLString(payloadCopy); + delete[] payloadCopy; + return; + } + if (strTopic.equals(MQTT_PREFIX + "/doupdate")) { if (UpdateManager.checkUpdate(true)) @@ -360,6 +368,7 @@ void onMqttConnected() "/reboot", "/moodlight", "/sound", + "/rtttl", "/sendscreen", "/r2d2"}; for (const char *topic : topics) @@ -438,12 +447,9 @@ void MQTTManager_::sendStats() Matrix->setState(!MATRIX_OFF, false); HALight::RGBColor color; color.isSet = true; - color.red = (TEXTCOLOR_888 >> 11) & 0x1F; - color.green = (TEXTCOLOR_888 >> 5) & 0x3F; - color.blue = TEXTCOLOR_888 & 0x1F; - color.red <<= 3; - color.green <<= 2; - color.blue <<= 3; + color.red = (TEXTCOLOR_888 >> 16) & 0xFF; // Die obersten 8 Bits für Rot + color.green = (TEXTCOLOR_888 >> 8) & 0xFF; // Die mittleren 8 Bits für Grün + color.blue = TEXTCOLOR_888 & 0xFF; // Die untersten 8 Bits für Blau Matrix->setRGBColor(color); int8_t rssiValue = WiFi.RSSI(); char rssiString[4]; @@ -502,14 +508,11 @@ void MQTTManager_::setup() HALight::RGBColor color; color.isSet = true; - color.red = (TEXTCOLOR_888 >> 11) & 0x1F; // Bitverschiebung um 11 Bits und Maskierung mit 0x1F - color.green = (TEXTCOLOR_888 >> 5) & 0x3F; // Bitverschiebung um 5 Bits und Maskierung mit 0x3F - color.blue = TEXTCOLOR_888 & 0x1F; // Maskierung mit 0x1F - color.red <<= 3; - color.green <<= 2; - color.blue <<= 3; + color.red = (TEXTCOLOR_888 >> 16) & 0xFF; // Die obersten 8 Bits für Rot + color.green = (TEXTCOLOR_888 >> 8) & 0xFF; // Die mittleren 8 Bits für Grün + color.blue = TEXTCOLOR_888 & 0xFF; // Die untersten 8 Bits für Blau Matrix->setCurrentRGBColor(color); - Matrix->setState(true, true); + Matrix->setState(MATRIX_OFF, true); sprintf(ind1ID, HAi1ID, macStr); Indikator1 = new HALight(ind1ID, HALight::RGBFeature); diff --git a/src/MatrixDisplayUi.cpp b/src/MatrixDisplayUi.cpp index c79f93d0..902013fa 100644 --- a/src/MatrixDisplayUi.cpp +++ b/src/MatrixDisplayUi.cpp @@ -359,7 +359,7 @@ void MatrixDisplayUi::drawApp() { case IN_TRANSITION: { - swaped=false; + swaped = false; gotNewTransition = false; if (currentTransition == SLIDE) { @@ -416,15 +416,13 @@ void MatrixDisplayUi::drawApp() { currentTransition = TRANS_EFFECT; // Wenn TRANS_EFFECT nicht RANDOM ist, setzen Sie currentTransition auf TRANS_EFFECT } - + (this->AppFunctions[this->state.currentApp])(this->matrix, &this->state, 0, 0, &gif1); - swaped=true; + swaped = true; break; } } - - bool MatrixDisplayUi::isCurrentAppValid() { for (size_t i = 0; i < AppCount; ++i) diff --git a/src/MatrixDisplayUi.h b/src/MatrixDisplayUi.h index 3b641814..820948a5 100644 --- a/src/MatrixDisplayUi.h +++ b/src/MatrixDisplayUi.h @@ -158,7 +158,6 @@ class MatrixDisplayUi * Disable automatic transition to next app. */ void disablesetAutoTransition(); - void SwapGif(); /** * Set the direction if the automatic transitioning */ diff --git a/src/ServerManager.cpp b/src/ServerManager.cpp index 5b698ee3..9e01d03a 100644 --- a/src/ServerManager.cpp +++ b/src/ServerManager.cpp @@ -54,12 +54,15 @@ void addHandler() { mws.webserver->send_P(200, "application/json", DisplayManager.getTransistionNames().c_str()); }); mws.addHandler("/api/reboot", HTTP_ANY, []() { mws.webserver->send(200,F("text/plain"),F("OK")); delay(200); ESP.restart(); }); + mws.addHandler("/api/rtttl", HTTP_POST, []() + { mws.webserver->send(200,F("text/plain"),F("OK")); PeripheryManager.playRTTTLString(mws.webserver->arg("plain").c_str()); }); mws.addHandler("/api/sound", HTTP_POST, []() { if (PeripheryManager.parseSound(mws.webserver->arg("plain").c_str())){ mws.webserver->send(200,F("text/plain"),F("OK")); }else{ mws.webserver->send(404,F("text/plain"),F("FileNotFound")); }; }); + mws.addHandler("/api/moodlight", HTTP_POST, []() { if (DisplayManager.moodlight(mws.webserver->arg("plain").c_str())) @@ -80,6 +83,8 @@ void addHandler() } }); mws.addHandler("/api/nextapp", HTTP_ANY, []() { DisplayManager.nextApp(); mws.webserver->send(200,F("text/plain"),F("OK")); }); + mws.addHandler("/fullscreen", HTTP_GET, []() + { mws.webserver->send(200, "text/html", screenfull_html); }); mws.addHandler("/screen", HTTP_GET, []() { mws.webserver->send(200, "text/html", screen_html); }); mws.addHandler("/backup", HTTP_GET, []() diff --git a/src/htmls.h b/src/htmls.h index f8e2f5d0..b333edf9 100644 --- a/src/htmls.h +++ b/src/htmls.h @@ -19,36 +19,30 @@ static const char custom_html[] PROGMEM = R"EOF(

-
)EOF"; static const char custom_css[] PROGMEM = R"EOF( - .iconcontent { width: 50%; justify-content: center; } - #form-con { width: 50%; margin: 0 auto; min-width: 200px; } - .button-row input { width: 50%; margin: 0 5px; } - .button-row { display: flex; justify-content: space-evenly; margin: 0 -5px; margin-top: 5px; } - #icon-container { margin: 0 auto; max-width: 150px; @@ -57,9 +51,7 @@ static const char custom_css[] PROGMEM = R"EOF( background-color: black; height: 150px; margin: 0 auto; - } - #icon-container img { image-rendering: pixelated; max-width: 150px; @@ -83,3 +75,7 @@ static const char screen_html[] PROGMEM = R"EOF( static const char backup_html[] PROGMEM = R"EOF( Backup & Restore

AWTRIX Light Backup & Restore


)EOF"; + +static const char screenfull_html[] PROGMEM = R"EOF( + LiveView +)EOF"; \ No newline at end of file