Shrink image size #39

Open
opened 2025-04-08 16:00:42 +02:00 by DeltaLima · 10 comments
Owner

ESP32-C3 cannot upload new firmware .bin because it got too large. Uploading by USB works fine so far

ESP32-C3 cannot upload new firmware .bin because it got too large. Uploading by USB works fine so far
DeltaLima added the
bug
label 2025-04-08 16:00:42 +02:00
DeltaLima added this to the CanGrow Firmware project 2025-04-08 16:00:42 +02:00
Author
Owner
ESP-ROM:esp32c3-api1-20210207
Build:Feb  7 2021
rst:0x3 (RTC_SW_SYS_RST),boot:0xf (SPI_FAST_FLASH_BOOT)
Saved PC:0x40048b82
SPIWP:0xee
mode:DIO, clock div:1
load:0x3fcd5820,len:0x1058
load:0x403cc710,len:0x8a8
load:0x403ce710,len:0x2fac
entry 0x403cc710
E (217) esp_image: Image length 1330800 doesn't fit in partition length 1310720
E (218) boot: OTA app partition slot 0 is not bootable
E (218) esp_image: image at 0x150000 has invalid magic byte (nothing flashed here?)
E (225) boot: OTA app partition slot 1 is not bootable
E (230) boot: No bootable app partitions in the partition table

partition schema has to be changed to 2mb

``` ESP-ROM:esp32c3-api1-20210207 Build:Feb 7 2021 rst:0x3 (RTC_SW_SYS_RST),boot:0xf (SPI_FAST_FLASH_BOOT) Saved PC:0x40048b82 SPIWP:0xee mode:DIO, clock div:1 load:0x3fcd5820,len:0x1058 load:0x403cc710,len:0x8a8 load:0x403ce710,len:0x2fac entry 0x403cc710 E (217) esp_image: Image length 1330800 doesn't fit in partition length 1310720 E (218) boot: OTA app partition slot 0 is not bootable E (218) esp_image: image at 0x150000 has invalid magic byte (nothing flashed here?) E (225) boot: OTA app partition slot 1 is not bootable E (230) boot: No bootable app partitions in the partition table ``` partition schema has to be changed to 2mb
Author
Owner

Convert file (best gziped) to C Array, which can be directly used within the code base

xxd -i file.html

Convert file (best gziped) to C Array, which can be directly used within the code base `xxd -i file.html`
Author
Owner

maybe making custom esp32 partition schema is enough too, see https://thelastoutpostworkshop.github.io/microcontroller_devkit/esp32partitionbuilder/

maybe making custom esp32 partition schema is enough too, see https://thelastoutpostworkshop.github.io/microcontroller_devkit/esp32partitionbuilder/
Author
Owner

arduino-cli change partition schema https://github.com/arduino/arduino-cli/issues/698

arduino-cli change partition schema https://github.com/arduino/arduino-cli/issues/698
DeltaLima added this to the v0.2.0 Release milestone 2025-04-12 02:44:48 +02:00
Author
Owner

I think there is a ton of stuff which can be easely put into javascript. Also, there is a lot of stuff, which can be put into PROGMEM variables to get re-used, like some very common html tags:

