diff --git a/GitOTA.cpp b/GitOTA.cpp index 289fa46..e0ceb85 100644 --- a/GitOTA.cpp +++ b/GitOTA.cpp @@ -19,6 +19,7 @@ extern rebootDelay_t rebootDelay; extern Web webServer; + #define MAX_BUFF_SIZE 4096 void GitRelease::setReleaseProperty(const char *key, const char *val) { if(strcmp(key, "id") == 0) this->id = atol(val); @@ -115,16 +116,16 @@ int16_t GitRepo::getReleases(uint8_t num) { strcpy(main->version.name, "main"); strcpy(main->name, "Main"); strcpy(main->hwVersions, "32,s3"); - HTTPClient *https = new HTTPClient(); - https->setReuse(false); - if(https->begin(sclient, url)) { - int httpCode = https->GET(); + HTTPClient https; + https.setReuse(false); + if(https.begin(sclient, url)) { + int httpCode = https.GET(); Serial.printf("[HTTPS] GET... code: %d\n", httpCode); if(httpCode > 0) { - int len = https->getSize(); + int len = https.getSize(); Serial.printf("[HTTPS] GET... code: %d - %d\n", httpCode, len); if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) { - WiFiClient *stream = https->getStreamPtr(); + WiFiClient *stream = https.getStreamPtr(); uint8_t buff[128] = {0}; char jsonElem[32] = ""; char jsonValue[128] = ""; @@ -135,7 +136,7 @@ int16_t GitRepo::getReleases(uint8_t num) { bool inValue = false; bool awaitValue = false; bool inAss = false; - while(https->connected() && (len > 0 || len == -1) && ndx < count) { + while(https.connected() && (len > 0 || len == -1) && ndx < count) { size_t size = stream->available(); if(size) { int c = stream->readBytes(buff, ((size > sizeof(buff)) ? sizeof(buff) : size)); @@ -226,16 +227,14 @@ int16_t GitRepo::getReleases(uint8_t num) { } } else { - https->end(); - sclient.stop(); - delete https; + https.end(); + //sclient.stop(); return httpCode; } } - https->end(); - delete https; + https.end(); + sclient.stop(); } - sclient.stop(); settings.printAvailHeap(); return 0; } @@ -399,15 +398,15 @@ void GitUpdater::emitUpdateCheck(uint8_t num) { int GitUpdater::checkInternet() { int err = 500; uint32_t t = millis(); - WiFiClientSecure client; - client.setInsecure(); - client.setHandshakeTimeout(3); - HTTPClient *https = new HTTPClient(); - https->setReuse(false); - if(https->begin(client, "https://github.com/rstrouse/ESPSomfy-RTS")) { - https->setFollowRedirects(HTTPC_FORCE_FOLLOW_REDIRECTS); - https->setTimeout(5000); - int httpCode = https->sendRequest("HEAD"); + WiFiClientSecure sclient; + sclient.setInsecure(); + sclient.setHandshakeTimeout(3); + HTTPClient https; + https.setReuse(false); + if(https.begin(sclient, "https://github.com/rstrouse/ESPSomfy-RTS")) { + https.setFollowRedirects(HTTPC_FORCE_FOLLOW_REDIRECTS); + https.setTimeout(5000); + int httpCode = https.sendRequest("HEAD"); if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY || httpCode == HTTP_CODE_FOUND) { err = 0; Serial.printf("Internet is Available: %ldms\n", millis() - t); @@ -418,10 +417,9 @@ int GitUpdater::checkInternet() { Serial.printf("Internet is Unavailable: %d: %ldms\n", err, millis() - t); this->inetAvailable = false; } - https->end(); + https.end(); + sclient.stop(); } - client.stop(); - delete https; return err; } void GitUpdater::emitDownloadProgress(size_t total, size_t loaded, const char *evt) { this->emitDownloadProgress(255, total, loaded, evt); } @@ -516,119 +514,114 @@ bool GitUpdater::recoverFilesystem() { } bool GitUpdater::endUpdate() { return true; } int8_t GitUpdater::downloadFile() { - WiFiClientSecure *client = new WiFiClientSecure; Serial.printf("Begin update %s\n", this->currentFile); - if(client) { - client->setInsecure(); - HTTPClient https; - char url[196]; - sprintf(url, "%s%s", this->baseUrl, this->currentFile); - Serial.println(url); - if(https.begin(*client, url)) { - https.setFollowRedirects(HTTPC_FORCE_FOLLOW_REDIRECTS); - Serial.print("[HTTPS] GET...\n"); - int httpCode = https.GET(); - if(httpCode > 0) { - size_t len = https.getSize(); - size_t total = 0; - uint8_t pct = 0; - Serial.printf("[HTTPS] GET... code: %d - %d\n", httpCode, len); - if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY || httpCode == HTTP_CODE_FOUND) { - WiFiClient *stream = https.getStreamPtr(); - if(!Update.begin(len, this->partition)) { - Serial.println("Update Error detected!!!!!"); - Update.printError(Serial); - https.end(); - return -(Update.getError() + UPDATE_ERR_OFFSET); - } - uint8_t *buff = (uint8_t *)malloc(MAX_BUFF_SIZE); - if(buff) { - this->emitDownloadProgress(len, total); - int timeouts = 0; - while(https.connected() && (len > 0 || len == -1) && total < len) { - size_t size = stream->available(); - if(size) { - if(this->cancelled && !this->lockFS) { - Update.abort(); - https.end(); - free(buff); - return -(Update.getError() + UPDATE_ERR_OFFSET); - } - int c = stream->readBytes(buff, ((size > MAX_BUFF_SIZE) ? MAX_BUFF_SIZE : size)); - total += c; - //Serial.println(total); - if (Update.write(buff, c) != c) { + WiFiClientSecure sclient; + sclient.setInsecure(); + HTTPClient https; + char url[196]; + sprintf(url, "%s%s", this->baseUrl, this->currentFile); + Serial.println(url); + if(https.begin(sclient, url)) { + https.setFollowRedirects(HTTPC_FORCE_FOLLOW_REDIRECTS); + Serial.print("[HTTPS] GET...\n"); + int httpCode = https.GET(); + if(httpCode > 0) { + size_t len = https.getSize(); + size_t total = 0; + uint8_t pct = 0; + Serial.printf("[HTTPS] GET... code: %d - %d\n", httpCode, len); + if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY || httpCode == HTTP_CODE_FOUND) { + WiFiClient *stream = https.getStreamPtr(); + if(!Update.begin(len, this->partition)) { + Serial.println("Update Error detected!!!!!"); + Update.printError(Serial); + https.end(); + return -(Update.getError() + UPDATE_ERR_OFFSET); + } + uint8_t *buff = (uint8_t *)malloc(MAX_BUFF_SIZE); + if(buff) { + this->emitDownloadProgress(len, total); + int timeouts = 0; + while(https.connected() && (len > 0 || len == -1) && total < len) { + size_t size = stream->available(); + if(size) { + if(this->cancelled && !this->lockFS) { + Update.abort(); + free(buff); + https.end(); + return -(Update.getError() + UPDATE_ERR_OFFSET); + } + int c = stream->readBytes(buff, ((size > MAX_BUFF_SIZE) ? MAX_BUFF_SIZE : size)); + total += c; + //Serial.println(total); + if (Update.write(buff, c) != c) { + Update.printError(Serial); + Serial.printf("Upload of %s aborted invalid size %d\n", url, c); + free(buff); + https.end(); + sclient.stop(); + return -(Update.getError() + UPDATE_ERR_OFFSET); + } + // Calculate the percentage. + uint8_t p = (uint8_t)floor(((float)total / (float)len) * 100.0f); + if(p != pct) { + pct = p; + Serial.printf("LEN:%d TOTAL:%d %d%%\n", len, total, pct); + this->emitDownloadProgress(len, total); + } + delay(1); + if(total >= len) { + if(!Update.end(true)) { + Serial.println("Error downloading update..."); Update.printError(Serial); - Serial.printf("Upload of %s aborted invalid size %d\n", url, c); - free(buff); - https.end(); - return -(Update.getError() + UPDATE_ERR_OFFSET); } - // Calculate the percentage. - uint8_t p = (uint8_t)floor(((float)total / (float)len) * 100.0f); - if(p != pct) { - pct = p; - Serial.printf("LEN:%d TOTAL:%d %d%%\n", len, total, pct); - this->emitDownloadProgress(len, total); + else { + Serial.println("Update.end Called..."); } - delay(1); - if(total >= len) { - if(!Update.end(true)) { - Serial.println("Error downloading update..."); - Update.printError(Serial); - } - else { - Serial.println("Update.end Called..."); - } - https.end(); - } - } - else { - timeouts++; - if(timeouts >= 500) { - Update.abort(); - https.end(); - free(buff); - Serial.println("Stream timeout!!!"); - return -43; - } - sockEmit.loop(); - webServer.loop(); - delay(100); + https.end(); + sclient.stop(); } } - free(buff); - if(len > total) { - Update.abort(); - somfy.commit(); - Serial.println("Error downloading file!!!"); - return -42; - + else { + timeouts++; + if(timeouts >= 500) { + Update.abort(); + https.end(); + free(buff); + Serial.println("Stream timeout!!!"); + return -43; + } + sockEmit.loop(); + webServer.loop(); + delay(100); } - else - Serial.printf("Update %s complete\n", this->currentFile); - } - else { - // TODO: memory allocation error. - Serial.println("Unable to allocate memory for update!!!"); + free(buff); + if(len > total) { + Update.abort(); + somfy.commit(); + Serial.println("Error downloading file!!!"); + return -42; } + else + Serial.printf("Update %s complete\n", this->currentFile); } else { - Serial.printf("Invalid HTTP Code... %d", httpCode); - return httpCode; + // TODO: memory allocation error. + Serial.println("Unable to allocate memory for update!!!"); } - } - else { - Serial.printf("Invalid HTTP Code: %d\n", httpCode); } - - if(https.connected()) https.end(); - Serial.printf("End update %s\n", this->currentFile); - + else { + Serial.printf("Invalid HTTP Code... %d", httpCode); + return httpCode; + } + } + else { + Serial.printf("Invalid HTTP Code: %d\n", httpCode); } - client->stop(); - delete client; + https.end(); + sclient.stop(); + Serial.printf("End update %s\n", this->currentFile); } return 0; } diff --git a/Network.cpp b/Network.cpp index 9b8bd11..45c7d74 100644 --- a/Network.cpp +++ b/Network.cpp @@ -17,12 +17,13 @@ extern rebootDelay_t rebootDelay; extern Network net; static bool _apScanning = false; +static uint32_t _lastMaxHeap = 0; static uint32_t _lastHeap = 0; int connectRetries = 0; void Network::end() { - sockEmit.end(); SSDP.end(); mqtt.end(); + sockEmit.end(); delay(100); } bool Network::setup() { @@ -39,7 +40,6 @@ bool Network::setup() { WiFi.mode(WIFI_STA); settings.WIFI.printNetworks(); } - sockEmit.begin(); if(!this->connect()) this->openSoftAP(); return true; } @@ -62,6 +62,7 @@ void Network::loop() { this->lastEmit = millis(); if(!this->connected()) return; } + sockEmit.loop(); if(this->connected() && millis() - this->lastMDNS > 60000) { // We are doing this every 60 seconds because of the BS related to // the MDNS library. The original library required manual updates @@ -87,7 +88,6 @@ void Network::loop() { else { uint16_t n = WiFi.scanComplete(); if( n > 0) { - _apScanning = false; uint8_t bssid[6]; int32_t channel = 0; if(this->getStrongestAP(settings.WIFI.ssid, bssid, &channel)) { @@ -96,6 +96,7 @@ void Network::loop() { this->changeAP(bssid, channel); } } + _apScanning = false; } } } @@ -109,6 +110,7 @@ void Network::loop() { bool Network::changeAP(const uint8_t *bssid, const int32_t channel) { if(SSDP.isStarted) SSDP.end(); mqtt.disconnect(); + sockEmit.end(); WiFi.disconnect(false, true); WiFi.begin(settings.WIFI.ssid, settings.WIFI.passphrase, channel, bssid); uint8_t retries = 0; @@ -248,6 +250,7 @@ void Network::setConnected(conn_types connType) { } this->wifiFallback = false; } + sockEmit.begin(); if(this->connectAttempts == 1) { Serial.println(); if(this->connType == conn_types::wifi) { @@ -365,6 +368,7 @@ bool Network::connectWired() { //if(this->connType == conn_types::ethernet && ETH.linkUp()) { if(ETH.linkUp()) { if(WiFi.status() == WL_CONNECTED) { + sockEmit.end(); WiFi.disconnect(true); WiFi.mode(WIFI_OFF); } @@ -637,7 +641,7 @@ bool Network::openSoftAP() { //pinMode(D0, INPUT_PULLUP); long startTime = millis(); int c = 0; - + sockEmit.begin(); while (!this->connected()) { int clients = WiFi.softAPgetStationNum(); @@ -748,13 +752,15 @@ void Network::networkEvent(WiFiEvent_t event) { } } void Network::emitHeap(uint8_t num) { - if(num != 255 || this->needsBroadcast || ESP.getMaxAllocHeap() != _lastHeap) { - _lastHeap = ESP.getMaxAllocHeap(); + if(num != 255 || this->needsBroadcast || (ESP.getMaxAllocHeap() != _lastMaxHeap || ESP.getFreeHeap() != _lastHeap)) { + _lastMaxHeap = ESP.getMaxAllocHeap(); + _lastHeap = ESP.getFreeHeap(); JsonSockEvent *json = sockEmit.beginEmit("memStatus"); json->beginObject(); - json->addElem("max", _lastHeap); - json->addElem("free", ESP.getFreeHeap()); + json->addElem("max", _lastMaxHeap); + json->addElem("free", _lastHeap); json->addElem("min", ESP.getMinFreeHeap()); + json->addElem("total", ESP.getHeapSize()); json->endObject(); sockEmit.endEmit(num); } diff --git a/SSDP.cpp b/SSDP.cpp index e8c871d..6f76a1f 100644 --- a/SSDP.cpp +++ b/SSDP.cpp @@ -418,28 +418,6 @@ void SSDPClass::_sendResponse(IPAddress addr, uint16_t port, UPNPDeviceType *d, buffer[sizeof(buffer) - 1] = '\0'; this->_sendResponse(addr, port, buffer); free(pbuff); -/* -static const char _ssdp_packet_template[] PROGMEM = - "%s" // _ssdp_response_template / _ssdp_notify_template - "CACHE-CONTROL: max-age=%u\r\n" // _interval - "SERVER: Arduino/1.0 UPNP/1.1 %s/%s\r\n" // _modelName, _modelNumber - "USN: %s\r\n" // _uuid - "%s: %s\r\n" // "NT" or "ST", _deviceType - "LOCATION: http://%u.%u.%u.%u:%u/%s\r\n" // WiFi.localIP(), _port, _schemaURL - "\r\n"; - - - - #ifdef DEBUG_SSDP - DEBUG_SSDP.print("Sending Response to "); - DEBUG_SSDP.print(IPAddress(addr)); - DEBUG_SSDP.print(":"); - DEBUG_SSDP.println(port); - DEBUG_SSDP.println(buffer); - #endif - - _server.writeTo((const uint8_t *)buffer, len, addr, port); - */ } void SSDPClass::_sendResponse(IPAddress addr, uint16_t port, const char *buff) { #ifdef DEBUG_SSDP @@ -545,6 +523,7 @@ void SSDPClass::_sendNotify(UPNPDeviceType *d, bool root) { ip[0], ip[1], ip[2], ip[3], _port, d->schemaURL, this->bootId, this->configId); this->_sendNotify(buffer); d->lastNotified = millis(); + free(pbuff); } void SSDPClass::setActive(uint8_t ndx, bool isActive) { UPNPDeviceType *d = &this->deviceTypes[ndx]; diff --git a/Sockets.cpp b/Sockets.cpp index ab028f8..66b4279 100644 --- a/Sockets.cpp +++ b/Sockets.cpp @@ -79,6 +79,7 @@ void SocketEmitter::begin() { settings.printAvailHeap(); } void SocketEmitter::loop() { + this->initClients(); sockServer.loop(); } /* @@ -175,7 +176,7 @@ JsonSockEvent *SocketEmitter::beginEmit(const char *evt) { this->json.beginEvent(&sockServer, evt, g_response, sizeof(g_response)); return &this->json; } -void SocketEmitter::endEmit(uint8_t num) { sockServer.loop(); this->json.endEvent(num); } +void SocketEmitter::endEmit(uint8_t num) { this->json.endEvent(num); sockServer.loop(); } void SocketEmitter::endEmitRoom(uint8_t room) { if(room < SOCK_MAX_ROOMS) { room_t *r = &this->rooms[room]; @@ -228,6 +229,30 @@ bool SocketEmitter::sendToClients(const char *evt, JsonDocument &doc) { return sockServer.broadcastTXT(this->evt.msg); } */ +void SocketEmitter::initClients() { + for(uint8_t i = 0; i < sizeof(this->newClients); i++) { + uint8_t num = this->newClients[i]; + if(num != 255) { + if(sockServer.clientIsConnected(num)) { + Serial.printf("Initializing Socket Client %u\n", num); + settings.emitSockets(num); + somfy.emitState(num); + git.emitUpdateCheck(num); + net.emitSockets(num); + } + this->newClients[i] = 255; + } + } +} +void SocketEmitter::delayInit(uint8_t num) { + for(uint8_t i=0; i < sizeof(this->newClients); i++) { + if(this->newClients[i] == num) break; + else if(this->newClients[i] == 255) { + this->newClients[i] = num; + break; + } + } +} void SocketEmitter::end() { sockServer.close(); } void SocketEmitter::disconnect() { sockServer.disconnect(); } void SocketEmitter::wsEvent(uint8_t num, WStype_t type, uint8_t *payload, size_t length) { @@ -253,13 +278,8 @@ void SocketEmitter::wsEvent(uint8_t num, WStype_t type, uint8_t *payload, size_t Serial.printf("Socket [%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload); // Send all the current shade settings to the client. sockServer.sendTXT(num, "Connected"); - sockServer.loop(); - settings.emitSockets(num); - somfy.emitState(num); - git.emitUpdateCheck(num); - net.emitSockets(num); - sockServer.loop(); - net.needsBroadcast = true; + //sockServer.loop(); + sockEmit.delayInit(num); } break; case WStype_TEXT: diff --git a/Sockets.h b/Sockets.h index 9c7c0a9..f5336c3 100644 --- a/Sockets.h +++ b/Sockets.h @@ -68,11 +68,16 @@ class ClientSocketEvent { }; */ class SocketEmitter { + protected: + uint8_t newclients = 0; + uint8_t newClients[5] = {255,255,255,255,255}; + void delayInit(uint8_t num); public: JsonSockEvent json; //ClientSocketEvent evt; room_t rooms[SOCK_MAX_ROOMS]; uint8_t activeClients(uint8_t room); + void initClients(); void startup(); void begin(); void loop(); diff --git a/Somfy.cpp b/Somfy.cpp index 0371d09..c929d8c 100644 --- a/Somfy.cpp +++ b/Somfy.cpp @@ -1925,6 +1925,7 @@ void SomfyRoom::emitState(uint8_t num, const char *evt) { } void SomfyGroup::emitState(const char *evt) { this->emitState(255, evt); } void SomfyGroup::emitState(uint8_t num, const char *evt) { + uint8_t flags = 0; JsonSockEvent *json = sockEmit.beginEmit(evt); json->beginObject(); json->addElem("groupId", this->groupId); @@ -1936,9 +1937,11 @@ void SomfyGroup::emitState(uint8_t num, const char *evt) { if(this->linkedShades[i] != 255 && this->linkedShades[i] != 0) { SomfyShade *shade = somfy.getShadeById(this->linkedShades[i]); if(shade) json->addElem(this->linkedShades[i]); + flags |= shade->flags; } } json->endArray(); + json->addElem("flags", flags); json->endObject(); sockEmit.endEmit(num); /* diff --git a/SomfyController.ino.esp32.bin b/SomfyController.ino.esp32.bin index 4cdbb66..2df4380 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 23cd4db..53e2c5b 100644 Binary files a/SomfyController.ino.esp32s3.bin and b/SomfyController.ino.esp32s3.bin differ diff --git a/SomfyController.littlefs.bin b/SomfyController.littlefs.bin index 1227b62..55ccfdb 100644 Binary files a/SomfyController.littlefs.bin and b/SomfyController.littlefs.bin differ diff --git a/Web.cpp b/Web.cpp index c7eb882..89621e0 100644 --- a/Web.cpp +++ b/Web.cpp @@ -834,6 +834,7 @@ void Web::handleDiscovery(WebServer &server) { resp.addElem("max", ESP.getMaxAllocHeap()); resp.addElem("free", ESP.getFreeHeap()); resp.addElem("min", ESP.getMinFreeHeap()); + resp.addElem("total", ESP.getHeapSize()); resp.endObject(); resp.beginArray("rooms"); somfy.toJSONRooms(resp); diff --git a/data/index.html b/data/index.html index 71c3afd..0817c4c 100644 --- a/data/index.html +++ b/data/index.html @@ -8,9 +8,9 @@ - - - + + + @@ -114,7 +114,7 @@ rel="apple-touch-startup-image"> - +
@@ -222,8 +222,8 @@
-