Add FS recovery for failed FS updates.

This commit is contained in:
Robert Strouse 2024-01-06 11:28:03 -08:00
parent 2bb23e6d3e
commit a3cb1d63fe
6 changed files with 41 additions and 4 deletions

View file

@ -372,20 +372,38 @@ bool GitUpdater::beginUpdate(const char *version) {
somfy.commit(); somfy.commit();
strcpy(this->currentFile, "SomfyController.littlefs.bin"); strcpy(this->currentFile, "SomfyController.littlefs.bin");
this->partition = U_SPIFFS; this->partition = U_SPIFFS;
this->lockFS = true;
this->error = this->downloadFile(); this->error = this->downloadFile();
this->lockFS = false;
if(this->error == 0) { if(this->error == 0) {
settings.fwVersion.parse(version); settings.fwVersion.parse(version);
delay(100); delay(100);
Serial.println("Committing Configuration..."); Serial.println("Committing Configuration...");
somfy.commit(); somfy.commit();
rebootDelay.reboot = true;
rebootDelay.rebootTime = millis() + 500;
} }
rebootDelay.reboot = true;
rebootDelay.rebootTime = millis() + 500;
} }
this->status = GIT_UPDATE_COMPLETE; this->status = GIT_UPDATE_COMPLETE;
this->emitUpdateCheck(); this->emitUpdateCheck();
return true; return true;
} }
bool GitUpdater::recoverFilesystem() {
sprintf(this->baseUrl, "https://github.com/rstrouse/ESPSomfy-RTS/releases/download/%s/", settings.fwVersion.name);
strcpy(this->currentFile, "SomfyController.littlefs.bin");
this->partition = U_SPIFFS;
this->lockFS = true;
this->error = this->downloadFile();
this->lockFS = false;
if(this->error == 0) {
delay(100);
Serial.println("Committing Configuration...");
somfy.commit();
}
rebootDelay.reboot = true;
rebootDelay.rebootTime = millis() + 500;
return true;
}
bool GitUpdater::endUpdate() { return true; } bool GitUpdater::endUpdate() { return true; }
int8_t GitUpdater::downloadFile() { int8_t GitUpdater::downloadFile() {
WiFiClientSecure *client = new WiFiClientSecure; WiFiClientSecure *client = new WiFiClientSecure;
@ -457,7 +475,7 @@ int8_t GitUpdater::downloadFile() {
} }
else { else {
timeouts++; timeouts++;
if(timeouts >= 300) { if(timeouts >= 500) {
Update.abort(); Update.abort();
https.end(); https.end();
free(buff); free(buff);

View file

@ -37,6 +37,7 @@ class GitRepo {
}; };
class GitUpdater { class GitUpdater {
public: public:
bool lockFS = false;
uint8_t status = 0; uint8_t status = 0;
uint32_t lastCheck = 0; uint32_t lastCheck = 0;
bool updateAvailable = false; bool updateAvailable = false;
@ -55,6 +56,7 @@ class GitUpdater {
void setCurrentRelease(GitRepo &repo); void setCurrentRelease(GitRepo &repo);
void loop(); void loop();
void toJSON(JsonObject &obj); void toJSON(JsonObject &obj);
bool recoverFilesystem();
int checkInternet(); int checkInternet();
void emitUpdateCheck(uint8_t num=255); void emitUpdateCheck(uint8_t num=255);
void emitDownloadProgress(size_t total, size_t loaded, const char *evt = "updateProgress"); void emitDownloadProgress(size_t total, size_t loaded, const char *evt = "updateProgress");

View file

@ -7,12 +7,14 @@
#include "Sockets.h" #include "Sockets.h"
#include "MQTT.h" #include "MQTT.h"
#include "ConfigFile.h" #include "ConfigFile.h"
#include "GitOTA.h"
extern Preferences pref; extern Preferences pref;
extern SomfyShadeController somfy; extern SomfyShadeController somfy;
extern SocketEmitter sockEmit; extern SocketEmitter sockEmit;
extern ConfigSettings settings; extern ConfigSettings settings;
extern MQTTClass mqtt; extern MQTTClass mqtt;
extern GitUpdater git;
uint8_t rxmode = 0; // Indicates whether the radio is in receive mode. Just to ensure there isn't more than one interrupt hooked. uint8_t rxmode = 0; // Indicates whether the radio is in receive mode. Just to ensure there isn't more than one interrupt hooked.
@ -545,6 +547,7 @@ bool SomfyShadeController::begin() {
return true; return true;
} }
void SomfyShadeController::commit() { void SomfyShadeController::commit() {
if(git.lockFS) return;
ShadeConfigFile file; ShadeConfigFile file;
file.begin(); file.begin();
file.save(this); file.save(this);
@ -553,6 +556,7 @@ void SomfyShadeController::commit() {
this->lastCommit = millis(); this->lastCommit = millis();
} }
void SomfyShadeController::writeBackup() { void SomfyShadeController::writeBackup() {
if(git.lockFS) return;
ShadeConfigFile file; ShadeConfigFile file;
file.begin("/controller.backup", false); file.begin("/controller.backup", false);
file.backup(this); file.backup(this);

Binary file not shown.

Binary file not shown.

15
Web.cpp
View file

@ -203,6 +203,10 @@ void Web::handleLogin(WebServer &server) {
return; return;
} }
void Web::handleStreamFile(WebServer &server, const char *filename, const char *encoding) { void Web::handleStreamFile(WebServer &server, const char *filename, const char *encoding) {
if(git.lockFS) {
server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"Filesystem update in progress\"}"));
return;
}
webServer.sendCORSHeaders(server); webServer.sendCORSHeaders(server);
if(server.method() == HTTP_OPTIONS) { server.send(200, "OK"); return; } if(server.method() == HTTP_OPTIONS) { server.send(200, "OK"); return; }
@ -1883,6 +1887,10 @@ void Web::begin() {
} }
}); });
server.on("/updateShadeConfig", HTTP_POST, []() { server.on("/updateShadeConfig", HTTP_POST, []() {
if(git.lockFS) {
server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"Filesystem update in progress\"}"));
return;
}
webServer.sendCORSHeaders(server); webServer.sendCORSHeaders(server);
if(server.method() == HTTP_OPTIONS) { server.send(200, "OK"); return; } if(server.method() == HTTP_OPTIONS) { server.send(200, "OK"); return; }
server.sendHeader("Connection", "close"); server.sendHeader("Connection", "close");
@ -2438,7 +2446,12 @@ void Web::begin() {
serializeJson(doc, g_content); serializeJson(doc, g_content);
server.send(200, _encoding_json, g_content); server.send(200, _encoding_json, g_content);
}); });
server.on("/recoverFilesystem", [] () {
if(server.method() == HTTP_OPTIONS) { server.send(200, "OK"); return; }
webServer.sendCORSHeaders(server);
git.recoverFilesystem();
server.send(200, "application/json", "{\"status\":\"OK\",\"desc\":\"Recovering filesystem from github please wait!!!\"}");
});
server.begin(); server.begin();
apiServer.begin(); apiServer.begin();
} }