$ grep -n -R "F(\"" *|grep -v "Log\."
include/Webserver/Page_root.h:47:          gaugeName += F("_");
include/Webserver/Page_root.h:49:          gaugeName += F("_");
include/Webserver/Page_root.h:55:            html += F("<div class='gaugeWrapper'>");
include/Webserver/Page_root.h:58:          html += F("<div class='gauge gauge--liveupdate spacer' id='gauge_");
include/Webserver/Page_root.h:60:          html += F("' style='float:left; ");
include/Webserver/Page_root.h:64:            html += F("margin-right: 10px;'>");
include/Webserver/Page_root.h:66:            html += F("'>");
include/Webserver/Page_root.h:70:          html += F("<div class='gaugeLabel'>");
include/Webserver/Page_root.h:79:          html += F("<br><span class='gaugeLabelSub'>");
include/Webserver/Page_root.h:81:          html += F("</span>");
include/Webserver/Page_root.h:82:          html += F("</div>\n");
include/Webserver/Page_root.h:89:            html += F("</div><div style='clear: both;'></div>\n");
include/Webserver/Page_root.h:99:      html += F("<script>");
include/Webserver/Page_root.h:108:          gaugeName += F("_");
include/Webserver/Page_root.h:110:          gaugeName += F("_");
include/Webserver/Page_root.h:113:          html += F("var gaugeJS_");
include/Webserver/Page_root.h:115:          html += F(" = new Gauge(document.getElementById('gauge_");
include/Webserver/Page_root.h:117:          html += F("'));\n");
include/Webserver/Page_root.h:119:          html += F("gaugeJS_");
include/Webserver/Page_root.h:121:          html += F(".value('");
include/Webserver/Page_root.h:124:          html += F("', ");
include/Webserver/Page_root.h:127:          html += F(", ' ");
include/Webserver/Page_root.h:140:          //unit.replace(F("%"), F("&#37;"));
include/Webserver/Page_root.h:141:          unit.replace(F("%"), F("%%"));
include/Webserver/Page_root.h:143:          html += F("');\n");
include/Webserver/Page_root.h:147:      html += F("</script>");
include/Webserver/Page_root.h:163:      html += F("<script type='application/json' id='chartJson'>");
include/Webserver/Page_root.h:166:      html += F("</script>");
include/Webserver/Page_root.h:167:      html += F("<link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/charts.css/dist/charts.min.css'>");
include/Webserver/Page_root.h:168:      html += F("<div id='chartDiv'><table id='chartTable' class='charts-css line multiple show-data-on-hover show-primary-axis show-6-secondary-axes'><caption>Linechart</caption>");
include/Webserver/Page_root.h:170:      html += F("</table><ul id='chartLegend' class='charts-css legend legend-line'></ul></div><script>DrawChart();</script>");
include/Webserver/Page_grow.h:198:        html += F("<form method='post' action='/grow/light/'>");
include/Webserver/Page_grow.h:200:        html += F("<input type='hidden' name='output' value='");
include/Webserver/Page_grow.h:202:        html += F("' required>"); 
include/Webserver/Page_grow.h:205:        html += F("<h2>");
include/Webserver/Page_grow.h:207:        html += F("</h2>");
include/Webserver/Page_grow.h:210:        html += F("<u>Device:</u><br><b>");
include/Webserver/Page_grow.h:212:        html += F(" (");
include/Webserver/Page_grow.h:214:        html += F(")</b><br>");
include/Webserver/Page_grow.h:217:        html += F("<u>Sunrise</u><br><b>Vegetation </b><input class='inputShort' type='number' name='sunriseHourVeg' min='0' max='23' value='");
include/Webserver/Page_grow.h:219:        html += F("' required><b>:</b> <input class='inputShort' type='number' name='sunriseMinuteVeg' min='0' max='59' value='");
include/Webserver/Page_grow.h:221:        html += F("' required><br>");
include/Webserver/Page_grow.h:225:          html += F("<b>Bloom </b><input class='inputShort' type='number' name='sunriseHourBloom' min='0' max='23' value='");
include/Webserver/Page_grow.h:227:          html += F("' required><b>:</b> <input class='inputShort' type='number' name='sunriseMinuteBloom' min='0' max='59' value='");
include/Webserver/Page_grow.h:229:          html += F("' required><br>");
include/Webserver/Page_grow.h:233:        html += F("<u>Sunset</u><br><b>Vegetation </b><input class='inputShort' type='number' name='sunsetHourVeg' min='0' max='23' value='");
include/Webserver/Page_grow.h:235:        html += F("' required><b>:</b> <input class='inputShort' type='number' name='sunsetMinuteVeg' min='0' max='59' value='");
include/Webserver/Page_grow.h:237:        html += F("' required><br>");
include/Webserver/Page_grow.h:240:          html += F("<b>Bloom </b><input class='inputShort' type='number' name='sunsetHourBloom' min='0' max='23' value='");
include/Webserver/Page_grow.h:242:          html += F("' required><b>:</b> <input class='inputShort' type='number' name='sunsetMinuteBloom' min='0' max='59' value='");
include/Webserver/Page_grow.h:244:          html += F("' required><br>");
include/Webserver/Page_grow.h:250:          html += F("<u>Power</u><br><input type='range' name='power' min='0' max='255' value='");
include/Webserver/Page_grow.h:252:          html += F("'/> &#37;<br>");
include/Webserver/Page_grow.h:255:          html += F("<u>Fade sunset/sunrise</u><br><select name='fade' required>");
include/Webserver/Page_grow.h:257:          html += F("'/></select><br>");
include/Webserver/Page_grow.h:260:          html += F("<u>Fade duration</u><br><input class='inputShort' type='number' name='fadeDuration' min='1' max='255' value='");
include/Webserver/Page_grow.h:262:          html += F("' required> Minutes<br>");
include/Webserver/Page_grow.h:264:          html += F("<u>Power</u><br><select name='power' required>");
include/Webserver/Page_grow.h:266:          html += F("'/></select><br>");
include/Webserver/Page_grow.h:270:        html += F("<input type='submit' value='&#x1F4BE; Save settings' style='margin-top: 8px;'></form>");
include/Webserver/Page_grow.h:273:        html += F("<hr>");
include/Webserver/Page_grow.h:418:        html += F("<form method='post' action='/grow/air/'>");
include/Webserver/Page_grow.h:420:        html += F("<input type='hidden' name='output' value='");
include/Webserver/Page_grow.h:422:        html += F("' required>"); 
include/Webserver/Page_grow.h:425:        html += F("<h2>");
include/Webserver/Page_grow.h:427:        html += F("</h2>");
include/Webserver/Page_grow.h:430:        html += F("<u>Device:</u><br><b>");
include/Webserver/Page_grow.h:432:        html += F(" (");
include/Webserver/Page_grow.h:434:        html += F(")</b><br>");
include/Webserver/Page_grow.h:442:            html += F("<u>Speed</u>");
include/Webserver/Page_grow.h:444:            html += F("<u>Power</u>");
include/Webserver/Page_grow.h:446:          html += F("<br><input type='range' name='power' min='0' max='255' value='");
include/Webserver/Page_grow.h:448:          html += F("'/> &#37;<br>");
include/Webserver/Page_grow.h:450:          html += F("<u>Power</u><br><select name='power' required>");
include/Webserver/Page_grow.h:453:          html += F("'/></select><br>");
include/Webserver/Page_grow.h:458:        html += F("<input type='hidden' name='controlSensor' value='");
include/Webserver/Page_grow.h:460:        html += F("' id='controlSensor");
include/Webserver/Page_grow.h:462:        html += F("'>"); 
include/Webserver/Page_grow.h:464:        html += F("<input type='hidden' name='controlRead' value='");
include/Webserver/Page_grow.h:466:        html += F("' id='controlRead");
include/Webserver/Page_grow.h:468:        html += F("'>"); 
include/Webserver/Page_grow.h:470:        html += F("<u>Controled by</u><br><select name='controlBy' id='ctrl");
include/Webserver/Page_grow.h:472:        html += F("' onChange=\"GrowSelectControlSensorRead('ctrl");
include/Webserver/Page_grow.h:474:        html += F("', 'controlSensor");
include/Webserver/Page_grow.h:476:        html += F("', 'controlRead");
include/Webserver/Page_grow.h:478:        html += F("');\"><option value='255:255' selected >---</option>");
include/Webserver/Page_grow.h:492:                    html += F("<option value='");
include/Webserver/Page_grow.h:496:                    html += F(":");
include/Webserver/Page_grow.h:499:                    html += F("'");
include/Webserver/Page_grow.h:501:                      html += F(" selected");
include/Webserver/Page_grow.h:502:                    html += F(">");
include/Webserver/Page_grow.h:504:                    html += F(" - ");
include/Webserver/Page_grow.h:506:                    html += F(" (");
include/Webserver/Page_grow.h:508:                    html += F(" ");
include/Webserver/Page_grow.h:513:                    html += F(" ");
include/Webserver/Page_grow.h:514:                    unit.replace(F("%"), F("&#37;"));
include/Webserver/Page_grow.h:516:                    html += F(")</option>");
include/Webserver/Page_grow.h:523:        html += F("</select><br>");
include/Webserver/Page_grow.h:526:        html += F("<u>Control mode</u><br><select name='controlMode' ><option value='' selected>---</option>");
include/Webserver/Page_grow.h:529:        html += F("'/> &#37;</select><br>");
include/Webserver/Page_grow.h:533:        html += F("<u>Min</u><br><input type='number' name='min' step='0.1' value='");
include/Webserver/Page_grow.h:535:        html += F("' required><br>");
include/Webserver/Page_grow.h:538:        html += F("<u>Max</u><br><input type='number' name='max' step='0.1' value='");
include/Webserver/Page_grow.h:540:        html += F("' required><br>");
include/Webserver/Page_grow.h:544:        html += F("<input type='submit' value='&#x1F4BE; Save settings' style='margin-top: 8px;'></form>");
include/Webserver/Page_grow.h:547:        html += F("<hr>");
include/Webserver/Page_grow.h:670:        html += F("<form method='post' action='/grow/water/'>");
include/Webserver/Page_grow.h:672:        html += F("<input type='hidden' name='output' value='");
include/Webserver/Page_grow.h:674:        html += F("' required>"); 
include/Webserver/Page_grow.h:677:        html += F("<h2>");
include/Webserver/Page_grow.h:679:        html += F("</h2>");
include/Webserver/Page_grow.h:682:        html += F("<u>Device:</u><br><b>");
include/Webserver/Page_grow.h:684:        html += F(" (");
include/Webserver/Page_grow.h:686:        html += F(")</b><br>");
include/Webserver/Page_grow.h:705:        html += F("<u>Pump On</u><br><input class='inputShort' type='number' name='onTime' min='0' max='255' value='");
include/Webserver/Page_grow.h:707:        html += F("' required> Seconds<br>");
include/Webserver/Page_grow.h:710:        html += F("<input type='hidden' name='controlSensor' value='");
include/Webserver/Page_grow.h:712:        html += F("' id='controlSensor");
include/Webserver/Page_grow.h:714:        html += F("'>"); 
include/Webserver/Page_grow.h:716:        html += F("<input type='hidden' name='controlRead' value='");
include/Webserver/Page_grow.h:718:        html += F("' id='controlRead");
include/Webserver/Page_grow.h:720:        html += F("'>"); 
include/Webserver/Page_grow.h:724:        html += F("<u>Control mode</u><br><select name='controlMode'><option value='' selected>---</option>");
include/Webserver/Page_grow.h:727:        html += F("</select><br>");
include/Webserver/Page_grow.h:730:        html += F("<u>Interval</u><br><input class='inputShort' type='number' name='interval' min='0' max='255' value='");
include/Webserver/Page_grow.h:732:        html += F("' required> ");
include/Webserver/Page_grow.h:735:        html += F("<select name='intervalUnit'>");
include/Webserver/Page_grow.h:741:          html += F("<option value='");
include/Webserver/Page_grow.h:743:          html += F("'");
include/Webserver/Page_grow.h:745:            html += F(" selected");
include/Webserver/Page_grow.h:746:          html += F(">");
include/Webserver/Page_grow.h:748:          html += F("</option>");
include/Webserver/Page_grow.h:751:        html += F("</select><br>");
include/Webserver/Page_grow.h:755:        html += F("<u>Controled by</u><br><select name='controlBy' id='ctrl");
include/Webserver/Page_grow.h:757:        html += F("' onChange=\"GrowSelectControlSensorRead('ctrl");
include/Webserver/Page_grow.h:759:        html += F("', 'controlSensor");
include/Webserver/Page_grow.h:761:        html += F("', 'controlRead");
include/Webserver/Page_grow.h:763:        html += F("');\"><option value='255:255' selected >---</option>");
include/Webserver/Page_grow.h:776:                    html += F("<option value='");
include/Webserver/Page_grow.h:780:                    html += F(":");
include/Webserver/Page_grow.h:783:                    html += F("'");
include/Webserver/Page_grow.h:785:                      html += F(" selected");
include/Webserver/Page_grow.h:786:                    html += F(">");
include/Webserver/Page_grow.h:788:                    html += F(" - (");
include/Webserver/Page_grow.h:790:                    html += F(") ");
include/Webserver/Page_grow.h:798:                    html += F(" (");
include/Webserver/Page_grow.h:800:                    html += F(" ");
include/Webserver/Page_grow.h:810:                    html += F(" ");
include/Webserver/Page_grow.h:811:                    unit.replace(F("%"), F("&#37;"));
include/Webserver/Page_grow.h:813:                    html += F(")</option>");
include/Webserver/Page_grow.h:820:        html += F("</select><br>");
include/Webserver/Page_grow.h:824:        html += F("<u>Min</u><br><input class='inputShort' type='number' name='min' min='0' max='255' value='");
include/Webserver/Page_grow.h:826:        html += F("' required><br>");
include/Webserver/Page_grow.h:829:        html += F("<u>Max</u><br><input class='inputShort' type='number' name='max' min='0' max='255' value='");
include/Webserver/Page_grow.h:831:        html += F("' required><br>");
include/Webserver/Page_grow.h:836:        html += F("<input type='submit' value='&#x1F4BE; Save settings' style='margin-top: 8px;'></form>");
include/Webserver/Page_grow.h:839:        html += F("<hr>");
include/Webserver/Page_grow.h:969:        return F("disabled force_hide");
include/Webserver/Page_grow.h:975:        return F("disabled force_hide");
include/Webserver/Page_grow.h:981:        return F("disabled force_hide");
include/Webserver/Page_grow.h:989:        html += F("<tr><td>");
include/Webserver/Page_grow.h:991:        html += F("</td><td>");
include/Webserver/Page_grow.h:993:        html += F("</td><td>");
include/Webserver/Page_grow.h:1005:        html += F("</td><td>");
include/Webserver/Page_grow.h:1009:        unit.replace(F("%"), F("&#37;"));
include/Webserver/Page_grow.h:1011:        html += F("</td><td>");
include/Webserver/Page_grow.h:1013:        html += F("<form class='linkForm' action='/grow/dashboard/gaugeAdd' method='get'>");
include/Webserver/Page_grow.h:1014:        html += F("<input type='hidden' name='edit' value='");
include/Webserver/Page_grow.h:1016:        html += F("'>");
include/Webserver/Page_grow.h:1017:        html += F("<input type='submit' value='&#x270F;&#xFE0F;' title='Edit'></form> ");
include/Webserver/Page_grow.h:1019:        html += F("<form class='linkForm' action='/grow/dashboard/' method='post'>");
include/Webserver/Page_grow.h:1020:        html += F("<input type='hidden' name='delete_gauge' value='");
include/Webserver/Page_grow.h:1022:        html += F("'>");
include/Webserver/Page_grow.h:1023:        html += F("<input type='submit' value='&#x274C;' onclick=\"return confirmDelete('");
include/Webserver/Page_grow.h:1024:        html += F("gauge for ");
include/Webserver/Page_grow.h:1026:        html += F(" ");
include/Webserver/Page_grow.h:1037:        html += F("')\" title='Delete'></form>");
include/Webserver/Page_grow.h:1038:        html += F("</td></tr>");
include/Webserver/Page_grow.h:1048:        html += F("<tr><td>");
include/Webserver/Page_grow.h:1050:        html += F("</td><td>");
include/Webserver/Page_grow.h:1052:        html += F("</td><td>");
include/Webserver/Page_grow.h:1064:        html += F("</td><td style='background-color: ");
include/Webserver/Page_grow.h:1066:        html += F(";'>");
include/Webserver/Page_grow.h:1071:        unit.replace(F("%"), F("&#37;"));
include/Webserver/Page_grow.h:1073:        html += F("</td><td>");
include/Webserver/Page_grow.h:1075:        html += F("<form class='linkForm' action='/grow/dashboard/chartAdd' method='get'>");
include/Webserver/Page_grow.h:1076:        html += F("<input type='hidden' name='edit' value='");
include/Webserver/Page_grow.h:1078:        html += F("'>");
include/Webserver/Page_grow.h:1079:        html += F("<input type='submit' value='&#x270F;&#xFE0F;' title='Edit'></form> ");
include/Webserver/Page_grow.h:1081:        html += F("<form class='linkForm' action='/grow/dashboard/' method='post'>");
include/Webserver/Page_grow.h:1082:        html += F("<input type='hidden' name='delete_chart' value='");
include/Webserver/Page_grow.h:1084:        html += F("'>");
include/Webserver/Page_grow.h:1085:        html += F("<input type='submit' value='&#x274C;' onclick=\"return confirmDelete('");
include/Webserver/Page_grow.h:1086:        html += F("chart for ");
include/Webserver/Page_grow.h:1088:        html += F(" ");
include/Webserver/Page_grow.h:1099:        html += F("')\" title='Delete'></form>");
include/Webserver/Page_grow.h:1100:        html += F("</td></tr>");
include/Webserver/Page_grow.h:1108:        html += F("<tr><td>");
include/Webserver/Page_grow.h:1110:        html += F("</td><td>");
include/Webserver/Page_grow.h:1112:        html += F("</td><td>");
include/Webserver/Page_grow.h:1124:        html += F("</td><td>");
include/Webserver/Page_grow.h:1129:        unit.replace(F("%"), F("&#37;"));
include/Webserver/Page_grow.h:1131:        html += F("</td><td>");
include/Webserver/Page_grow.h:1133:        html += F("<form class='linkForm' action='/grow/dashboard/dataAdd' method='get'>");
include/Webserver/Page_grow.h:1134:        html += F("<input type='hidden' name='edit' value='");
include/Webserver/Page_grow.h:1136:        html += F("'>");
include/Webserver/Page_grow.h:1137:        html += F("<input type='submit' value='&#x270F;&#xFE0F;' title='Edit'></form> ");
include/Webserver/Page_grow.h:1139:        html += F("<form class='linkForm' action='/grow/dashboard/' method='post'>");
include/Webserver/Page_grow.h:1140:        html += F("<input type='hidden' name='delete_data' value='");
include/Webserver/Page_grow.h:1142:        html += F("'>");
include/Webserver/Page_grow.h:1143:        html += F("<input type='submit' value='&#x274C;' onclick=\"return confirmDelete('");
include/Webserver/Page_grow.h:1144:        html += F("data for ");
include/Webserver/Page_grow.h:1146:        html += F(" ");
include/Webserver/Page_grow.h:1157:        html += F("')\" title='Delete'></form>");
include/Webserver/Page_grow.h:1158:        html += F("</td></tr>");
include/Webserver/Api_chartdata.h:12:  AsyncWebServerResponse *response = request->beginResponse(200, F("application/json"), json);
include/Webserver/Page_system.h:115:        return F(" &#x26A0;&#xFE0F; ");
include/Webserver/Page_system.h:117:        return F(" &#x2705; ");
include/Webserver/Page_system.h:370:    response->addHeader(F("Connection"), F("close"));
include/Webserver/Page_system.h:417:    request->redirect(F("/system/update?success"));
include/Webserver/Page_system.h:479:      return F("disabled force_hide");
include/Webserver/Page_system.h:491:        html += F("<tr><td>");
include/Webserver/Page_system.h:494:          html += F(" &#x26A0;&#xFE0F;");
include/Webserver/Page_system.h:496:          html += F(" &#x2705;");
include/Webserver/Page_system.h:499:        html += F("&nbsp;&nbsp;");
include/Webserver/Page_system.h:500:        html += F("</td><td>");
include/Webserver/Page_system.h:503:        html += F("</td><td>");
include/Webserver/Page_system.h:505:        html += F("</td><td>");
include/Webserver/Page_system.h:509:          html += F(" (");
include/Webserver/Page_system.h:524:          html += F(")");
include/Webserver/Page_system.h:527:        html += F("</td><td>");
include/Webserver/Page_system.h:529:        html += F("</td><td>");
include/Webserver/Page_system.h:532:          html += F("&nbsp;&#x1F7E2;&nbsp;");
include/Webserver/Page_system.h:534:          html += F("&nbsp;&#x1F534;&nbsp;&nbsp;");
include/Webserver/Page_system.h:537:        html += F("</td><td>");
include/Webserver/Page_system.h:540:        html += F("<form class='linkForm' action='/system/output/add' method='get'>");
include/Webserver/Page_system.h:541:        html += F("<input type='hidden' name='edit' value='");
include/Webserver/Page_system.h:543:        html += F("'>");
include/Webserver/Page_system.h:544:        html += F("<input type='submit' value='&#x270F;&#xFE0F;' title='Edit'></form> ");
include/Webserver/Page_system.h:548:        html += F("<form class='linkForm' action='/system/output/' method='post'>");
include/Webserver/Page_system.h:549:        html += F("<input type='hidden' name='delete_output' value='");
include/Webserver/Page_system.h:551:        html += F("'>");
include/Webserver/Page_system.h:552:        html += F("<input type='submit' value='&#x274C;' onclick=\"return confirmDelete('");
include/Webserver/Page_system.h:554:        html += F("')\"  title='Delete'></form>");
include/Webserver/Page_system.h:556:        html += F("</td></tr>");
include/Webserver/Page_system.h:630:    html += F("<option value='");
include/Webserver/Page_system.h:632:    html += F("'");
include/Webserver/Page_system.h:634:      html += F(" selected");
include/Webserver/Page_system.h:636:    html += F(">");
include/Webserver/Page_system.h:638:    html += F("</option>");
include/Webserver/Page_system.h:654:    js += F("[");
include/Webserver/Page_system.h:657:      js += F("['0x");
include/Webserver/Page_system.h:660:      js += F("', '");
include/Webserver/Page_system.h:664:      js += F("', [");
include/Webserver/Page_system.h:670:          js += F("'");
include/Webserver/Page_system.h:680:          js += F("',");
include/Webserver/Page_system.h:685:      js += F("]],");
include/Webserver/Page_system.h:687:  js += F("],\n");
include/Webserver/Page_system.h:746:    return F("editmode");
include/Webserver/Page_system.h:762:    outputName.replace(F("%"), F("&#37;"));
include/Webserver/Page_system.h:789:    js += F("showSelect('type_sel', 'type_', 'hidden'); SystemOutputAddselectRequired('type_sel');");
include/Webserver/Page_system.h:791:    //js += F("document.getElementById('i2c_type').value='");
include/Webserver/Page_system.h:793:    //js += F("';\n");
include/Webserver/Page_system.h:795:    js += F("SystemOutputAdd_replaceI2cAddr('i2c_type', 'i2c_addr');");
include/Webserver/Page_system.h:797:    js += F("document.getElementById('i2c_addr').value='");
include/Webserver/Page_system.h:799:    js += F("';\n");
include/Webserver/Page_system.h:801:    js += F("SystemOutputAdd_replaceI2cPort('i2c_type', 'i2c_addr', 'i2c_port');\n");
include/Webserver/Page_system.h:803:    js += F("document.getElementById('i2c_port').value='");
include/Webserver/Page_system.h:805:    js += F("';\n");
include/Webserver/Page_system.h:817:    webcallPathOn.replace(F("%"), F("&#37;"));
include/Webserver/Page_system.h:822:    webcallPathOff.replace(F("%"), F("&#37;"));
include/Webserver/Page_system.h:830:    return F("visible");
include/Webserver/Page_system.h:1011:    request->redirect(F("/system/output/?success"));
include/Webserver/Page_system.h:1076:        return F("disabled force_hide");
include/Webserver/Page_system.h:1087:        html += F("<tr><td>");
include/Webserver/Page_system.h:1090:          html += F(" &#x26A0;&#xFE0F;");
include/Webserver/Page_system.h:1092:          html += F(" &#x2705;");
include/Webserver/Page_system.h:1095:        html += F("&nbsp;&nbsp;");
include/Webserver/Page_system.h:1096:        html += F("</td><td>");
include/Webserver/Page_system.h:1100:        html += F("</td><td>");
include/Webserver/Page_system.h:1102:        html += F("</td><td>");
include/Webserver/Page_system.h:1111:          html += F(" (");
include/Webserver/Page_system.h:1117:              html += F("/");
include/Webserver/Page_system.h:1121:            html += F("0x");
include/Webserver/Page_system.h:1124:          html += F(")");
include/Webserver/Page_system.h:1127:        html += F("</td><td>");
include/Webserver/Page_system.h:1130:        html += F("<form class='linkForm' action='/system/sensor/calibrate' method='get'>");
include/Webserver/Page_system.h:1131:        html += F("<input type='hidden' name='calibrate' value='");
include/Webserver/Page_system.h:1133:        html += F("'>");
include/Webserver/Page_system.h:1134:        html += F("<input type='submit' value='&#x1F39B;&#xFE0F;' title='Calibrate'></form> ");
include/Webserver/Page_system.h:1137:        html += F("<form class='linkForm' action='/system/sensor/add' method='get'>");
include/Webserver/Page_system.h:1138:        html += F("<input type='hidden' name='edit' value='");
include/Webserver/Page_system.h:1140:        html += F("'>");
include/Webserver/Page_system.h:1141:        html += F("<input type='submit' value='&#x270F;&#xFE0F;' title='Edit'></form> ");
include/Webserver/Page_system.h:1144:        html += F("<form class='linkForm' action='/system/sensor/' method='post'>");
include/Webserver/Page_system.h:1145:        html += F("<input type='hidden' name='delete_sensor' value='");
include/Webserver/Page_system.h:1147:        html += F("'>");
include/Webserver/Page_system.h:1148:        html += F("<input type='submit' value='&#x274C;' onclick=\"return confirmDelete('");
include/Webserver/Page_system.h:1150:        html += F("')\" title='Delete'></form>");
include/Webserver/Page_system.h:1152:        html += F("</td></tr>");
include/Webserver/Page_system.h:1215:    html += F("<option value='");
include/Webserver/Page_system.h:1217:    html += F("'");
include/Webserver/Page_system.h:1219:      html += F(" selected");
include/Webserver/Page_system.h:1221:    html += F(">");
include/Webserver/Page_system.h:1223:    html += F("</option>");
include/Webserver/Page_system.h:1239:    js += F("[");
include/Webserver/Page_system.h:1242:      js += F("['0x");
include/Webserver/Page_system.h:1245:      js += F("', '");
include/Webserver/Page_system.h:1249:      js += F("', '");
include/Webserver/Page_system.h:1254:            js += F("1");
include/Webserver/Page_system.h:1263:      js += F("'],");
include/Webserver/Page_system.h:1265:  js += F("],\n");
include/Webserver/Page_system.h:1292:    return F("8266");
include/Webserver/Page_system.h:1296:    return F("32");
include/Webserver/Page_system.h:1327:    sensorName.replace(F("%"), F("&#37;"));
include/Webserver/Page_system.h:1335:    return F("8266");
include/Webserver/Page_system.h:1339:    return F("32");
include/Webserver/Page_system.h:1349:    js += F("SystemSensorAddGpioI2cSel('type_sel');SystemSensor_replaceAddr('type_sel', 'i2c_addr');");
include/Webserver/Page_system.h:1350:    js += F("document.getElementById('i2c_addr').value='");
include/Webserver/Page_system.h:1352:    js += F("';");
include/Webserver/Page_system.h:1474:    js += F("[");
include/Webserver/Page_system.h:1477:      js += F("['0x");
include/Webserver/Page_system.h:1480:      js += F("', '");
include/Webserver/Page_system.h:1484:      js += F("', '");
include/Webserver/Page_system.h:1489:            js += F("1");
include/Webserver/Page_system.h:1498:      js += F("'],");
include/Webserver/Page_system.h:1500:  js += F("],\n");
include/Webserver/Page_system.h:1513:    return F("&#10133; Add");
include/Webserver/Page_system.h:1528:    return F("8266");
include/Webserver/Page_system.h:1532:    return F("32");
include/Webserver/Page_system.h:1558:    sensorName.replace(F("%"), F("&#37;"));
include/Webserver/Page_system.h:1566:    html += F("<script>SensorJsonRefresh(); var refreshJson = setInterval(SensorJsonRefresh, 1000);</script>");
include/Webserver/Page_system.h:1569:        html += F("<form method='post' action='/system/sensor/calibrate'>");
include/Webserver/Page_system.h:1570:        html += F("<input type='hidden' name='sensorId' value='");
include/Webserver/Page_system.h:1572:        html += F("'/>");
include/Webserver/Page_system.h:1573:        html += F("<input type='hidden' name='readId' value='");
include/Webserver/Page_system.h:1575:        html += F("'/>");
include/Webserver/Page_system.h:1577:        html += F("<u>Reading ");
include/Webserver/Page_system.h:1579:        html += F(":</u><br><b>");
include/Webserver/Page_system.h:1581:        html += F("</b> (");
include/Webserver/Page_system.h:1582:        html += F("<span class='sensorReading' id='raw-");
include/Webserver/Page_system.h:1586:        html += F("'>");
include/Webserver/Page_system.h:1608:            unit.replace(F("%"), F("&#37;"));
include/Webserver/Page_system.h:1614:        html += F("</span>)");
include/Webserver/Page_system.h:1617:          html += F("<script>var raw_");
include/Webserver/Page_system.h:1619:          html += F("_");
include/Webserver/Page_system.h:1621:          html += F(" = setInterval(rawRefresh, 1000, ");
include/Webserver/Page_system.h:1623:          html += F(", ");
include/Webserver/Page_system.h:1625:          html += F(", 'raw-');</script>");
include/Webserver/Page_system.h:1628:        html += F("<br>");
include/Webserver/Page_system.h:1631:          html += F("<u>Convert RAW value to:</u><br>");
include/Webserver/Page_system.h:1632:          html += F("<select name='rawConvert'><option value='0' >---</option>");
include/Webserver/Page_system.h:1634:            html += F("<option value='");
include/Webserver/Page_system.h:1637:            html += F("'");
include/Webserver/Page_system.h:1639:              html += F(" selected");
include/Webserver/Page_system.h:1640:            html += F(">");
include/Webserver/Page_system.h:1642:            html += F("</option>");
include/Webserver/Page_system.h:1644:          html += F("</select><br>");
include/Webserver/Page_system.h:1648:            //html += F("<span class='sensorReading'>");
include/Webserver/Page_system.h:1649:            html += F("<span class='sensorReading' id='reading-");
include/Webserver/Page_system.h:1653:            html += F("'>");
include/Webserver/Page_system.h:1659:            unit.replace(F("%"), F("&#37;"));
include/Webserver/Page_system.h:1661:            html += F("</span>");
include/Webserver/Page_system.h:1663:            html += F("<script>var reading_");
include/Webserver/Page_system.h:1665:            html += F("_");
include/Webserver/Page_system.h:1667:            html += F(" = setInterval(sensorRefresh, 1000, ");
include/Webserver/Page_system.h:1669:            html += F(", ");
include/Webserver/Page_system.h:1671:            html += F(", 'reading-');</script>");
include/Webserver/Page_system.h:1673:            html += F("<br>");
include/Webserver/Page_system.h:1676:          html += F("<u>Low:</u><br>");
include/Webserver/Page_system.h:1677:          html += F("<input type='number' name='low' value='");
include/Webserver/Page_system.h:1679:          html += F("'/><br>");
include/Webserver/Page_system.h:1681:          html += F("<u>High:</u><br>");
include/Webserver/Page_system.h:1682:          html += F("<input type='number' name='high' value='");
include/Webserver/Page_system.h:1684:          html += F("'/><br>");
include/Webserver/Page_system.h:1688:          html += F("<u>Offset:</u><br>");
include/Webserver/Page_system.h:1689:          html += F("<input type='number' step='0.01' name='offset' value='");
include/Webserver/Page_system.h:1691:          html += F("'/><br>");
include/Webserver/Page_system.h:1694:        html += F("<br><input type='submit' value='&#x1F4BE; Save settings'></form>");
include/Webserver/Page_system.h:1695:        html += F("<hr>\n\n");
include/Webserver/Page_wifi.h:24:      html += F("<option value='");
include/Webserver/Page_wifi.h:26:      html += F("'>");
include/Webserver/Page_wifi.h:28:      html += F("</option>");
include/Webserver/File_favicon_ico.h:34:  AsyncWebServerResponse *response = request->beginResponse_P(200, F("image/x-icon"), File_favicon_ico_gz, File_favicon_ico_gz_len);
include/Webserver/File_favicon_ico.h:35:  response->addHeader(F("Content-Encoding"), F("gzip"));
include/Webserver/File_favicon_ico.h:36:  response->addHeader(F("Cache-control"), F("max-age=600"));
include/Webserver/Api_sensor.h:84:      root["msg"] = String(F("not a RAW reading"));
include/Webserver/Api_sensor.h:87:    root["msg"] = String(F("sensor or reading not given"));
include/Webserver/File_cangrow_CSS.h:423:  AsyncWebServerResponse *response = request->beginResponse_P(200, F("text/css"), File_cangrow_CSS);
include/Webserver/File_cangrow_CSS.h:424:  response->addHeader(F("Cache-control"), F("max-age=600"));
include/Webserver/Webserver_Common.h:65:  String activeNav_ClassName = F("activeNav");
include/Webserver/Webserver_Common.h:114:      gpioIndex_html += F("<option value='");
include/Webserver/Webserver_Common.h:116:      gpioIndex_html += F("'");
include/Webserver/Webserver_Common.h:129:        gpioIndex_html += F(" disabled");
include/Webserver/Webserver_Common.h:133:        gpioIndex_html += F(" selected");
include/Webserver/Webserver_Common.h:135:      gpioIndex_html += F(">GPIO ");
include/Webserver/Webserver_Common.h:139:      gpioIndex_html += F(" ");
include/Webserver/Webserver_Common.h:144:        gpioIndex_html += F(" (N/A)");
include/Webserver/Webserver_Common.h:147:        gpioIndex_html += F(" (used)");
include/Webserver/Webserver_Common.h:149:      gpioIndex_html += F("</option>");
include/Webserver/Webserver_Common.h:157:  html += F("<option value='1'");
include/Webserver/Webserver_Common.h:158:  html += ((selectVal > 0) && (selectVal < 255)) ? F(" selected") : F("");
include/Webserver/Webserver_Common.h:159:  html += F(">");
include/Webserver/Webserver_Common.h:161:  html += F("</option>");
include/Webserver/Webserver_Common.h:163:  html += F("<option value='0'");
include/Webserver/Webserver_Common.h:164:  html += (selectVal == 0) ? F(" selected") : F(""); 
include/Webserver/Webserver_Common.h:165:  html += F(">");
include/Webserver/Webserver_Common.h:167:  html += F("</option>");
include/Webserver/Webserver_Common.h:178:    html += F("<option value='");
include/Webserver/Webserver_Common.h:180:    html += F("'");
include/Webserver/Webserver_Common.h:182:      html += F(" selected");
include/Webserver/Webserver_Common.h:184:    html += F(">");
include/Webserver/Webserver_Common.h:187:    html += F("</option>");
include/Webserver/Webserver_Common.h:200:              html += F("<option value='");
include/Webserver/Webserver_Common.h:204:              html += F(":");
include/Webserver/Webserver_Common.h:207:              html += F("'");
include/Webserver/Webserver_Common.h:210:                html += F(" selected");
include/Webserver/Webserver_Common.h:211:              html += F(">");
include/Webserver/Webserver_Common.h:213:              html += F(" - ");
include/Webserver/Webserver_Common.h:221:              html += F(" (");
include/Webserver/Webserver_Common.h:223:              html += F(" ");
include/Webserver/Webserver_Common.h:228:              html += F(" ");
include/Webserver/Webserver_Common.h:229:              unit.replace(F("%"), F("&#37;"));
include/Webserver/Webserver_Common.h:231:              html += F(")</option>");
include/Webserver/File_cangrow_JS.h:396:  AsyncWebServerResponse *response = request->beginResponse_P(200, F("text/javascript"), File_cangrow_JS);
include/Webserver/File_cangrow_JS.h:397:  response->addHeader(F("Cache-control"), F("max-age=600"));
include/CanGrow_Core.h:464:    str_time += F("0");
include/CanGrow_Core.h:466:  str_time += F(":");
include/CanGrow_Core.h:468:    str_time += F("0");
include/CanGrow_Core.h:470:  str_time += F(":");
include/CanGrow_Core.h:472:    str_time += F("0");
include/CanGrow_Core.h:481:    str_date += F("0");
include/CanGrow_Core.h:483:  str_date += F(".");
include/CanGrow_Core.h:485:    str_date += F("0");
include/CanGrow_Core.h:487:  str_date += F(".");
include/CanGrow_Core.h:766:        unit.replace(F("%"), F("%%"));
include/CanGrow_LittleFS.h:82:    return String(F("ERROR CANNOT OPEN"));
include/CanGrow_Output.h:192:  url += F("http://");
include/CanGrow_Output.h:194:  url += F("/");

