diff --git a/ConfigFile.cpp b/ConfigFile.cpp index ca0e93f..f1bcd30 100644 --- a/ConfigFile.cpp +++ b/ConfigFile.cpp @@ -7,7 +7,7 @@ extern Preferences pref; -#define SHADE_HDR_VER 23 +#define SHADE_HDR_VER 24 #define SHADE_HDR_SIZE 76 #define SHADE_REC_SIZE 276 #define GROUP_REC_SIZE 200 @@ -728,12 +728,7 @@ bool ShadeConfigFile::readGroupRecord(SomfyGroup *group) { this->readString(group->name, sizeof(group->name)); group->proto = static_cast(this->readUInt8(0)); group->bitLength = this->readUInt8(56); - if(this->header.version >= 23) group->lastRollingCode = this->readUInt16(0); - if(group->getRemoteAddress() != 0) { - uint16_t rc = pref.getUShort(group->getRemotePrefId(), 0); - group->lastRollingCode = max(rc, group->lastRollingCode); - if(rc < group->lastRollingCode) pref.putUShort(group->getRemotePrefId(), group->lastRollingCode); - } + if(this->header.version == 23) group->lastRollingCode = this->readUInt16(0); uint8_t lsd = 0; memset(group->linkedShades, 0x00, sizeof(group->linkedShades)); for(uint8_t j = 0; j < SOMFY_MAX_GROUPED_SHADES; j++) { @@ -749,6 +744,13 @@ bool ShadeConfigFile::readGroupRecord(SomfyGroup *group) { else group->compressLinkedShadeIds(); if(this->header.version >= 18) group->flipCommands = this->readBool(false); if(this->header.version >= 19) group->roomId = this->readUInt8(0); + if(this->header.version >= 24) group->lastRollingCode = this->readUInt16(0); + if(group->getRemoteAddress() != 0) { + uint16_t rc = pref.getUShort(group->getRemotePrefId(), 0); + group->lastRollingCode = max(rc, group->lastRollingCode); + if(rc < group->lastRollingCode) pref.putUShort(group->getRemotePrefId(), group->lastRollingCode); + } + pref.end(); if(this->file.position() != startPos + this->header.groupRecordSize) { Serial.println("Reading to end of group record"); @@ -927,14 +929,14 @@ bool ShadeConfigFile::writeGroupRecord(SomfyGroup *group) { this->writeString(group->name, sizeof(group->name)); this->writeUInt8(static_cast(group->proto)); this->writeUInt8(group->bitLength); - this->writeUInt16(group->lastRollingCode); for(uint8_t j = 0; j < SOMFY_MAX_GROUPED_SHADES; j++) { this->writeUInt8(group->linkedShades[j]); } this->writeUInt8(group->repeats); this->writeUInt8(group->sortOrder); this->writeBool(group->flipCommands); - this->writeUInt8(group->roomId, CFG_REC_END); + this->writeUInt8(group->roomId); + this->writeUInt16(group->lastRollingCode, CFG_REC_END); return true; } bool ShadeConfigFile::writeRepeaterRecord(SomfyShadeController *s) { diff --git a/ConfigSettings.cpp b/ConfigSettings.cpp index 1194d68..a6bf603 100644 --- a/ConfigSettings.cpp +++ b/ConfigSettings.cpp @@ -658,6 +658,7 @@ void WifiSettings::printNetworks() { Serial.print(WiFi.BSSIDstr(i)); Serial.println(); } + } bool WifiSettings::ssidExists(const char *ssid) { int n = WiFi.scanNetworks(false, true); diff --git a/GitOTA.cpp b/GitOTA.cpp index 66a71ec..ac0410b 100644 --- a/GitOTA.cpp +++ b/GitOTA.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include "GitOTA.h" #include "Utils.h" #include "ConfigSettings.h" @@ -105,6 +106,7 @@ int16_t GitRepo::getReleases(uint8_t num) { HTTPClient https; https.setReuse(false); if(https.begin(sclient, url)) { + esp_task_wdt_reset(); int httpCode = https.GET(); Serial.printf("[HTTPS] GET... code: %d\n", httpCode); if(httpCode > 0) { @@ -125,6 +127,7 @@ int16_t GitRepo::getReleases(uint8_t num) { while(https.connected() && (len > 0 || len == -1) && ndx < count) { size_t size = stream->available(); if(size) { + esp_task_wdt_reset(); int c = stream->readBytes(buff, ((size > sizeof(buff)) ? sizeof(buff) : size)); //Serial.write(buff, c); if(len > 0) len -= c; @@ -347,6 +350,7 @@ int GitUpdater::checkInternet() { WiFiClientSecure sclient; sclient.setInsecure(); sclient.setHandshakeTimeout(3); + esp_task_wdt_reset(); HTTPClient https; https.setReuse(false); if(https.begin(sclient, "https://github.com/rstrouse/ESPSomfy-RTS")) { @@ -366,6 +370,7 @@ int GitUpdater::checkInternet() { https.end(); sclient.stop(); } + esp_task_wdt_reset(); return err; } void GitUpdater::emitDownloadProgress(size_t total, size_t loaded, const char *evt) { this->emitDownloadProgress(255, total, loaded, evt); } @@ -467,6 +472,7 @@ int8_t GitUpdater::downloadFile() { char url[196]; sprintf(url, "%s%s", this->baseUrl, this->currentFile); Serial.println(url); + esp_task_wdt_reset(); if(https.begin(sclient, url)) { https.setFollowRedirects(HTTPC_FORCE_FOLLOW_REDIRECTS); Serial.print("[HTTPS] GET...\n"); @@ -491,6 +497,7 @@ int8_t GitUpdater::downloadFile() { while(https.connected() && (len > 0 || len == -1) && total < len) { size_t size = stream->available(); if(size) { + esp_task_wdt_reset(); if(this->cancelled && !this->lockFS) { Update.abort(); free(buff); @@ -569,5 +576,6 @@ int8_t GitUpdater::downloadFile() { sclient.stop(); Serial.printf("End update %s\n", this->currentFile); } + esp_task_wdt_reset(); return 0; } diff --git a/Network.cpp b/Network.cpp index 54459b6..728894b 100644 --- a/Network.cpp +++ b/Network.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include "ConfigSettings.h" #include "Network.h" #include "Web.h" @@ -520,7 +521,9 @@ bool Network::getStrongestAP(const char *ssid, uint8_t *bssid, int32_t *channel) int32_t strength = this->connected() ? WiFi.RSSI() + 10 : -127; int32_t chan = -1; memset(bssid, 0x00, 6); + esp_task_wdt_delete(NULL); uint8_t n = this->connected() ? WiFi.scanComplete() : WiFi.scanNetworks(false, false, false, 300, 0, ssid); + esp_task_wdt_add(NULL); for(uint8_t i = 0; i < n; i++) { if(WiFi.SSID(i).compareTo(ssid) == 0) { if(WiFi.RSSI(i) > strength) { @@ -533,9 +536,12 @@ bool Network::getStrongestAP(const char *ssid, uint8_t *bssid, int32_t *channel) WiFi.scanDelete(); return chan > 0; } +/* int Network::getStrengthBySSID(const char *ssid) { int32_t strength = -100; - int n = WiFi.scanNetworks(false, false); + esp_task_wdt_delete(NULL); + int n = WiFi.scanNetworks(false, false, false, 300, 0, ssid); + esp_task_wdt_add(NULL); for(int i = 0; i < n; i++) { if(WiFi.SSID(i).compareTo(ssid) == 0) strength = max(WiFi.RSSI(i), strength); } @@ -564,6 +570,7 @@ int Network::getStrengthBySSID(const char *ssid) { } return strength; } +*/ bool Network::openSoftAP() { Serial.println(); Serial.println("Turning the HotSpot On"); @@ -624,6 +631,7 @@ bool Network::openSoftAP() { Serial.println(); c = 0; } + esp_task_wdt_reset(); yield(); } return true; diff --git a/Network.h b/Network.h index 9025b73..d05d664 100644 --- a/Network.h +++ b/Network.h @@ -37,7 +37,7 @@ class Network { bool getStrongestAP(const char *ssid, uint8_t *bssid, int32_t *channel); bool changeAP(const uint8_t *bssid, const int32_t channel); //int getStrengthByMac(const char *mac); - int getStrengthBySSID(const char *ssid); + //int getStrengthBySSID(const char *ssid); void updateHostname(); bool setup(); void loop(); diff --git a/SomfyController.ino b/SomfyController.ino index a814649..129ef04 100644 --- a/SomfyController.ino +++ b/SomfyController.ino @@ -1,5 +1,6 @@ #include #include +#include #include "ConfigSettings.h" #include "Network.h" #include "Web.h" @@ -36,6 +37,9 @@ void setup() { net.setup(); somfy.begin(); //git.checkForUpdate(); + esp_task_wdt_init(5, true); //enable panic so ESP32 restarts + esp_task_wdt_add(NULL); //add current thread to WDT watch + } void loop() { @@ -48,6 +52,7 @@ void loop() { ESP.restart(); } uint32_t timing = millis(); + net.loop(); if(millis() - timing > 100) Serial.printf("Timing Net: %ldms\n", millis() - timing); timing = millis(); @@ -67,6 +72,8 @@ void loop() { net.end(); ESP.restart(); } + esp_task_wdt_reset(); + /* if(heap < oldheap) { Serial.print("Heap: "); diff --git a/SomfyController.ino.esp32.bin b/SomfyController.ino.esp32.bin index ba757ee..f9ed802 100644 Binary files a/SomfyController.ino.esp32.bin and b/SomfyController.ino.esp32.bin differ diff --git a/SomfyController.ino.esp32s3.bin b/SomfyController.ino.esp32s3.bin index 9ba9049..369cad0 100644 Binary files a/SomfyController.ino.esp32s3.bin and b/SomfyController.ino.esp32s3.bin differ diff --git a/Web.cpp b/Web.cpp index 89621e0..bd056ba 100644 --- a/Web.cpp +++ b/Web.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include "mbedtls/md.h" #include "ConfigSettings.h" #include "ConfigFile.h" @@ -227,42 +228,6 @@ void Web::handleStreamFile(WebServer &server, const char *filename, const char * server.streamFile(file, encoding); file.close(); } -/* -void Web::chunkGroupResponse(WebServer &server, SomfyGroup * grp, const char *prefix) { - grp->updateFlags(); - snprintf(g_content, sizeof(g_content), "%s{\"groupId\":%d,\"roomId\":%d,\"name\":\"%s\",\"remoteAddress\":%d,\"lastRollingCode\":%d,\"bitLength\":%d,\"proto\":%d,\"sunSensor\":%s,\"flipCommands\":%s,\"flags\":%d,\"repeats\":%d,\"sortOrder\":%d,\"linkedShades\":[ ", - prefix ? prefix : "", grp->getGroupId(), grp->roomId, grp->name, grp->getRemoteAddress(), grp->lastRollingCode, grp->bitLength, static_cast(grp->proto), grp->hasSunSensor() ? "true" : "false", grp->flipCommands ? "true" : "false", grp->flags, grp->repeats, grp->sortOrder); - server.sendContent(g_content); - uint8_t n = 0; - for(uint8_t i = 0; i < SOMFY_MAX_GROUPED_SHADES; i++) { - uint8_t shadeId = grp->linkedShades[i]; - if(shadeId > 0 && shadeId < 255) { - SomfyShade *shade = somfy.getShadeById(shadeId); - if(shade) { - snprintf(g_content, sizeof(g_content), "%s{\"shadeId\":%d,\"roomId\":%d,\"name\":\"%s\",\"remoteAddress\":%d,\"paired\":%s,\"shadeType\":%d,\"bitLength\":%d,\"proto\":%d,\"flags\":%d,\"sunSensor\":%s,\"hasLight\":%s,\"repeats\":%d}", - n == 0 ? "" : ",", shade->getShadeId(), shade->roomId, shade->name, shade->getRemoteAddress(), shade->paired ? "true" : "false", static_cast(shade->shadeType), shade->bitLength, static_cast(shade->proto), shade->flags, - shade->hasSunSensor() ? "true" : "false", shade->hasLight() ? "true" : "false", shade->repeats); - server.sendContent(g_content); - n++; - } - } - } - server.sendContent("]}"); -} -void Web::chunkGroupsResponse(WebServer &server, const char * elem) { - uint8_t ndx = 0; - if(elem && strlen(elem) > 0) { - sprintf(g_content, "\"%s\":", elem); - server.sendContent(g_content); - } - for(uint8_t i = 0; i < SOMFY_MAX_GROUPS; i++) { - if(somfy.groups[i].getGroupId() != 255) { - this->chunkGroupResponse(server, &somfy.groups[i], ndx++ != 0 ? "," : "["); - } - } - server.sendContent(ndx == 0 ? "[]" : "]"); -} -*/ void Web::handleController(WebServer &server) { webServer.sendCORSHeaders(server); if(server.method() == HTTP_OPTIONS) { server.send(200, "OK"); return; } @@ -1181,6 +1146,7 @@ void Web::begin() { rebootDelay.rebootTime = millis() + 1000; } }, []() { + esp_task_wdt_reset(); HTTPUpload& upload = server.upload(); if (upload.status == UPLOAD_FILE_START) { webServer.uploadSuccess = false; @@ -1191,12 +1157,15 @@ void Web::begin() { } else if (upload.status == UPLOAD_FILE_WRITE) { File fup = LittleFS.open("/shades.tmp", "a"); + //upload.buf[upload.currentSize] = 0x00; + //Serial.print((char *)upload.buf); fup.write(upload.buf, upload.currentSize); fup.close(); } else if (upload.status == UPLOAD_FILE_END) { webServer.uploadSuccess = true; } + }); server.on("/index.js", []() { webServer.sendCacheHeaders(604800); webServer.handleStreamFile(server, "/index.js", "text/javascript"); }); server.on("/main.css", []() { webServer.sendCacheHeaders(604800); webServer.handleStreamFile(server, "/main.css", "text/css"); }); @@ -2104,6 +2073,7 @@ void Web::begin() { Update.printError(Serial); } } + esp_task_wdt_reset(); }); server.on("/updateShadeConfig", HTTP_POST, []() { if(git.lockFS) { @@ -2181,11 +2151,17 @@ void Web::begin() { Update.printError(Serial); } } + esp_task_wdt_reset(); }); server.on("/scanaps", []() { webServer.sendCORSHeaders(server); + esp_task_wdt_reset(); + if(server.method() == HTTP_OPTIONS) { server.send(200, "OK"); return; } + esp_task_wdt_delete(NULL); int n = WiFi.scanNetworks(); + esp_task_wdt_add(NULL); + Serial.print("Scanned "); Serial.print(n); Serial.println(" networks"); diff --git a/data/index.js b/data/index.js index 56c79a3..8a9b1c7 100644 --- a/data/index.js +++ b/data/index.js @@ -4200,7 +4200,7 @@ class Firmware { init() { this.initialized = true; } isMobile() { let agt = navigator.userAgent.toLowerCase(); - return /Android|iPhone|iPod|BlackBerry|BB|PlayBook|IEMobile|Windows Phone|Kindle|Silk|Opera Mini/i.test(navigator.userAgent); + return /Android|iPhone|iPad|iPod|BlackBerry|BB|PlayBook|IEMobile|Windows Phone|Kindle|Silk|Opera Mini/i.test(navigator.userAgent); } async backup() { let overlay = ui.waitMessage(document.getElementById('divContainer'));