diff --git a/ConfigSettings.cpp b/ConfigSettings.cpp index 84e7375..e41827d 100644 --- a/ConfigSettings.cpp +++ b/ConfigSettings.cpp @@ -649,3 +649,11 @@ void EthernetSettings::print() { Serial.println("Ethernet Settings"); Serial.printf("Board:%d PHYType:%d CLK:%d ADDR:%d PWR:%d MDC:%d MDIO:%d\n", this->boardType, this->phyType, this->CLKMode, this->phyAddress, this->PWRPin, this->MDCPin, this->MDIOPin); } +void ConfigSettings::printAvailHeap() { + Serial.print("Max Heap: "); + Serial.println(ESP.getMaxAllocHeap()); + Serial.print("Free Heap: "); + Serial.println(ESP.getFreeHeap()); + Serial.print("Min Heap: "); + Serial.println(ESP.getMinFreeHeap()); +} diff --git a/ConfigSettings.h b/ConfigSettings.h index 12fcb83..48b57c7 100644 --- a/ConfigSettings.h +++ b/ConfigSettings.h @@ -153,6 +153,7 @@ enum class conn_types : byte { }; class ConfigSettings: BaseSettings { public: + static void printAvailHeap(); char serverId[10] = ""; char hostname[32] = "ESPSomfyRTS"; char chipModel[10] = "ESP32"; diff --git a/GitOTA.cpp b/GitOTA.cpp index 791f6a5..4e164ce 100644 --- a/GitOTA.cpp +++ b/GitOTA.cpp @@ -83,136 +83,142 @@ bool GitRelease::toJSON(JsonObject &obj) { #define ERR_CLIENT_OFFSET -50 int16_t GitRepo::getReleases(uint8_t num) { - WiFiClientSecure *client = new WiFiClientSecure; - if(client) { - client->setInsecure(); - HTTPClient https; - uint8_t ndx = 0; - uint8_t count = min((uint8_t)GIT_MAX_RELEASES, num); - char url[128]; - memset(this->releases, 0x00, sizeof(GitRelease) * GIT_MAX_RELEASES); - sprintf(url, "https://api.github.com/repos/rstrouse/espsomfy-rts/releases?per_page=%d&page=1", count); - GitRelease *main = &this->releases[GIT_MAX_RELEASES]; - main->releaseDate = Timestamp::now(); - main->id = 1; - main->main = true; - strcpy(main->version.name, "main"); - strcpy(main->name, "Main"); - strcpy(main->hwVersions, "32,s3"); - if(https.begin(*client, url)) { - int httpCode = https.GET(); - Serial.printf("[HTTPS] GET... code: %d\n", httpCode); - if(httpCode > 0) { - 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(); - uint8_t buff[128] = {0}; - char jsonElem[32] = ""; - char jsonValue[128] = ""; - int arrTok = 0; - int objTok = 0; - bool inQuote = false; - bool inElem = false; - bool inValue = false; - bool awaitValue = false; - bool inAss = false; - 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)); - //Serial.write(buff, c); - if(len > 0) len -= c; - // Now we should have some data. - for(uint8_t i = 0; i < c; i++) { - // Read the buffer a byte at a time until we have a key value pair. - char ch = static_cast(buff[i]); - if(ch == '[') { - arrTok++; - if(arrTok == 2 && strcmp(jsonElem, "assets") == 0) { - inElem = inValue = awaitValue = false; - inAss = true; - //Serial.printf("%s: %d\n", jsonElem, arrTok); + WiFiClientSecure sclient; + sclient.setInsecure(); + uint8_t ndx = 0; + uint8_t count = min((uint8_t)GIT_MAX_RELEASES, num); + char url[128]; + memset(this->releases, 0x00, sizeof(GitRelease) * GIT_MAX_RELEASES); + sprintf(url, "https://api.github.com/repos/rstrouse/espsomfy-rts/releases?per_page=%d&page=1", count); + GitRelease *main = &this->releases[GIT_MAX_RELEASES]; + main->releaseDate = Timestamp::now(); + main->id = 1; + main->main = true; + 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(); + Serial.printf("[HTTPS] GET... code: %d\n", httpCode); + if(httpCode > 0) { + 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(); + uint8_t buff[128] = {0}; + char jsonElem[32] = ""; + char jsonValue[128] = ""; + int arrTok = 0; + int objTok = 0; + bool inQuote = false; + bool inElem = false; + bool inValue = false; + bool awaitValue = false; + bool inAss = false; + 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)); + //Serial.write(buff, c); + if(len > 0) len -= c; + // Now we should have some data. + for(uint8_t i = 0; i < c; i++) { + // Read the buffer a byte at a time until we have a key value pair. + char ch = static_cast(buff[i]); + if(ch == '[') { + arrTok++; + if(arrTok == 2 && strcmp(jsonElem, "assets") == 0) { + inElem = inValue = awaitValue = false; + inAss = true; + //Serial.printf("%s: %d\n", jsonElem, arrTok); + } + else if(arrTok < 2) inAss = false; + } + else if(ch == ']') { + arrTok--; + if(arrTok < 2) inAss = false; + } + else if(ch == '{') { + objTok++; + if(objTok != 1 && !inAss) inElem = inValue = awaitValue = false; + } + else if(ch == '}') { + objTok--; + if(objTok == 0) ndx++; + } + else if(objTok == 1 || inAss) { + // We only want data from the root object. + //if(inAss) Serial.print(ch); + if(ch == '\"') { + inQuote = !inQuote; + if(inElem) { + inElem = false; + awaitValue = true; } - else if(arrTok < 2) inAss = false; - } - else if(ch == ']') { - arrTok--; - if(arrTok < 2) inAss = false; - } - else if(ch == '{') { - objTok++; - if(objTok != 1 && !inAss) inElem = inValue = awaitValue = false; - } - else if(ch == '}') { - objTok--; - if(objTok == 0) ndx++; - } - else if(objTok == 1 || inAss) { - // We only want data from the root object. - //if(inAss) Serial.print(ch); - if(ch == '\"') { - inQuote = !inQuote; - if(inElem) { - inElem = false; - awaitValue = true; - } - else if(inValue) { - inValue = false; - inElem = false; - awaitValue = false; - if(inAss) - this->releases[ndx].setAssetProperty(jsonElem, jsonValue); - else - this->releases[ndx].setReleaseProperty(jsonElem, jsonValue); - memset(jsonElem, 0x00, sizeof(jsonElem)); - memset(jsonValue, 0x00, sizeof(jsonValue)); - } - else if(awaitValue) inValue = true; - else { - inElem = true; - awaitValue = false; - } - } - else if(awaitValue) { - if(ch != ' ' && ch != ':') { - strncat(jsonValue, &ch, 1); - awaitValue = false; - inValue = true; - } - } - else if((!inQuote && ch == ',') || ch == '\r' || ch == '\n') { - inElem = inValue = awaitValue = false; - if(strlen(jsonElem) > 0) { - if(inAss) - this->releases[ndx].setAssetProperty(jsonElem, jsonValue); - else - this->releases[ndx].setReleaseProperty(jsonElem, jsonValue); - } + else if(inValue) { + inValue = false; + inElem = false; + awaitValue = false; + if(inAss) + this->releases[ndx].setAssetProperty(jsonElem, jsonValue); + else + this->releases[ndx].setReleaseProperty(jsonElem, jsonValue); memset(jsonElem, 0x00, sizeof(jsonElem)); memset(jsonValue, 0x00, sizeof(jsonValue)); } + else if(awaitValue) inValue = true; else { - if(inElem) { - if(strlen(jsonElem) < sizeof(jsonElem) - 1) strncat(jsonElem, &ch, 1); - } - else if(inValue) { - if(strlen(jsonValue) < sizeof(jsonValue) - 1) strncat(jsonValue, &ch, 1); - } + inElem = true; + awaitValue = false; + } + } + else if(awaitValue) { + if(ch != ' ' && ch != ':') { + strncat(jsonValue, &ch, 1); + awaitValue = false; + inValue = true; + } + } + else if((!inQuote && ch == ',') || ch == '\r' || ch == '\n') { + inElem = inValue = awaitValue = false; + if(strlen(jsonElem) > 0) { + if(inAss) + this->releases[ndx].setAssetProperty(jsonElem, jsonValue); + else + this->releases[ndx].setReleaseProperty(jsonElem, jsonValue); + } + memset(jsonElem, 0x00, sizeof(jsonElem)); + memset(jsonValue, 0x00, sizeof(jsonValue)); + } + else { + if(inElem) { + if(strlen(jsonElem) < sizeof(jsonElem) - 1) strncat(jsonElem, &ch, 1); + } + else if(inValue) { + if(strlen(jsonValue) < sizeof(jsonValue) - 1) strncat(jsonValue, &ch, 1); } } } - delay(1); } - //else break; + delay(1); } + //else break; } - else return httpCode; } - https.end(); + else { + https->end(); + sclient.stop(); + delete https; + return httpCode; + } } - delete client; + https->end(); + delete https; } + sclient.stop(); + settings.printAvailHeap(); return 0; } bool GitRepo::toJSON(JsonObject &obj) { @@ -257,6 +263,7 @@ void GitUpdater::checkForUpdate() { if(this->status != 0) return; // If we are already checking. Serial.println("Check github for updates..."); this->status = GIT_STATUS_CHECK; + settings.printAvailHeap(); if(this->checkInternet() == 0) { GitRepo repo; this->lastCheck = millis(); @@ -310,26 +317,26 @@ void GitUpdater::emitUpdateCheck(uint8_t num) { int GitUpdater::checkInternet() { int err = 500; uint32_t t = millis(); - WiFiClientSecure *client = new WiFiClientSecure; - if(client) { - client->setInsecure(); - HTTPClient https; - if(https.begin(*client, "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("Check Internet Success: %ldms\n", millis() - t); - } - else { - err = httpCode; - Serial.printf("Check Internet Error: %d: %ldms\n", err, millis() - t); - } - https.end(); + WiFiClientSecure client; + client.setInsecure(); + 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"); + if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY || httpCode == HTTP_CODE_FOUND) { + err = 0; + Serial.printf("Check Internet Success: %ldms\n", millis() - t); } - delete client; + else { + err = httpCode; + Serial.printf("Check Internet Error: %d: %ldms\n", err, millis() - t); + } + https->end(); } + client.stop(); + delete https; return err; } void GitUpdater::emitDownloadProgress(size_t total, size_t loaded, const char *evt) { this->emitDownloadProgress(255, total, loaded, evt); } @@ -523,6 +530,7 @@ int8_t GitUpdater::downloadFile() { Serial.printf("End update %s\n", this->currentFile); } + client->stop(); delete client; } return 0; diff --git a/Network.cpp b/Network.cpp index 76e1223..8fe5c93 100644 --- a/Network.cpp +++ b/Network.cpp @@ -214,6 +214,7 @@ void Network::setConnected(conn_types connType) { } else if(SSDP.isStarted) SSDP.end(); this->emitSockets(); + settings.printAvailHeap(); } bool Network::connectWired() { if(this->connType == conn_types::ethernet) { diff --git a/Sockets.cpp b/Sockets.cpp index 815c60e..7506223 100644 --- a/Sockets.cpp +++ b/Sockets.cpp @@ -69,6 +69,8 @@ void SocketEmitter::begin() { sockServer.begin(); sockServer.enableHeartbeat(20000, 10000, 3); sockServer.onEvent(this->wsEvent); + Serial.println("Socket Server Started..."); + settings.printAvailHeap(); } void SocketEmitter::loop() { sockServer.loop(); diff --git a/Sockets.h b/Sockets.h index fa158f3..4d1fc06 100644 --- a/Sockets.h +++ b/Sockets.h @@ -1,7 +1,6 @@ #include #ifndef sockets_h #define sockets_h -#include #define SOCK_MAX_ROOMS 1 #define ROOM_EMIT_FRAME 0 diff --git a/Somfy.cpp b/Somfy.cpp index 3de7f65..ab6acd7 100644 --- a/Somfy.cpp +++ b/Somfy.cpp @@ -446,6 +446,7 @@ void SomfyShadeController::updateGroupFlags() { } } } +#ifdef USE_NVS bool SomfyShadeController::loadLegacy() { Serial.println("Loading Legacy shades using NVS"); pref.begin("Shades", true); @@ -485,18 +486,22 @@ bool SomfyShadeController::loadLegacy() { } Serial.println(); #endif + #ifdef USE_NVS if(!this->useNVS()) { pref.begin("Shades"); pref.putBytes("shadeIds", this->m_shadeIds, sizeof(this->m_shadeIds)); pref.end(); } + #endif this->commit(); return true; } +#endif bool SomfyShadeController::begin() { // Load up all the configuration data. //ShadeConfigFile::getAppVersion(this->appVersion); Serial.printf("App Version:%u.%u.%u\n", settings.appVersion.major, settings.appVersion.minor, settings.appVersion.build); + #ifdef USE_NVS if(!this->useNVS()) { // At 1.4 we started using the configuration file. If the file doesn't exist then booh. // We need to remove all the extraeneous data from NVS for the shades. From here on out we // will rely on the shade configuration. @@ -523,13 +528,16 @@ bool SomfyShadeController::begin() { pref.end(); } } - else if(ShadeConfigFile::exists()) { + #endif + if(ShadeConfigFile::exists()) { Serial.println("shades.cfg exists so we are using that"); ShadeConfigFile::load(this); } else { Serial.println("Starting clean"); + #ifdef USE_NVS this->loadLegacy(); + #endif } this->transceiver.begin(); @@ -538,7 +546,7 @@ bool SomfyShadeController::begin() { for(uint8_t i = 0; i < SOMFY_MAX_SHADES; i++) { SomfyShade *shade = &this->shades[i]; if(shade->getShadeId() != 255 && shade->bitLength == 0) { - Serial.printf("Setting bit length to %d\n", this->transceiver.config.type); + //Serial.printf("Setting bit length to %d\n", this->transceiver.config.type); shade->bitLength = this->transceiver.config.type; saveFlag = true; } @@ -650,6 +658,7 @@ bool SomfyShade::linkRemote(uint32_t address, uint16_t rollingCode) { if(this->linkedRemotes[i].getRemoteAddress() == 0) { this->linkedRemotes[i].setRemoteAddress(address); this->linkedRemotes[i].setRollingCode(rollingCode); + #ifdef USE_NVS if(somfy.useNVS()) { uint32_t linkedAddresses[SOMFY_MAX_LINKED_REMOTES]; memset(linkedAddresses, 0x00, sizeof(linkedAddresses)); @@ -664,6 +673,7 @@ bool SomfyShade::linkRemote(uint32_t address, uint16_t rollingCode) { pref.putBytes("linkedAddr", linkedAddresses, sizeof(uint32_t) * SOMFY_MAX_LINKED_REMOTES); pref.end(); } + #endif this->commit(); return true; } @@ -689,6 +699,7 @@ bool SomfyGroup::linkShade(uint8_t shadeId) { void SomfyShade::commit() { somfy.commit(); } void SomfyShade::commitShadePosition() { somfy.isDirty = true; + #ifdef USE_NVS char shadeKey[15]; if(somfy.useNVS()) { snprintf(shadeKey, sizeof(shadeKey), "SomfyShade%u", this->shadeId); @@ -698,9 +709,11 @@ void SomfyShade::commitShadePosition() { pref.putFloat("currentPos", this->currentPos); pref.end(); } + #endif } void SomfyShade::commitMyPosition() { somfy.isDirty = true; + #ifdef USE_NVS if(somfy.useNVS()) { char shadeKey[15]; snprintf(shadeKey, sizeof(shadeKey), "SomfyShade%u", this->shadeId); @@ -711,9 +724,11 @@ void SomfyShade::commitMyPosition() { pref.putUShort("myPos", this->myPos); pref.end(); } + #endif } void SomfyShade::commitTiltPosition() { somfy.isDirty = true; + #ifdef USE_NVS if(somfy.useNVS()) { char shadeKey[15]; snprintf(shadeKey, sizeof(shadeKey), "SomfyShade%u", this->shadeId); @@ -723,11 +738,13 @@ void SomfyShade::commitTiltPosition() { pref.putFloat("currentTiltPos", this->currentTiltPos); pref.end(); } + #endif } bool SomfyShade::unlinkRemote(uint32_t address) { for(uint8_t i = 0; i < SOMFY_MAX_LINKED_REMOTES; i++) { if(this->linkedRemotes[i].getRemoteAddress() == address) { this->linkedRemotes[i].setRemoteAddress(0); + #ifdef USE_NVS if(somfy.useNVS()) { char shadeKey[15]; snprintf(shadeKey, sizeof(shadeKey), "SomfyShade%u", this->getShadeId()); @@ -742,6 +759,7 @@ bool SomfyShade::unlinkRemote(uint32_t address) { pref.putBytes("linkedAddr", linkedAddresses, sizeof(uint32_t) * SOMFY_MAX_LINKED_REMOTES); pref.end(); } + #endif this->commit(); return true; } @@ -1257,6 +1275,7 @@ void SomfyShade::checkMovement() { this->emitState(); } } +#ifdef USE_NVS void SomfyShade::load() { char shadeKey[15]; uint32_t linkedAddresses[SOMFY_MAX_LINKED_REMOTES]; @@ -1317,6 +1336,7 @@ void SomfyShade::load() { } pref.end(); } +#endif void SomfyRoom::publish() { if(mqtt.connected()) { char topic[64]; @@ -2787,6 +2807,7 @@ void SomfyShade::moveToTarget(float pos, float tilt) { } } bool SomfyShade::save() { + #ifdef USE_NVS if(somfy.useNVS()) { char shadeKey[15]; snprintf(shadeKey, sizeof(shadeKey), "SomfyShade%u", this->getShadeId()); @@ -2814,6 +2835,7 @@ bool SomfyShade::save() { pref.putBytes("linkedAddr", linkedAddresses, sizeof(uint32_t) * SOMFY_MAX_LINKED_REMOTES); pref.end(); } + #endif this->commit(); this->publish(); return true; @@ -3338,6 +3360,7 @@ SomfyShade *SomfyShadeController::addShade() { shade->sortOrder = this->getMaxShadeOrder() + 1; Serial.printf("Sort order set to %d\n", shade->sortOrder); this->isDirty = true; + #ifdef USE_NVS if(this->useNVS()) { for(uint8_t i = 0; i < sizeof(this->m_shadeIds); i++) { this->m_shadeIds[i] = this->shades[i].getShadeId(); @@ -3384,6 +3407,7 @@ SomfyShade *SomfyShadeController::addShade() { } Serial.println(); } + #endif } return shade; } @@ -3587,6 +3611,7 @@ bool SomfyShadeController::deleteShade(uint8_t shadeId) { this->shades[i].clear(); } } + #ifdef USE_NVS if(this->useNVS()) { for(uint8_t i = 0; i < sizeof(this->m_shadeIds) - 1; i++) { if(this->m_shadeIds[i] == shadeId) { @@ -3601,6 +3626,7 @@ bool SomfyShadeController::deleteShade(uint8_t shadeId) { pref.putBytes("shadeIds", this->m_shadeIds, sizeof(this->m_shadeIds)); pref.end(); } + #endif this->commit(); return true; } diff --git a/Somfy.h b/Somfy.h index 222b99d..b91814d 100644 --- a/Somfy.h +++ b/Somfy.h @@ -267,7 +267,9 @@ class SomfyShade : public SomfyRemote { bool flipPosition = false; shade_types shadeType = shade_types::roller; tilt_types tiltType = tilt_types::none; + #ifdef USE_NVS void load(); + #endif somfy_tx_queue_t txQueue; float currentPos = 0.0f; float currentTiltPos = 0.0f; @@ -546,7 +548,9 @@ class SomfyShadeController { void commit(); void writeBackup(); bool loadShadesFile(const char *filename); + #ifdef USE_NVS bool loadLegacy(); + #endif }; #endif diff --git a/SomfyController.ino.esp32.bin b/SomfyController.ino.esp32.bin index ac397ba..f7a19f5 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 d364a25..40d457d 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 f1aded8..b0405fe 100644 Binary files a/SomfyController.littlefs.bin and b/SomfyController.littlefs.bin differ diff --git a/Utils.h b/Utils.h index d71ff5d..b31e3ab 100644 --- a/Utils.h +++ b/Utils.h @@ -1,9 +1,13 @@ #ifndef utils_h #define utils_h +#include #define DEBUG_SOMFY Serial + + + [[maybe_unused]] static void SETCHARPROP(char *prop, const char *value, size_t size) {strncpy(prop, value, size); prop[size - 1] = '\0';} namespace util { // Createa a custom to_string function. C++ can be annoying diff --git a/Web.cpp b/Web.cpp index 579bf8b..0a20249 100644 --- a/Web.cpp +++ b/Web.cpp @@ -60,6 +60,19 @@ void Web::sendCacheHeaders(uint32_t seconds) { void Web::end() { //server.end(); } +void Web::handleDeserializationError(WebServer &server, DeserializationError &err) { + switch (err.code()) { + case DeserializationError::InvalidInput: + server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"Invalid JSON payload\"}")); + break; + case DeserializationError::NoMemory: + server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"Out of memory parsing JSON\"}")); + break; + default: + server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"General JSON Deserialization failed\"}")); + break; + } +} bool Web::isAuthenticated(WebServer &server, bool cfg) { Serial.println("Checking authentication"); if(settings.Security.type == security_types::None) return true; @@ -148,17 +161,7 @@ void Web::handleLogin(WebServer &server) { DynamicJsonDocument docin(512); DeserializationError err = deserializeJson(docin, server.arg("plain")); if (err) { - switch (err.code()) { - case DeserializationError::InvalidInput: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"Invalid JSON payload\"}")); - break; - case DeserializationError::NoMemory: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"Out of memory parsing JSON\"}")); - break; - default: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"General JSON Deserialization failed\"}")); - break; - } + this->handleDeserializationError(server, err); return; } else { @@ -223,16 +226,17 @@ void Web::handleStreamFile(WebServer &server, const char *filename, const char * file.close(); } void Web::handleController(WebServer &server) { - webServer.sendCORSHeaders(server); - if(server.method() == HTTP_OPTIONS) { server.send(200, "OK"); return; } - HTTPMethod method = server.method(); - if (method == HTTP_POST || method == HTTP_GET) { - DynamicJsonDocument doc(16384); - somfy.toJSON(doc); - serializeJson(doc, g_content); - server.send(200, _encoding_json, g_content); - } - else server.send(404, _encoding_text, _response_404); + webServer.sendCORSHeaders(server); + if(server.method() == HTTP_OPTIONS) { server.send(200, "OK"); return; } + HTTPMethod method = server.method(); + settings.printAvailHeap(); + if (method == HTTP_POST || method == HTTP_GET) { + DynamicJsonDocument doc(16384); + somfy.toJSON(doc); + serializeJson(doc, g_content); + server.send(200, _encoding_json, g_content); + } + else server.send(404, _encoding_text, _response_404); } void Web::handleLoginContext(WebServer &server) { webServer.sendCORSHeaders(server); @@ -307,17 +311,7 @@ void Web::handleShadeCommand(WebServer& server) { DynamicJsonDocument doc(256); DeserializationError err = deserializeJson(doc, server.arg("plain")); if (err) { - switch (err.code()) { - case DeserializationError::InvalidInput: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"Invalid JSON payload\"}")); - break; - case DeserializationError::NoMemory: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"Out of memory parsing JSON\"}")); - break; - default: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"General JSON Deserialization failed\"}")); - break; - } + this->handleDeserializationError(server, err); return; } else { @@ -376,17 +370,7 @@ void Web::handleRepeatCommand(WebServer& server) { DynamicJsonDocument doc(256); DeserializationError err = deserializeJson(doc, server.arg("plain")); if (err) { - switch (err.code()) { - case DeserializationError::InvalidInput: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"Invalid JSON payload\"}")); - break; - case DeserializationError::NoMemory: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"Out of memory parsing JSON\"}")); - break; - default: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"General JSON Deserialization failed\"}")); - break; - } + this->handleDeserializationError(server, err); return; } else { @@ -459,17 +443,7 @@ void Web::handleGroupCommand(WebServer &server) { DynamicJsonDocument doc(256); DeserializationError err = deserializeJson(doc, server.arg("plain")); if (err) { - switch (err.code()) { - case DeserializationError::InvalidInput: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"Invalid JSON payload\"}")); - break; - case DeserializationError::NoMemory: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"Out of memory parsing JSON\"}")); - break; - default: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"General JSON Deserialization failed\"}")); - break; - } + this->handleDeserializationError(server, err); return; } else { @@ -522,17 +496,7 @@ void Web::handleTiltCommand(WebServer &server) { DynamicJsonDocument doc(256); DeserializationError err = deserializeJson(doc, server.arg("plain")); if (err) { - switch (err.code()) { - case DeserializationError::InvalidInput: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"Invalid JSON payload\"}")); - break; - case DeserializationError::NoMemory: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"Out of memory parsing JSON\"}")); - break; - default: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"General JSON Deserialization failed\"}")); - break; - } + this->handleDeserializationError(server, err); return; } else { @@ -599,17 +563,8 @@ void Web::handleRoom(WebServer &server) { DynamicJsonDocument doc(512); DeserializationError err = deserializeJson(doc, server.arg("plain")); if (err) { - switch (err.code()) { - case DeserializationError::InvalidInput: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"Invalid JSON payload\"}")); - break; - case DeserializationError::NoMemory: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"Out of memory parsing JSON\"}")); - break; - default: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"General JSON Deserialization failed\"}")); - break; - } + this->handleDeserializationError(server, err); + return; } else { JsonObject obj = doc.as(); @@ -668,17 +623,8 @@ void Web::handleShade(WebServer &server) { DynamicJsonDocument doc(512); DeserializationError err = deserializeJson(doc, server.arg("plain")); if (err) { - switch (err.code()) { - case DeserializationError::InvalidInput: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"Invalid JSON payload\"}")); - break; - case DeserializationError::NoMemory: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"Out of memory parsing JSON\"}")); - break; - default: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"General JSON Deserialization failed\"}")); - break; - } + this->handleDeserializationError(server, err); + return; } else { JsonObject obj = doc.as(); @@ -737,17 +683,8 @@ void Web::handleGroup(WebServer &server) { DynamicJsonDocument doc(512); DeserializationError err = deserializeJson(doc, server.arg("plain")); if (err) { - switch (err.code()) { - case DeserializationError::InvalidInput: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"Invalid JSON payload\"}")); - break; - case DeserializationError::NoMemory: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"Out of memory parsing JSON\"}")); - break; - default: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"General JSON Deserialization failed\"}")); - break; - } + this->handleDeserializationError(server, err); + return; } else { JsonObject obj = doc.as(); @@ -845,17 +782,8 @@ void Web::handleSetPositions(WebServer &server) { DynamicJsonDocument doc(512); DeserializationError err = deserializeJson(doc, server.arg("plain")); if (err) { - switch (err.code()) { - case DeserializationError::InvalidInput: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"Invalid JSON payload\"}")); - break; - case DeserializationError::NoMemory: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"Out of memory parsing JSON\"}")); - break; - default: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"General JSON Deserialization failed\"}")); - break; - } + this->handleDeserializationError(server, err); + return; } else { JsonObject obj = doc.as(); @@ -895,17 +823,8 @@ void Web::handleSetSensor(WebServer &server) { DynamicJsonDocument doc(512); DeserializationError err = deserializeJson(doc, server.arg("plain")); if (err) { - switch (err.code()) { - case DeserializationError::InvalidInput: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"Invalid JSON payload\"}")); - break; - case DeserializationError::NoMemory: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"Out of memory parsing JSON\"}")); - break; - default: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"General JSON Deserialization failed\"}")); - break; - } + this->handleDeserializationError(server, err); + return; } else { JsonObject obj = doc.as(); @@ -1026,6 +945,20 @@ void Web::handleNotFound(WebServer &server) { snprintf(g_content, sizeof(g_content), "404 Service Not Found: %s", server.uri().c_str()); server.send(404, _encoding_text, g_content); } +void Web::handleReboot(WebServer &server) { + webServer.sendCORSHeaders(server); + if(server.method() == HTTP_OPTIONS) { server.send(200, "OK"); return; } + HTTPMethod method = server.method(); + if (method == HTTP_POST || method == HTTP_PUT) { + Serial.println("Rebooting ESP..."); + rebootDelay.reboot = true; + rebootDelay.rebootTime = millis() + 500; + server.send(200, "application/json", "{\"status\":\"OK\",\"desc\":\"Successfully started reboot\"}"); + } + else { + server.send(201, _encoding_json, "{\"status\":\"ERROR\",\"desc\":\"Invalid HTTP Method: \"}"); + } +} void Web::begin() { Serial.println("Creating Web MicroServices..."); server.enableCORS(true); @@ -1052,6 +985,7 @@ void Web::begin() { apiServer.on("/setSensor", []() { webServer.handleSetSensor(apiServer); }); apiServer.on("/downloadFirmware", []() { webServer.handleDownloadFirmware(apiServer); }); apiServer.on("/backup", []() { webServer.handleBackup(apiServer); }); + apiServer.on("/reboot", []() { webServer.handleReboot(apiServer); }); // Web Interface server.on("/tiltCommand", []() { webServer.handleTiltCommand(server); }); @@ -1102,18 +1036,7 @@ void Web::begin() { StaticJsonDocument<256> doc; DeserializationError err = deserializeJson(doc, server.arg("data")); if (err) { - switch (err.code()) { - case DeserializationError::InvalidInput: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"Invalid JSON payload\"}")); - break; - case DeserializationError::NoMemory: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"Out of memory parsing JSON\"}")); - break; - default: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"General JSON Deserialization failed\"}")); - break; - } - Serial.println("An error occurred when deserializing the restore data"); + webServer.handleDeserializationError(server, err); return; } else { @@ -1208,17 +1131,8 @@ void Web::begin() { DynamicJsonDocument doc(512); DeserializationError err = deserializeJson(doc, server.arg("plain")); if (err) { - switch (err.code()) { - case DeserializationError::InvalidInput: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"Invalid JSON payload\"}")); - break; - case DeserializationError::NoMemory: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"Out of memory parsing JSON\"}")); - break; - default: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"General JSON Deserialization failed\"}")); - break; - } + webServer.handleDeserializationError(server, err); + return; } else { JsonObject obj = doc.as(); @@ -1263,17 +1177,8 @@ void Web::begin() { DynamicJsonDocument doc(1024); DeserializationError err = deserializeJson(doc, server.arg("plain")); if (err) { - switch (err.code()) { - case DeserializationError::InvalidInput: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"Invalid JSON payload\"}")); - break; - case DeserializationError::NoMemory: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"Out of memory parsing JSON\"}")); - break; - default: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"General JSON Deserialization failed\"}")); - break; - } + webServer.handleDeserializationError(server, err); + return; } else { JsonObject obj = doc.as(); @@ -1319,17 +1224,8 @@ void Web::begin() { DynamicJsonDocument doc(512); DeserializationError err = deserializeJson(doc, server.arg("plain")); if (err) { - switch (err.code()) { - case DeserializationError::InvalidInput: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"Invalid JSON payload\"}")); - break; - case DeserializationError::NoMemory: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"Out of memory parsing JSON\"}")); - break; - default: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"General JSON Deserialization failed\"}")); - break; - } + webServer.handleDeserializationError(server, err); + return; } else { JsonObject obj = doc.as(); @@ -1416,17 +1312,8 @@ void Web::begin() { DynamicJsonDocument doc(512); DeserializationError err = deserializeJson(doc, server.arg("plain")); if (err) { - switch (err.code()) { - case DeserializationError::InvalidInput: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"Invalid JSON payload\"}")); - break; - case DeserializationError::NoMemory: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"Out of memory parsing JSON\"}")); - break; - default: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"General JSON Deserialization failed\"}")); - break; - } + webServer.handleDeserializationError(server, err); + return; } else { JsonObject obj = doc.as(); @@ -1461,17 +1348,8 @@ void Web::begin() { DynamicJsonDocument doc(1024); DeserializationError err = deserializeJson(doc, server.arg("plain")); if (err) { - switch (err.code()) { - case DeserializationError::InvalidInput: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"Invalid JSON payload\"}")); - break; - case DeserializationError::NoMemory: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"Out of memory parsing JSON\"}")); - break; - default: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"General JSON Deserialization failed\"}")); - break; - } + webServer.handleDeserializationError(server, err); + return; } else { JsonObject obj = doc.as(); @@ -1511,17 +1389,8 @@ void Web::begin() { DynamicJsonDocument doc(512); DeserializationError err = deserializeJson(doc, server.arg("plain")); if (err) { - switch (err.code()) { - case DeserializationError::InvalidInput: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"Invalid JSON payload\"}")); - break; - case DeserializationError::NoMemory: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"Out of memory parsing JSON\"}")); - break; - default: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"General JSON Deserialization failed\"}")); - break; - } + webServer.handleDeserializationError(server, err); + return; } else { JsonObject obj = doc.as(); @@ -1561,17 +1430,7 @@ void Web::begin() { DynamicJsonDocument doc(256); DeserializationError err = deserializeJson(doc, server.arg("plain")); if (err) { - switch (err.code()) { - case DeserializationError::InvalidInput: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"Invalid JSON payload\"}")); - break; - case DeserializationError::NoMemory: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"Out of memory parsing JSON\"}")); - break; - default: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"General JSON Deserialization failed\"}")); - break; - } + webServer.handleDeserializationError(server, err); return; } else { @@ -1615,17 +1474,8 @@ void Web::begin() { StaticJsonDocument<129> doc; DeserializationError err = deserializeJson(doc, server.arg("plain")); if (err) { - switch (err.code()) { - case DeserializationError::InvalidInput: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"Invalid JSON payload\"}")); - break; - case DeserializationError::NoMemory: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"Out of memory parsing JSON\"}")); - break; - default: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"General JSON Deserialization failed\"}")); - break; - } + webServer.handleDeserializationError(server, err); + return; } else { JsonObject obj = doc.as(); @@ -1661,17 +1511,8 @@ void Web::begin() { DynamicJsonDocument doc(512); DeserializationError err = deserializeJson(doc, server.arg("plain")); if(err) { - switch(err.code()) { - case DeserializationError::InvalidInput: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"Invalid JSON payload\"}")); - break; - case DeserializationError::NoMemory: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"Out of memory parsing JSON\"}")); - break; - default: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"General JSON Deserialization failed\"}")); - break; - } + webServer.handleDeserializationError(server, err); + return; } else { JsonObject obj = doc.as(); @@ -1709,17 +1550,8 @@ void Web::begin() { DynamicJsonDocument doc(512); DeserializationError err = deserializeJson(doc, server.arg("plain")); if (err) { - switch (err.code()) { - case DeserializationError::InvalidInput: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"Invalid JSON payload\"}")); - break; - case DeserializationError::NoMemory: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"Out of memory parsing JSON\"}")); - break; - default: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"General JSON Deserialization failed\"}")); - break; - } + webServer.handleDeserializationError(server, err); + return; } else { JsonObject obj = doc.as(); @@ -1758,17 +1590,8 @@ void Web::begin() { DynamicJsonDocument doc(512); DeserializationError err = deserializeJson(doc, server.arg("plain")); if (err) { - switch (err.code()) { - case DeserializationError::InvalidInput: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"Invalid JSON payload\"}")); - break; - case DeserializationError::NoMemory: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"Out of memory parsing JSON\"}")); - break; - default: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"General JSON Deserialization failed\"}")); - break; - } + webServer.handleDeserializationError(server, err); + return; } else { JsonObject obj = doc.as(); @@ -1806,17 +1629,8 @@ void Web::begin() { DynamicJsonDocument doc(512); DeserializationError err = deserializeJson(doc, server.arg("plain")); if (err) { - switch (err.code()) { - case DeserializationError::InvalidInput: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"Invalid JSON payload\"}")); - break; - case DeserializationError::NoMemory: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"Out of memory parsing JSON\"}")); - break; - default: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"General JSON Deserialization failed\"}")); - break; - } + webServer.handleDeserializationError(server, err); + return; } else { JsonObject obj = doc.as(); @@ -1854,17 +1668,8 @@ void Web::begin() { DynamicJsonDocument doc(512); DeserializationError err = deserializeJson(doc, server.arg("plain")); if (err) { - switch (err.code()) { - case DeserializationError::InvalidInput: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"Invalid JSON payload\"}")); - break; - case DeserializationError::NoMemory: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"Out of memory parsing JSON\"}")); - break; - default: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"General JSON Deserialization failed\"}")); - break; - } + webServer.handleDeserializationError(server, err); + return; } else { JsonObject obj = doc.as(); @@ -1968,17 +1773,8 @@ void Web::begin() { DynamicJsonDocument doc(256); DeserializationError err = deserializeJson(doc, server.arg("plain")); if (err) { - switch (err.code()) { - case DeserializationError::InvalidInput: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"Invalid JSON payload\"}")); - break; - case DeserializationError::NoMemory: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"Out of memory parsing JSON\"}")); - break; - default: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"General JSON Deserialization failed\"}")); - break; - } + webServer.handleDeserializationError(server, err); + return; } else { JsonObject obj = doc.as(); @@ -2009,17 +1805,8 @@ void Web::begin() { DynamicJsonDocument doc(256); DeserializationError err = deserializeJson(doc, server.arg("plain")); if (err) { - switch (err.code()) { - case DeserializationError::InvalidInput: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"Invalid JSON payload\"}")); - break; - case DeserializationError::NoMemory: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"Out of memory parsing JSON\"}")); - break; - default: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"General JSON Deserialization failed\"}")); - break; - } + webServer.handleDeserializationError(server, err); + return; } else { JsonObject obj = doc.as(); @@ -2053,17 +1840,8 @@ void Web::begin() { DynamicJsonDocument doc(256); DeserializationError err = deserializeJson(doc, server.arg("plain")); if (err) { - switch (err.code()) { - case DeserializationError::InvalidInput: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"Invalid JSON payload\"}")); - break; - case DeserializationError::NoMemory: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"Out of memory parsing JSON\"}")); - break; - default: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"General JSON Deserialization failed\"}")); - break; - } + webServer.handleDeserializationError(server, err); + return; } else { JsonObject obj = doc.as(); @@ -2239,20 +2017,7 @@ void Web::begin() { */ server.send(statusCode, "application/json", g_content); }); - server.on("/reboot", []() { - webServer.sendCORSHeaders(server); - if(server.method() == HTTP_OPTIONS) { server.send(200, "OK"); return; } - HTTPMethod method = server.method(); - if (method == HTTP_POST || method == HTTP_PUT) { - Serial.println("Rebooting ESP..."); - rebootDelay.reboot = true; - rebootDelay.rebootTime = millis() + 500; - server.send(200, "application/json", "{\"status\":\"OK\",\"desc\":\"Successfully started reboot\"}"); - } - else { - server.send(201, _encoding_json, "{\"status\":\"ERROR\",\"desc\":\"Invalid HTTP Method: \"}"); - } - }); + server.on("/reboot", []() { webServer.handleReboot(server);}); server.on("/saveSecurity", []() { webServer.sendCORSHeaders(server); if(server.method() == HTTP_OPTIONS) { server.send(200, "OK"); return; } @@ -2347,17 +2112,7 @@ void Web::begin() { StaticJsonDocument<128> doc; DeserializationError err = deserializeJson(doc, server.arg("plain")); if (err) { - switch (err.code()) { - case DeserializationError::InvalidInput: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"Invalid JSON payload\"}")); - break; - case DeserializationError::NoMemory: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"Out of memory parsing JSON\"}")); - break; - default: - server.send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"General JSON Deserialization failed\"}")); - break; - } + webServer.handleDeserializationError(server, err); return; } else { @@ -2389,10 +2144,8 @@ void Web::begin() { Serial.println(server.arg("plain")); DeserializationError err = deserializeJson(doc, server.arg("plain")); if (err) { - Serial.print("Error parsing JSON "); - Serial.println(err.c_str()); - String msg = err.c_str(); - server.send(400, _encoding_html, "Error parsing JSON body
" + msg); + webServer.handleDeserializationError(server, err); + return; } else { JsonObject obj = doc.as(); @@ -2471,10 +2224,8 @@ void Web::begin() { DynamicJsonDocument doc(1024); DeserializationError err = deserializeJson(doc, server.arg("plain")); if (err) { - Serial.print("Error parsing JSON "); - Serial.println(err.c_str()); - String msg = err.c_str(); - server.send(400, "text/html", "Error parsing JSON body
" + msg); + webServer.handleDeserializationError(server, err); + return; } else { JsonObject obj = doc.as(); @@ -2496,10 +2247,8 @@ void Web::begin() { DynamicJsonDocument doc(512); DeserializationError err = deserializeJson(doc, server.arg("plain")); if (err) { - Serial.print("Error parsing JSON "); - Serial.println(err.c_str()); - String msg = err.c_str(); - server.send(400, "text/html", "Error parsing JSON body
" + msg); + webServer.handleDeserializationError(server, err); + return; } else { JsonObject obj = doc.as(); @@ -2567,10 +2316,8 @@ void Web::begin() { DynamicJsonDocument doc(1024); DeserializationError err = deserializeJson(doc, server.arg("plain")); if (err) { - Serial.print("Error parsing JSON "); - Serial.println(err.c_str()); - String msg = err.c_str(); - server.send(400, F("text/html"), "Error parsing JSON body
" + msg); + webServer.handleDeserializationError(server, err); + return; } else { JsonObject obj = doc.as(); @@ -2610,10 +2357,8 @@ void Web::begin() { Serial.println(server.arg("plain")); DeserializationError err = deserializeJson(doc, server.arg("plain")); if (err) { - Serial.print("Error parsing JSON "); - Serial.println(err.c_str()); - String msg = err.c_str(); - server.send(400, _encoding_html, "Error parsing JSON body
" + msg); + webServer.handleDeserializationError(server, err); + return; } else { JsonArray arr = doc.as(); @@ -2644,10 +2389,8 @@ void Web::begin() { Serial.println(server.arg("plain")); DeserializationError err = deserializeJson(doc, server.arg("plain")); if (err) { - Serial.print("Error parsing JSON "); - Serial.println(err.c_str()); - String msg = err.c_str(); - server.send(400, _encoding_html, "Error parsing JSON body
" + msg); + webServer.handleDeserializationError(server, err); + return; } else { JsonArray arr = doc.as(); @@ -2677,10 +2420,8 @@ void Web::begin() { Serial.println(server.arg("plain")); DeserializationError err = deserializeJson(doc, server.arg("plain")); if (err) { - Serial.print("Error parsing JSON "); - Serial.println(err.c_str()); - String msg = err.c_str(); - server.send(400, _encoding_html, "Error parsing JSON body
" + msg); + webServer.handleDeserializationError(server, err); + return; } else { JsonArray arr = doc.as(); diff --git a/Web.h b/Web.h index 1358eb3..b972cb1 100644 --- a/Web.h +++ b/Web.h @@ -28,6 +28,8 @@ class Web { void handleSetSensor(WebServer &server); void handleDownloadFirmware(WebServer &server); void handleBackup(WebServer &server, bool attach = false); + void handleReboot(WebServer &server); + void handleDeserializationError(WebServer &server, DeserializationError &err); void begin(); void loop(); void end(); diff --git a/data/index.html b/data/index.html index bee6364..7523f35 100644 --- a/data/index.html +++ b/data/index.html @@ -3,11 +3,11 @@ - - - + + + - +
diff --git a/data/main.css b/data/main.css index 7fd28d8..e3fe079 100644 --- a/data/main.css +++ b/data/main.css @@ -10,8 +10,8 @@ body { font-family: "Helvetica Neue",Helvetica,Arial,sans-serif; font-size: 14px; background-color: #eeeeee; - margin-top: 77px; box-sizing: border-box; + margin-top: 77px; } @@ -844,3 +844,12 @@ div.frame-pulses { text-overflow:ellipsis; display:none; } +@media only screen and (max-device-width: 480px) { + body { + margin-top: 0px; + } + .subtab-content { + padding-left:14px; + padding-right:14px; + } +} diff --git a/data/widgets.css b/data/widgets.css index 3083bcf..3a35e46 100644 --- a/data/widgets.css +++ b/data/widgets.css @@ -303,3 +303,13 @@ .room-selector-list .room-row:hover { color: var(--shade-color, gray); } +@media only screen and (max-device-width: 480px) { + body { + margin-top: 0px; + } + + .container { + padding-left: 10px; + padding-right: 10px; + } +}