its a LOT

also .css and .js files should be minified and gzipd. this will also save some kb. put the .gz into a variable with xxd -i

I think there is a ton of stuff which can be easely put into javascript. Also, there is a lot of stuff, which can be put into PROGMEM variables to get re-used, like some very common html tags: ```bash $ grep -n -R "F(\"" *|grep -v "Log\." include/Webserver/Page_root.h:47: gaugeName += F("_"); include/Webserver/Page_root.h:49: gaugeName += F("_"); include/Webserver/Page_root.h:55: html += F("<div class='gaugeWrapper'>"); include/Webserver/Page_root.h:58: html += F("<div class='gauge gauge--liveupdate spacer' id='gauge_"); include/Webserver/Page_root.h:60: html += F("' style='float:left; "); include/Webserver/Page_root.h:64: html += F("margin-right: 10px;'>"); include/Webserver/Page_root.h:66: html += F("'>"); include/Webserver/Page_root.h:70: html += F("<div class='gaugeLabel'>"); include/Webserver/Page_root.h:79: html += F("<br><span class='gaugeLabelSub'>"); include/Webserver/Page_root.h:81: html += F("</span>"); include/Webserver/Page_root.h:82: html += F("</div>\n"); include/Webserver/Page_root.h:89: html += F("</div><div style='clear: both;'></div>\n"); include/Webserver/Page_root.h:99: html += F("<script>"); include/Webserver/Page_root.h:108: gaugeName += F("_"); include/Webserver/Page_root.h:110: gaugeName += F("_"); include/Webserver/Page_root.h:113: html += F("var gaugeJS_"); include/Webserver/Page_root.h:115: html += F(" = new Gauge(document.getElementById('gauge_"); include/Webserver/Page_root.h:117: html += F("'));\n"); include/Webserver/Page_root.h:119: html += F("gaugeJS_"); include/Webserver/Page_root.h:121: html += F(".value('"); include/Webserver/Page_root.h:124: html += F("', "); include/Webserver/Page_root.h:127: html += F(", ' "); include/Webserver/Page_root.h:140: //unit.replace(F("%"), F("&#37;")); include/Webserver/Page_root.h:141: unit.replace(F("%"), F("%%")); include/Webserver/Page_root.h:143: html += F("');\n"); include/Webserver/Page_root.h:147: html += F("</script>"); include/Webserver/Page_root.h:163: html += F("<script type='application/json' id='chartJson'>"); include/Webserver/Page_root.h:166: html += F("</script>"); include/Webserver/Page_root.h:167: html += F("<link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/charts.css/dist/charts.min.css'>"); include/Webserver/Page_root.h:168: html += F("<div id='chartDiv'><table id='chartTable' class='charts-css line multiple show-data-on-hover show-primary-axis show-6-secondary-axes'><caption>Linechart</caption>"); include/Webserver/Page_root.h:170: html += F("</table><ul id='chartLegend' class='charts-css legend legend-line'></ul></div><script>DrawChart();</script>"); include/Webserver/Page_grow.h:198: html += F("<form method='post' action='/grow/light/'>"); include/Webserver/Page_grow.h:200: html += F("<input type='hidden' name='output' value='"); include/Webserver/Page_grow.h:202: html += F("' required>"); include/Webserver/Page_grow.h:205: html += F("<h2>"); include/Webserver/Page_grow.h:207: html += F("</h2>"); include/Webserver/Page_grow.h:210: html += F("<u>Device:</u><br><b>"); include/Webserver/Page_grow.h:212: html += F(" ("); include/Webserver/Page_grow.h:214: html += F(")</b><br>"); include/Webserver/Page_grow.h:217: html += F("<u>Sunrise</u><br><b>Vegetation </b><input class='inputShort' type='number' name='sunriseHourVeg' min='0' max='23' value='"); include/Webserver/Page_grow.h:219: html += F("' required><b>:</b> <input class='inputShort' type='number' name='sunriseMinuteVeg' min='0' max='59' value='"); include/Webserver/Page_grow.h:221: html += F("' required><br>"); include/Webserver/Page_grow.h:225: html += F("<b>Bloom </b><input class='inputShort' type='number' name='sunriseHourBloom' min='0' max='23' value='"); include/Webserver/Page_grow.h:227: html += F("' required><b>:</b> <input class='inputShort' type='number' name='sunriseMinuteBloom' min='0' max='59' value='"); include/Webserver/Page_grow.h:229: html += F("' required><br>"); include/Webserver/Page_grow.h:233: html += F("<u>Sunset</u><br><b>Vegetation </b><input class='inputShort' type='number' name='sunsetHourVeg' min='0' max='23' value='"); include/Webserver/Page_grow.h:235: html += F("' required><b>:</b> <input class='inputShort' type='number' name='sunsetMinuteVeg' min='0' max='59' value='"); include/Webserver/Page_grow.h:237: html += F("' required><br>"); include/Webserver/Page_grow.h:240: html += F("<b>Bloom </b><input class='inputShort' type='number' name='sunsetHourBloom' min='0' max='23' value='"); include/Webserver/Page_grow.h:242: html += F("' required><b>:</b> <input class='inputShort' type='number' name='sunsetMinuteBloom' min='0' max='59' value='"); include/Webserver/Page_grow.h:244: html += F("' required><br>"); include/Webserver/Page_grow.h:250: html += F("<u>Power</u><br><input type='range' name='power' min='0' max='255' value='"); include/Webserver/Page_grow.h:252: html += F("'/> &#37;<br>"); include/Webserver/Page_grow.h:255: html += F("<u>Fade sunset/sunrise</u><br><select name='fade' required>"); include/Webserver/Page_grow.h:257: html += F("'/></select><br>"); include/Webserver/Page_grow.h:260: html += F("<u>Fade duration</u><br><input class='inputShort' type='number' name='fadeDuration' min='1' max='255' value='"); include/Webserver/Page_grow.h:262: html += F("' required> Minutes<br>"); include/Webserver/Page_grow.h:264: html += F("<u>Power</u><br><select name='power' required>"); include/Webserver/Page_grow.h:266: html += F("'/></select><br>"); include/Webserver/Page_grow.h:270: html += F("<input type='submit' value='&#x1F4BE; Save settings' style='margin-top: 8px;'></form>"); include/Webserver/Page_grow.h:273: html += F("<hr>"); include/Webserver/Page_grow.h:418: html += F("<form method='post' action='/grow/air/'>"); include/Webserver/Page_grow.h:420: html += F("<input type='hidden' name='output' value='"); include/Webserver/Page_grow.h:422: html += F("' required>"); include/Webserver/Page_grow.h:425: html += F("<h2>"); include/Webserver/Page_grow.h:427: html += F("</h2>"); include/Webserver/Page_grow.h:430: html += F("<u>Device:</u><br><b>"); include/Webserver/Page_grow.h:432: html += F(" ("); include/Webserver/Page_grow.h:434: html += F(")</b><br>"); include/Webserver/Page_grow.h:442: html += F("<u>Speed</u>"); include/Webserver/Page_grow.h:444: html += F("<u>Power</u>"); include/Webserver/Page_grow.h:446: html += F("<br><input type='range' name='power' min='0' max='255' value='"); include/Webserver/Page_grow.h:448: html += F("'/> &#37;<br>"); include/Webserver/Page_grow.h:450: html += F("<u>Power</u><br><select name='power' required>"); include/Webserver/Page_grow.h:453: html += F("'/></select><br>"); include/Webserver/Page_grow.h:458: html += F("<input type='hidden' name='controlSensor' value='"); include/Webserver/Page_grow.h:460: html += F("' id='controlSensor"); include/Webserver/Page_grow.h:462: html += F("'>"); include/Webserver/Page_grow.h:464: html += F("<input type='hidden' name='controlRead' value='"); include/Webserver/Page_grow.h:466: html += F("' id='controlRead"); include/Webserver/Page_grow.h:468: html += F("'>"); include/Webserver/Page_grow.h:470: html += F("<u>Controled by</u><br><select name='controlBy' id='ctrl"); include/Webserver/Page_grow.h:472: html += F("' onChange=\"GrowSelectControlSensorRead('ctrl"); include/Webserver/Page_grow.h:474: html += F("', 'controlSensor"); include/Webserver/Page_grow.h:476: html += F("', 'controlRead"); include/Webserver/Page_grow.h:478: html += F("');\"><option value='255:255' selected >---</option>"); include/Webserver/Page_grow.h:492: html += F("<option value='"); include/Webserver/Page_grow.h:496: html += F(":"); include/Webserver/Page_grow.h:499: html += F("'"); include/Webserver/Page_grow.h:501: html += F(" selected"); include/Webserver/Page_grow.h:502: html += F(">"); include/Webserver/Page_grow.h:504: html += F(" - "); include/Webserver/Page_grow.h:506: html += F(" ("); include/Webserver/Page_grow.h:508: html += F(" "); include/Webserver/Page_grow.h:513: html += F(" "); include/Webserver/Page_grow.h:514: unit.replace(F("%"), F("&#37;")); include/Webserver/Page_grow.h:516: html += F(")</option>"); include/Webserver/Page_grow.h:523: html += F("</select><br>"); include/Webserver/Page_grow.h:526: html += F("<u>Control mode</u><br><select name='controlMode' ><option value='' selected>---</option>"); include/Webserver/Page_grow.h:529: html += F("'/> &#37;</select><br>"); include/Webserver/Page_grow.h:533: html += F("<u>Min</u><br><input type='number' name='min' step='0.1' value='"); include/Webserver/Page_grow.h:535: html += F("' required><br>"); include/Webserver/Page_grow.h:538: html += F("<u>Max</u><br><input type='number' name='max' step='0.1' value='"); include/Webserver/Page_grow.h:540: html += F("' required><br>"); include/Webserver/Page_grow.h:544: html += F("<input type='submit' value='&#x1F4BE; Save settings' style='margin-top: 8px;'></form>"); include/Webserver/Page_grow.h:547: html += F("<hr>"); include/Webserver/Page_grow.h:670: html += F("<form method='post' action='/grow/water/'>"); include/Webserver/Page_grow.h:672: html += F("<input type='hidden' name='output' value='"); include/Webserver/Page_grow.h:674: html += F("' required>"); include/Webserver/Page_grow.h:677: html += F("<h2>"); include/Webserver/Page_grow.h:679: html += F("</h2>"); include/Webserver/Page_grow.h:682: html += F("<u>Device:</u><br><b>"); include/Webserver/Page_grow.h:684: html += F(" ("); include/Webserver/Page_grow.h:686: html += F(")</b><br>"); include/Webserver/Page_grow.h:705: html += F("<u>Pump On</u><br><input class='inputShort' type='number' name='onTime' min='0' max='255' value='"); include/Webserver/Page_grow.h:707: html += F("' required> Seconds<br>"); include/Webserver/Page_grow.h:710: html += F("<input type='hidden' name='controlSensor' value='"); include/Webserver/Page_grow.h:712: html += F("' id='controlSensor"); include/Webserver/Page_grow.h:714: html += F("'>"); include/Webserver/Page_grow.h:716: html += F("<input type='hidden' name='controlRead' value='"); include/Webserver/Page_grow.h:718: html += F("' id='controlRead"); include/Webserver/Page_grow.h:720: html += F("'>"); include/Webserver/Page_grow.h:724: html += F("<u>Control mode</u><br><select name='controlMode'><option value='' selected>---</option>"); include/Webserver/Page_grow.h:727: html += F("</select><br>"); include/Webserver/Page_grow.h:730: html += F("<u>Interval</u><br><input class='inputShort' type='number' name='interval' min='0' max='255' value='"); include/Webserver/Page_grow.h:732: html += F("' required> "); include/Webserver/Page_grow.h:735: html += F("<select name='intervalUnit'>"); include/Webserver/Page_grow.h:741: html += F("<option value='"); include/Webserver/Page_grow.h:743: html += F("'"); include/Webserver/Page_grow.h:745: html += F(" selected"); include/Webserver/Page_grow.h:746: html += F(">"); include/Webserver/Page_grow.h:748: html += F("</option>"); include/Webserver/Page_grow.h:751: html += F("</select><br>"); include/Webserver/Page_grow.h:755: html += F("<u>Controled by</u><br><select name='controlBy' id='ctrl"); include/Webserver/Page_grow.h:757: html += F("' onChange=\"GrowSelectControlSensorRead('ctrl"); include/Webserver/Page_grow.h:759: html += F("', 'controlSensor"); include/Webserver/Page_grow.h:761: html += F("', 'controlRead"); include/Webserver/Page_grow.h:763: html += F("');\"><option value='255:255' selected >---</option>"); include/Webserver/Page_grow.h:776: html += F("<option value='"); include/Webserver/Page_grow.h:780: html += F(":"); include/Webserver/Page_grow.h:783: html += F("'"); include/Webserver/Page_grow.h:785: html += F(" selected"); include/Webserver/Page_grow.h:786: html += F(">"); include/Webserver/Page_grow.h:788: html += F(" - ("); include/Webserver/Page_grow.h:790: html += F(") "); include/Webserver/Page_grow.h:798: html += F(" ("); include/Webserver/Page_grow.h:800: html += F(" "); include/Webserver/Page_grow.h:810: html += F(" "); include/Webserver/Page_grow.h:811: unit.replace(F("%"), F("&#37;")); include/Webserver/Page_grow.h:813: html += F(")</option>"); include/Webserver/Page_grow.h:820: html += F("</select><br>"); include/Webserver/Page_grow.h:824: html += F("<u>Min</u><br><input class='inputShort' type='number' name='min' min='0' max='255' value='"); include/Webserver/Page_grow.h:826: html += F("' required><br>"); include/Webserver/Page_grow.h:829: html += F("<u>Max</u><br><input class='inputShort' type='number' name='max' min='0' max='255' value='"); include/Webserver/Page_grow.h:831: html += F("' required><br>"); include/Webserver/Page_grow.h:836: html += F("<input type='submit' value='&#x1F4BE; Save settings' style='margin-top: 8px;'></form>"); include/Webserver/Page_grow.h:839: html += F("<hr>"); include/Webserver/Page_grow.h:969: return F("disabled force_hide"); include/Webserver/Page_grow.h:975: return F("disabled force_hide"); include/Webserver/Page_grow.h:981: return F("disabled force_hide"); include/Webserver/Page_grow.h:989: html += F("<tr><td>"); include/Webserver/Page_grow.h:991: html += F("</td><td>"); include/Webserver/Page_grow.h:993: html += F("</td><td>"); include/Webserver/Page_grow.h:1005: html += F("</td><td>"); include/Webserver/Page_grow.h:1009: unit.replace(F("%"), F("&#37;")); include/Webserver/Page_grow.h:1011: html += F("</td><td>"); include/Webserver/Page_grow.h:1013: html += F("<form class='linkForm' action='/grow/dashboard/gaugeAdd' method='get'>"); include/Webserver/Page_grow.h:1014: html += F("<input type='hidden' name='edit' value='"); include/Webserver/Page_grow.h:1016: html += F("'>"); include/Webserver/Page_grow.h:1017: html += F("<input type='submit' value='&#x270F;&#xFE0F;' title='Edit'></form> "); include/Webserver/Page_grow.h:1019: html += F("<form class='linkForm' action='/grow/dashboard/' method='post'>"); include/Webserver/Page_grow.h:1020: html += F("<input type='hidden' name='delete_gauge' value='"); include/Webserver/Page_grow.h:1022: html += F("'>"); include/Webserver/Page_grow.h:1023: html += F("<input type='submit' value='&#x274C;' onclick=\"return confirmDelete('"); include/Webserver/Page_grow.h:1024: html += F("gauge for "); include/Webserver/Page_grow.h:1026: html += F(" "); include/Webserver/Page_grow.h:1037: html += F("')\" title='Delete'></form>"); include/Webserver/Page_grow.h:1038: html += F("</td></tr>"); include/Webserver/Page_grow.h:1048: html += F("<tr><td>"); include/Webserver/Page_grow.h:1050: html += F("</td><td>"); include/Webserver/Page_grow.h:1052: html += F("</td><td>"); include/Webserver/Page_grow.h:1064: html += F("</td><td style='background-color: "); include/Webserver/Page_grow.h:1066: html += F(";'>"); include/Webserver/Page_grow.h:1071: unit.replace(F("%"), F("&#37;")); include/Webserver/Page_grow.h:1073: html += F("</td><td>"); include/Webserver/Page_grow.h:1075: html += F("<form class='linkForm' action='/grow/dashboard/chartAdd' method='get'>"); include/Webserver/Page_grow.h:1076: html += F("<input type='hidden' name='edit' value='"); include/Webserver/Page_grow.h:1078: html += F("'>"); include/Webserver/Page_grow.h:1079: html += F("<input type='submit' value='&#x270F;&#xFE0F;' title='Edit'></form> "); include/Webserver/Page_grow.h:1081: html += F("<form class='linkForm' action='/grow/dashboard/' method='post'>"); include/Webserver/Page_grow.h:1082: html += F("<input type='hidden' name='delete_chart' value='"); include/Webserver/Page_grow.h:1084: html += F("'>"); include/Webserver/Page_grow.h:1085: html += F("<input type='submit' value='&#x274C;' onclick=\"return confirmDelete('"); include/Webserver/Page_grow.h:1086: html += F("chart for "); include/Webserver/Page_grow.h:1088: html += F(" "); include/Webserver/Page_grow.h:1099: html += F("')\" title='Delete'></form>"); include/Webserver/Page_grow.h:1100: html += F("</td></tr>"); include/Webserver/Page_grow.h:1108: html += F("<tr><td>"); include/Webserver/Page_grow.h:1110: html += F("</td><td>"); include/Webserver/Page_grow.h:1112: html += F("</td><td>"); include/Webserver/Page_grow.h:1124: html += F("</td><td>"); include/Webserver/Page_grow.h:1129: unit.replace(F("%"), F("&#37;")); include/Webserver/Page_grow.h:1131: html += F("</td><td>"); include/Webserver/Page_grow.h:1133: html += F("<form class='linkForm' action='/grow/dashboard/dataAdd' method='get'>"); include/Webserver/Page_grow.h:1134: html += F("<input type='hidden' name='edit' value='"); include/Webserver/Page_grow.h:1136: html += F("'>"); include/Webserver/Page_grow.h:1137: html += F("<input type='submit' value='&#x270F;&#xFE0F;' title='Edit'></form> "); include/Webserver/Page_grow.h:1139: html += F("<form class='linkForm' action='/grow/dashboard/' method='post'>"); include/Webserver/Page_grow.h:1140: html += F("<input type='hidden' name='delete_data' value='"); include/Webserver/Page_grow.h:1142: html += F("'>"); include/Webserver/Page_grow.h:1143: html += F("<input type='submit' value='&#x274C;' onclick=\"return confirmDelete('"); include/Webserver/Page_grow.h:1144: html += F("data for "); include/Webserver/Page_grow.h:1146: html += F(" "); include/Webserver/Page_grow.h:1157: html += F("')\" title='Delete'></form>"); include/Webserver/Page_grow.h:1158: html += F("</td></tr>"); include/Webserver/Api_chartdata.h:12: AsyncWebServerResponse *response = request->beginResponse(200, F("application/json"), json); include/Webserver/Page_system.h:115: return F(" &#x26A0;&#xFE0F; "); include/Webserver/Page_system.h:117: return F(" &#x2705; "); include/Webserver/Page_system.h:370: response->addHeader(F("Connection"), F("close")); include/Webserver/Page_system.h:417: request->redirect(F("/system/update?success")); include/Webserver/Page_system.h:479: return F("disabled force_hide"); include/Webserver/Page_system.h:491: html += F("<tr><td>"); include/Webserver/Page_system.h:494: html += F(" &#x26A0;&#xFE0F;"); include/Webserver/Page_system.h:496: html += F(" &#x2705;"); include/Webserver/Page_system.h:499: html += F("&nbsp;&nbsp;"); include/Webserver/Page_system.h:500: html += F("</td><td>"); include/Webserver/Page_system.h:503: html += F("</td><td>"); include/Webserver/Page_system.h:505: html += F("</td><td>"); include/Webserver/Page_system.h:509: html += F(" ("); include/Webserver/Page_system.h:524: html += F(")"); include/Webserver/Page_system.h:527: html += F("</td><td>"); include/Webserver/Page_system.h:529: html += F("</td><td>"); include/Webserver/Page_system.h:532: html += F("&nbsp;&#x1F7E2;&nbsp;"); include/Webserver/Page_system.h:534: html += F("&nbsp;&#x1F534;&nbsp;&nbsp;"); include/Webserver/Page_system.h:537: html += F("</td><td>"); include/Webserver/Page_system.h:540: html += F("<form class='linkForm' action='/system/output/add' method='get'>"); include/Webserver/Page_system.h:541: html += F("<input type='hidden' name='edit' value='"); include/Webserver/Page_system.h:543: html += F("'>"); include/Webserver/Page_system.h:544: html += F("<input type='submit' value='&#x270F;&#xFE0F;' title='Edit'></form> "); include/Webserver/Page_system.h:548: html += F("<form class='linkForm' action='/system/output/' method='post'>"); include/Webserver/Page_system.h:549: html += F("<input type='hidden' name='delete_output' value='"); include/Webserver/Page_system.h:551: html += F("'>"); include/Webserver/Page_system.h:552: html += F("<input type='submit' value='&#x274C;' onclick=\"return confirmDelete('"); include/Webserver/Page_system.h:554: html += F("')\" title='Delete'></form>"); include/Webserver/Page_system.h:556: html += F("</td></tr>"); include/Webserver/Page_system.h:630: html += F("<option value='"); include/Webserver/Page_system.h:632: html += F("'"); include/Webserver/Page_system.h:634: html += F(" selected"); include/Webserver/Page_system.h:636: html += F(">"); include/Webserver/Page_system.h:638: html += F("</option>"); include/Webserver/Page_system.h:654: js += F("["); include/Webserver/Page_system.h:657: js += F("['0x"); include/Webserver/Page_system.h:660: js += F("', '"); include/Webserver/Page_system.h:664: js += F("', ["); include/Webserver/Page_system.h:670: js += F("'"); include/Webserver/Page_system.h:680: js += F("',"); include/Webserver/Page_system.h:685: js += F("]],"); include/Webserver/Page_system.h:687: js += F("],\n"); include/Webserver/Page_system.h:746: return F("editmode"); include/Webserver/Page_system.h:762: outputName.replace(F("%"), F("&#37;")); include/Webserver/Page_system.h:789: js += F("showSelect('type_sel', 'type_', 'hidden'); SystemOutputAddselectRequired('type_sel');"); include/Webserver/Page_system.h:791: //js += F("document.getElementById('i2c_type').value='"); include/Webserver/Page_system.h:793: //js += F("';\n"); include/Webserver/Page_system.h:795: js += F("SystemOutputAdd_replaceI2cAddr('i2c_type', 'i2c_addr');"); include/Webserver/Page_system.h:797: js += F("document.getElementById('i2c_addr').value='"); include/Webserver/Page_system.h:799: js += F("';\n"); include/Webserver/Page_system.h:801: js += F("SystemOutputAdd_replaceI2cPort('i2c_type', 'i2c_addr', 'i2c_port');\n"); include/Webserver/Page_system.h:803: js += F("document.getElementById('i2c_port').value='"); include/Webserver/Page_system.h:805: js += F("';\n"); include/Webserver/Page_system.h:817: webcallPathOn.replace(F("%"), F("&#37;")); include/Webserver/Page_system.h:822: webcallPathOff.replace(F("%"), F("&#37;")); include/Webserver/Page_system.h:830: return F("visible"); include/Webserver/Page_system.h:1011: request->redirect(F("/system/output/?success")); include/Webserver/Page_system.h:1076: return F("disabled force_hide"); include/Webserver/Page_system.h:1087: html += F("<tr><td>"); include/Webserver/Page_system.h:1090: html += F(" &#x26A0;&#xFE0F;"); include/Webserver/Page_system.h:1092: html += F(" &#x2705;"); include/Webserver/Page_system.h:1095: html += F("&nbsp;&nbsp;"); include/Webserver/Page_system.h:1096: html += F("</td><td>"); include/Webserver/Page_system.h:1100: html += F("</td><td>"); include/Webserver/Page_system.h:1102: html += F("</td><td>"); include/Webserver/Page_system.h:1111: html += F(" ("); include/Webserver/Page_system.h:1117: html += F("/"); include/Webserver/Page_system.h:1121: html += F("0x"); include/Webserver/Page_system.h:1124: html += F(")"); include/Webserver/Page_system.h:1127: html += F("</td><td>"); include/Webserver/Page_system.h:1130: html += F("<form class='linkForm' action='/system/sensor/calibrate' method='get'>"); include/Webserver/Page_system.h:1131: html += F("<input type='hidden' name='calibrate' value='"); include/Webserver/Page_system.h:1133: html += F("'>"); include/Webserver/Page_system.h:1134: html += F("<input type='submit' value='&#x1F39B;&#xFE0F;' title='Calibrate'></form> "); include/Webserver/Page_system.h:1137: html += F("<form class='linkForm' action='/system/sensor/add' method='get'>"); include/Webserver/Page_system.h:1138: html += F("<input type='hidden' name='edit' value='"); include/Webserver/Page_system.h:1140: html += F("'>"); include/Webserver/Page_system.h:1141: html += F("<input type='submit' value='&#x270F;&#xFE0F;' title='Edit'></form> "); include/Webserver/Page_system.h:1144: html += F("<form class='linkForm' action='/system/sensor/' method='post'>"); include/Webserver/Page_system.h:1145: html += F("<input type='hidden' name='delete_sensor' value='"); include/Webserver/Page_system.h:1147: html += F("'>"); include/Webserver/Page_system.h:1148: html += F("<input type='submit' value='&#x274C;' onclick=\"return confirmDelete('"); include/Webserver/Page_system.h:1150: html += F("')\" title='Delete'></form>"); include/Webserver/Page_system.h:1152: html += F("</td></tr>"); include/Webserver/Page_system.h:1215: html += F("<option value='"); include/Webserver/Page_system.h:1217: html += F("'"); include/Webserver/Page_system.h:1219: html += F(" selected"); include/Webserver/Page_system.h:1221: html += F(">"); include/Webserver/Page_system.h:1223: html += F("</option>"); include/Webserver/Page_system.h:1239: js += F("["); include/Webserver/Page_system.h:1242: js += F("['0x"); include/Webserver/Page_system.h:1245: js += F("', '"); include/Webserver/Page_system.h:1249: js += F("', '"); include/Webserver/Page_system.h:1254: js += F("1"); include/Webserver/Page_system.h:1263: js += F("'],"); include/Webserver/Page_system.h:1265: js += F("],\n"); include/Webserver/Page_system.h:1292: return F("8266"); include/Webserver/Page_system.h:1296: return F("32"); include/Webserver/Page_system.h:1327: sensorName.replace(F("%"), F("&#37;")); include/Webserver/Page_system.h:1335: return F("8266"); include/Webserver/Page_system.h:1339: return F("32"); include/Webserver/Page_system.h:1349: js += F("SystemSensorAddGpioI2cSel('type_sel');SystemSensor_replaceAddr('type_sel', 'i2c_addr');"); include/Webserver/Page_system.h:1350: js += F("document.getElementById('i2c_addr').value='"); include/Webserver/Page_system.h:1352: js += F("';"); include/Webserver/Page_system.h:1474: js += F("["); include/Webserver/Page_system.h:1477: js += F("['0x"); include/Webserver/Page_system.h:1480: js += F("', '"); include/Webserver/Page_system.h:1484: js += F("', '"); include/Webserver/Page_system.h:1489: js += F("1"); include/Webserver/Page_system.h:1498: js += F("'],"); include/Webserver/Page_system.h:1500: js += F("],\n"); include/Webserver/Page_system.h:1513: return F("&#10133; Add"); include/Webserver/Page_system.h:1528: return F("8266"); include/Webserver/Page_system.h:1532: return F("32"); include/Webserver/Page_system.h:1558: sensorName.replace(F("%"), F("&#37;")); include/Webserver/Page_system.h:1566: html += F("<script>SensorJsonRefresh(); var refreshJson = setInterval(SensorJsonRefresh, 1000);</script>"); include/Webserver/Page_system.h:1569: html += F("<form method='post' action='/system/sensor/calibrate'>"); include/Webserver/Page_system.h:1570: html += F("<input type='hidden' name='sensorId' value='"); include/Webserver/Page_system.h:1572: html += F("'/>"); include/Webserver/Page_system.h:1573: html += F("<input type='hidden' name='readId' value='"); include/Webserver/Page_system.h:1575: html += F("'/>"); include/Webserver/Page_system.h:1577: html += F("<u>Reading "); include/Webserver/Page_system.h:1579: html += F(":</u><br><b>"); include/Webserver/Page_system.h:1581: html += F("</b> ("); include/Webserver/Page_system.h:1582: html += F("<span class='sensorReading' id='raw-"); include/Webserver/Page_system.h:1586: html += F("'>"); include/Webserver/Page_system.h:1608: unit.replace(F("%"), F("&#37;")); include/Webserver/Page_system.h:1614: html += F("</span>)"); include/Webserver/Page_system.h:1617: html += F("<script>var raw_"); include/Webserver/Page_system.h:1619: html += F("_"); include/Webserver/Page_system.h:1621: html += F(" = setInterval(rawRefresh, 1000, "); include/Webserver/Page_system.h:1623: html += F(", "); include/Webserver/Page_system.h:1625: html += F(", 'raw-');</script>"); include/Webserver/Page_system.h:1628: html += F("<br>"); include/Webserver/Page_system.h:1631: html += F("<u>Convert RAW value to:</u><br>"); include/Webserver/Page_system.h:1632: html += F("<select name='rawConvert'><option value='0' >---</option>"); include/Webserver/Page_system.h:1634: html += F("<option value='"); include/Webserver/Page_system.h:1637: html += F("'"); include/Webserver/Page_system.h:1639: html += F(" selected"); include/Webserver/Page_system.h:1640: html += F(">"); include/Webserver/Page_system.h:1642: html += F("</option>"); include/Webserver/Page_system.h:1644: html += F("</select><br>"); include/Webserver/Page_system.h:1648: //html += F("<span class='sensorReading'>"); include/Webserver/Page_system.h:1649: html += F("<span class='sensorReading' id='reading-"); include/Webserver/Page_system.h:1653: html += F("'>"); include/Webserver/Page_system.h:1659: unit.replace(F("%"), F("&#37;")); include/Webserver/Page_system.h:1661: html += F("</span>"); include/Webserver/Page_system.h:1663: html += F("<script>var reading_"); include/Webserver/Page_system.h:1665: html += F("_"); include/Webserver/Page_system.h:1667: html += F(" = setInterval(sensorRefresh, 1000, "); include/Webserver/Page_system.h:1669: html += F(", "); include/Webserver/Page_system.h:1671: html += F(", 'reading-');</script>"); include/Webserver/Page_system.h:1673: html += F("<br>"); include/Webserver/Page_system.h:1676: html += F("<u>Low:</u><br>"); include/Webserver/Page_system.h:1677: html += F("<input type='number' name='low' value='"); include/Webserver/Page_system.h:1679: html += F("'/><br>"); include/Webserver/Page_system.h:1681: html += F("<u>High:</u><br>"); include/Webserver/Page_system.h:1682: html += F("<input type='number' name='high' value='"); include/Webserver/Page_system.h:1684: html += F("'/><br>"); include/Webserver/Page_system.h:1688: html += F("<u>Offset:</u><br>"); include/Webserver/Page_system.h:1689: html += F("<input type='number' step='0.01' name='offset' value='"); include/Webserver/Page_system.h:1691: html += F("'/><br>"); include/Webserver/Page_system.h:1694: html += F("<br><input type='submit' value='&#x1F4BE; Save settings'></form>"); include/Webserver/Page_system.h:1695: html += F("<hr>\n\n"); include/Webserver/Page_wifi.h:24: html += F("<option value='"); include/Webserver/Page_wifi.h:26: html += F("'>"); include/Webserver/Page_wifi.h:28: html += F("</option>"); include/Webserver/File_favicon_ico.h:34: AsyncWebServerResponse *response = request->beginResponse_P(200, F("image/x-icon"), File_favicon_ico_gz, File_favicon_ico_gz_len); include/Webserver/File_favicon_ico.h:35: response->addHeader(F("Content-Encoding"), F("gzip")); include/Webserver/File_favicon_ico.h:36: response->addHeader(F("Cache-control"), F("max-age=600")); include/Webserver/Api_sensor.h:84: root["msg"] = String(F("not a RAW reading")); include/Webserver/Api_sensor.h:87: root["msg"] = String(F("sensor or reading not given")); include/Webserver/File_cangrow_CSS.h:423: AsyncWebServerResponse *response = request->beginResponse_P(200, F("text/css"), File_cangrow_CSS); include/Webserver/File_cangrow_CSS.h:424: response->addHeader(F("Cache-control"), F("max-age=600")); include/Webserver/Webserver_Common.h:65: String activeNav_ClassName = F("activeNav"); include/Webserver/Webserver_Common.h:114: gpioIndex_html += F("<option value='"); include/Webserver/Webserver_Common.h:116: gpioIndex_html += F("'"); include/Webserver/Webserver_Common.h:129: gpioIndex_html += F(" disabled"); include/Webserver/Webserver_Common.h:133: gpioIndex_html += F(" selected"); include/Webserver/Webserver_Common.h:135: gpioIndex_html += F(">GPIO "); include/Webserver/Webserver_Common.h:139: gpioIndex_html += F(" "); include/Webserver/Webserver_Common.h:144: gpioIndex_html += F(" (N/A)"); include/Webserver/Webserver_Common.h:147: gpioIndex_html += F(" (used)"); include/Webserver/Webserver_Common.h:149: gpioIndex_html += F("</option>"); include/Webserver/Webserver_Common.h:157: html += F("<option value='1'"); include/Webserver/Webserver_Common.h:158: html += ((selectVal > 0) && (selectVal < 255)) ? F(" selected") : F(""); include/Webserver/Webserver_Common.h:159: html += F(">"); include/Webserver/Webserver_Common.h:161: html += F("</option>"); include/Webserver/Webserver_Common.h:163: html += F("<option value='0'"); include/Webserver/Webserver_Common.h:164: html += (selectVal == 0) ? F(" selected") : F(""); include/Webserver/Webserver_Common.h:165: html += F(">"); include/Webserver/Webserver_Common.h:167: html += F("</option>"); include/Webserver/Webserver_Common.h:178: html += F("<option value='"); include/Webserver/Webserver_Common.h:180: html += F("'"); include/Webserver/Webserver_Common.h:182: html += F(" selected"); include/Webserver/Webserver_Common.h:184: html += F(">"); include/Webserver/Webserver_Common.h:187: html += F("</option>"); include/Webserver/Webserver_Common.h:200: html += F("<option value='"); include/Webserver/Webserver_Common.h:204: html += F(":"); include/Webserver/Webserver_Common.h:207: html += F("'"); include/Webserver/Webserver_Common.h:210: html += F(" selected"); include/Webserver/Webserver_Common.h:211: html += F(">"); include/Webserver/Webserver_Common.h:213: html += F(" - "); include/Webserver/Webserver_Common.h:221: html += F(" ("); include/Webserver/Webserver_Common.h:223: html += F(" "); include/Webserver/Webserver_Common.h:228: html += F(" "); include/Webserver/Webserver_Common.h:229: unit.replace(F("%"), F("&#37;")); include/Webserver/Webserver_Common.h:231: html += F(")</option>"); include/Webserver/File_cangrow_JS.h:396: AsyncWebServerResponse *response = request->beginResponse_P(200, F("text/javascript"), File_cangrow_JS); include/Webserver/File_cangrow_JS.h:397: response->addHeader(F("Cache-control"), F("max-age=600")); include/CanGrow_Core.h:464: str_time += F("0"); include/CanGrow_Core.h:466: str_time += F(":"); include/CanGrow_Core.h:468: str_time += F("0"); include/CanGrow_Core.h:470: str_time += F(":"); include/CanGrow_Core.h:472: str_time += F("0"); include/CanGrow_Core.h:481: str_date += F("0"); include/CanGrow_Core.h:483: str_date += F("."); include/CanGrow_Core.h:485: str_date += F("0"); include/CanGrow_Core.h:487: str_date += F("."); include/CanGrow_Core.h:766: unit.replace(F("%"), F("%%")); include/CanGrow_LittleFS.h:82: return String(F("ERROR CANNOT OPEN")); include/CanGrow_Output.h:192: url += F("http://"); include/CanGrow_Output.h:194: url += F("/"); ``` its a LOT also .css and .js files should be minified and gzipd. this will also save some kb. put the .gz into a variable with `xxd -i`
DeltaLima added reference firmware_v0.2-dev 2025-04-12 03:16:39 +02:00
Author
Owner

