42
42
#define SHAPE_CIRCLE 2
43
43
#define SHAPE_PIXEL 3
44
44
#define STATE_NORMAL 0
45
- #define STATE_UPDATING 1
45
+ #define STATE_DISABLED 1
46
46
47
47
// Configuration
48
48
#define ROUNDED_RECT_RADIUS 3 // The radius to use for rounded rectangles
161
161
#include < WiFiClientSecure.h>
162
162
#include < HTTPClient.h>
163
163
#include < WiFiMulti.h>
164
- // #define sint16_t signed short
165
- // #define sint32_t signed long
166
164
#else // ESP8266 Specific
167
165
#include < ESPAsyncTCP.h>
168
166
#include < LittleFS.h>
187
185
#include " TinyIcons.h"
188
186
#endif
189
187
#if USE_SUNRISE
190
- #include < SunMoonCalc.h>
188
+ #include " SunMoonCalc.h"
191
189
#endif
192
190
#if USE_TETRIS
193
191
#include < TetrisMatrixDraw.h>
@@ -321,6 +319,8 @@ bool needsConfig; // If a configuration is needed
321
319
bool needsUpdate; // If a full update is needed
322
320
bool needsRestart; // If a system reboot is needed
323
321
bool needsTimezone; // If the timezone needs to be set still
322
+ bool needsFormat; // If a FS format is needed
323
+ bool needsFactoryReset; // If a factory reset is needed
324
324
uint8_t theHour12;
325
325
uint8_t theHour;
326
326
uint8_t theMinute;
@@ -335,6 +335,7 @@ time_t sunSetTime;
335
335
uint8_t scanPattern;
336
336
uint8_t muxPattern;
337
337
uint8_t muxDelay;
338
+ AsyncClient* finalClient; // Client to wait for closing before restart
338
339
339
340
#ifdef ESP32
340
341
#define P_LAT 22
@@ -433,6 +434,7 @@ uint16_t parseHexColorString(std::string s) {
433
434
}
434
435
435
436
void closeFiles () {
437
+ DEBUG (" Closing widget files\n " );
436
438
for (uint i = 0 ; i < widgets.size (); i++)
437
439
widgets[i].file .close ();
438
440
}
@@ -650,12 +652,22 @@ bool getConfig() {
650
652
651
653
#pragma region Web Server
652
654
655
+ void restartAfterDisconnect (AsyncWebServerRequest *request) {
656
+ needsRestart = true ;
657
+ finalClient = request->client ();
658
+ }
659
+
653
660
void closeConnection (AsyncWebServerRequest *request) {
654
661
AsyncWebServerResponse *response = request->beginResponse (200 );
655
662
response->addHeader (" Connection" , " close" );
656
663
request->send (response);
657
664
}
658
665
666
+ void closeAndRestart (AsyncWebServerRequest *request) {
667
+ closeConnection (request);
668
+ restartAfterDisconnect (request);
669
+ }
670
+
659
671
void onStartAccessPoint (AsyncWiFiManager *wiFiManager) {
660
672
Serial.println (F (" Entering AP config mode" ));
661
673
display.fillScreen (BLUE);
@@ -681,15 +693,6 @@ String getContentType(String filename) {
681
693
return F (" text/plain" );
682
694
}
683
695
684
- int getHeaderCacheVersion (AsyncWebServerRequest *request) {
685
- if (!request->hasHeader (F (" If-None-Match" )))
686
- return -1 ;
687
- for (int i = 0 ; i < request->headers (); i++ )
688
- if (request->headerName (i).equals (F (" If-None-Match" )))
689
- return request->header (i).toInt ();
690
- return -1 ;
691
- }
692
-
693
696
bool sendFile (AsyncWebServerRequest *request, String path, bool cache = true ) {
694
697
if (path.endsWith (F (" /" )))
695
698
return false ;
@@ -794,24 +797,7 @@ void serveNotFound(AsyncWebServerRequest *request) {
794
797
}
795
798
796
799
void serveRestart (AsyncWebServerRequest *request) {
797
- closeConnection (request);
798
- needsRestart = true ;
799
- }
800
-
801
- // Todo: Replace start and abort OTA functions with direct update functions
802
- void startOTA (AsyncWebServerRequest *request) {
803
- state = STATE_UPDATING;
804
- disableDisplay = true ;
805
- LittleFS.end ();
806
- request->send (200 );
807
- }
808
-
809
- void abortOTA (AsyncWebServerRequest *request) {
810
- state = STATE_NORMAL;
811
- disableDisplay = false ;
812
- LittleFS.begin ();
813
- request->send (200 );
814
- needsUpdate = true ;
800
+ closeAndRestart (request);
815
801
}
816
802
817
803
void serveStats (AsyncWebServerRequest *request) {
@@ -977,8 +963,7 @@ void serveImageData(AsyncWebServerRequest *request) {
977
963
}
978
964
979
965
void serveUploadImage (AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final ) {
980
- for (uint i = 0 ; i < widgets.size (); i++)
981
- widgets[i].file .close ();
966
+ closeFiles ();
982
967
String imageFilename = " /images/" + request->arg (" name" );
983
968
984
969
if (!index) {
@@ -1027,6 +1012,7 @@ void serveImage(AsyncWebServerRequest *request) {
1027
1012
}
1028
1013
1029
1014
void serveRenameImage (AsyncWebServerRequest *request) {
1015
+ closeFiles ();
1030
1016
String name = request->arg (F (" name" ));
1031
1017
String newName = request->arg (F (" newName" ));
1032
1018
if (!LittleFS.exists (" /images/" + name)) {
@@ -1045,8 +1031,7 @@ void serveRenameImage(AsyncWebServerRequest *request) {
1045
1031
}
1046
1032
1047
1033
void serveDeleteImage (AsyncWebServerRequest *request) {
1048
- for (uint i = 0 ; i < widgets.size (); i++)
1049
- widgets[i].file .close ();
1034
+ closeFiles ();
1050
1035
std::string name = request->arg (F (" name" )).c_str ();
1051
1036
std::map <std::string, FSImage> fsImageData = getFSImageData ();
1052
1037
fsImageData.erase (name);
@@ -1058,8 +1043,8 @@ void serveDeleteImage(AsyncWebServerRequest *request) {
1058
1043
}
1059
1044
1060
1045
void deleteAllImages () {
1061
- for (uint i = 0 ; i < widgets. size (); i++)
1062
- widgets[i]. file . close ();
1046
+ DEBUG ( " Deleting all custom images \n " );
1047
+ closeFiles ();
1063
1048
writeDefaultImageData ();
1064
1049
Dir dir = getImageDir ();
1065
1050
LittleFS.rmdir (F (" /images" ));
@@ -1081,33 +1066,43 @@ void serveDeleteAllImages(AsyncWebServerRequest *request) {
1081
1066
}
1082
1067
1083
1068
void serveResetConfiguration (AsyncWebServerRequest *request) {
1069
+ closeFiles ();
1084
1070
writeDefaultConfig ();
1085
- closeConnection (request);
1086
- needsRestart = true ;
1071
+ closeAndRestart (request);
1087
1072
}
1088
1073
1089
1074
void serveOK (AsyncWebServerRequest *request) {
1090
1075
request->send (200 );
1091
1076
}
1092
1077
1093
1078
void serveFactoryReset (AsyncWebServerRequest *request) {
1094
- writeDefaultConfig ();
1095
- deleteAllImages ();
1096
- AsyncWiFiManager wifiManager (&server, &dnsServer);
1097
- wifiManager.resetSettings ();
1098
- needsRestart = true ;
1099
- closeConnection (request);
1079
+ needsFactoryReset = true ;
1080
+ closeAndRestart (request);
1081
+ }
1082
+
1083
+ void serveFormatFilesystem (AsyncWebServerRequest *request) {
1084
+ needsFormat = true ;
1085
+ closeAndRestart (request);
1100
1086
}
1101
1087
1102
1088
void serveOTA (AsyncWebServerRequest *request) {
1103
- needsRestart = !Update.hasError ();
1104
- AsyncWebServerResponse *response = request->beginResponse (200 , " text/plain" , needsRestart ? " OK" : String (Update.getError (), 10 ));
1089
+ bool success = !Update.hasError ();
1090
+ if (!success) {
1091
+ state = STATE_NORMAL;
1092
+ disableDisplay = false ;
1093
+ LittleFS.begin ();
1094
+ needsUpdate = true ;
1095
+ } else
1096
+ restartAfterDisconnect (request);
1097
+ AsyncWebServerResponse *response = request->beginResponse (200 , " text/plain" , success ? " OK" : String (Update.getError (), 10 ));
1105
1098
response->addHeader (" Connection" , " close" );
1106
1099
request->send (response);
1107
1100
}
1108
1101
1109
1102
void serveOTAUpload (AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final ) {
1110
1103
if (!index) {
1104
+ state = STATE_DISABLED;
1105
+ disableDisplay = true ;
1111
1106
#ifdef ESP8266
1112
1107
Update.runAsync (true );
1113
1108
#endif
@@ -1130,7 +1125,7 @@ void serveOTAUpload(AsyncWebServerRequest *request, String filename, size_t inde
1130
1125
Update.printError (Serial);
1131
1126
if (final ) {
1132
1127
if (Update.end (true ))
1133
- Serial.printf (" Update Success: %uB\n " , index+ len);
1128
+ Serial.printf (" Update Success: %uB\n " , index + len);
1134
1129
else
1135
1130
Update.printError (Serial);
1136
1131
}
@@ -1170,8 +1165,6 @@ void setupWebserver() {
1170
1165
server.addHandler (new AsyncCallbackJsonWebHandler (" /config" , serveSaveConfig, MAX_CONFIG_FILE_SIZE));
1171
1166
server.on (" /update" , HTTP_POST, serveOTA, serveOTAUpload);
1172
1167
server.on (" /recovery" , HTTP_GET, serveRecovery);
1173
- server.on (" /abortUpdate" , abortOTA);
1174
- server.on (" /beginUpdate" , startOTA);
1175
1168
server.on (" /fullRefresh" , serveFullUpdate);
1176
1169
server.on (" /forceUpdate" , serveForceUpdate);
1177
1170
server.on (" /refreshWeather" , serveWeatherUpdate);
@@ -1187,6 +1180,7 @@ void setupWebserver() {
1187
1180
server.on (" /deleteAllImages" , serveDeleteAllImages);
1188
1181
server.on (" /renameImage" , serveRenameImage);
1189
1182
server.on (" /factoryReset" , serveFactoryReset);
1183
+ server.on (" /formatFilesystem" , serveFormatFilesystem);
1190
1184
server.on (" /resetConfiguration" , serveResetConfiguration);
1191
1185
server.serveStatic (" /" , LittleFS, " /" , CACHE_DASHBOARD ? " no-cache" : NULL );
1192
1186
server.onNotFound (serveNotFound);
@@ -2026,6 +2020,29 @@ void updateArduinoOTA() {
2026
2020
#endif
2027
2021
}
2028
2022
2023
+ void updateRestartFlags () {
2024
+ if (needsRestart && (!finalClient || finalClient->disconnected ())) {
2025
+ if (needsFormat) {
2026
+ closeFiles ();
2027
+ LittleFS.end ();
2028
+ state = STATE_DISABLED;
2029
+ disableDisplay = true ;
2030
+ DEBUG (" Formatting filesystem\n " );
2031
+ LittleFS.format ();
2032
+ }
2033
+
2034
+ if (needsFactoryReset) {
2035
+ writeDefaultConfig ();
2036
+ deleteAllImages ();
2037
+ DEBUG (" Erasing WiFi settings\n " );
2038
+ AsyncWiFiManager wifiManager (&server, &dnsServer);
2039
+ wifiManager.resetSettings ();
2040
+ }
2041
+
2042
+ ESP.restart ();
2043
+ }
2044
+ }
2045
+
2029
2046
void setup () {
2030
2047
Serial.begin (115200 );
2031
2048
Serial.println ();
@@ -2124,6 +2141,7 @@ void setup() {
2124
2141
display.showBuffer ();
2125
2142
needsConfig = true ;
2126
2143
while (needsConfig) {
2144
+ updateRestartFlags ();
2127
2145
updateArduinoOTA ();
2128
2146
updateTime ();
2129
2147
yield ();
@@ -2139,13 +2157,12 @@ void setup() {
2139
2157
}
2140
2158
2141
2159
void loop () {
2142
- if (needsRestart)
2143
- ESP.restart ();
2160
+ updateRestartFlags ();
2144
2161
2145
2162
switch (state) {
2146
2163
default :
2147
2164
Serial.printf (" Unknown state: %i/n" , state);
2148
- case STATE_UPDATING :
2165
+ case STATE_DISABLED :
2149
2166
break ;
2150
2167
case STATE_NORMAL:
2151
2168
updateTime ();
0 commit comments