ESP32-S2 has no problem,. the firmware fits within the available space, 94% used

$ TTY=/dev/ttyACM0 BOARD="esp32:esp32:lolin_s2_mini"  ./cangrow.sh upload
:: Build and upload firmware 0.2-dev3 1452ae2-esp32_lolin_s2_mini-20250412160502 to /dev/ttyACM0
Der Sketch verwendet 1242978 Bytes (94%) des Programmspeicherplatzes. Das Maximum sind 1310720 Bytes.
Globale Variablen verwenden 66680 Bytes (20%) des dynamischen Speichers, 261000 Bytes für lokale Variablen verbleiben. Das Maximum sind 327680 Bytes.
esptool.py v4.6
Serial port /dev/ttyACM0
Connecting...

ESP32-S2 has no problem,. the firmware fits within the available space, 94% used ```bash $ TTY=/dev/ttyACM0 BOARD="esp32:esp32:lolin_s2_mini" ./cangrow.sh upload :: Build and upload firmware 0.2-dev3 1452ae2-esp32_lolin_s2_mini-20250412160502 to /dev/ttyACM0 Der Sketch verwendet 1242978 Bytes (94%) des Programmspeicherplatzes. Das Maximum sind 1310720 Bytes. Globale Variablen verwenden 66680 Bytes (20%) des dynamischen Speichers, 261000 Bytes für lokale Variablen verbleiben. Das Maximum sind 327680 Bytes. esptool.py v4.6 Serial port /dev/ttyACM0 Connecting... ```
Author
Owner
https://stackoverflow.com/questions/5448545/how-to-retrieve-get-parameters-from-javascript https://stackoverflow.com/questions/11985156/clone-div-and-change-id
DeltaLima added the
v0.2.x
v0.3.x
labels 2025-04-19 02:28:36 +02:00
DeltaLima removed the
v0.3.x
label 2025-04-19 18:30:56 +02:00
Author
Owner

minimized and compressed javascript and css file. also began to use TinyJS https://github.com/victorqribeiro/TinyJS to reduce javascript code to write.

Todo are the grow and system pages have to be remade in javascript

minimized and compressed javascript and css file. also began to use TinyJS https://github.com/victorqribeiro/TinyJS to reduce javascript code to write. Todo are the grow and system pages have to be remade in javascript
Author
Owner

About 4KB of just cutting html strings together

$ grep -r "html += F(" *| cut -d = -f 2| sed -e 's/F(\"//g' -e 's/\")\;//g'| wc -c
4045

Plus what I have all in PROGMEM in the _HTML.h files I guess this would be a very worthy work to put all those into javascript to save up space on the flash.

With the work already done, ESP32-C3 is still unhappy :(

$ TTY=/dev/ttyACM0 BOARD="esp32:esp32:makergo_c3_supermini" ./cangrow.sh upload
:: Build and upload firmware 0.2-dev3 c4b64d6-esp32_makergo_c3_supermini-20250420023727 to /dev/ttyACM0
:: Minimize and compress static webserver files
:: - cangrow.js has not changed
:: - cangrow.css has not changed
Der Sketch verwendet 1253380 Bytes (95%) des Programmspeicherplatzes. Das Maximum sind 1310720 Bytes.
Globale Variablen verwenden 45252 Bytes (13%) des dynamischen Speichers, 282428 Bytes für lokale Variablen verbleiben. Das Maximum sind 327680 Bytes.
esptool.py v4.6
Serial port /dev/ttyACM0
Connecting...
Chip is ESP32-C3 (revision v0.4)
.... succesful compile & upload ....

$ TTY=/dev/ttyACM0 BOARD="esp32:esp32:makergo_c3_supermini" ./cangrow.sh monitor
:: Open serial monitor /dev/ttyACM0
Porteinstellunegn für Monitor:
  baudrate=115200
  bits=8
  dtr=off
  parity=none
  rts=off
  stop_bits=1

Verbindung zu /dev/ttyACM0 wird hergestellt. Abbrechen mit STRG-C.
E (216) esp_image: Image length 1319392 doesn't fit in partitionE (227) esp_image: Image length 1319392 doesn't fit in partition length 1310720
E (227) boot: OTA app partition slot 0 is not bootable
E (228) esp_image: image at 0x150000 has invalid magic byte (nothing flashed here?)
E (235) boot: OTA app partition slot 1 is not bootable
E (240) boot: No bootable app partitions in the partition table
ESP-ROM:esp32c3-api1-20210207
Build:Feb  7 2021
rst:0x3 (RTC_SW_SYS_RST),boot:0xd (SPI_FAST_FLASH_BOOT)
Saved PC:0x40048b82
SPIWP:0xee
mode:DIO, clock div:1
load:0x3fcd5820,len:0x1058
load:0x403cc710,len:0x8a8
load:0x403ce710,len:0x2fac
entry 0x403cc710
About 4KB of just cutting html strings together ```sh $ grep -r "html += F(" *| cut -d = -f 2| sed -e 's/F(\"//g' -e 's/\")\;//g'| wc -c 4045 ``` Plus what I have all in PROGMEM in the `_HTML.h` files I guess this would be a very worthy work to put all those into javascript to save up space on the flash. With the work already done, ESP32-C3 is still unhappy :( ```sh $ TTY=/dev/ttyACM0 BOARD="esp32:esp32:makergo_c3_supermini" ./cangrow.sh upload :: Build and upload firmware 0.2-dev3 c4b64d6-esp32_makergo_c3_supermini-20250420023727 to /dev/ttyACM0 :: Minimize and compress static webserver files :: - cangrow.js has not changed :: - cangrow.css has not changed Der Sketch verwendet 1253380 Bytes (95%) des Programmspeicherplatzes. Das Maximum sind 1310720 Bytes. Globale Variablen verwenden 45252 Bytes (13%) des dynamischen Speichers, 282428 Bytes für lokale Variablen verbleiben. Das Maximum sind 327680 Bytes. esptool.py v4.6 Serial port /dev/ttyACM0 Connecting... Chip is ESP32-C3 (revision v0.4) .... succesful compile & upload .... $ TTY=/dev/ttyACM0 BOARD="esp32:esp32:makergo_c3_supermini" ./cangrow.sh monitor :: Open serial monitor /dev/ttyACM0 Porteinstellunegn für Monitor: baudrate=115200 bits=8 dtr=off parity=none rts=off stop_bits=1 Verbindung zu /dev/ttyACM0 wird hergestellt. Abbrechen mit STRG-C. E (216) esp_image: Image length 1319392 doesn't fit in partitionE (227) esp_image: Image length 1319392 doesn't fit in partition length 1310720 E (227) boot: OTA app partition slot 0 is not bootable E (228) esp_image: image at 0x150000 has invalid magic byte (nothing flashed here?) E (235) boot: OTA app partition slot 1 is not bootable E (240) boot: No bootable app partitions in the partition table ESP-ROM:esp32c3-api1-20210207 Build:Feb 7 2021 rst:0x3 (RTC_SW_SYS_RST),boot:0xd (SPI_FAST_FLASH_BOOT) Saved PC:0x40048b82 SPIWP:0xee mode:DIO, clock div:1 load:0x3fcd5820,len:0x1058 load:0x403cc710,len:0x8a8 load:0x403ce710,len:0x2fac entry 0x403cc710 ```
Author
Owner
https://johnmu.com/2024-esp32-partition-update/ https://github.com/softplus/Esp32Repartition
Sign in to join this conversation.
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Reference: DeltaLima/CanGrow#39
No description provided.