From 253adfeb45b4923207a8e2a0aee4c496ec647eb1 Mon Sep 17 00:00:00 2001 From: Proddy Date: Mon, 5 Feb 2024 09:38:11 +0100 Subject: [PATCH 01/54] memory optimizations --- interface/package.json | 2 +- interface/yarn.lock | 10 +-- lib/AsyncTCP/library.json | 23 ------ lib/ESPAsyncWebServer/library.json | 43 ----------- lib/ESPAsyncWebServer/src/AsyncJson.h | 102 ++------------------------ lib/framework/HttpEndpoint.h | 33 +++++---- pio_local.ini_example | 2 +- 7 files changed, 33 insertions(+), 182 deletions(-) delete mode 100644 lib/AsyncTCP/library.json delete mode 100644 lib/ESPAsyncWebServer/library.json diff --git a/interface/package.json b/interface/package.json index 3c9391ce4..362e03882 100644 --- a/interface/package.json +++ b/interface/package.json @@ -32,7 +32,7 @@ "@types/imagemin": "^8.0.5", "@types/lodash-es": "^4.17.12", "@types/node": "^20.11.16", - "@types/react": "^18.2.52", + "@types/react": "^18.2.53", "@types/react-dom": "^18.2.18", "@types/react-router-dom": "^5.3.3", "alova": "^2.17.0", diff --git a/interface/yarn.lock b/interface/yarn.lock index c4aa445c8..0f649fefe 100644 --- a/interface/yarn.lock +++ b/interface/yarn.lock @@ -1670,14 +1670,14 @@ __metadata: languageName: node linkType: hard -"@types/react@npm:^18.2.52": - version: 18.2.52 - resolution: "@types/react@npm:18.2.52" +"@types/react@npm:^18.2.53": + version: 18.2.53 + resolution: "@types/react@npm:18.2.53" dependencies: "@types/prop-types": "npm:*" "@types/scheduler": "npm:*" csstype: "npm:^3.0.2" - checksum: 10/0ab90a37fd82028c3559f18ce50790d01b262589a2ea49d014d8888291f47d9c91e65cb7db031a3e5d58818cb5376577afb4b593068473abfd0c695fa7e6b7c4 + checksum: 10/9a518aef07c6bb743aa18a2aea7f618d4e7c9e44e14d25119d2e255c48e68ecd901ede8b4eaf22ffe4f52c1ff85e11634ec75e73dcfc0719cc52269629f13d69 languageName: node linkType: hard @@ -1859,7 +1859,7 @@ __metadata: "@types/imagemin": "npm:^8.0.5" "@types/lodash-es": "npm:^4.17.12" "@types/node": "npm:^20.11.16" - "@types/react": "npm:^18.2.52" + "@types/react": "npm:^18.2.53" "@types/react-dom": "npm:^18.2.18" "@types/react-router-dom": "npm:^5.3.3" "@typescript-eslint/eslint-plugin": "npm:^6.20.0" diff --git a/lib/AsyncTCP/library.json b/lib/AsyncTCP/library.json deleted file mode 100644 index e6befd42b..000000000 --- a/lib/AsyncTCP/library.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "name": "AsyncTCP-esphome", - "description": "Asynchronous TCP Library for ESP32", - "keywords": "async,tcp", - "authors": { - "name": "Hristo Gochkov", - "maintainer": true - }, - "repository": { - "type": "git", - "url": "https://github.com/esphome/AsyncTCP.git" - }, - "version": "2.1.1", - "license": "LGPL-3.0", - "frameworks": "arduino", - "platforms": [ - "espressif32", - "libretiny" - ], - "build": { - "libCompatMode": 2 - } -} diff --git a/lib/ESPAsyncWebServer/library.json b/lib/ESPAsyncWebServer/library.json deleted file mode 100644 index 94271bdd4..000000000 --- a/lib/ESPAsyncWebServer/library.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "name": "ESP Async WebServer", - "version": "2.6.1", - "description": "Asynchronous HTTP and WebSocket Server Library for ESP32. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", - "keywords": "http,async,websocket,webserver", - "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", - "repository": { - "type": "git", - "url": "https://github.com/mathieucarbou/ESPAsyncWebServer.git" - }, - "authors": [ - { - "name": "Hristo Gochkov" - }, - { - "name": "Mathieu Carbou", - "maintainer": true - } - ], - "license": "LGPL-3.0", - "frameworks": "arduino", - "platforms": [ - "espressif32" - ], - "dependencies": [ - { - "owner": "esphome", - "name": "AsyncTCP-esphome", - "version": "^2.1.1", - "platforms": "espressif32" - } - ], - "export": { - "include": [ - "examples", - "src", - "library.json", - "library.properties", - "LICENSE", - "README.md" - ] - } -} \ No newline at end of file diff --git a/lib/ESPAsyncWebServer/src/AsyncJson.h b/lib/ESPAsyncWebServer/src/AsyncJson.h index 7c8e278e4..48f5b7867 100644 --- a/lib/ESPAsyncWebServer/src/AsyncJson.h +++ b/lib/ESPAsyncWebServer/src/AsyncJson.h @@ -38,18 +38,8 @@ #include #include -#if ARDUINOJSON_VERSION_MAJOR == 6 -#ifndef DYNAMIC_JSON_DOCUMENT_SIZE -#define DYNAMIC_JSON_DOCUMENT_SIZE 1024 -#endif -#endif - constexpr const char * JSON_MIMETYPE = "application/json"; -/* - * Json Response - * */ - class ChunkPrint : public Print { private: uint8_t * _destination; @@ -129,40 +119,11 @@ class MsgpackAsyncJsonResponse : public AsyncAbstractResponse { class AsyncJsonResponse : public AsyncAbstractResponse { protected: -#if ARDUINOJSON_VERSION_MAJOR == 5 - DynamicJsonBuffer _jsonBuffer; -#elif ARDUINOJSON_VERSION_MAJOR == 6 - DynamicJsonDocument _jsonBuffer; -#else JsonDocument _jsonBuffer; -#endif - - JsonVariant _root; - bool _isValid; + JsonVariant _root; + bool _isValid; public: -#if ARDUINOJSON_VERSION_MAJOR == 5 - AsyncJsonResponse(bool isArray = false) - : _isValid{false} { - _code = 200; - _contentType = JSON_MIMETYPE; - if (isArray) - _root = _jsonBuffer.createArray(); - else - _root = _jsonBuffer.createObject(); - } -#elif ARDUINOJSON_VERSION_MAJOR == 6 - AsyncJsonResponse(bool isArray = false, size_t maxJsonBufferSize = DYNAMIC_JSON_DOCUMENT_SIZE) - : _jsonBuffer(maxJsonBufferSize) - , _isValid{false} { - _code = 200; - _contentType = JSON_MIMETYPE; - if (isArray) - _root = _jsonBuffer.createNestedArray(); - else - _root = _jsonBuffer.createNestedObject(); - } -#else AsyncJsonResponse(bool isArray = false) : _isValid{false} { _code = 200; @@ -172,7 +133,6 @@ class AsyncJsonResponse : public AsyncAbstractResponse { else _root = _jsonBuffer.add(); } -#endif ~AsyncJsonResponse() { } @@ -183,11 +143,7 @@ class AsyncJsonResponse : public AsyncAbstractResponse { return _isValid; } size_t setLength() { -#if ARDUINOJSON_VERSION_MAJOR == 5 - _contentLength = _root.measureLength(); -#else _contentLength = measureJson(_root); -#endif if (_contentLength) { _isValid = true; @@ -201,33 +157,18 @@ class AsyncJsonResponse : public AsyncAbstractResponse { size_t _fillBuffer(uint8_t * data, size_t len) { ChunkPrint dest(data, _sentLength, len); - -#if ARDUINOJSON_VERSION_MAJOR == 5 - _root.printTo(dest); -#else serializeJson(_root, dest); -#endif return len; } }; class PrettyAsyncJsonResponse : public AsyncJsonResponse { public: -#if ARDUINOJSON_VERSION_MAJOR == 6 - PrettyAsyncJsonResponse(bool isArray = false, size_t maxJsonBufferSize = DYNAMIC_JSON_DOCUMENT_SIZE) - : AsyncJsonResponse{isArray, maxJsonBufferSize} { - } -#else PrettyAsyncJsonResponse(bool isArray = false) : AsyncJsonResponse{isArray} { } -#endif size_t setLength() { -#if ARDUINOJSON_VERSION_MAJOR == 5 - _contentLength = _root.measurePrettyLength(); -#else _contentLength = measureJsonPretty(_root); -#endif if (_contentLength) { _isValid = true; } @@ -235,11 +176,7 @@ class PrettyAsyncJsonResponse : public AsyncJsonResponse { } size_t _fillBuffer(uint8_t * data, size_t len) { ChunkPrint dest(data, _sentLength, len); -#if ARDUINOJSON_VERSION_MAJOR == 5 - _root.prettyPrintTo(dest); -#else serializeJsonPretty(_root, dest); -#endif return len; } }; @@ -253,28 +190,15 @@ class AsyncCallbackJsonWebHandler : public AsyncWebHandler { WebRequestMethodComposite _method; ArJsonRequestHandlerFunction _onRequest; size_t _contentLength; -#if ARDUINOJSON_VERSION_MAJOR == 6 - const size_t maxJsonBufferSize; -#endif - size_t _maxContentLength; + size_t _maxContentLength; public: -#if ARDUINOJSON_VERSION_MAJOR == 6 - AsyncCallbackJsonWebHandler(const String & uri, ArJsonRequestHandlerFunction onRequest, size_t maxJsonBufferSize = DYNAMIC_JSON_DOCUMENT_SIZE) - : _uri(uri) - , _method(HTTP_POST | HTTP_PUT | HTTP_PATCH) - , _onRequest(onRequest) - , maxJsonBufferSize(maxJsonBufferSize) - , _maxContentLength(16384) { - } -#else AsyncCallbackJsonWebHandler(const String & uri, ArJsonRequestHandlerFunction onRequest) : _uri(uri) - , _method(HTTP_POST | HTTP_PUT | HTTP_PATCH) + , _method(HTTP_GET | HTTP_POST | HTTP_PUT | HTTP_PATCH) , _onRequest(onRequest) , _maxContentLength(16384) { } -#endif void setMethod(WebRequestMethodComposite method) { _method = method; @@ -286,6 +210,7 @@ class AsyncCallbackJsonWebHandler : public AsyncWebHandler { _onRequest = fn; } + virtual bool canHandle(AsyncWebServerRequest * request) override final { if (!_onRequest) return false; @@ -305,28 +230,17 @@ class AsyncCallbackJsonWebHandler : public AsyncWebHandler { virtual void handleRequest(AsyncWebServerRequest * request) override final { if (_onRequest) { + JsonVariant json; // empty variant if (request->_tempObject != NULL) { -#if ARDUINOJSON_VERSION_MAJOR == 5 - DynamicJsonBuffer jsonBuffer; - JsonVariant json = jsonBuffer.parse((uint8_t *)(request->_tempObject)); - if (json.success()) { -#elif ARDUINOJSON_VERSION_MAJOR == 6 - DynamicJsonDocument jsonBuffer(this->maxJsonBufferSize); - DeserializationError error = deserializeJson(jsonBuffer, (uint8_t *)(request->_tempObject)); - if (!error) { - JsonVariant json = jsonBuffer.as(); -#else JsonDocument jsonBuffer; DeserializationError error = deserializeJson(jsonBuffer, (uint8_t *)(request->_tempObject)); if (!error) { - JsonVariant json = jsonBuffer.as(); -#endif - + json = jsonBuffer.as(); _onRequest(request, json); return; } } - request->send(_contentLength > _maxContentLength ? 413 : 400); + _onRequest(request, json); } else { request->send(500); } diff --git a/lib/framework/HttpEndpoint.h b/lib/framework/HttpEndpoint.h index 3c1902583..00cf6e20f 100644 --- a/lib/framework/HttpEndpoint.h +++ b/lib/framework/HttpEndpoint.h @@ -34,21 +34,19 @@ class HttpEndpoint { , _stateUpdater(stateUpdater) , _statefulService(statefulService) { // Create the GET and POST endpoints - // We can't use HTTP_ANY and process one a single endpoint due to the way the ESPAsyncWebServer library works - // Could also use server->on() but this is more efficient - - // create the GET - GEThandler = new AsyncCallbackWebHandler(); - GEThandler->setUri(servicePath); - GEThandler->setMethod(HTTP_GET); - GEThandler->onRequest(securityManager->wrapRequest(std::bind(&HttpEndpoint::fetchSettings, this, _1), authenticationPredicate)); - server->addHandler(GEThandler); - - // create the POST - POSThandler = - new AsyncCallbackJsonWebHandler(servicePath, - securityManager->wrapCallback(std::bind(&HttpEndpoint::updateSettings, this, _1, _2), authenticationPredicate)); - POSThandler->setMethod(HTTP_POST); + POSThandler = new AsyncCallbackJsonWebHandler(servicePath, + securityManager->wrapCallback( + [this](AsyncWebServerRequest * request, JsonVariant json) { + // + if (request->method() == HTTP_GET) { + fetchSettings(request); + } else if (request->method() == HTTP_POST) { + updateSettings(request, json); + } else { + request->send(405, "application/json", "{\"message\":\"Method Not Allowed\"}"); + } + }, + authenticationPredicate)); server->addHandler(POSThandler); } @@ -59,20 +57,25 @@ class HttpEndpoint { request->send(400); return; } + JsonObject jsonObject = json.as(); StateUpdateResult outcome = _statefulService->updateWithoutPropagation(jsonObject, _stateUpdater); + if (outcome == StateUpdateResult::ERROR) { request->send(400); return; } else if ((outcome == StateUpdateResult::CHANGED) || (outcome == StateUpdateResult::CHANGED_RESTART)) { request->onDisconnect([this]() { _statefulService->callUpdateHandlers(HTTP_ENDPOINT_ORIGIN_ID); }); } + AsyncJsonResponse * response = new AsyncJsonResponse(false); jsonObject = response->getRoot().to(); _statefulService->read(jsonObject, _stateReader); + if (outcome == StateUpdateResult::CHANGED_RESTART) { response->setCode(205); // reboot required } + response->setLength(); request->send(response); } diff --git a/pio_local.ini_example b/pio_local.ini_example index 77c68f171..9e25f8543 100644 --- a/pio_local.ini_example +++ b/pio_local.ini_example @@ -71,7 +71,7 @@ build_flags = -D EMSESP_TEST -D EMSESP_DEBUG -D CONFIG_ETH_ENABLED - -D TASMOTA_SDK + -D CONFIG_ASYNC_TCP_STACK_SIZE=8192 '-DEMSESP_DEFAULT_BOARD_PROFILE="Test"' [env:lolin_s3] From 1024dbb61f19a0d2df592406e853ad8dcb04bfe8 Mon Sep 17 00:00:00 2001 From: proddy Date: Fri, 9 Feb 2024 18:23:55 +0100 Subject: [PATCH 02/54] refactoring --- interface/package.json | 18 +- interface/yarn.lock | 265 +++++++++++++------------- lib/ESPAsyncWebServer/src/AsyncJson.h | 89 +-------- lib/framework/HttpEndpoint.h | 64 +++---- src/web/WebCustomizationService.cpp | 2 +- src/web/WebDataService.cpp | 2 +- 6 files changed, 178 insertions(+), 262 deletions(-) diff --git a/interface/package.json b/interface/package.json index 362e03882..14b862a2a 100644 --- a/interface/package.json +++ b/interface/package.json @@ -26,14 +26,14 @@ "@babel/core": "^7.23.9", "@emotion/react": "^11.11.3", "@emotion/styled": "^11.11.0", - "@mui/icons-material": "^5.15.7", - "@mui/material": "^5.15.7", + "@mui/icons-material": "^5.15.9", + "@mui/material": "^5.15.9", "@table-library/react-table-library": "4.1.7", "@types/imagemin": "^8.0.5", "@types/lodash-es": "^4.17.12", - "@types/node": "^20.11.16", - "@types/react": "^18.2.53", - "@types/react-dom": "^18.2.18", + "@types/node": "^20.11.17", + "@types/react": "^18.2.55", + "@types/react-dom": "^18.2.19", "@types/react-router-dom": "^5.3.3", "alova": "^2.17.0", "async-validator": "^4.2.5", @@ -54,8 +54,8 @@ "devDependencies": { "@preact/compat": "^17.1.2", "@preact/preset-vite": "^2.8.1", - "@typescript-eslint/eslint-plugin": "^6.20.0", - "@typescript-eslint/parser": "^6.20.0", + "@typescript-eslint/eslint-plugin": "^6.21.0", + "@typescript-eslint/parser": "^6.21.0", "concurrently": "^8.2.2", "eslint": "^8.56.0", "eslint-config-airbnb": "^19.0.4", @@ -68,11 +68,11 @@ "eslint-plugin-prettier": "alpha", "eslint-plugin-react": "^7.33.2", "eslint-plugin-react-hooks": "^4.6.0", - "preact": "^10.19.3", + "preact": "^10.19.4", "prettier": "^3.2.5", "rollup-plugin-visualizer": "^5.12.0", "terser": "^5.27.0", - "vite": "^5.0.12", + "vite": "^5.1.1", "vite-plugin-imagemin": "^0.6.1", "vite-tsconfig-paths": "^4.3.1" }, diff --git a/interface/yarn.lock b/interface/yarn.lock index 0f649fefe..10b067180 100644 --- a/interface/yarn.lock +++ b/interface/yarn.lock @@ -992,14 +992,14 @@ __metadata: languageName: node linkType: hard -"@mui/base@npm:5.0.0-beta.34": - version: 5.0.0-beta.34 - resolution: "@mui/base@npm:5.0.0-beta.34" +"@mui/base@npm:5.0.0-beta.36": + version: 5.0.0-beta.36 + resolution: "@mui/base@npm:5.0.0-beta.36" dependencies: "@babel/runtime": "npm:^7.23.9" "@floating-ui/react-dom": "npm:^2.0.8" "@mui/types": "npm:^7.2.13" - "@mui/utils": "npm:^5.15.7" + "@mui/utils": "npm:^5.15.9" "@popperjs/core": "npm:^2.11.8" clsx: "npm:^2.1.0" prop-types: "npm:^15.8.1" @@ -1010,20 +1010,20 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 10/8705872e4290bec1a0e19cdb62cf0ead3b18c2fc4d404a4c2913107cc3418524d2f53c337878636af59595c5ac3631d1f108cbc236f6f9cd51b6efe768b65ea5 + checksum: 10/32be203df3ffa2e36095d37295adae7870489fb2ed82a156c10f9ea4a51c3d06b0c3415e8503b110aa2ee98d3d86d6c1c50e190e85130aa1c1db694afa56ab7a languageName: node linkType: hard -"@mui/core-downloads-tracker@npm:^5.15.7": - version: 5.15.7 - resolution: "@mui/core-downloads-tracker@npm:5.15.7" - checksum: 10/cdaea04222020086fd68e25bdf0f4dfdfc9a3b58a558297ef0a247f02cce8ea7671f9a31c07c5b53cfe553d24110baed2b03b701b1bea60f5c2b2e3ba56ba6fc +"@mui/core-downloads-tracker@npm:^5.15.9": + version: 5.15.9 + resolution: "@mui/core-downloads-tracker@npm:5.15.9" + checksum: 10/f0f7af8e8f6f50df29a4e41ecb59c75869f760f22df0dc534476094089c74edcd7eacb4d17e636e0b7dd06ea1f3bb6564b21dbe072f89d1b9d87373760d69e2b languageName: node linkType: hard -"@mui/icons-material@npm:^5.15.7": - version: 5.15.7 - resolution: "@mui/icons-material@npm:5.15.7" +"@mui/icons-material@npm:^5.15.9": + version: 5.15.9 + resolution: "@mui/icons-material@npm:5.15.9" dependencies: "@babel/runtime": "npm:^7.23.9" peerDependencies: @@ -1033,23 +1033,23 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 10/d6c612aab0f10f57462e5bd467f8e32240123bc59728d471b7ae3724be4b02247db694e21e03ab58341e7737da87cef3aab35f98bbed14883688b8d667ff0f30 + checksum: 10/bcda24107125108569fe8252d05297f441362d33dbb96f8c32b35ac6d280a3c9a2f03548344c73d316e26c89d2d3e74057b292be6677ab1b582d94b6cf3ba100 languageName: node linkType: hard -"@mui/material@npm:^5.15.7": - version: 5.15.7 - resolution: "@mui/material@npm:5.15.7" +"@mui/material@npm:^5.15.9": + version: 5.15.9 + resolution: "@mui/material@npm:5.15.9" dependencies: "@babel/runtime": "npm:^7.23.9" - "@mui/base": "npm:5.0.0-beta.34" - "@mui/core-downloads-tracker": "npm:^5.15.7" - "@mui/system": "npm:^5.15.7" + "@mui/base": "npm:5.0.0-beta.36" + "@mui/core-downloads-tracker": "npm:^5.15.9" + "@mui/system": "npm:^5.15.9" "@mui/types": "npm:^7.2.13" - "@mui/utils": "npm:^5.15.7" + "@mui/utils": "npm:^5.15.9" "@types/react-transition-group": "npm:^4.4.10" clsx: "npm:^2.1.0" - csstype: "npm:^3.1.2" + csstype: "npm:^3.1.3" prop-types: "npm:^15.8.1" react-is: "npm:^18.2.0" react-transition-group: "npm:^4.4.5" @@ -1066,16 +1066,16 @@ __metadata: optional: true "@types/react": optional: true - checksum: 10/bc7a31e53770b27b49786567d4d2912d6ecf163a438d75806ec98dea8fa2f0e0b2daeb6ee97cba57c9636ed2d7e3b42c5c801f9d3479f02716933f839b7df6a4 + checksum: 10/fbbb33f83520f2f0a31d7a75be02c3c038da0bd2d2a914eadbe890783f18e9a93f818ea93da21cc6a6c303352662b4da764c67094183cee5133f810ffabead07 languageName: node linkType: hard -"@mui/private-theming@npm:^5.15.7": - version: 5.15.7 - resolution: "@mui/private-theming@npm:5.15.7" +"@mui/private-theming@npm:^5.15.9": + version: 5.15.9 + resolution: "@mui/private-theming@npm:5.15.9" dependencies: "@babel/runtime": "npm:^7.23.9" - "@mui/utils": "npm:^5.15.7" + "@mui/utils": "npm:^5.15.9" prop-types: "npm:^15.8.1" peerDependencies: "@types/react": ^17.0.0 || ^18.0.0 @@ -1083,17 +1083,17 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 10/07d85483924f1ab641ff9810f5379d28bd0661db1b42604e1c1602d610d114396c1bd187eefd26b9c303727d7d16a4758ca5c8ffbc1b410cbae156edf8b9472f + checksum: 10/ca6d0643289eb14e127d46a516311807a7935994dcbb14a108e756ba9fe39bf08e2fe2f2bd75cec5a71817f3b2fe74de2f3322b67931539ced5e2f13aa9e2326 languageName: node linkType: hard -"@mui/styled-engine@npm:^5.15.7": - version: 5.15.7 - resolution: "@mui/styled-engine@npm:5.15.7" +"@mui/styled-engine@npm:^5.15.9": + version: 5.15.9 + resolution: "@mui/styled-engine@npm:5.15.9" dependencies: "@babel/runtime": "npm:^7.23.9" "@emotion/cache": "npm:^11.11.0" - csstype: "npm:^3.1.2" + csstype: "npm:^3.1.3" prop-types: "npm:^15.8.1" peerDependencies: "@emotion/react": ^11.4.1 @@ -1104,21 +1104,21 @@ __metadata: optional: true "@emotion/styled": optional: true - checksum: 10/965e5738577db0d40904554b341395d337c93d7b4ebba783cb5362b6aa7f7e0be2cf1999d7c14daca6caba37a51f13188eaf260ff5b4099a269b1c155eee3773 + checksum: 10/ddf0bda85507419829c8fe3735b5b05d9544fea0f954de574a9841d46d14dd750050834aae5b1f0b676a1dc5fe1278c22fb16415df7d6202d6aa49fea12d59de languageName: node linkType: hard -"@mui/system@npm:^5.15.7": - version: 5.15.7 - resolution: "@mui/system@npm:5.15.7" +"@mui/system@npm:^5.15.9": + version: 5.15.9 + resolution: "@mui/system@npm:5.15.9" dependencies: "@babel/runtime": "npm:^7.23.9" - "@mui/private-theming": "npm:^5.15.7" - "@mui/styled-engine": "npm:^5.15.7" + "@mui/private-theming": "npm:^5.15.9" + "@mui/styled-engine": "npm:^5.15.9" "@mui/types": "npm:^7.2.13" - "@mui/utils": "npm:^5.15.7" + "@mui/utils": "npm:^5.15.9" clsx: "npm:^2.1.0" - csstype: "npm:^3.1.2" + csstype: "npm:^3.1.3" prop-types: "npm:^15.8.1" peerDependencies: "@emotion/react": ^11.5.0 @@ -1132,7 +1132,7 @@ __metadata: optional: true "@types/react": optional: true - checksum: 10/49db180adf1e3341cf14791c93711d16c76aad371dd43966da49c8727751d5c611835be8bac61278269414820c8f6bbd41481fa615df9a1cbc79be5846ef8896 + checksum: 10/85c2d18f3846cc1554db48071606a52f22186cf4ac1b0be748b275a8e200c12528c477acb794b8eb545e4603e5b8566186ea022eb09b5b1a3668554dd0ea9c7d languageName: node linkType: hard @@ -1148,9 +1148,9 @@ __metadata: languageName: node linkType: hard -"@mui/utils@npm:^5.15.7": - version: 5.15.7 - resolution: "@mui/utils@npm:5.15.7" +"@mui/utils@npm:^5.15.9": + version: 5.15.9 + resolution: "@mui/utils@npm:5.15.9" dependencies: "@babel/runtime": "npm:^7.23.9" "@types/prop-types": "npm:^15.7.11" @@ -1162,7 +1162,7 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 10/34f4ed23d1ac8ed7cc4c027789ea60def6a85d922f742ff57a614c0a77a839d38de40031895a867c0dadc1e5f226ac7044f2fea084297201326f0201c3f85237 + checksum: 10/8628e4402856427bbc1ee3628afff596149ae3067ca6d62a1890d7b15217248fbeb65ec9360afc6963b330c08945fe6452deef2849d8ca35d894b42746cdad77 languageName: node linkType: hard @@ -1590,12 +1590,12 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:^20.11.16": - version: 20.11.16 - resolution: "@types/node@npm:20.11.16" +"@types/node@npm:^20.11.17": + version: 20.11.17 + resolution: "@types/node@npm:20.11.17" dependencies: undici-types: "npm:~5.26.4" - checksum: 10/751f50ec5c9332b11515e82fe37c71479ac4449b711280aa3c7910edf67b1e3f5ac00041512add543f9a892096a68356406998bf02a2c809a73d176c44c28414 + checksum: 10/3342df87258d1c56154bcd4b85180f48675427b235971e6e6e2e037353f5a2ae9aaa05ba5df0fe1e2d2f1022c8d856fd39056b9d7f50ea30c0ca3214137cae1d languageName: node linkType: hard @@ -1620,12 +1620,12 @@ __metadata: languageName: node linkType: hard -"@types/react-dom@npm:^18.2.18": - version: 18.2.18 - resolution: "@types/react-dom@npm:18.2.18" +"@types/react-dom@npm:^18.2.19": + version: 18.2.19 + resolution: "@types/react-dom@npm:18.2.19" dependencies: "@types/react": "npm:*" - checksum: 10/4ef7725b4cebd4a32e049097ddfdfd855a178e63ead97ab6d3084872e7d6c1acd71aa923488123cd1015f0e0b11489d2b44f674a1df8fe82d7827eabbec6dbf1 + checksum: 10/98eb760ce78f1016d97c70f605f0b1a53873a548d3c2192b40c897f694fd9c8bb12baeada16581a9c7b26f5022c1d2613547be98284d8f1b82d1611b1e3e7df0 languageName: node linkType: hard @@ -1670,14 +1670,14 @@ __metadata: languageName: node linkType: hard -"@types/react@npm:^18.2.53": - version: 18.2.53 - resolution: "@types/react@npm:18.2.53" +"@types/react@npm:^18.2.55": + version: 18.2.55 + resolution: "@types/react@npm:18.2.55" dependencies: "@types/prop-types": "npm:*" "@types/scheduler": "npm:*" csstype: "npm:^3.0.2" - checksum: 10/9a518aef07c6bb743aa18a2aea7f618d4e7c9e44e14d25119d2e255c48e68ecd901ede8b4eaf22ffe4f52c1ff85e11634ec75e73dcfc0719cc52269629f13d69 + checksum: 10/bf8fe19e73575489e63c0726355f164157cd69e75f2a862436ad2c0586e732cb953a7255a6bc73145e8f9506ee7a723f9a569ca9a39c53984e5b12b84e1c718a languageName: node linkType: hard @@ -1713,15 +1713,15 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:^6.20.0": - version: 6.20.0 - resolution: "@typescript-eslint/eslint-plugin@npm:6.20.0" +"@typescript-eslint/eslint-plugin@npm:^6.21.0": + version: 6.21.0 + resolution: "@typescript-eslint/eslint-plugin@npm:6.21.0" dependencies: "@eslint-community/regexpp": "npm:^4.5.1" - "@typescript-eslint/scope-manager": "npm:6.20.0" - "@typescript-eslint/type-utils": "npm:6.20.0" - "@typescript-eslint/utils": "npm:6.20.0" - "@typescript-eslint/visitor-keys": "npm:6.20.0" + "@typescript-eslint/scope-manager": "npm:6.21.0" + "@typescript-eslint/type-utils": "npm:6.21.0" + "@typescript-eslint/utils": "npm:6.21.0" + "@typescript-eslint/visitor-keys": "npm:6.21.0" debug: "npm:^4.3.4" graphemer: "npm:^1.4.0" ignore: "npm:^5.2.4" @@ -1734,44 +1734,44 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 10/dee6a2392c831e6ae69611ecc4de06e66a7b16f6bf6d8e3bfd25091eb14d88c9d0bb9c9cd634efcfa318902341f7a459cf48f713d55cb1d610145ca1f52af4d3 + checksum: 10/a57de0f630789330204cc1531f86cfc68b391cafb1ba67c8992133f1baa2a09d629df66e71260b040de4c9a3ff1252952037093c4128b0d56c4dbb37720b4c1d languageName: node linkType: hard -"@typescript-eslint/parser@npm:^6.20.0": - version: 6.20.0 - resolution: "@typescript-eslint/parser@npm:6.20.0" +"@typescript-eslint/parser@npm:^6.21.0": + version: 6.21.0 + resolution: "@typescript-eslint/parser@npm:6.21.0" dependencies: - "@typescript-eslint/scope-manager": "npm:6.20.0" - "@typescript-eslint/types": "npm:6.20.0" - "@typescript-eslint/typescript-estree": "npm:6.20.0" - "@typescript-eslint/visitor-keys": "npm:6.20.0" + "@typescript-eslint/scope-manager": "npm:6.21.0" + "@typescript-eslint/types": "npm:6.21.0" + "@typescript-eslint/typescript-estree": "npm:6.21.0" + "@typescript-eslint/visitor-keys": "npm:6.21.0" debug: "npm:^4.3.4" peerDependencies: eslint: ^7.0.0 || ^8.0.0 peerDependenciesMeta: typescript: optional: true - checksum: 10/691062d47cae7977604ede848ffff3689162428a53577f298989f585954aa3a3450e7fd5c2b363d024cd5f16022c163cecf0f1f1d138234bbd78048050b4b8bf + checksum: 10/4d51cdbc170e72275efc5ef5fce48a81ec431e4edde8374f4d0213d8d370a06823e1a61ae31d502a5f1b0d1f48fc4d29a1b1b5c2dcf809d66d3872ccf6e46ac7 languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:6.20.0": - version: 6.20.0 - resolution: "@typescript-eslint/scope-manager@npm:6.20.0" +"@typescript-eslint/scope-manager@npm:6.21.0": + version: 6.21.0 + resolution: "@typescript-eslint/scope-manager@npm:6.21.0" dependencies: - "@typescript-eslint/types": "npm:6.20.0" - "@typescript-eslint/visitor-keys": "npm:6.20.0" - checksum: 10/2c1a644f2931454b34875f2e6dffad52a1fc7b6ac508d7d1ad3cd9da028a7dff9c6191feeea2c9ca691deba199ac9e83cbd0036914be4cd45b6954437f03c09a + "@typescript-eslint/types": "npm:6.21.0" + "@typescript-eslint/visitor-keys": "npm:6.21.0" + checksum: 10/fe91ac52ca8e09356a71dc1a2f2c326480f3cccfec6b2b6d9154c1a90651ab8ea270b07c67df5678956c3bbf0bbe7113ab68f68f21b20912ea528b1214197395 languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:6.20.0": - version: 6.20.0 - resolution: "@typescript-eslint/type-utils@npm:6.20.0" +"@typescript-eslint/type-utils@npm:6.21.0": + version: 6.21.0 + resolution: "@typescript-eslint/type-utils@npm:6.21.0" dependencies: - "@typescript-eslint/typescript-estree": "npm:6.20.0" - "@typescript-eslint/utils": "npm:6.20.0" + "@typescript-eslint/typescript-estree": "npm:6.21.0" + "@typescript-eslint/utils": "npm:6.21.0" debug: "npm:^4.3.4" ts-api-utils: "npm:^1.0.1" peerDependencies: @@ -1779,23 +1779,23 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 10/bc2f2793cfec3463164b5f5ded31b4e169e21c3a1990c1ce4effe70a359c486d92fbbc4cd92758bbf1c30a468ad0839e0fa890bd452c707d0c294cb3a7b14021 + checksum: 10/d03fb3ee1caa71f3ce053505f1866268d7ed79ffb7fed18623f4a1253f5b8f2ffc92636d6fd08fcbaf5bd265a6de77bf192c53105131e4724643dfc910d705fc languageName: node linkType: hard -"@typescript-eslint/types@npm:6.20.0": - version: 6.20.0 - resolution: "@typescript-eslint/types@npm:6.20.0" - checksum: 10/74ed1761e27c3c1a29fd260fe51096f42cfb1472b20390d6df6ec41de0420208f379e809de416e81cd7c00fdc3d5550b2391872be56bf4a1b0c595f71db0b1ea +"@typescript-eslint/types@npm:6.21.0": + version: 6.21.0 + resolution: "@typescript-eslint/types@npm:6.21.0" + checksum: 10/e26da86d6f36ca5b6ef6322619f8ec55aabcd7d43c840c977ae13ae2c964c3091fc92eb33730d8be08927c9de38466c5323e78bfb270a9ff1d3611fe821046c5 languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:6.20.0": - version: 6.20.0 - resolution: "@typescript-eslint/typescript-estree@npm:6.20.0" +"@typescript-eslint/typescript-estree@npm:6.21.0": + version: 6.21.0 + resolution: "@typescript-eslint/typescript-estree@npm:6.21.0" dependencies: - "@typescript-eslint/types": "npm:6.20.0" - "@typescript-eslint/visitor-keys": "npm:6.20.0" + "@typescript-eslint/types": "npm:6.21.0" + "@typescript-eslint/visitor-keys": "npm:6.21.0" debug: "npm:^4.3.4" globby: "npm:^11.1.0" is-glob: "npm:^4.0.3" @@ -1805,34 +1805,34 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 10/55b280c6e71c79cb009ac80189a7f0e1aa9011bc7206c810bbb52d9703a894aa2817dfd44d947edf64d62f3aa0962e01f3423fcb21d2f39964a4840287d9e196 + checksum: 10/b32fa35fca2a229e0f5f06793e5359ff9269f63e9705e858df95d55ca2cd7fdb5b3e75b284095a992c48c5fc46a1431a1a4b6747ede2dd08929dc1cbacc589b8 languageName: node linkType: hard -"@typescript-eslint/utils@npm:6.20.0": - version: 6.20.0 - resolution: "@typescript-eslint/utils@npm:6.20.0" +"@typescript-eslint/utils@npm:6.21.0": + version: 6.21.0 + resolution: "@typescript-eslint/utils@npm:6.21.0" dependencies: "@eslint-community/eslint-utils": "npm:^4.4.0" "@types/json-schema": "npm:^7.0.12" "@types/semver": "npm:^7.5.0" - "@typescript-eslint/scope-manager": "npm:6.20.0" - "@typescript-eslint/types": "npm:6.20.0" - "@typescript-eslint/typescript-estree": "npm:6.20.0" + "@typescript-eslint/scope-manager": "npm:6.21.0" + "@typescript-eslint/types": "npm:6.21.0" + "@typescript-eslint/typescript-estree": "npm:6.21.0" semver: "npm:^7.5.4" peerDependencies: eslint: ^7.0.0 || ^8.0.0 - checksum: 10/6d4604be6123e0073dd5e7dd357c95b370c678572d2e982478d0d6937d4d65f0cad0ac207b8b724f3bce239e64ba1ddd6bece11e1592734d8bf691177e6971e6 + checksum: 10/b404a2c55a425a79d054346ae123087d30c7ecf7ed7abcf680c47bf70c1de4fabadc63434f3f460b2fa63df76bc9e4a0b9fa2383bb8a9fcd62733fb5c4e4f3e3 languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:6.20.0": - version: 6.20.0 - resolution: "@typescript-eslint/visitor-keys@npm:6.20.0" +"@typescript-eslint/visitor-keys@npm:6.21.0": + version: 6.21.0 + resolution: "@typescript-eslint/visitor-keys@npm:6.21.0" dependencies: - "@typescript-eslint/types": "npm:6.20.0" + "@typescript-eslint/types": "npm:6.21.0" eslint-visitor-keys: "npm:^3.4.1" - checksum: 10/df066c73f3880ad78880c442f307e58f026e6047d9caab9d7c356d13276f4fe466fab3e8d19cdb1e6749e87639cb7c4babcfe118f554fcd2d3929ce9f4983216 + checksum: 10/30422cdc1e2ffad203df40351a031254b272f9c6f2b7e02e9bfa39e3fc2c7b1c6130333b0057412968deda17a3a68a578a78929a8139c6acef44d9d841dc72e1 languageName: node linkType: hard @@ -1851,19 +1851,19 @@ __metadata: "@babel/core": "npm:^7.23.9" "@emotion/react": "npm:^11.11.3" "@emotion/styled": "npm:^11.11.0" - "@mui/icons-material": "npm:^5.15.7" - "@mui/material": "npm:^5.15.7" + "@mui/icons-material": "npm:^5.15.9" + "@mui/material": "npm:^5.15.9" "@preact/compat": "npm:^17.1.2" "@preact/preset-vite": "npm:^2.8.1" "@table-library/react-table-library": "npm:4.1.7" "@types/imagemin": "npm:^8.0.5" "@types/lodash-es": "npm:^4.17.12" - "@types/node": "npm:^20.11.16" - "@types/react": "npm:^18.2.53" - "@types/react-dom": "npm:^18.2.18" + "@types/node": "npm:^20.11.17" + "@types/react": "npm:^18.2.55" + "@types/react-dom": "npm:^18.2.19" "@types/react-router-dom": "npm:^5.3.3" - "@typescript-eslint/eslint-plugin": "npm:^6.20.0" - "@typescript-eslint/parser": "npm:^6.20.0" + "@typescript-eslint/eslint-plugin": "npm:^6.21.0" + "@typescript-eslint/parser": "npm:^6.21.0" alova: "npm:^2.17.0" async-validator: "npm:^4.2.5" concurrently: "npm:^8.2.2" @@ -1882,7 +1882,7 @@ __metadata: jwt-decode: "npm:^4.0.0" lodash-es: "npm:^4.17.21" mime-types: "npm:^2.1.35" - preact: "npm:^10.19.3" + preact: "npm:^10.19.4" prettier: "npm:^3.2.5" react: "npm:latest" react-dom: "npm:latest" @@ -1895,7 +1895,7 @@ __metadata: terser: "npm:^5.27.0" typesafe-i18n: "npm:^5.26.2" typescript: "npm:^5.3.3" - vite: "npm:^5.0.12" + vite: "npm:^5.1.1" vite-plugin-imagemin: "npm:^0.6.1" vite-tsconfig-paths: "npm:^4.3.1" languageName: unknown @@ -2889,13 +2889,20 @@ __metadata: languageName: node linkType: hard -"csstype@npm:^3.0.2, csstype@npm:^3.1.2": +"csstype@npm:^3.0.2": version: 3.1.2 resolution: "csstype@npm:3.1.2" checksum: 10/1f39c541e9acd9562996d88bc9fb62d1cb234786ef11ed275567d4b2bd82e1ceacde25debc8de3d3b4871ae02c2933fa02614004c97190711caebad6347debc2 languageName: node linkType: hard +"csstype@npm:^3.1.3": + version: 3.1.3 + resolution: "csstype@npm:3.1.3" + checksum: 10/f593cce41ff5ade23f44e77521e3a1bcc2c64107041e1bf6c3c32adc5187d0d60983292fda326154d20b01079e24931aa5b08e4467cc488b60bb1e7f6d478ade + languageName: node + linkType: hard + "currently-unhandled@npm:^0.4.1": version: 0.4.1 resolution: "currently-unhandled@npm:0.4.1" @@ -7058,21 +7065,21 @@ __metadata: languageName: node linkType: hard -"postcss@npm:^8.4.32": - version: 8.4.32 - resolution: "postcss@npm:8.4.32" +"postcss@npm:^8.4.35": + version: 8.4.35 + resolution: "postcss@npm:8.4.35" dependencies: nanoid: "npm:^3.3.7" picocolors: "npm:^1.0.0" source-map-js: "npm:^1.0.2" - checksum: 10/28084864122f29148e1f632261c408444f5ead0e0b9ea9bd9729d0468818ebe73fe5dc0075acd50c1365dbe639b46a79cba27d355ec857723a24bc9af0f18525 + checksum: 10/93a7ce50cd6188f5f486a9ca98950ad27c19dfed996c45c414fa242944497e4d084a8760d3537f078630226f2bd3c6ab84b813b488740f4432e7c7039cd73a20 languageName: node linkType: hard -"preact@npm:^10.19.3": - version: 10.19.3 - resolution: "preact@npm:10.19.3" - checksum: 10/16478272162a986f03bbde7bb681103339dd00bfe0a6dffe78f9124f3999586647a31e9cb2324ae59ca51eb7d8dd5659eef6df0f7a5f424107cd9f99dddb08e8 +"preact@npm:^10.19.4": + version: 10.19.4 + resolution: "preact@npm:10.19.4" + checksum: 10/e79051c08d61c6723a4535606c9136ea752f8bae984ae8056039e2a56f6d58d6200aa941850478dc822dca38c16469d23368e9f75d7a7e57f9ca4df70a305d0f languageName: node linkType: hard @@ -8786,13 +8793,13 @@ __metadata: languageName: node linkType: hard -"vite@npm:^5.0.12": - version: 5.0.12 - resolution: "vite@npm:5.0.12" +"vite@npm:^5.1.1": + version: 5.1.1 + resolution: "vite@npm:5.1.1" dependencies: esbuild: "npm:^0.19.3" fsevents: "npm:~2.3.3" - postcss: "npm:^8.4.32" + postcss: "npm:^8.4.35" rollup: "npm:^4.2.0" peerDependencies: "@types/node": ^18.0.0 || >=20.0.0 @@ -8822,7 +8829,7 @@ __metadata: optional: true bin: vite: bin/vite.js - checksum: 10/ed0bb26a0d0c8e1dae0b70af9e36adffd7e15d80297443fe4da762596dc81570bad7f0291f590a57c1553f5e435338d8c7ffc483bd9431a95c09d9ac90665fad + checksum: 10/bdb8e683caddaa0a9adcbf40144ca8ea3660836b208862b07d43787ea867845919af16e58745365bd13ed3b7f66bbf9788a6869ee22cfaacac01645b59729c34 languageName: node linkType: hard diff --git a/lib/ESPAsyncWebServer/src/AsyncJson.h b/lib/ESPAsyncWebServer/src/AsyncJson.h index 48f5b7867..d5eb6753b 100644 --- a/lib/ESPAsyncWebServer/src/AsyncJson.h +++ b/lib/ESPAsyncWebServer/src/AsyncJson.h @@ -1,39 +1,8 @@ // AsyncJson.h -/* - Async Response to use with ArduinoJson and AsyncWebServer - Written by Andrew Melvin (SticilFace) with help from me-no-dev and BBlanchon. - Example of callback in use - - server.on("/json", HTTP_ANY, [](AsyncWebServerRequest * request) { - - AsyncJsonResponse * response = new AsyncJsonResponse(); - JsonObject& root = response->getRoot(); - root["key1"] = "key number one"; - JsonObject& nested = root.createNestedObject("nested"); - nested["key1"] = "key number one"; - - response->setLength(); - request->send(response); - }); - - -------------------- - - Async Request to use with ArduinoJson and AsyncWebServer - Written by Arsène von Wyss (avonwyss) - - Example - - AsyncCallbackJsonWebHandler* handler = new AsyncCallbackJsonWebHandler("/rest/endpoint"); - handler->onRequest([](AsyncWebServerRequest *request, JsonVariant &json) { - JsonObject& jsonObj = json.as(); - // ... - }); - server.addHandler(handler); - -*/ #ifndef ASYNC_JSON_H_ #define ASYNC_JSON_H_ + #include #include #include @@ -72,60 +41,18 @@ class ChunkPrint : public Print { } }; -// added by Proddy -class MsgpackAsyncJsonResponse : public AsyncAbstractResponse { - protected: - JsonDocument _jsonBuffer; - JsonVariant _root; - bool _isValid; - - public: - MsgpackAsyncJsonResponse(bool isArray = false) - : _isValid{false} { - _code = 200; - _contentType = JSON_MIMETYPE; - if (isArray) - _root = _jsonBuffer.to(); - else - _root = _jsonBuffer.add(); - } - - ~MsgpackAsyncJsonResponse() { - } - JsonVariant getRoot() { - return _root; - } - bool _sourceValid() const { - return _isValid; - } - size_t setLength() { - _contentLength = measureMsgPack(_root); - if (_contentLength) { - _isValid = true; - } - return _contentLength; - } - - size_t getSize() { - return _jsonBuffer.size(); - } - - size_t _fillBuffer(uint8_t * data, size_t len) { - ChunkPrint dest(data, _sentLength, len); - serializeMsgPack(_root, dest); - return len; - } -}; - +// added msgPack by Proddy class AsyncJsonResponse : public AsyncAbstractResponse { protected: JsonDocument _jsonBuffer; JsonVariant _root; bool _isValid; + bool _msgPack; public: - AsyncJsonResponse(bool isArray = false) - : _isValid{false} { + AsyncJsonResponse(bool isArray = false, bool msgPack = false) + : _isValid{false} + , _msgPack{msgPack} { _code = 200; _contentType = JSON_MIMETYPE; if (isArray) @@ -143,7 +70,7 @@ class AsyncJsonResponse : public AsyncAbstractResponse { return _isValid; } size_t setLength() { - _contentLength = measureJson(_root); + _contentLength = _msgPack ? measureMsgPack(_root) : measureJson(_root); if (_contentLength) { _isValid = true; @@ -157,7 +84,7 @@ class AsyncJsonResponse : public AsyncAbstractResponse { size_t _fillBuffer(uint8_t * data, size_t len) { ChunkPrint dest(data, _sentLength, len); - serializeJson(_root, dest); + _msgPack ? serializeMsgPack(_root, dest) : serializeJson(_root, dest); return len; } }; diff --git a/lib/framework/HttpEndpoint.h b/lib/framework/HttpEndpoint.h index 00cf6e20f..a2c18b23b 100644 --- a/lib/framework/HttpEndpoint.h +++ b/lib/framework/HttpEndpoint.h @@ -35,57 +35,39 @@ class HttpEndpoint { , _statefulService(statefulService) { // Create the GET and POST endpoints POSThandler = new AsyncCallbackJsonWebHandler(servicePath, - securityManager->wrapCallback( - [this](AsyncWebServerRequest * request, JsonVariant json) { - // - if (request->method() == HTTP_GET) { - fetchSettings(request); - } else if (request->method() == HTTP_POST) { - updateSettings(request, json); - } else { - request->send(405, "application/json", "{\"message\":\"Method Not Allowed\"}"); - } - }, - authenticationPredicate)); + securityManager->wrapCallback([this](AsyncWebServerRequest * request, + JsonVariant json) { handleRequest(request, json); }, + authenticationPredicate)); server->addHandler(POSThandler); } protected: // for POST - void updateSettings(AsyncWebServerRequest * request, JsonVariant json) { - if (!json.is()) { - request->send(400); - return; + void handleRequest(AsyncWebServerRequest * request, JsonVariant json) { + if (request->method() == HTTP_POST) { + // Handle POST + if (!json.is()) { + request->send(400); + return; + } + + StateUpdateResult outcome = _statefulService->updateWithoutPropagation(json.as(), _stateUpdater); + + if (outcome == StateUpdateResult::ERROR) { + request->send(400); // error + return; + } else if (outcome == StateUpdateResult::CHANGED_RESTART) { + // TODO check if works + request->send(205); // reboot required + return; + } else if (outcome == StateUpdateResult::CHANGED) { + request->onDisconnect([this]() { _statefulService->callUpdateHandlers(HTTP_ENDPOINT_ORIGIN_ID); }); + } } - JsonObject jsonObject = json.as(); - StateUpdateResult outcome = _statefulService->updateWithoutPropagation(jsonObject, _stateUpdater); - - if (outcome == StateUpdateResult::ERROR) { - request->send(400); - return; - } else if ((outcome == StateUpdateResult::CHANGED) || (outcome == StateUpdateResult::CHANGED_RESTART)) { - request->onDisconnect([this]() { _statefulService->callUpdateHandlers(HTTP_ENDPOINT_ORIGIN_ID); }); - } - - AsyncJsonResponse * response = new AsyncJsonResponse(false); - jsonObject = response->getRoot().to(); - _statefulService->read(jsonObject, _stateReader); - - if (outcome == StateUpdateResult::CHANGED_RESTART) { - response->setCode(205); // reboot required - } - - response->setLength(); - request->send(response); - } - - // for GET - void fetchSettings(AsyncWebServerRequest * request) { AsyncJsonResponse * response = new AsyncJsonResponse(false); JsonObject jsonObject = response->getRoot().to(); _statefulService->read(jsonObject, _stateReader); - response->setLength(); request->send(response); } diff --git a/src/web/WebCustomizationService.cpp b/src/web/WebCustomizationService.cpp index 04b6c1b61..5e96f1ba2 100644 --- a/src/web/WebCustomizationService.cpp +++ b/src/web/WebCustomizationService.cpp @@ -186,7 +186,7 @@ void WebCustomizationService::device_entities(AsyncWebServerRequest * request) { if (request->hasParam(F_(id))) { id = Helpers::atoint(request->getParam(F_(id))->value().c_str()); // get id from url - auto * response = new MsgpackAsyncJsonResponse(true); + auto * response = new AsyncJsonResponse(true, true); // array and msgpack // while (!response) { // delete response; diff --git a/src/web/WebDataService.cpp b/src/web/WebDataService.cpp index f1f8ab1b4..4fba68a1f 100644 --- a/src/web/WebDataService.cpp +++ b/src/web/WebDataService.cpp @@ -178,7 +178,7 @@ void WebDataService::device_data(AsyncWebServerRequest * request) { if (request->hasParam(F_(id))) { id = Helpers::atoint(request->getParam(F_(id))->value().c_str()); // get id from url - auto * response = new MsgpackAsyncJsonResponse(false); + auto * response = new AsyncJsonResponse(false, true); // use msgPack // check size // while (!response) { From b8f66641760ad8f674230e733b1d99b69dedb9af Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 10 Feb 2024 09:49:53 +0100 Subject: [PATCH 03/54] rename msgpack --- lib/ESPAsyncWebServer/src/AsyncJson.h | 10 +++--- lib_standalone/AsyncJson.h | 51 +++------------------------ 2 files changed, 9 insertions(+), 52 deletions(-) diff --git a/lib/ESPAsyncWebServer/src/AsyncJson.h b/lib/ESPAsyncWebServer/src/AsyncJson.h index d5eb6753b..207200519 100644 --- a/lib/ESPAsyncWebServer/src/AsyncJson.h +++ b/lib/ESPAsyncWebServer/src/AsyncJson.h @@ -47,12 +47,12 @@ class AsyncJsonResponse : public AsyncAbstractResponse { JsonDocument _jsonBuffer; JsonVariant _root; bool _isValid; - bool _msgPack; + bool _isMsgPack; public: - AsyncJsonResponse(bool isArray = false, bool msgPack = false) + AsyncJsonResponse(bool isArray = false, bool isMsgPack = false) : _isValid{false} - , _msgPack{msgPack} { + , _isMsgPack{isMsgPack} { _code = 200; _contentType = JSON_MIMETYPE; if (isArray) @@ -70,7 +70,7 @@ class AsyncJsonResponse : public AsyncAbstractResponse { return _isValid; } size_t setLength() { - _contentLength = _msgPack ? measureMsgPack(_root) : measureJson(_root); + _contentLength = _isMsgPack ? measureMsgPack(_root) : measureJson(_root); if (_contentLength) { _isValid = true; @@ -84,7 +84,7 @@ class AsyncJsonResponse : public AsyncAbstractResponse { size_t _fillBuffer(uint8_t * data, size_t len) { ChunkPrint dest(data, _sentLength, len); - _msgPack ? serializeMsgPack(_root, dest) : serializeJson(_root, dest); + _isMsgPack ? serializeMsgPack(_root, dest) : serializeJson(_root, dest); return len; } }; diff --git a/lib_standalone/AsyncJson.h b/lib_standalone/AsyncJson.h index 6ab5a5c35..676062f34 100644 --- a/lib_standalone/AsyncJson.h +++ b/lib_standalone/AsyncJson.h @@ -86,61 +86,18 @@ class PrettyAsyncJsonResponse { } }; -class MsgpackAsyncJsonResponse { - protected: - JsonDocument _jsonBuffer; - JsonVariant _root; - bool _isValid; - - public: - MsgpackAsyncJsonResponse(bool isArray = false) - : _isValid{false} { - if (isArray) - _root = _jsonBuffer.to(); - else - _root = _jsonBuffer.add(); - } - - ~MsgpackAsyncJsonResponse() { - } - - JsonVariant getRoot() { - return _root; - } - - bool _sourceValid() const { - return _isValid; - } - - size_t setLength() { - return 0; - } - - void setContentType(const char * s) { - } - - size_t getSize() { - return _jsonBuffer.size(); - } - - size_t _fillBuffer(uint8_t * data, size_t len) { - return len; - } - - void setCode(uint16_t) { - } -}; - class AsyncJsonResponse { protected: JsonDocument _jsonBuffer; JsonVariant _root; bool _isValid; + bool _isMsgPack; public: - AsyncJsonResponse(bool isArray = false) - : _isValid{false} { + AsyncJsonResponse(bool isArray = false, bool isMsgPack = false) + : _isValid{false} + , _isMsgPack{isMsgPack} { if (isArray) _root = _jsonBuffer.to(); else From 8c602cd05859c1691dc40154213ac32cc5891bce Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 10 Feb 2024 09:50:04 +0100 Subject: [PATCH 04/54] default -O2 --- platformio.ini | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/platformio.ini b/platformio.ini index 28433fa36..c515f2765 100644 --- a/platformio.ini +++ b/platformio.ini @@ -15,6 +15,7 @@ extra_configs = core_build_flags = -D ARDUINO_ARCH_ESP32=1 -D ESP32=1 + -O2 -std=gnu++17 core_unbuild_flags = -std=gnu++11 @@ -98,7 +99,6 @@ board_build.partitions = esp32_partition_16M.csv build_unflags = ${common.unbuild_flags} build_flags = ${espressi32_base.build_flags} - -O2 '-DEMSESP_DEFAULT_BOARD_PROFILE="S32S3"' [env:esp32_4M] @@ -108,7 +108,6 @@ board_upload.flash_size = 4MB board_build.partitions = esp32_partition_4M.csv build_flags = ${espressi32_base_tasmota.build_flags} - -Os [env:esp32_4Mplus] extends = espressi32_base_tasmota @@ -163,7 +162,6 @@ board_upload.use_1200bps_touch = false board_upload.wait_for_upload_port = false build_flags = ${espressi32_base.build_flags} - -O2 '-DEMSESP_DEFAULT_BOARD_PROFILE="S32S3"' ; to build and run: pio run -e standalone -t exec From 4ac2d1a9a7f9058a4b19cd1ee35d97ea11b787e1 Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 10 Feb 2024 09:50:13 +0100 Subject: [PATCH 05/54] remove extra v --- interface/src/framework/system/SystemStatusForm.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/framework/system/SystemStatusForm.tsx b/interface/src/framework/system/SystemStatusForm.tsx index 940b4339d..f6f7203cb 100644 --- a/interface/src/framework/system/SystemStatusForm.tsx +++ b/interface/src/framework/system/SystemStatusForm.tsx @@ -215,7 +215,7 @@ const SystemStatusForm: FC = () => { - + From f167be37a1339a6bdea4e4c0b937c8fd3b4d27cf Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 10 Feb 2024 09:50:32 +0100 Subject: [PATCH 06/54] ArduinoJson 7.0.3 --- lib/ArduinoJson/ArduinoJson.h | 0 lib/ArduinoJson/CHANGELOG.md | 7 + lib/ArduinoJson/CMakeLists.txt | 25 --- lib/ArduinoJson/LICENSE.txt | 0 lib/ArduinoJson/README.md | 155 ++++++++++++++++++ lib/ArduinoJson/SUPPORT.md | 27 +++ lib/ArduinoJson/idf_component.yml | 13 -- lib/ArduinoJson/library.json | 23 --- lib/ArduinoJson/library.properties | 11 -- lib/ArduinoJson/src/ArduinoJson.h | 0 lib/ArduinoJson/src/ArduinoJson.hpp | 0 .../src/ArduinoJson/Array/ArrayData.hpp | 0 .../src/ArduinoJson/Array/ArrayImpl.hpp | 0 .../src/ArduinoJson/Array/ElementProxy.hpp | 10 +- .../src/ArduinoJson/Array/JsonArray.hpp | 29 ++-- .../src/ArduinoJson/Array/JsonArrayConst.hpp | 20 +-- .../ArduinoJson/Array/JsonArrayIterator.hpp | 0 .../src/ArduinoJson/Array/Utilities.hpp | 0 .../ArduinoJson/Collection/CollectionData.hpp | 4 + .../ArduinoJson/Collection/CollectionImpl.hpp | 0 .../src/ArduinoJson/Configuration.hpp | 0 .../Deserialization/DeserializationError.hpp | 0 .../DeserializationOptions.hpp | 0 .../ArduinoJson/Deserialization/Filter.hpp | 0 .../Deserialization/NestingLimit.hpp | 0 .../ArduinoJson/Deserialization/Reader.hpp | 0 .../Readers/ArduinoStreamReader.hpp | 0 .../Readers/ArduinoStringReader.hpp | 0 .../Deserialization/Readers/FlashReader.hpp | 0 .../Readers/IteratorReader.hpp | 0 .../Deserialization/Readers/RamReader.hpp | 0 .../Readers/StdStreamReader.hpp | 0 .../Deserialization/Readers/VariantReader.hpp | 0 .../Deserialization/deserialize.hpp | 0 .../src/ArduinoJson/Document/JsonDocument.hpp | 45 +++-- .../src/ArduinoJson/Json/EscapeSequence.hpp | 0 .../src/ArduinoJson/Json/JsonDeserializer.hpp | 0 .../src/ArduinoJson/Json/JsonSerializer.hpp | 34 ++-- .../src/ArduinoJson/Json/Latch.hpp | 0 .../ArduinoJson/Json/PrettyJsonSerializer.hpp | 0 .../src/ArduinoJson/Json/TextFormatter.hpp | 0 .../src/ArduinoJson/Json/Utf16.hpp | 0 lib/ArduinoJson/src/ArduinoJson/Json/Utf8.hpp | 0 .../src/ArduinoJson/Memory/Alignment.hpp | 0 .../src/ArduinoJson/Memory/Allocator.hpp | 0 .../ArduinoJson/Memory/ResourceManager.hpp | 0 .../src/ArduinoJson/Memory/StringBuilder.hpp | 0 .../src/ArduinoJson/Memory/StringNode.hpp | 0 .../src/ArduinoJson/Memory/StringPool.hpp | 0 .../src/ArduinoJson/Memory/VariantPool.hpp | 0 .../ArduinoJson/Memory/VariantPoolImpl.hpp | 0 .../ArduinoJson/Memory/VariantPoolList.hpp | 0 .../src/ArduinoJson/Misc/SerializedValue.hpp | 0 .../MsgPack/MsgPackDeserializer.hpp | 0 .../ArduinoJson/MsgPack/MsgPackSerializer.hpp | 22 ++- .../src/ArduinoJson/MsgPack/endianess.hpp | 0 .../src/ArduinoJson/MsgPack/ieee754.hpp | 0 lib/ArduinoJson/src/ArduinoJson/Namespace.hpp | 0 .../src/ArduinoJson/Numbers/FloatParts.hpp | 0 .../src/ArduinoJson/Numbers/FloatTraits.hpp | 0 .../src/ArduinoJson/Numbers/JsonFloat.hpp | 0 .../src/ArduinoJson/Numbers/JsonInteger.hpp | 0 .../ArduinoJson/Numbers/arithmeticCompare.hpp | 0 .../src/ArduinoJson/Numbers/convertNumber.hpp | 0 .../src/ArduinoJson/Numbers/parseNumber.hpp | 0 .../src/ArduinoJson/Object/JsonObject.hpp | 47 +++--- .../ArduinoJson/Object/JsonObjectConst.hpp | 24 +-- .../ArduinoJson/Object/JsonObjectIterator.hpp | 0 .../src/ArduinoJson/Object/JsonPair.hpp | 0 .../src/ArduinoJson/Object/MemberProxy.hpp | 14 +- .../src/ArduinoJson/Object/ObjectData.hpp | 0 .../src/ArduinoJson/Object/ObjectImpl.hpp | 0 .../src/ArduinoJson/Polyfills/alias_cast.hpp | 0 .../src/ArduinoJson/Polyfills/assert.hpp | 0 .../src/ArduinoJson/Polyfills/attributes.hpp | 3 - .../src/ArduinoJson/Polyfills/ctype.hpp | 0 .../src/ArduinoJson/Polyfills/integer.hpp | 0 .../src/ArduinoJson/Polyfills/limits.hpp | 0 .../src/ArduinoJson/Polyfills/math.hpp | 0 .../src/ArduinoJson/Polyfills/mpl/max.hpp | 0 .../src/ArduinoJson/Polyfills/pgmspace.hpp | 0 .../Polyfills/pgmspace_generic.hpp | 0 .../ArduinoJson/Polyfills/preprocessor.hpp | 0 .../src/ArduinoJson/Polyfills/type_traits.hpp | 0 .../Polyfills/type_traits/conditional.hpp | 0 .../Polyfills/type_traits/declval.hpp | 0 .../Polyfills/type_traits/enable_if.hpp | 0 .../type_traits/integral_constant.hpp | 0 .../Polyfills/type_traits/is_array.hpp | 0 .../Polyfills/type_traits/is_base_of.hpp | 0 .../Polyfills/type_traits/is_class.hpp | 0 .../Polyfills/type_traits/is_const.hpp | 0 .../Polyfills/type_traits/is_convertible.hpp | 0 .../Polyfills/type_traits/is_enum.hpp | 0 .../type_traits/is_floating_point.hpp | 0 .../Polyfills/type_traits/is_integral.hpp | 0 .../Polyfills/type_traits/is_pointer.hpp | 0 .../Polyfills/type_traits/is_same.hpp | 0 .../Polyfills/type_traits/is_signed.hpp | 0 .../Polyfills/type_traits/is_unsigned.hpp | 0 .../Polyfills/type_traits/make_unsigned.hpp | 0 .../Polyfills/type_traits/make_void.hpp | 0 .../Polyfills/type_traits/remove_const.hpp | 0 .../Polyfills/type_traits/remove_cv.hpp | 0 .../type_traits/remove_reference.hpp | 0 .../Polyfills/type_traits/type_identity.hpp | 0 .../src/ArduinoJson/Polyfills/utility.hpp | 0 .../Serialization/CountingDecorator.hpp | 0 .../src/ArduinoJson/Serialization/Writer.hpp | 0 .../Writers/ArduinoStringWriter.hpp | 0 .../Serialization/Writers/DummyWriter.hpp | 0 .../Serialization/Writers/PrintWriter.hpp | 0 .../Writers/StaticStringWriter.hpp | 0 .../Serialization/Writers/StdStreamWriter.hpp | 0 .../Serialization/Writers/StdStringWriter.hpp | 6 +- .../src/ArduinoJson/Serialization/measure.hpp | 0 .../ArduinoJson/Serialization/serialize.hpp | 0 .../Strings/Adapters/FlashString.hpp | 0 .../Strings/Adapters/JsonString.hpp | 0 .../Strings/Adapters/RamString.hpp | 0 .../Strings/Adapters/StringObject.hpp | 0 .../src/ArduinoJson/Strings/IsString.hpp | 0 .../src/ArduinoJson/Strings/JsonString.hpp | 0 .../src/ArduinoJson/Strings/StringAdapter.hpp | 0 .../ArduinoJson/Strings/StringAdapters.hpp | 0 .../src/ArduinoJson/Strings/StringTraits.hpp | 0 .../src/ArduinoJson/Variant/Converter.hpp | 0 .../src/ArduinoJson/Variant/ConverterImpl.hpp | 10 ++ .../src/ArduinoJson/Variant/JsonVariant.hpp | 6 +- .../ArduinoJson/Variant/JsonVariantConst.hpp | 42 ++--- .../ArduinoJson/Variant/JsonVariantCopier.hpp | 0 .../Variant/JsonVariantVisitor.hpp | 0 .../ArduinoJson/Variant/VariantAttorney.hpp | 7 +- .../ArduinoJson/Variant/VariantCompare.hpp | 0 .../ArduinoJson/Variant/VariantContent.hpp | 0 .../src/ArduinoJson/Variant/VariantData.hpp | 0 .../Variant/VariantDataVisitor.hpp | 0 .../ArduinoJson/Variant/VariantOperators.hpp | 0 .../ArduinoJson/Variant/VariantRefBase.hpp | 62 ++++--- .../Variant/VariantRefBaseImpl.hpp | 0 .../src/ArduinoJson/Variant/VariantSlot.hpp | 0 .../src/ArduinoJson/Variant/VariantTag.hpp | 0 .../src/ArduinoJson/Variant/VariantTo.hpp | 0 .../src/ArduinoJson/compatibility.hpp | 0 lib/ArduinoJson/src/ArduinoJson/version.hpp | 6 +- lib/ArduinoJson/src/CMakeLists.txt | 91 ---------- 146 files changed, 390 insertions(+), 353 deletions(-) mode change 100644 => 100755 lib/ArduinoJson/ArduinoJson.h mode change 100644 => 100755 lib/ArduinoJson/CHANGELOG.md delete mode 100644 lib/ArduinoJson/CMakeLists.txt mode change 100644 => 100755 lib/ArduinoJson/LICENSE.txt create mode 100755 lib/ArduinoJson/README.md create mode 100755 lib/ArduinoJson/SUPPORT.md delete mode 100644 lib/ArduinoJson/idf_component.yml delete mode 100644 lib/ArduinoJson/library.json delete mode 100644 lib/ArduinoJson/library.properties mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson.h mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Array/ArrayData.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Array/ArrayImpl.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Array/ElementProxy.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Array/JsonArray.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Array/JsonArrayConst.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Array/JsonArrayIterator.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Array/Utilities.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Collection/CollectionData.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Collection/CollectionImpl.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Configuration.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Deserialization/DeserializationError.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Deserialization/DeserializationOptions.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Deserialization/Filter.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Deserialization/NestingLimit.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Deserialization/Reader.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Deserialization/Readers/ArduinoStreamReader.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Deserialization/Readers/ArduinoStringReader.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Deserialization/Readers/FlashReader.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Deserialization/Readers/IteratorReader.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Deserialization/Readers/RamReader.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Deserialization/Readers/StdStreamReader.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Deserialization/Readers/VariantReader.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Deserialization/deserialize.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Document/JsonDocument.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Json/EscapeSequence.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Json/JsonDeserializer.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Json/JsonSerializer.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Json/Latch.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Json/PrettyJsonSerializer.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Json/TextFormatter.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Json/Utf16.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Json/Utf8.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Memory/Alignment.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Memory/Allocator.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Memory/ResourceManager.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Memory/StringBuilder.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Memory/StringNode.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Memory/StringPool.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Memory/VariantPool.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Memory/VariantPoolImpl.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Memory/VariantPoolList.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Misc/SerializedValue.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/MsgPack/MsgPackDeserializer.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/MsgPack/MsgPackSerializer.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/MsgPack/endianess.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/MsgPack/ieee754.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Namespace.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Numbers/FloatParts.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Numbers/FloatTraits.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Numbers/JsonFloat.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Numbers/JsonInteger.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Numbers/arithmeticCompare.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Numbers/convertNumber.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Numbers/parseNumber.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Object/JsonObject.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Object/JsonObjectConst.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Object/JsonObjectIterator.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Object/JsonPair.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Object/MemberProxy.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Object/ObjectData.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Object/ObjectImpl.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Polyfills/alias_cast.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Polyfills/assert.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Polyfills/attributes.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Polyfills/ctype.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Polyfills/integer.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Polyfills/limits.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Polyfills/math.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Polyfills/mpl/max.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Polyfills/pgmspace.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Polyfills/pgmspace_generic.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Polyfills/preprocessor.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/conditional.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/declval.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/enable_if.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/integral_constant.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_array.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_base_of.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_class.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_const.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_convertible.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_enum.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_floating_point.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_integral.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_pointer.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_same.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_signed.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_unsigned.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/make_unsigned.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/make_void.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/remove_const.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/remove_cv.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/remove_reference.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/type_identity.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Polyfills/utility.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Serialization/CountingDecorator.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Serialization/Writer.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Serialization/Writers/ArduinoStringWriter.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Serialization/Writers/DummyWriter.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Serialization/Writers/PrintWriter.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Serialization/Writers/StaticStringWriter.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Serialization/Writers/StdStreamWriter.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Serialization/Writers/StdStringWriter.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Serialization/measure.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Serialization/serialize.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Strings/Adapters/FlashString.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Strings/Adapters/JsonString.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Strings/Adapters/RamString.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Strings/Adapters/StringObject.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Strings/IsString.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Strings/JsonString.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Strings/StringAdapter.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Strings/StringAdapters.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Strings/StringTraits.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Variant/Converter.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Variant/ConverterImpl.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Variant/JsonVariant.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Variant/JsonVariantConst.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Variant/JsonVariantCopier.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Variant/JsonVariantVisitor.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Variant/VariantAttorney.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Variant/VariantCompare.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Variant/VariantContent.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Variant/VariantData.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Variant/VariantDataVisitor.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Variant/VariantOperators.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Variant/VariantRefBase.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Variant/VariantRefBaseImpl.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Variant/VariantSlot.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Variant/VariantTag.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/Variant/VariantTo.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/compatibility.hpp mode change 100644 => 100755 lib/ArduinoJson/src/ArduinoJson/version.hpp delete mode 100644 lib/ArduinoJson/src/CMakeLists.txt diff --git a/lib/ArduinoJson/ArduinoJson.h b/lib/ArduinoJson/ArduinoJson.h old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/CHANGELOG.md b/lib/ArduinoJson/CHANGELOG.md old mode 100644 new mode 100755 index e82281e20..fa4cfe6f0 --- a/lib/ArduinoJson/CHANGELOG.md +++ b/lib/ArduinoJson/CHANGELOG.md @@ -1,6 +1,13 @@ ArduinoJson: change log ======================= +v7.0.3 (2024-02-05) +------ + +* Improve error messages when using `char` or `char*` (issue #2043) +* Reduce stack consumption (issue #2046) +* Fix compatibility with GCC 4.8 (issue #2045) + v7.0.2 (2024-01-19) ------ diff --git a/lib/ArduinoJson/CMakeLists.txt b/lib/ArduinoJson/CMakeLists.txt deleted file mode 100644 index 6efa04b3b..000000000 --- a/lib/ArduinoJson/CMakeLists.txt +++ /dev/null @@ -1,25 +0,0 @@ -# ArduinoJson - https://arduinojson.org -# Copyright © 2014-2024, Benoit BLANCHON -# MIT License - -cmake_minimum_required(VERSION 3.15) - -if(ESP_PLATFORM) - # Build ArduinoJson as an ESP-IDF component - idf_component_register(INCLUDE_DIRS src) - return() -endif() - -project(ArduinoJson VERSION 7.0.2) - -if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME) - include(CTest) -endif() - -add_subdirectory(src) - -if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME AND BUILD_TESTING) - include(extras/CompileOptions.cmake) - add_subdirectory(extras/tests) - add_subdirectory(extras/fuzzing) -endif() diff --git a/lib/ArduinoJson/LICENSE.txt b/lib/ArduinoJson/LICENSE.txt old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/README.md b/lib/ArduinoJson/README.md new file mode 100755 index 000000000..2900240e5 --- /dev/null +++ b/lib/ArduinoJson/README.md @@ -0,0 +1,155 @@ +

+ ArduinoJson +

+ +--- + +[![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/bblanchon/ArduinoJson/ci.yml?branch=7.x&logo=github)](https://github.com/bblanchon/ArduinoJson/actions?query=workflow%3A%22Continuous+Integration%22+branch%3A7.x) +[![Continuous Integration](https://ci.appveyor.com/api/projects/status/m7s53wav1l0abssg/branch/7.x?svg=true)](https://ci.appveyor.com/project/bblanchon/arduinojson/branch/7.x) +[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/arduinojson.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:arduinojson) +[![Coveralls branch](https://img.shields.io/coveralls/github/bblanchon/ArduinoJson/7.x?logo=coveralls)](https://coveralls.io/github/bblanchon/ArduinoJson?branch=7.x) +[![GitHub stars](https://img.shields.io/github/stars/bblanchon/ArduinoJson?style=flat&logo=github&color=orange)](https://github.com/bblanchon/ArduinoJson/stargazers) +[![GitHub Sponsors](https://img.shields.io/github/sponsors/bblanchon?logo=github&color=orange)](https://github.com/sponsors/bblanchon) + +ArduinoJson is a C++ JSON library for Arduino and IoT (Internet Of Things). + +## Features + +* [JSON deserialization](https://arduinojson.org/v7/api/json/deserializejson/) + * [Optionally decodes UTF-16 escape sequences to UTF-8](https://arduinojson.org/v7/api/config/decode_unicode/) + * [Optionally supports comments in the input](https://arduinojson.org/v7/api/config/enable_comments/) + * [Optionally filters the input to keep only desired values](https://arduinojson.org/v7/api/json/deserializejson/#filtering) + * Supports single quotes as a string delimiter + * Compatible with [NDJSON](http://ndjson.org/) and [JSON Lines](https://jsonlines.org/) +* [JSON serialization](https://arduinojson.org/v7/api/json/serializejson/) + * [Can write to a buffer or a stream](https://arduinojson.org/v7/api/json/serializejson/) + * [Optionally indents the document (prettified JSON)](https://arduinojson.org/v7/api/json/serializejsonpretty/) +* [MessagePack serialization](https://arduinojson.org/v7/api/msgpack/serializemsgpack/) +* [MessagePack deserialization](https://arduinojson.org/v7/api/msgpack/deserializemsgpack/) +* Efficient + * [Twice smaller than the "official" Arduino_JSON library](https://arduinojson.org/2019/11/19/arduinojson-vs-arduino_json/) + * [Almost 10% faster than the "official" Arduino_JSON library](https://arduinojson.org/2019/11/19/arduinojson-vs-arduino_json/) + * [Consumes roughly 10% less RAM than the "official" Arduino_JSON library](https://arduinojson.org/2019/11/19/arduinojson-vs-arduino_json/) + * [Deduplicates strings](https://arduinojson.org/news/2020/08/01/version-6-16-0/) +* Versatile + * Supports [custom allocators (to use external RAM chip, for example)](https://arduinojson.org/v7/how-to/use-external-ram-on-esp32/) + * Supports [`String`](https://arduinojson.org/v7/api/config/enable_arduino_string/), [`std::string`](https://arduinojson.org/v7/api/config/enable_std_string/), and [`std::string_view`](https://arduinojson.org/v7/api/config/enable_string_view/) + * Supports [`Stream`](https://arduinojson.org/v7/api/config/enable_arduino_stream/) and [`std::istream`/`std::ostream`](https://arduinojson.org/v7/api/config/enable_std_stream/) + * Supports [Flash strings](https://arduinojson.org/v7/api/config/enable_progmem/) + * Supports [custom readers](https://arduinojson.org/v7/api/json/deserializejson/#custom-reader) and [custom writers](https://arduinojson.org/v7/api/json/serializejson/#custom-writer) + * Supports [custom converters](https://arduinojson.org/news/2021/05/04/version-6-18-0/) +* Portable + * Usable on any C++ project (not limited to Arduino) + * Compatible with C++11, C++14 and C++17 + * Support for C++98/C++03 available on [ArduinoJson 6.20.x](https://github.com/bblanchon/ArduinoJson/tree/6.20.x) + * Zero warnings with `-Wall -Wextra -pedantic` and `/W4` + * [Header-only library](https://en.wikipedia.org/wiki/Header-only) + * Works with virtually any board + * Arduino boards: [Uno](https://amzn.to/38aL2ik), [Due](https://amzn.to/36YkWi2), [Micro](https://amzn.to/35WkdwG), [Nano](https://amzn.to/2QTvwRX), [Mega](https://amzn.to/36XWhuf), [Yun](https://amzn.to/30odURc), [Leonardo](https://amzn.to/36XWjlR)... + * Espressif chips: [ESP8266](https://amzn.to/36YluV8), [ESP32](https://amzn.to/2G4pRCB) + * Lolin (WeMos) boards: [D1 mini](https://amzn.to/2QUpz7q), [D1 Mini Pro](https://amzn.to/36UsGSs)... + * Teensy boards: [4.0](https://amzn.to/30ljXGq), [3.2](https://amzn.to/2FT0EuC), [2.0](https://amzn.to/2QXUMXj) + * Particle boards: [Argon](https://amzn.to/2FQHa9X), [Boron](https://amzn.to/36WgLUd), [Electron](https://amzn.to/30vEc4k), [Photon](https://amzn.to/387F9Cd)... + * Texas Instruments boards: [MSP430](https://amzn.to/30nJWgg)... + * Soft cores: [Nios II](https://en.wikipedia.org/wiki/Nios_II)... + * Tested on all major development environments + * [Arduino IDE](https://www.arduino.cc/en/Main/Software) + * [Atmel Studio](http://www.atmel.com/microsite/atmel-studio/) + * [Atollic TrueSTUDIO](https://atollic.com/truestudio/) + * [Energia](http://energia.nu/) + * [IAR Embedded Workbench](https://www.iar.com/iar-embedded-workbench/) + * [Keil uVision](http://www.keil.com/) + * [MPLAB X IDE](http://www.microchip.com/mplab/mplab-x-ide) + * [Particle](https://www.particle.io/) + * [PlatformIO](http://platformio.org/) + * [Sloeber plugin for Eclipse](https://eclipse.baeyens.it/) + * [Visual Micro](http://www.visualmicro.com/) + * [Visual Studio](https://www.visualstudio.com/) + * [Even works with online compilers like wandbox.org](https://wandbox.org/permlink/RlZSKy17DjJ6HcdN) + * [CMake friendly](https://arduinojson.org/v7/how-to/use-arduinojson-with-cmake/) +* Well designed + * [Elegant API](http://arduinojson.org/v7/example/) + * [Thread-safe](https://en.wikipedia.org/wiki/Thread_safety) + * Self-contained (no external dependency) + * `const` friendly + * [`for` friendly](https://arduinojson.org/v7/api/jsonobject/begin_end/) + * [TMP friendly](https://en.wikipedia.org/wiki/Template_metaprogramming) + * Handles [integer overflows](https://arduinojson.org/v7/api/jsonvariant/as/#integer-overflows) +* Well tested + * [Unit test coverage close to 100%](https://coveralls.io/github/bblanchon/ArduinoJson?branch=7.x) + * Continuously tested on + * [Visual Studio 2017, 2019, 2022](https://ci.appveyor.com/project/bblanchon/arduinojson/branch/7.x) + * [GCC 4.8, 5, 6, 7, 8, 9, 10, 11, 12](https://github.com/bblanchon/ArduinoJson/actions?query=workflow%3A%22Continuous+Integration%22) + * [Clang 3.9, 4.0, 5.0, 6.0, 7, 8, 9, 10, 11, 12, 13, 14, 15](https://github.com/bblanchon/ArduinoJson/actions?query=workflow%3A%22Continuous+Integration%22) + * [Continuously fuzzed with Google OSS Fuzz](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:arduinojson) + * Passes all default checks of [clang-tidy](https://releases.llvm.org/10.0.0/tools/clang/tools/extra/docs/clang-tidy/) +* Well documented + * [Tutorials](https://arduinojson.org/v7/doc/deserialization/) + * [Examples](https://arduinojson.org/v7/example/) + * [How-tos](https://arduinojson.org/v7/example/) + * [FAQ](https://arduinojson.org/v7/faq/) + * [Troubleshooter](https://arduinojson.org/v7/troubleshooter/) + * [Book](https://arduinojson.org/book/) + * [Changelog](CHANGELOG.md) +* Vibrant user community + * Most popular of all Arduino libraries on [GitHub](https://github.com/search?o=desc&q=arduino+library&s=stars&type=Repositories) + * [Used in hundreds of projects](https://www.hackster.io/search?i=projects&q=arduinojson) + * [Responsive support](https://github.com/bblanchon/ArduinoJson/issues?q=is%3Aissue+is%3Aclosed) + +## Quickstart + +### Deserialization + +Here is a program that parses a JSON document with ArduinoJson. + +```c++ +const char* json = "{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}"; + +JsonDocument doc; +deserializeJson(doc, json); + +const char* sensor = doc["sensor"]; +long time = doc["time"]; +double latitude = doc["data"][0]; +double longitude = doc["data"][1]; +``` + +See the [tutorial on arduinojson.org](https://arduinojson.org/v7/doc/deserialization/) + +### Serialization + +Here is a program that generates a JSON document with ArduinoJson: + +```c++ +JsonDocument doc; + +doc["sensor"] = "gps"; +doc["time"] = 1351824120; +doc["data"][0] = 48.756080; +doc["data"][1] = 2.302038; + +serializeJson(doc, Serial); +// This prints: +// {"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]} +``` + +See the [tutorial on arduinojson.org](https://arduinojson.org/v7/doc/serialization/) + +## Sponsors + +ArduinoJson is thankful to its sponsors. Please give them a visit; they deserve it! + +

+ + Programming Electronics Academy + +

+

+ + 1technophile + +

+ +If you run a commercial project that embeds ArduinoJson, think about [sponsoring the library's development](https://github.com/sponsors/bblanchon): it ensures the code that your products rely on stays actively maintained. It can also give your project some exposure to the makers' community. + +If you are an individual user and want to support the development (or give a sign of appreciation), consider purchasing the book [Mastering ArduinoJson](https://arduinojson.org/book/) ❤, or simply [cast a star](https://github.com/bblanchon/ArduinoJson/stargazers) ⭐. diff --git a/lib/ArduinoJson/SUPPORT.md b/lib/ArduinoJson/SUPPORT.md new file mode 100755 index 000000000..c47e1b1ba --- /dev/null +++ b/lib/ArduinoJson/SUPPORT.md @@ -0,0 +1,27 @@ +# ArduinoJson Support + +First off, thank you very much for using ArduinoJson. + +We'll be very happy to help you, but first please read the following. + +## Before asking for help + +1. Read the [FAQ](https://arduinojson.org/faq/?utm_source=github&utm_medium=support) +2. Search in the [API Reference](https://arduinojson.org/api/?utm_source=github&utm_medium=support) + +If you did not find the answer, please create a [new issue on GitHub](https://github.com/bblanchon/ArduinoJson/issues/new). + +It is OK to add a comment to a currently opened issue, but please avoid adding comments to a closed issue. + +## Before hitting the Submit button + +Please provide all the relevant information: + +* Good title +* Short description of the problem +* Target platform +* Compiler model and version +* [MVCE](https://stackoverflow.com/help/mcve) +* Compiler output + +Good questions get fast answers! diff --git a/lib/ArduinoJson/idf_component.yml b/lib/ArduinoJson/idf_component.yml deleted file mode 100644 index 429d37339..000000000 --- a/lib/ArduinoJson/idf_component.yml +++ /dev/null @@ -1,13 +0,0 @@ -version: "7.0.2" -description: >- - A simple and efficient JSON library for embedded C++. - ⭐ 6444 stars on GitHub! - Supports serialization, deserialization, MessagePack, streams, filtering, and more. - Fully tested and documented. -url: https://arduinojson.org/ -files: - exclude: - - "**/.vs/**/*" - - ".devcontainer/**/*" - - "examples/**/*" - - "extras/**/*" diff --git a/lib/ArduinoJson/library.json b/lib/ArduinoJson/library.json deleted file mode 100644 index 46f156ac4..000000000 --- a/lib/ArduinoJson/library.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "name": "ArduinoJson", - "keywords": "json, rest, http, web", - "description": "A simple and efficient JSON library for embedded C++. ⭐ 6444 stars on GitHub! Supports serialization, deserialization, MessagePack, streams, filtering, and more. Fully tested and documented.", - "homepage": "https://arduinojson.org/?utm_source=meta&utm_medium=library.json", - "repository": { - "type": "git", - "url": "https://github.com/bblanchon/ArduinoJson.git" - }, - "version": "7.0.2", - "authors": { - "name": "Benoit Blanchon", - "url": "https://blog.benoitblanchon.fr" - }, - "export": { - "include": ["src", "examples", "LICENSE.txt", "ArduinoJson.h"] - }, - "frameworks": "*", - "platforms": "*", - "build": { - "libArchive": false - } -} diff --git a/lib/ArduinoJson/library.properties b/lib/ArduinoJson/library.properties deleted file mode 100644 index e9d9c2c7d..000000000 --- a/lib/ArduinoJson/library.properties +++ /dev/null @@ -1,11 +0,0 @@ -name=ArduinoJson -version=7.0.2 -author=Benoit Blanchon -maintainer=Benoit Blanchon -sentence=A simple and efficient JSON library for embedded C++. -paragraph=⭐ 6444 stars on GitHub! Supports serialization, deserialization, MessagePack, streams, filtering, and more. Fully tested and documented. -category=Data Processing -url=https://arduinojson.org/?utm_source=meta&utm_medium=library.properties -architectures=* -repository=https://github.com/bblanchon/ArduinoJson.git -license=MIT diff --git a/lib/ArduinoJson/src/ArduinoJson.h b/lib/ArduinoJson/src/ArduinoJson.h old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson.hpp b/lib/ArduinoJson/src/ArduinoJson.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Array/ArrayData.hpp b/lib/ArduinoJson/src/ArduinoJson/Array/ArrayData.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Array/ArrayImpl.hpp b/lib/ArduinoJson/src/ArduinoJson/Array/ArrayImpl.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Array/ElementProxy.hpp b/lib/ArduinoJson/src/ArduinoJson/Array/ElementProxy.hpp old mode 100644 new mode 100755 index 2ae26624a..f36b68ea3 --- a/lib/ArduinoJson/src/ArduinoJson/Array/ElementProxy.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Array/ElementProxy.hpp @@ -22,25 +22,25 @@ class ElementProxy : public VariantRefBase>, ElementProxy(const ElementProxy& src) : upstream_(src.upstream_), index_(src.index_) {} - FORCE_INLINE ElementProxy& operator=(const ElementProxy& src) { + ElementProxy& operator=(const ElementProxy& src) { this->set(src); return *this; } template - FORCE_INLINE ElementProxy& operator=(const T& src) { + ElementProxy& operator=(const T& src) { this->set(src); return *this; } template - FORCE_INLINE ElementProxy& operator=(T* src) { + ElementProxy& operator=(T* src) { this->set(src); return *this; } private: - FORCE_INLINE ResourceManager* getResourceManager() const { + ResourceManager* getResourceManager() const { return VariantAttorney::getResourceManager(upstream_); } @@ -50,7 +50,7 @@ class ElementProxy : public VariantRefBase>, VariantAttorney::getResourceManager(upstream_)); } - FORCE_INLINE VariantData* getOrCreateData() const { + VariantData* getOrCreateData() const { auto data = VariantAttorney::getOrCreateData(upstream_); if (!data) return nullptr; diff --git a/lib/ArduinoJson/src/ArduinoJson/Array/JsonArray.hpp b/lib/ArduinoJson/src/ArduinoJson/Array/JsonArray.hpp old mode 100644 new mode 100755 index 069c353de..292336308 --- a/lib/ArduinoJson/src/ArduinoJson/Array/JsonArray.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Array/JsonArray.hpp @@ -20,11 +20,10 @@ class JsonArray : public detail::VariantOperators { typedef JsonArrayIterator iterator; // Constructs an unbound reference. - FORCE_INLINE JsonArray() : data_(0), resources_(0) {} + JsonArray() : data_(0), resources_(0) {} // INTERNAL USE ONLY - FORCE_INLINE JsonArray(detail::ArrayData* data, - detail::ResourceManager* resources) + JsonArray(detail::ArrayData* data, detail::ResourceManager* resources) : data_(data), resources_(resources) {} // Returns a JsonVariant pointing to the array. @@ -63,20 +62,20 @@ class JsonArray : public detail::VariantOperators { // Appends a value to the array. // https://arduinojson.org/v7/api/jsonarray/add/ template - FORCE_INLINE bool add(const T& value) const { + bool add(const T& value) const { return add().set(value); } // Appends a value to the array. // https://arduinojson.org/v7/api/jsonarray/add/ template - FORCE_INLINE bool add(T* value) const { + bool add(T* value) const { return add().set(value); } // Returns an iterator to the first element of the array. // https://arduinojson.org/v7/api/jsonarray/begin/ - FORCE_INLINE iterator begin() const { + iterator begin() const { if (!data_) return iterator(); return iterator(data_->createIterator(resources_), resources_); @@ -84,13 +83,13 @@ class JsonArray : public detail::VariantOperators { // Returns an iterator following the last element of the array. // https://arduinojson.org/v7/api/jsonarray/end/ - FORCE_INLINE iterator end() const { + iterator end() const { return iterator(); } // Copies an array. // https://arduinojson.org/v7/api/jsonarray/set/ - FORCE_INLINE bool set(JsonArrayConst src) const { + bool set(JsonArrayConst src) const { if (!data_) return false; @@ -105,13 +104,13 @@ class JsonArray : public detail::VariantOperators { // Removes the element at the specified iterator. // https://arduinojson.org/v7/api/jsonarray/remove/ - FORCE_INLINE void remove(iterator it) const { + void remove(iterator it) const { detail::ArrayData::remove(data_, it.iterator_, resources_); } // Removes the element at the specified index. // https://arduinojson.org/v7/api/jsonarray/remove/ - FORCE_INLINE void remove(size_t index) const { + void remove(size_t index) const { detail::ArrayData::removeElement(data_, index, resources_); } @@ -123,7 +122,7 @@ class JsonArray : public detail::VariantOperators { // Gets or sets the element at the specified index. // https://arduinojson.org/v7/api/jsonarray/subscript/ - FORCE_INLINE detail::ElementProxy operator[](size_t index) const { + detail::ElementProxy operator[](size_t index) const { return {*this, index}; } @@ -133,25 +132,25 @@ class JsonArray : public detail::VariantOperators { // Returns true if the reference is unbound. // https://arduinojson.org/v7/api/jsonarray/isnull/ - FORCE_INLINE bool isNull() const { + bool isNull() const { return data_ == 0; } // Returns true if the reference is bound. // https://arduinojson.org/v7/api/jsonarray/isnull/ - FORCE_INLINE operator bool() const { + operator bool() const { return data_ != 0; } // Returns the depth (nesting level) of the array. // https://arduinojson.org/v7/api/jsonarray/nesting/ - FORCE_INLINE size_t nesting() const { + size_t nesting() const { return detail::VariantData::nesting(collectionToVariant(data_), resources_); } // Returns the number of elements in the array. // https://arduinojson.org/v7/api/jsonarray/size/ - FORCE_INLINE size_t size() const { + size_t size() const { return data_ ? data_->size(resources_) : 0; } diff --git a/lib/ArduinoJson/src/ArduinoJson/Array/JsonArrayConst.hpp b/lib/ArduinoJson/src/ArduinoJson/Array/JsonArrayConst.hpp old mode 100644 new mode 100755 index 526975a24..6c0d7db2f --- a/lib/ArduinoJson/src/ArduinoJson/Array/JsonArrayConst.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Array/JsonArrayConst.hpp @@ -23,7 +23,7 @@ class JsonArrayConst : public detail::VariantOperators { // Returns an iterator to the first element of the array. // https://arduinojson.org/v7/api/jsonarrayconst/begin/ - FORCE_INLINE iterator begin() const { + iterator begin() const { if (!data_) return iterator(); return iterator(data_->createIterator(resources_), resources_); @@ -31,21 +31,21 @@ class JsonArrayConst : public detail::VariantOperators { // Returns an iterator to the element following the last element of the array. // https://arduinojson.org/v7/api/jsonarrayconst/end/ - FORCE_INLINE iterator end() const { + iterator end() const { return iterator(); } // Creates an unbound reference. - FORCE_INLINE JsonArrayConst() : data_(0) {} + JsonArrayConst() : data_(0) {} // INTERNAL USE ONLY - FORCE_INLINE JsonArrayConst(const detail::ArrayData* data, - const detail::ResourceManager* resources) + JsonArrayConst(const detail::ArrayData* data, + const detail::ResourceManager* resources) : data_(data), resources_(resources) {} // Returns the element at the specified index. // https://arduinojson.org/v7/api/jsonarrayconst/subscript/ - FORCE_INLINE JsonVariantConst operator[](size_t index) const { + JsonVariantConst operator[](size_t index) const { return JsonVariantConst( detail::ArrayData::getElement(data_, index, resources_), resources_); } @@ -56,25 +56,25 @@ class JsonArrayConst : public detail::VariantOperators { // Returns true if the reference is unbound. // https://arduinojson.org/v7/api/jsonarrayconst/isnull/ - FORCE_INLINE bool isNull() const { + bool isNull() const { return data_ == 0; } // Returns true if the reference is bound. // https://arduinojson.org/v7/api/jsonarrayconst/isnull/ - FORCE_INLINE operator bool() const { + operator bool() const { return data_ != 0; } // Returns the depth (nesting level) of the array. // https://arduinojson.org/v7/api/jsonarrayconst/nesting/ - FORCE_INLINE size_t nesting() const { + size_t nesting() const { return detail::VariantData::nesting(getData(), resources_); } // Returns the number of elements in the array. // https://arduinojson.org/v7/api/jsonarrayconst/size/ - FORCE_INLINE size_t size() const { + size_t size() const { return data_ ? data_->size(resources_) : 0; } diff --git a/lib/ArduinoJson/src/ArduinoJson/Array/JsonArrayIterator.hpp b/lib/ArduinoJson/src/ArduinoJson/Array/JsonArrayIterator.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Array/Utilities.hpp b/lib/ArduinoJson/src/ArduinoJson/Array/Utilities.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Collection/CollectionData.hpp b/lib/ArduinoJson/src/ArduinoJson/Collection/CollectionData.hpp old mode 100644 new mode 100755 index 1010795ce..07fe7e043 --- a/lib/ArduinoJson/src/ArduinoJson/Collection/CollectionData.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Collection/CollectionData.hpp @@ -107,6 +107,10 @@ class CollectionData { return collection->remove(it, resources); } + SlotId head() const { + return head_; + } + protected: iterator addSlot(ResourceManager*); diff --git a/lib/ArduinoJson/src/ArduinoJson/Collection/CollectionImpl.hpp b/lib/ArduinoJson/src/ArduinoJson/Collection/CollectionImpl.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Configuration.hpp b/lib/ArduinoJson/src/ArduinoJson/Configuration.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Deserialization/DeserializationError.hpp b/lib/ArduinoJson/src/ArduinoJson/Deserialization/DeserializationError.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Deserialization/DeserializationOptions.hpp b/lib/ArduinoJson/src/ArduinoJson/Deserialization/DeserializationOptions.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Deserialization/Filter.hpp b/lib/ArduinoJson/src/ArduinoJson/Deserialization/Filter.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Deserialization/NestingLimit.hpp b/lib/ArduinoJson/src/ArduinoJson/Deserialization/NestingLimit.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Deserialization/Reader.hpp b/lib/ArduinoJson/src/ArduinoJson/Deserialization/Reader.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Deserialization/Readers/ArduinoStreamReader.hpp b/lib/ArduinoJson/src/ArduinoJson/Deserialization/Readers/ArduinoStreamReader.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Deserialization/Readers/ArduinoStringReader.hpp b/lib/ArduinoJson/src/ArduinoJson/Deserialization/Readers/ArduinoStringReader.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Deserialization/Readers/FlashReader.hpp b/lib/ArduinoJson/src/ArduinoJson/Deserialization/Readers/FlashReader.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Deserialization/Readers/IteratorReader.hpp b/lib/ArduinoJson/src/ArduinoJson/Deserialization/Readers/IteratorReader.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Deserialization/Readers/RamReader.hpp b/lib/ArduinoJson/src/ArduinoJson/Deserialization/Readers/RamReader.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Deserialization/Readers/StdStreamReader.hpp b/lib/ArduinoJson/src/ArduinoJson/Deserialization/Readers/StdStreamReader.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Deserialization/Readers/VariantReader.hpp b/lib/ArduinoJson/src/ArduinoJson/Deserialization/Readers/VariantReader.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Deserialization/deserialize.hpp b/lib/ArduinoJson/src/ArduinoJson/Deserialization/deserialize.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Document/JsonDocument.hpp b/lib/ArduinoJson/src/ArduinoJson/Document/JsonDocument.hpp old mode 100644 new mode 100755 index d2daf97ad..0f336f1a2 --- a/lib/ArduinoJson/src/ArduinoJson/Document/JsonDocument.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Document/JsonDocument.hpp @@ -30,7 +30,8 @@ class JsonDocument : public detail::VariantOperators { } // Move-constructor - JsonDocument(JsonDocument&& src) : JsonDocument() { + JsonDocument(JsonDocument&& src) + : JsonDocument(detail::DefaultAllocator::instance()) { swap(*this, src); } @@ -169,9 +170,8 @@ class JsonDocument : public detail::VariantOperators { // Gets or sets a root object's member. // https://arduinojson.org/v7/api/jsondocument/subscript/ template - FORCE_INLINE typename detail::enable_if< - detail::IsString::value, - detail::MemberProxy>::type + typename detail::enable_if::value, + detail::MemberProxy>::type operator[](const TString& key) { return {*this, key}; } @@ -179,9 +179,8 @@ class JsonDocument : public detail::VariantOperators { // Gets or sets a root object's member. // https://arduinojson.org/v7/api/jsondocument/subscript/ template - FORCE_INLINE typename detail::enable_if< - detail::IsString::value, - detail::MemberProxy>::type + typename detail::enable_if::value, + detail::MemberProxy>::type operator[](TChar* key) { return {*this, key}; } @@ -189,8 +188,8 @@ class JsonDocument : public detail::VariantOperators { // Gets a root object's member. // https://arduinojson.org/v7/api/jsondocument/subscript/ template - FORCE_INLINE typename detail::enable_if::value, - JsonVariantConst>::type + typename detail::enable_if::value, + JsonVariantConst>::type operator[](const TString& key) const { return JsonVariantConst( data_.getMember(detail::adaptString(key), &resources_), &resources_); @@ -199,8 +198,8 @@ class JsonDocument : public detail::VariantOperators { // Gets a root object's member. // https://arduinojson.org/v7/api/jsondocument/subscript/ template - FORCE_INLINE typename detail::enable_if::value, - JsonVariantConst>::type + typename detail::enable_if::value, + JsonVariantConst>::type operator[](TChar* key) const { return JsonVariantConst( data_.getMember(detail::adaptString(key), &resources_), &resources_); @@ -208,13 +207,13 @@ class JsonDocument : public detail::VariantOperators { // Gets or sets a root array's element. // https://arduinojson.org/v7/api/jsondocument/subscript/ - FORCE_INLINE detail::ElementProxy operator[](size_t index) { + detail::ElementProxy operator[](size_t index) { return {*this, index}; } // Gets a root array's member. // https://arduinojson.org/v7/api/jsondocument/subscript/ - FORCE_INLINE JsonVariantConst operator[](size_t index) const { + JsonVariantConst operator[](size_t index) const { return JsonVariantConst(data_.getElement(index, &resources_), &resources_); } @@ -239,28 +238,28 @@ class JsonDocument : public detail::VariantOperators { // Appends a value to the root array. // https://arduinojson.org/v7/api/jsondocument/add/ template - FORCE_INLINE bool add(const TValue& value) { + bool add(const TValue& value) { return add().set(value); } // Appends a value to the root array. // https://arduinojson.org/v7/api/jsondocument/add/ template - FORCE_INLINE bool add(TChar* value) { + bool add(TChar* value) { return add().set(value); } // Removes an element of the root array. // https://arduinojson.org/v7/api/jsondocument/remove/ - FORCE_INLINE void remove(size_t index) { + void remove(size_t index) { detail::VariantData::removeElement(getData(), index, getResourceManager()); } // Removes a member of the root object. // https://arduinojson.org/v7/api/jsondocument/remove/ template - FORCE_INLINE typename detail::enable_if::value>::type - remove(TChar* key) { + typename detail::enable_if::value>::type remove( + TChar* key) { detail::VariantData::removeMember(getData(), detail::adaptString(key), getResourceManager()); } @@ -268,18 +267,18 @@ class JsonDocument : public detail::VariantOperators { // Removes a member of the root object. // https://arduinojson.org/v7/api/jsondocument/remove/ template - FORCE_INLINE - typename detail::enable_if::value>::type - remove(const TString& key) { + + typename detail::enable_if::value>::type remove( + const TString& key) { detail::VariantData::removeMember(getData(), detail::adaptString(key), getResourceManager()); } - FORCE_INLINE operator JsonVariant() { + operator JsonVariant() { return getVariant(); } - FORCE_INLINE operator JsonVariantConst() const { + operator JsonVariantConst() const { return getVariant(); } diff --git a/lib/ArduinoJson/src/ArduinoJson/Json/EscapeSequence.hpp b/lib/ArduinoJson/src/ArduinoJson/Json/EscapeSequence.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Json/JsonDeserializer.hpp b/lib/ArduinoJson/src/ArduinoJson/Json/JsonDeserializer.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Json/JsonSerializer.hpp b/lib/ArduinoJson/src/ArduinoJson/Json/JsonSerializer.hpp old mode 100644 new mode 100755 index f4751f0c2..6b02cc593 --- a/lib/ArduinoJson/src/ArduinoJson/Json/JsonSerializer.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Json/JsonSerializer.hpp @@ -19,19 +19,20 @@ class JsonSerializer : public VariantDataVisitor { JsonSerializer(TWriter writer, const ResourceManager* resources) : formatter_(writer), resources_(resources) {} - FORCE_INLINE size_t visit(const ArrayData& array) { + size_t visit(const ArrayData& array) { write('['); - auto it = array.createIterator(resources_); + auto slotId = array.head(); - while (!it.done()) { - it->accept(*this); + while (slotId != NULL_SLOT) { + auto slot = resources_->getSlot(slotId); - it.next(resources_); - if (it.done()) - break; + slot->data()->accept(*this); - write(','); + slotId = slot->next(); + + if (slotId != NULL_SLOT) + write(','); } write(']'); @@ -41,18 +42,19 @@ class JsonSerializer : public VariantDataVisitor { size_t visit(const ObjectData& object) { write('{'); - auto it = object.createIterator(resources_); + auto slotId = object.head(); - while (!it.done()) { - formatter_.writeString(it.key()); + while (slotId != NULL_SLOT) { + auto slot = resources_->getSlot(slotId); + + formatter_.writeString(slot->key()); write(':'); - it->accept(*this); + slot->data()->accept(*this); - it.next(resources_); - if (it.done()) - break; + slotId = slot->next(); - write(','); + if (slotId != NULL_SLOT) + write(','); } write('}'); diff --git a/lib/ArduinoJson/src/ArduinoJson/Json/Latch.hpp b/lib/ArduinoJson/src/ArduinoJson/Json/Latch.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Json/PrettyJsonSerializer.hpp b/lib/ArduinoJson/src/ArduinoJson/Json/PrettyJsonSerializer.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Json/TextFormatter.hpp b/lib/ArduinoJson/src/ArduinoJson/Json/TextFormatter.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Json/Utf16.hpp b/lib/ArduinoJson/src/ArduinoJson/Json/Utf16.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Json/Utf8.hpp b/lib/ArduinoJson/src/ArduinoJson/Json/Utf8.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Memory/Alignment.hpp b/lib/ArduinoJson/src/ArduinoJson/Memory/Alignment.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Memory/Allocator.hpp b/lib/ArduinoJson/src/ArduinoJson/Memory/Allocator.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Memory/ResourceManager.hpp b/lib/ArduinoJson/src/ArduinoJson/Memory/ResourceManager.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Memory/StringBuilder.hpp b/lib/ArduinoJson/src/ArduinoJson/Memory/StringBuilder.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Memory/StringNode.hpp b/lib/ArduinoJson/src/ArduinoJson/Memory/StringNode.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Memory/StringPool.hpp b/lib/ArduinoJson/src/ArduinoJson/Memory/StringPool.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Memory/VariantPool.hpp b/lib/ArduinoJson/src/ArduinoJson/Memory/VariantPool.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Memory/VariantPoolImpl.hpp b/lib/ArduinoJson/src/ArduinoJson/Memory/VariantPoolImpl.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Memory/VariantPoolList.hpp b/lib/ArduinoJson/src/ArduinoJson/Memory/VariantPoolList.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Misc/SerializedValue.hpp b/lib/ArduinoJson/src/ArduinoJson/Misc/SerializedValue.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/MsgPack/MsgPackDeserializer.hpp b/lib/ArduinoJson/src/ArduinoJson/MsgPack/MsgPackDeserializer.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/MsgPack/MsgPackSerializer.hpp b/lib/ArduinoJson/src/ArduinoJson/MsgPack/MsgPackSerializer.hpp old mode 100644 new mode 100755 index 5c3fc24ea..15c5a0e32 --- a/lib/ArduinoJson/src/ArduinoJson/MsgPack/MsgPackSerializer.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/MsgPack/MsgPackSerializer.hpp @@ -59,10 +59,14 @@ class MsgPackSerializer : public VariantDataVisitor { writeByte(0xDD); writeInteger(uint32_t(n)); } - for (auto it = array.createIterator(resources_); !it.done(); - it.next(resources_)) { - it->accept(*this); + + auto slotId = array.head(); + while (slotId != NULL_SLOT) { + auto slot = resources_->getSlot(slotId); + slot->data()->accept(*this); + slotId = slot->next(); } + return bytesWritten(); } @@ -77,11 +81,15 @@ class MsgPackSerializer : public VariantDataVisitor { writeByte(0xDF); writeInteger(uint32_t(n)); } - for (auto it = object.createIterator(resources_); !it.done(); - it.next(resources_)) { - visit(it.key()); - it->accept(*this); + + auto slotId = object.head(); + while (slotId != NULL_SLOT) { + auto slot = resources_->getSlot(slotId); + visit(slot->key()); + slot->data()->accept(*this); + slotId = slot->next(); } + return bytesWritten(); } diff --git a/lib/ArduinoJson/src/ArduinoJson/MsgPack/endianess.hpp b/lib/ArduinoJson/src/ArduinoJson/MsgPack/endianess.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/MsgPack/ieee754.hpp b/lib/ArduinoJson/src/ArduinoJson/MsgPack/ieee754.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Namespace.hpp b/lib/ArduinoJson/src/ArduinoJson/Namespace.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Numbers/FloatParts.hpp b/lib/ArduinoJson/src/ArduinoJson/Numbers/FloatParts.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Numbers/FloatTraits.hpp b/lib/ArduinoJson/src/ArduinoJson/Numbers/FloatTraits.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Numbers/JsonFloat.hpp b/lib/ArduinoJson/src/ArduinoJson/Numbers/JsonFloat.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Numbers/JsonInteger.hpp b/lib/ArduinoJson/src/ArduinoJson/Numbers/JsonInteger.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Numbers/arithmeticCompare.hpp b/lib/ArduinoJson/src/ArduinoJson/Numbers/arithmeticCompare.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Numbers/convertNumber.hpp b/lib/ArduinoJson/src/ArduinoJson/Numbers/convertNumber.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Numbers/parseNumber.hpp b/lib/ArduinoJson/src/ArduinoJson/Numbers/parseNumber.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Object/JsonObject.hpp b/lib/ArduinoJson/src/ArduinoJson/Object/JsonObject.hpp old mode 100644 new mode 100755 index 096afa87b..e4e7dee4a --- a/lib/ArduinoJson/src/ArduinoJson/Object/JsonObject.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Object/JsonObject.hpp @@ -20,11 +20,10 @@ class JsonObject : public detail::VariantOperators { typedef JsonObjectIterator iterator; // Creates an unbound reference. - FORCE_INLINE JsonObject() : data_(0), resources_(0) {} + JsonObject() : data_(0), resources_(0) {} // INTERNAL USE ONLY - FORCE_INLINE JsonObject(detail::ObjectData* data, - detail::ResourceManager* resource) + JsonObject(detail::ObjectData* data, detail::ResourceManager* resource) : data_(data), resources_(resource) {} operator JsonVariant() const { @@ -43,31 +42,31 @@ class JsonObject : public detail::VariantOperators { // Returns true if the reference is unbound. // https://arduinojson.org/v7/api/jsonobject/isnull/ - FORCE_INLINE bool isNull() const { + bool isNull() const { return data_ == 0; } // Returns true if the reference is bound. // https://arduinojson.org/v7/api/jsonobject/isnull/ - FORCE_INLINE operator bool() const { + operator bool() const { return data_ != 0; } // Returns the depth (nesting level) of the object. // https://arduinojson.org/v7/api/jsonobject/nesting/ - FORCE_INLINE size_t nesting() const { + size_t nesting() const { return detail::VariantData::nesting(collectionToVariant(data_), resources_); } // Returns the number of members in the object. // https://arduinojson.org/v7/api/jsonobject/size/ - FORCE_INLINE size_t size() const { + size_t size() const { return data_ ? data_->size(resources_) : 0; } // Returns an iterator to the first key-value pair of the object. // https://arduinojson.org/v7/api/jsonobject/begin/ - FORCE_INLINE iterator begin() const { + iterator begin() const { if (!data_) return iterator(); return iterator(data_->createIterator(resources_), resources_); @@ -75,7 +74,7 @@ class JsonObject : public detail::VariantOperators { // Returns an iterator following the last key-value pair of the object. // https://arduinojson.org/v7/api/jsonobject/end/ - FORCE_INLINE iterator end() const { + iterator end() const { return iterator(); } @@ -87,7 +86,7 @@ class JsonObject : public detail::VariantOperators { // Copies an object. // https://arduinojson.org/v7/api/jsonobject/set/ - FORCE_INLINE bool set(JsonObjectConst src) { + bool set(JsonObjectConst src) { if (!data_ || !src.data_) return false; @@ -103,20 +102,20 @@ class JsonObject : public detail::VariantOperators { // Gets or sets the member with specified key. // https://arduinojson.org/v7/api/jsonobject/subscript/ template - FORCE_INLINE - typename detail::enable_if::value, - detail::MemberProxy>::type - operator[](const TString& key) const { + + typename detail::enable_if::value, + detail::MemberProxy>::type + operator[](const TString& key) const { return {*this, key}; } // Gets or sets the member with specified key. // https://arduinojson.org/v7/api/jsonobject/subscript/ template - FORCE_INLINE - typename detail::enable_if::value, - detail::MemberProxy>::type - operator[](TChar* key) const { + + typename detail::enable_if::value, + detail::MemberProxy>::type + operator[](TChar* key) const { return {*this, key}; } @@ -145,9 +144,9 @@ class JsonObject : public detail::VariantOperators { // Returns true if the object contains the specified key. // https://arduinojson.org/v7/api/jsonobject/containskey/ template - FORCE_INLINE - typename detail::enable_if::value, bool>::type - containsKey(const TString& key) const { + + typename detail::enable_if::value, bool>::type + containsKey(const TString& key) const { return detail::ObjectData::getMember(data_, detail::adaptString(key), resources_) != 0; } @@ -155,9 +154,9 @@ class JsonObject : public detail::VariantOperators { // Returns true if the object contains the specified key. // https://arduinojson.org/v7/api/jsonobject/containskey/ template - FORCE_INLINE - typename detail::enable_if::value, bool>::type - containsKey(TChar* key) const { + + typename detail::enable_if::value, bool>::type + containsKey(TChar* key) const { return detail::ObjectData::getMember(data_, detail::adaptString(key), resources_) != 0; } diff --git a/lib/ArduinoJson/src/ArduinoJson/Object/JsonObjectConst.hpp b/lib/ArduinoJson/src/ArduinoJson/Object/JsonObjectConst.hpp old mode 100644 new mode 100755 index 8f2c8bb10..908fa275d --- a/lib/ArduinoJson/src/ArduinoJson/Object/JsonObjectConst.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Object/JsonObjectConst.hpp @@ -32,31 +32,31 @@ class JsonObjectConst : public detail::VariantOperators { // Returns true if the reference is unbound. // https://arduinojson.org/v7/api/jsonobjectconst/isnull/ - FORCE_INLINE bool isNull() const { + bool isNull() const { return data_ == 0; } // Returns true if the reference is bound. // https://arduinojson.org/v7/api/jsonobjectconst/isnull/ - FORCE_INLINE operator bool() const { + operator bool() const { return data_ != 0; } // Returns the depth (nesting level) of the object. // https://arduinojson.org/v7/api/jsonobjectconst/nesting/ - FORCE_INLINE size_t nesting() const { + size_t nesting() const { return detail::VariantData::nesting(getData(), resources_); } // Returns the number of members in the object. // https://arduinojson.org/v7/api/jsonobjectconst/size/ - FORCE_INLINE size_t size() const { + size_t size() const { return data_ ? data_->size(resources_) : 0; } // Returns an iterator to the first key-value pair of the object. // https://arduinojson.org/v7/api/jsonobjectconst/begin/ - FORCE_INLINE iterator begin() const { + iterator begin() const { if (!data_) return iterator(); return iterator(data_->createIterator(resources_), resources_); @@ -64,14 +64,14 @@ class JsonObjectConst : public detail::VariantOperators { // Returns an iterator following the last key-value pair of the object. // https://arduinojson.org/v7/api/jsonobjectconst/end/ - FORCE_INLINE iterator end() const { + iterator end() const { return iterator(); } // Returns true if the object contains the specified key. // https://arduinojson.org/v7/api/jsonobjectconst/containskey/ template - FORCE_INLINE bool containsKey(const TString& key) const { + bool containsKey(const TString& key) const { return detail::ObjectData::getMember(data_, detail::adaptString(key), resources_) != 0; } @@ -79,7 +79,7 @@ class JsonObjectConst : public detail::VariantOperators { // Returns true if the object contains the specified key. // https://arduinojson.org/v7/api/jsonobjectconst/containskey/ template - FORCE_INLINE bool containsKey(TChar* key) const { + bool containsKey(TChar* key) const { return detail::ObjectData::getMember(data_, detail::adaptString(key), resources_) != 0; } @@ -87,8 +87,8 @@ class JsonObjectConst : public detail::VariantOperators { // Gets the member with specified key. // https://arduinojson.org/v7/api/jsonobjectconst/subscript/ template - FORCE_INLINE typename detail::enable_if::value, - JsonVariantConst>::type + typename detail::enable_if::value, + JsonVariantConst>::type operator[](const TString& key) const { return JsonVariantConst(detail::ObjectData::getMember( data_, detail::adaptString(key), resources_), @@ -98,8 +98,8 @@ class JsonObjectConst : public detail::VariantOperators { // Gets the member with specified key. // https://arduinojson.org/v7/api/jsonobjectconst/subscript/ template - FORCE_INLINE typename detail::enable_if::value, - JsonVariantConst>::type + typename detail::enable_if::value, + JsonVariantConst>::type operator[](TChar* key) const { return JsonVariantConst(detail::ObjectData::getMember( data_, detail::adaptString(key), resources_), diff --git a/lib/ArduinoJson/src/ArduinoJson/Object/JsonObjectIterator.hpp b/lib/ArduinoJson/src/ArduinoJson/Object/JsonObjectIterator.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Object/JsonPair.hpp b/lib/ArduinoJson/src/ArduinoJson/Object/JsonPair.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Object/MemberProxy.hpp b/lib/ArduinoJson/src/ArduinoJson/Object/MemberProxy.hpp old mode 100644 new mode 100755 index 2a56f6dae..eb9feedeb --- a/lib/ArduinoJson/src/ArduinoJson/Object/MemberProxy.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Object/MemberProxy.hpp @@ -17,41 +17,41 @@ class MemberProxy friend class VariantAttorney; public: - FORCE_INLINE MemberProxy(TUpstream upstream, TStringRef key) + MemberProxy(TUpstream upstream, TStringRef key) : upstream_(upstream), key_(key) {} MemberProxy(const MemberProxy& src) : upstream_(src.upstream_), key_(src.key_) {} - FORCE_INLINE MemberProxy& operator=(const MemberProxy& src) { + MemberProxy& operator=(const MemberProxy& src) { this->set(src); return *this; } template - FORCE_INLINE MemberProxy& operator=(const T& src) { + MemberProxy& operator=(const T& src) { this->set(src); return *this; } template - FORCE_INLINE MemberProxy& operator=(T* src) { + MemberProxy& operator=(T* src) { this->set(src); return *this; } private: - FORCE_INLINE ResourceManager* getResourceManager() const { + ResourceManager* getResourceManager() const { return VariantAttorney::getResourceManager(upstream_); } - FORCE_INLINE VariantData* getData() const { + VariantData* getData() const { return VariantData::getMember( VariantAttorney::getData(upstream_), adaptString(key_), VariantAttorney::getResourceManager(upstream_)); } - FORCE_INLINE VariantData* getOrCreateData() const { + VariantData* getOrCreateData() const { auto data = VariantAttorney::getOrCreateData(upstream_); if (!data) return nullptr; diff --git a/lib/ArduinoJson/src/ArduinoJson/Object/ObjectData.hpp b/lib/ArduinoJson/src/ArduinoJson/Object/ObjectData.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Object/ObjectImpl.hpp b/lib/ArduinoJson/src/ArduinoJson/Object/ObjectImpl.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/alias_cast.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/alias_cast.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/assert.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/assert.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/attributes.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/attributes.hpp old mode 100644 new mode 100755 index 2eaaa57cf..268026f21 --- a/lib/ArduinoJson/src/ArduinoJson/Polyfills/attributes.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Polyfills/attributes.hpp @@ -7,7 +7,6 @@ #ifdef _MSC_VER // Visual Studio # define FORCE_INLINE // __forceinline causes C4714 when returning std::string -# define NO_INLINE __declspec(noinline) # ifndef ARDUINOJSON_DEPRECATED # define ARDUINOJSON_DEPRECATED(msg) __declspec(deprecated(msg)) @@ -16,7 +15,6 @@ #elif defined(__GNUC__) // GCC or Clang # define FORCE_INLINE __attribute__((always_inline)) -# define NO_INLINE __attribute__((noinline)) # ifndef ARDUINOJSON_DEPRECATED # if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) @@ -29,7 +27,6 @@ #else // Other compilers # define FORCE_INLINE -# define NO_INLINE # ifndef ARDUINOJSON_DEPRECATED # define ARDUINOJSON_DEPRECATED(msg) diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/ctype.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/ctype.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/integer.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/integer.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/limits.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/limits.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/math.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/math.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/mpl/max.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/mpl/max.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/pgmspace.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/pgmspace.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/pgmspace_generic.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/pgmspace_generic.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/preprocessor.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/preprocessor.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/conditional.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/conditional.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/declval.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/declval.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/enable_if.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/enable_if.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/integral_constant.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/integral_constant.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_array.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_array.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_base_of.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_base_of.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_class.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_class.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_const.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_const.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_convertible.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_convertible.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_enum.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_enum.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_floating_point.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_floating_point.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_integral.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_integral.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_pointer.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_pointer.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_same.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_same.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_signed.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_signed.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_unsigned.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_unsigned.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/make_unsigned.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/make_unsigned.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/make_void.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/make_void.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/remove_const.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/remove_const.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/remove_cv.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/remove_cv.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/remove_reference.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/remove_reference.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/type_identity.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/type_identity.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Polyfills/utility.hpp b/lib/ArduinoJson/src/ArduinoJson/Polyfills/utility.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Serialization/CountingDecorator.hpp b/lib/ArduinoJson/src/ArduinoJson/Serialization/CountingDecorator.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Serialization/Writer.hpp b/lib/ArduinoJson/src/ArduinoJson/Serialization/Writer.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Serialization/Writers/ArduinoStringWriter.hpp b/lib/ArduinoJson/src/ArduinoJson/Serialization/Writers/ArduinoStringWriter.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Serialization/Writers/DummyWriter.hpp b/lib/ArduinoJson/src/ArduinoJson/Serialization/Writers/DummyWriter.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Serialization/Writers/PrintWriter.hpp b/lib/ArduinoJson/src/ArduinoJson/Serialization/Writers/PrintWriter.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Serialization/Writers/StaticStringWriter.hpp b/lib/ArduinoJson/src/ArduinoJson/Serialization/Writers/StaticStringWriter.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Serialization/Writers/StdStreamWriter.hpp b/lib/ArduinoJson/src/ArduinoJson/Serialization/Writers/StdStreamWriter.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Serialization/Writers/StdStringWriter.hpp b/lib/ArduinoJson/src/ArduinoJson/Serialization/Writers/StdStringWriter.hpp old mode 100644 new mode 100755 index 46dc8ba55..6ac4d9738 --- a/lib/ArduinoJson/src/ArduinoJson/Serialization/Writers/StdStringWriter.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Serialization/Writers/StdStringWriter.hpp @@ -9,15 +9,13 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE -template -using void_t = void; - template struct is_std_string : false_type {}; template struct is_std_string< - T, void_t> + T, typename enable_if::value && + is_same::value>::type> : true_type {}; template diff --git a/lib/ArduinoJson/src/ArduinoJson/Serialization/measure.hpp b/lib/ArduinoJson/src/ArduinoJson/Serialization/measure.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Serialization/serialize.hpp b/lib/ArduinoJson/src/ArduinoJson/Serialization/serialize.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Strings/Adapters/FlashString.hpp b/lib/ArduinoJson/src/ArduinoJson/Strings/Adapters/FlashString.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Strings/Adapters/JsonString.hpp b/lib/ArduinoJson/src/ArduinoJson/Strings/Adapters/JsonString.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Strings/Adapters/RamString.hpp b/lib/ArduinoJson/src/ArduinoJson/Strings/Adapters/RamString.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Strings/Adapters/StringObject.hpp b/lib/ArduinoJson/src/ArduinoJson/Strings/Adapters/StringObject.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Strings/IsString.hpp b/lib/ArduinoJson/src/ArduinoJson/Strings/IsString.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Strings/JsonString.hpp b/lib/ArduinoJson/src/ArduinoJson/Strings/JsonString.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Strings/StringAdapter.hpp b/lib/ArduinoJson/src/ArduinoJson/Strings/StringAdapter.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Strings/StringAdapters.hpp b/lib/ArduinoJson/src/ArduinoJson/Strings/StringAdapters.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Strings/StringTraits.hpp b/lib/ArduinoJson/src/ArduinoJson/Strings/StringTraits.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Variant/Converter.hpp b/lib/ArduinoJson/src/ArduinoJson/Variant/Converter.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Variant/ConverterImpl.hpp b/lib/ArduinoJson/src/ArduinoJson/Variant/ConverterImpl.hpp old mode 100644 new mode 100755 index cc89687ee..8e35f72b5 --- a/lib/ArduinoJson/src/ArduinoJson/Variant/ConverterImpl.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Variant/ConverterImpl.hpp @@ -21,6 +21,10 @@ ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE template struct Converter { + static_assert(!detail::is_same::value, + "type 'char' is not supported, use 'signed char', 'unsigned " + "char' or another integer type instead"); + static void toJson(const T& src, JsonVariant dst) { // clang-format off convertToJson(src, dst); // Error here? See https://arduinojson.org/v7/unsupported-set/ @@ -28,6 +32,9 @@ struct Converter { } static T fromJson(JsonVariantConst src) { + static_assert(!detail::is_same::value, + "type 'char*' is not supported, use 'const char*' instead"); + // clang-format off T result; // Error here? See https://arduinojson.org/v7/non-default-constructible/ convertFromJson(src, result); // Error here? See https://arduinojson.org/v7/unsupported-as/ @@ -36,6 +43,9 @@ struct Converter { } static bool checkJson(JsonVariantConst src) { + static_assert(!detail::is_same::value, + "type 'char*' is not supported, use 'const char*' instead"); + T dummy = T(); // clang-format off return canConvertFromJson(src, dummy); // Error here? See https://arduinojson.org/v7/unsupported-is/ diff --git a/lib/ArduinoJson/src/ArduinoJson/Variant/JsonVariant.hpp b/lib/ArduinoJson/src/ArduinoJson/Variant/JsonVariant.hpp old mode 100644 new mode 100755 index f38963c1b..5039c38ae --- a/lib/ArduinoJson/src/ArduinoJson/Variant/JsonVariant.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Variant/JsonVariant.hpp @@ -23,15 +23,15 @@ class JsonVariant : public detail::VariantRefBase, : data_(data), resources_(resources) {} private: - FORCE_INLINE detail::ResourceManager* getResourceManager() const { + detail::ResourceManager* getResourceManager() const { return resources_; } - FORCE_INLINE detail::VariantData* getData() const { + detail::VariantData* getData() const { return data_; } - FORCE_INLINE detail::VariantData* getOrCreateData() const { + detail::VariantData* getOrCreateData() const { return data_; } diff --git a/lib/ArduinoJson/src/ArduinoJson/Variant/JsonVariantConst.hpp b/lib/ArduinoJson/src/ArduinoJson/Variant/JsonVariantConst.hpp old mode 100644 new mode 100755 index 8ff741110..7e7b8c0d8 --- a/lib/ArduinoJson/src/ArduinoJson/Variant/JsonVariantConst.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Variant/JsonVariantConst.hpp @@ -38,18 +38,18 @@ class JsonVariantConst : public detail::VariantTag, // Returns true if the value is null or the reference is unbound. // https://arduinojson.org/v7/api/jsonvariantconst/isnull/ - FORCE_INLINE bool isNull() const { + bool isNull() const { return detail::VariantData::isNull(data_); } // Returns true if the reference is unbound. - FORCE_INLINE bool isUnbound() const { + bool isUnbound() const { return !data_; } // Returns the depth (nesting level) of the value. // https://arduinojson.org/v7/api/jsonvariantconst/nesting/ - FORCE_INLINE size_t nesting() const { + size_t nesting() const { return detail::VariantData::nesting(data_, resources_); } @@ -62,9 +62,9 @@ class JsonVariantConst : public detail::VariantTag, // Casts the value to the specified type. // https://arduinojson.org/v7/api/jsonvariantconst/as/ template - FORCE_INLINE typename detail::enable_if::value && - !detail::is_same::value, - T>::type + typename detail::enable_if::value && + !detail::is_same::value, + T>::type as() const { return Converter::fromJson(*this); } @@ -72,21 +72,21 @@ class JsonVariantConst : public detail::VariantTag, // Returns true if the value is of the specified type. // https://arduinojson.org/v7/api/jsonvariantconst/is/ template - FORCE_INLINE typename detail::enable_if::value && - !detail::is_same::value, - bool>::type + typename detail::enable_if::value && + !detail::is_same::value, + bool>::type is() const { return Converter::checkJson(*this); } template - FORCE_INLINE operator T() const { + operator T() const { return as(); } // Gets array's element at specified index. // https://arduinojson.org/v7/api/jsonvariantconst/subscript/ - FORCE_INLINE JsonVariantConst operator[](size_t index) const { + JsonVariantConst operator[](size_t index) const { return JsonVariantConst( detail::VariantData::getElement(data_, index, resources_), resources_); } @@ -94,8 +94,8 @@ class JsonVariantConst : public detail::VariantTag, // Gets object's member with specified key. // https://arduinojson.org/v7/api/jsonvariantconst/subscript/ template - FORCE_INLINE typename detail::enable_if::value, - JsonVariantConst>::type + typename detail::enable_if::value, + JsonVariantConst>::type operator[](const TString& key) const { return JsonVariantConst(detail::VariantData::getMember( data_, detail::adaptString(key), resources_), @@ -105,8 +105,8 @@ class JsonVariantConst : public detail::VariantTag, // Gets object's member with specified key. // https://arduinojson.org/v7/api/jsonvariantconst/subscript/ template - FORCE_INLINE typename detail::enable_if::value, - JsonVariantConst>::type + typename detail::enable_if::value, + JsonVariantConst>::type operator[](TChar* key) const { return JsonVariantConst(detail::VariantData::getMember( data_, detail::adaptString(key), resources_), @@ -116,9 +116,9 @@ class JsonVariantConst : public detail::VariantTag, // Returns true if tge object contains the specified key. // https://arduinojson.org/v7/api/jsonvariantconst/containskey/ template - FORCE_INLINE - typename detail::enable_if::value, bool>::type - containsKey(const TString& key) const { + + typename detail::enable_if::value, bool>::type + containsKey(const TString& key) const { return detail::VariantData::getMember(getData(), detail::adaptString(key), resources_) != 0; } @@ -126,9 +126,9 @@ class JsonVariantConst : public detail::VariantTag, // Returns true if tge object contains the specified key. // https://arduinojson.org/v7/api/jsonvariantconst/containskey/ template - FORCE_INLINE - typename detail::enable_if::value, bool>::type - containsKey(TChar* key) const { + + typename detail::enable_if::value, bool>::type + containsKey(TChar* key) const { return detail::VariantData::getMember(getData(), detail::adaptString(key), resources_) != 0; } diff --git a/lib/ArduinoJson/src/ArduinoJson/Variant/JsonVariantCopier.hpp b/lib/ArduinoJson/src/ArduinoJson/Variant/JsonVariantCopier.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Variant/JsonVariantVisitor.hpp b/lib/ArduinoJson/src/ArduinoJson/Variant/JsonVariantVisitor.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Variant/VariantAttorney.hpp b/lib/ArduinoJson/src/ArduinoJson/Variant/VariantAttorney.hpp old mode 100644 new mode 100755 index 24f22dda5..b75eb3806 --- a/lib/ArduinoJson/src/ArduinoJson/Variant/VariantAttorney.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Variant/VariantAttorney.hpp @@ -16,19 +16,18 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE class VariantAttorney { public: template - FORCE_INLINE static auto getResourceManager(TClient& client) + static auto getResourceManager(TClient& client) -> decltype(client.getResourceManager()) { return client.getResourceManager(); } template - FORCE_INLINE static auto getData(TClient& client) - -> decltype(client.getData()) { + static auto getData(TClient& client) -> decltype(client.getData()) { return client.getData(); } template - FORCE_INLINE static VariantData* getOrCreateData(TClient& client) { + static VariantData* getOrCreateData(TClient& client) { return client.getOrCreateData(); } }; diff --git a/lib/ArduinoJson/src/ArduinoJson/Variant/VariantCompare.hpp b/lib/ArduinoJson/src/ArduinoJson/Variant/VariantCompare.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Variant/VariantContent.hpp b/lib/ArduinoJson/src/ArduinoJson/Variant/VariantContent.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Variant/VariantData.hpp b/lib/ArduinoJson/src/ArduinoJson/Variant/VariantData.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Variant/VariantDataVisitor.hpp b/lib/ArduinoJson/src/ArduinoJson/Variant/VariantDataVisitor.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Variant/VariantOperators.hpp b/lib/ArduinoJson/src/ArduinoJson/Variant/VariantOperators.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Variant/VariantRefBase.hpp b/lib/ArduinoJson/src/ArduinoJson/Variant/VariantRefBase.hpp old mode 100644 new mode 100755 index c81334af2..318915e8d --- a/lib/ArduinoJson/src/ArduinoJson/Variant/VariantRefBase.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/Variant/VariantRefBase.hpp @@ -28,39 +28,38 @@ class VariantRefBase : public VariantTag { public: // Sets the value to null. // https://arduinojson.org/v7/api/jsonvariant/clear/ - FORCE_INLINE void clear() const { + void clear() const { VariantData::setNull(getOrCreateData(), getResourceManager()); } // Returns true if the value is null or the reference is unbound. // https://arduinojson.org/v7/api/jsonvariant/isnull/ - FORCE_INLINE bool isNull() const { + bool isNull() const { return VariantData::isNull(getData()); } // Returns true if the reference is unbound. - FORCE_INLINE bool isUnbound() const { + bool isUnbound() const { return !getData(); } // Casts the value to the specified type. // https://arduinojson.org/v7/api/jsonvariant/as/ template - FORCE_INLINE - typename enable_if::value, T>::type - as() const { + + typename enable_if::value, T>::type as() + const { return Converter::fromJson(getVariantConst()); } // Casts the value to the specified type. // https://arduinojson.org/v7/api/jsonvariant/as/ template - FORCE_INLINE typename enable_if::value, T>::type - as() const; + typename enable_if::value, T>::type as() const; template ::value>::type> - FORCE_INLINE operator T() const { + operator T() const { return as(); } @@ -91,33 +90,31 @@ class VariantRefBase : public VariantTag { // Returns true if the value is of the specified type. // https://arduinojson.org/v7/api/jsonvariant/is/ template - FORCE_INLINE typename enable_if::value && - !is_same::value && - !is_same::value, - bool>::type - is() const { + FORCE_INLINE + typename enable_if::value, bool>::type + is() const { return Converter::checkJson(getVariantConst()); } // Copies the specified value. // https://arduinojson.org/v7/api/jsonvariant/set/ template - FORCE_INLINE bool set(const T& value) const; + bool set(const T& value) const; // Copies the specified value. // https://arduinojson.org/v7/api/jsonvariant/set/ template - FORCE_INLINE bool set(T* value) const; + bool set(T* value) const; // Returns the size of the array or object. // https://arduinojson.org/v7/api/jsonvariant/size/ - FORCE_INLINE size_t size() const { + size_t size() const { return VariantData::size(getData(), getResourceManager()); } // Returns the depth (nesting level) of the value. // https://arduinojson.org/v7/api/jsonvariant/nesting/ - FORCE_INLINE size_t nesting() const { + size_t nesting() const { return VariantData::nesting(getData(), getResourceManager()); } @@ -138,28 +135,27 @@ class VariantRefBase : public VariantTag { // Appends a value to the array. // https://arduinojson.org/v7/api/jsonvariant/add/ template - FORCE_INLINE bool add(const T& value) const { + bool add(const T& value) const { return add().set(value); } // Appends a value to the array. // https://arduinojson.org/v7/api/jsonvariant/add/ template - FORCE_INLINE bool add(T* value) const { + bool add(T* value) const { return add().set(value); } // Removes an element of the array. // https://arduinojson.org/v7/api/jsonvariant/remove/ - FORCE_INLINE void remove(size_t index) const { + void remove(size_t index) const { VariantData::removeElement(getData(), index, getResourceManager()); } // Removes a member of the object. // https://arduinojson.org/v7/api/jsonvariant/remove/ template - FORCE_INLINE typename enable_if::value>::type remove( - TChar* key) const { + typename enable_if::value>::type remove(TChar* key) const { VariantData::removeMember(getData(), adaptString(key), getResourceManager()); } @@ -167,7 +163,7 @@ class VariantRefBase : public VariantTag { // Removes a member of the object. // https://arduinojson.org/v7/api/jsonvariant/remove/ template - FORCE_INLINE typename enable_if::value>::type remove( + typename enable_if::value>::type remove( const TString& key) const { VariantData::removeMember(getData(), adaptString(key), getResourceManager()); @@ -175,19 +171,19 @@ class VariantRefBase : public VariantTag { // Gets or sets an array element. // https://arduinojson.org/v7/api/jsonvariant/subscript/ - FORCE_INLINE ElementProxy operator[](size_t index) const; + ElementProxy operator[](size_t index) const; // Returns true if the object contains the specified key. // https://arduinojson.org/v7/api/jsonvariant/containskey/ template - FORCE_INLINE typename enable_if::value, bool>::type - containsKey(const TString& key) const; + typename enable_if::value, bool>::type containsKey( + const TString& key) const; // Returns true if the object contains the specified key. // https://arduinojson.org/v7/api/jsonvariant/containskey/ template - FORCE_INLINE typename enable_if::value, bool>::type - containsKey(TChar* key) const; + typename enable_if::value, bool>::type containsKey( + TChar* key) const; // Gets or sets an object member. // https://arduinojson.org/v7/api/jsonvariant/subscript/ @@ -256,15 +252,15 @@ class VariantRefBase : public VariantTag { return static_cast(*this); } - FORCE_INLINE ResourceManager* getResourceManager() const { + ResourceManager* getResourceManager() const { return VariantAttorney::getResourceManager(derived()); } - FORCE_INLINE VariantData* getData() const { + VariantData* getData() const { return VariantAttorney::getData(derived()); } - FORCE_INLINE VariantData* getOrCreateData() const { + VariantData* getOrCreateData() const { return VariantAttorney::getOrCreateData(derived()); } @@ -274,7 +270,7 @@ class VariantRefBase : public VariantTag { return ArduinoJson::JsonVariantConst(getData(), getResourceManager()); } - FORCE_INLINE ArduinoJson::JsonVariant getOrCreateVariant() const; + ArduinoJson::JsonVariant getOrCreateVariant() const; }; ARDUINOJSON_END_PRIVATE_NAMESPACE diff --git a/lib/ArduinoJson/src/ArduinoJson/Variant/VariantRefBaseImpl.hpp b/lib/ArduinoJson/src/ArduinoJson/Variant/VariantRefBaseImpl.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Variant/VariantSlot.hpp b/lib/ArduinoJson/src/ArduinoJson/Variant/VariantSlot.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Variant/VariantTag.hpp b/lib/ArduinoJson/src/ArduinoJson/Variant/VariantTag.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/Variant/VariantTo.hpp b/lib/ArduinoJson/src/ArduinoJson/Variant/VariantTo.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/compatibility.hpp b/lib/ArduinoJson/src/ArduinoJson/compatibility.hpp old mode 100644 new mode 100755 diff --git a/lib/ArduinoJson/src/ArduinoJson/version.hpp b/lib/ArduinoJson/src/ArduinoJson/version.hpp old mode 100644 new mode 100755 index e41890e9f..dc1215a6d --- a/lib/ArduinoJson/src/ArduinoJson/version.hpp +++ b/lib/ArduinoJson/src/ArduinoJson/version.hpp @@ -4,8 +4,8 @@ #pragma once -#define ARDUINOJSON_VERSION "7.0.2" +#define ARDUINOJSON_VERSION "7.0.3" #define ARDUINOJSON_VERSION_MAJOR 7 #define ARDUINOJSON_VERSION_MINOR 0 -#define ARDUINOJSON_VERSION_REVISION 2 -#define ARDUINOJSON_VERSION_MACRO V702 +#define ARDUINOJSON_VERSION_REVISION 3 +#define ARDUINOJSON_VERSION_MACRO V703 diff --git a/lib/ArduinoJson/src/CMakeLists.txt b/lib/ArduinoJson/src/CMakeLists.txt deleted file mode 100644 index cc782e702..000000000 --- a/lib/ArduinoJson/src/CMakeLists.txt +++ /dev/null @@ -1,91 +0,0 @@ -# ArduinoJson - https://arduinojson.org -# Copyright © 2014-2024, Benoit BLANCHON -# MIT License - -# I have no idea what this is about, I simply followed the instructions from: -# https://dominikberner.ch/cmake-interface-lib/ - -add_library(ArduinoJson INTERFACE) - -include(GNUInstallDirs) - -# Adding the install interface generator expression makes sure that the include -# files are installed to the proper location (provided by GNUInstallDirs) -target_include_directories(ArduinoJson - INTERFACE - $ - $ -) - -target_compile_definitions(ArduinoJson - INTERFACE - ARDUINOJSON_DEBUG=$ -) - -# locations are provided by GNUInstallDirs -install( - TARGETS - ArduinoJson - EXPORT - ArduinoJson_Targets - ARCHIVE DESTINATION - ${CMAKE_INSTALL_LIBDIR} - LIBRARY DESTINATION - ${CMAKE_INSTALL_LIBDIR} - RUNTIME DESTINATION - ${CMAKE_INSTALL_BINDIR} -) - -include(CMakePackageConfigHelpers) - -if(${CMAKE_VERSION} VERSION_GREATER "3.14.0") - set(ARCH_INDEPENDENT "ARCH_INDEPENDENT") -endif() - -write_basic_package_version_file( - "${PROJECT_BINARY_DIR}/ArduinoJsonConfigVersion.cmake" - VERSION - ${PROJECT_VERSION} - COMPATIBILITY - SameMajorVersion - ${ARCH_INDEPENDENT} -) - -configure_package_config_file( - "${PROJECT_SOURCE_DIR}/extras/ArduinoJsonConfig.cmake.in" - "${PROJECT_BINARY_DIR}/ArduinoJsonConfig.cmake" - INSTALL_DESTINATION - ${CMAKE_INSTALL_DATAROOTDIR}/ArduinoJson/cmake -) - -install( - EXPORT - ArduinoJson_Targets - FILE - ArduinoJsonTargets.cmake - DESTINATION - ${CMAKE_INSTALL_DATAROOTDIR}/ArduinoJson/cmake -) - -install( - FILES - "${PROJECT_BINARY_DIR}/ArduinoJsonConfig.cmake" - "${PROJECT_BINARY_DIR}/ArduinoJsonConfigVersion.cmake" - DESTINATION - "${CMAKE_INSTALL_DATAROOTDIR}/ArduinoJson/cmake" -) - -install( - FILES - ArduinoJson.h - ArduinoJson.hpp - DESTINATION - include -) - -install( - DIRECTORY - "${CMAKE_CURRENT_SOURCE_DIR}/ArduinoJson" - DESTINATION - include -) From e6b61b7a51c77afed2ca2763050bc8121249140c Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 10 Feb 2024 09:50:58 +0100 Subject: [PATCH 07/54] bump 3.6.5-dev.13 --- src/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h b/src/version.h index 61c82db0d..259e9ea01 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define EMSESP_APP_VERSION "3.6.5-dev.12" +#define EMSESP_APP_VERSION "3.6.5-dev.13" From 257b40c2e4f18a6197d72ab4d3713fe2d7929ada Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 10 Feb 2024 09:51:29 +0100 Subject: [PATCH 08/54] fix MQTT discovery of custom entity doesn't consider type of data #1587 --- src/mqtt.cpp | 211 +++++++++++++++-------------- src/mqtt.h | 2 + src/web/WebCustomEntityService.cpp | 2 + src/web/WebCustomEntityService.h | 2 +- 4 files changed, 113 insertions(+), 104 deletions(-) diff --git a/src/mqtt.cpp b/src/mqtt.cpp index 200873df8..0930109f7 100644 --- a/src/mqtt.cpp +++ b/src/mqtt.cpp @@ -909,9 +909,6 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev doc["uniq_id"] = uniq_id; doc["obj_id"] = uniq_id; // same as unique_id - const char * ic_ha = "ic"; // icon - only set this if there is no device class - const char * uom_ha = "unit_of_meas"; // unit of measure - char sample_val[30] = "0"; // sample, correct(!) entity value, used only to prevent warning/error in HA if real value is not published yet // we add the command topic parameter for commands @@ -970,10 +967,10 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev case DeviceValueUOM::DEGREES: case DeviceValueUOM::DEGREES_R: case DeviceValueUOM::K: - doc[ic_ha] = F_(icondegrees); + doc["ic"] = F_(icondegrees); break; case DeviceValueUOM::PERCENT: - doc[ic_ha] = F_(iconpercent); + doc["ic"] = F_(iconpercent); break; default: break; @@ -1027,9 +1024,35 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev doc["pl_off"] = Helpers::render_boolean(result, false); snprintf(sample_val, sizeof(sample_val), "'%s'", Helpers::render_boolean(result, false)); } - } else { - // always set the uom, using the standards except for hours/minutes/seconds - // using HA specific codes from https://github.com/home-assistant/core/blob/dev/homeassistant/const.py + } + + doc["val_tpl"] = (std::string) "{{" + val_obj + " if " + val_cond + " else " + sample_val + "}}"; + + // Add the state class, device class and sometimes the icon. Used only for read-only sensors like Sensor and Binary Sensor + if (readonly_sensors) { + // first set the catagory for System entities + // https://github.com/emsesp/EMS-ESP32/discussions/1459#discussioncomment-7694873 + if (device_type == EMSdevice::DeviceType::SYSTEM) { + doc["ent_cat"] = "diagnostic"; + } + + add_ha_uom(doc.as(), type, uom, entity); // add the UoM, device and state class + } + + doc["dev"] = dev_json; // add the dev json object to the end + add_ha_sections_to_doc(nullptr, stat_t, doc, false, val_cond); // no name, since the "dev" has already been added + + return queue_ha(topic, doc.as()); +} + +void Mqtt::add_ha_uom(JsonObject doc, const uint8_t type, const uint8_t uom, const char * entity) { + const char * dc_ha = "dev_cla"; // device class + const char * sc_ha = "stat_cla"; // state class + const char * uom_ha = "unit_of_meas"; // unit of measure + + // set icon, except for booleans + // using HA specific codes from https://github.com/home-assistant/core/blob/dev/homeassistant/const.py + if (type != DeviceValueType::BOOL) { if (uom == DeviceValueUOM::HOURS) { doc[uom_ha] = "h"; } else if (uom == DeviceValueUOM::MINUTES) { @@ -1041,105 +1064,87 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev } } - doc["val_tpl"] = (std::string) "{{" + val_obj + " if " + val_cond + " else " + sample_val + "}}"; - - // Add the state class, device class and sometimes the icon. Used only for read-only sensors Sensor and Binary Sensor - if (readonly_sensors) { - // first set the catagory for System entities - // https://github.com/emsesp/EMS-ESP32/discussions/1459#discussioncomment-7694873 - if (device_type == EMSdevice::DeviceType::SYSTEM) { - doc["ent_cat"] = "diagnostic"; - } - - const char * dc_ha = "dev_cla"; // device class - const char * sc_ha = "stat_cla"; // state class - - switch (uom) { - case DeviceValueUOM::DEGREES: - case DeviceValueUOM::DEGREES_R: - case DeviceValueUOM::K: - doc[sc_ha] = F_(measurement); - doc[dc_ha] = "temperature"; // no icon needed - break; - case DeviceValueUOM::PERCENT: - doc[sc_ha] = F_(measurement); - doc[dc_ha] = "power_factor"; // no icon needed - break; - case DeviceValueUOM::SECONDS: - case DeviceValueUOM::MINUTES: - case DeviceValueUOM::HOURS: - if (type == DeviceValueType::TIME) { - doc[sc_ha] = F_(total_increasing); - } else { - doc[sc_ha] = F_(measurement); - } - doc[dc_ha] = "duration"; // https://github.com/emsesp/EMS-ESP32/issues/822 - break; - case DeviceValueUOM::KB: - doc[ic_ha] = F_(iconkb); - break; - case DeviceValueUOM::LMIN: - doc[ic_ha] = F_(iconlmin); - doc[sc_ha] = F_(measurement); - break; - case DeviceValueUOM::WH: - if (entity == FL_(energyToday)[0]) { - doc[sc_ha] = F_(total_increasing); - } else { - doc[sc_ha] = F_(measurement); - } - doc[dc_ha] = "energy"; - break; - case DeviceValueUOM::KWH: + // set state and device class + switch (uom) { + case DeviceValueUOM::DEGREES: + case DeviceValueUOM::DEGREES_R: + case DeviceValueUOM::K: + doc[sc_ha] = F_(measurement); + doc[dc_ha] = "temperature"; + break; + case DeviceValueUOM::PERCENT: + doc[sc_ha] = F_(measurement); + doc[dc_ha] = "power_factor"; + break; + case DeviceValueUOM::SECONDS: + case DeviceValueUOM::MINUTES: + case DeviceValueUOM::HOURS: + if (type == DeviceValueType::TIME) { doc[sc_ha] = F_(total_increasing); - doc[dc_ha] = "energy"; - break; - case DeviceValueUOM::UA: - doc[ic_ha] = F_(iconua); + } else { doc[sc_ha] = F_(measurement); - break; - case DeviceValueUOM::BAR: - doc[sc_ha] = F_(measurement); - doc[dc_ha] = "pressure"; - break; - case DeviceValueUOM::W: - case DeviceValueUOM::KW: - doc[sc_ha] = F_(measurement); - doc[dc_ha] = "power"; - break; - case DeviceValueUOM::DBM: - doc[sc_ha] = F_(measurement); - doc[dc_ha] = "signal_strength"; - break; - case DeviceValueUOM::CONNECTIVITY: - doc[sc_ha] = F_(measurement); - doc[dc_ha] = "connectivity"; - break; - case DeviceValueUOM::NONE: - // for device entities which have numerical values, with no UOM - if ((type != DeviceValueType::STRING) - && (type == DeviceValueType::INT || type == DeviceValueType::UINT || type == DeviceValueType::SHORT || type == DeviceValueType::USHORT - || type == DeviceValueType::ULONG)) { - doc[ic_ha] = F_(iconnum); // set icon - // determine if its a measurement or total increasing - // most of the values are measurement. for example Tx Reads will increment but can be reset to 0 after a restart - // all the starts are increasing, and they are ULONGs - if (type == DeviceValueType::ULONG) { - doc[sc_ha] = F_(total_increasing); - } else { - doc[sc_ha] = F_(measurement); // default to measurement - } - } - break; - default: - break; } + doc[dc_ha] = "duration"; // https://github.com/emsesp/EMS-ESP32/issues/822 + break; + case DeviceValueUOM::KB: + doc["ic"] = F_(iconkb); + break; + case DeviceValueUOM::LMIN: + doc["ic"] = F_(iconlmin); + doc[sc_ha] = F_(measurement); + break; + case DeviceValueUOM::WH: + if (entity == FL_(energyToday)[0]) { + doc[sc_ha] = F_(total_increasing); + } else { + doc[sc_ha] = F_(measurement); + } + doc[dc_ha] = "energy"; + break; + case DeviceValueUOM::KWH: + doc[sc_ha] = F_(total_increasing); + doc[dc_ha] = "energy"; + break; + case DeviceValueUOM::UA: + doc["ic"] = F_(iconua); + doc[sc_ha] = F_(measurement); + break; + case DeviceValueUOM::BAR: + doc[sc_ha] = F_(measurement); + doc[dc_ha] = "pressure"; + break; + case DeviceValueUOM::W: + case DeviceValueUOM::KW: + doc[sc_ha] = F_(measurement); + doc[dc_ha] = "power"; + break; + case DeviceValueUOM::DBM: + doc[sc_ha] = F_(measurement); + doc[dc_ha] = "signal_strength"; + break; + case DeviceValueUOM::CONNECTIVITY: + doc[sc_ha] = F_(measurement); + doc[dc_ha] = "connectivity"; + break; + case DeviceValueUOM::NONE: + // for device entities which have numerical values, with no UOM + if ((type != DeviceValueType::STRING) + && (type == DeviceValueType::INT || type == DeviceValueType::UINT || type == DeviceValueType::SHORT || type == DeviceValueType::USHORT + || type == DeviceValueType::ULONG)) { + doc["ic"] = F_(iconnum); // set icon + // determine if its a measurement or total increasing + // most of the values are measurement. for example Tx Reads will increment but can be reset to 0 after a restart + // all the starts are increasing, and they are ULONGs + if (type == DeviceValueType::ULONG) { + doc[sc_ha] = F_(total_increasing); + } else { + doc[sc_ha] = F_(measurement); // default to measurement + } + } + break; + default: + break; } - - doc["dev"] = dev_json; // add the dev json object to the end - add_ha_sections_to_doc(nullptr, stat_t, doc, false, val_cond); // no name, since the "dev" has already been added - - return queue_ha(topic, doc.as()); } bool Mqtt::publish_ha_climate_config(const uint8_t tag, const bool has_roomtemp, const bool remove, const int16_t min, const uint32_t max) { diff --git a/src/mqtt.h b/src/mqtt.h index 909c2e5e7..414787667 100644 --- a/src/mqtt.h +++ b/src/mqtt.h @@ -221,6 +221,8 @@ class Mqtt { static std::string tag_to_topic(uint8_t device_type, uint8_t tag); + static void add_ha_uom(JsonObject doc, const uint8_t type, const uint8_t uom, const char * entity = nullptr); + static void add_ha_sections_to_doc(const char * name, const char * state_t, JsonDocument & config, diff --git a/src/web/WebCustomEntityService.cpp b/src/web/WebCustomEntityService.cpp index 94d6241d1..0a3019f7c 100644 --- a/src/web/WebCustomEntityService.cpp +++ b/src/web/WebCustomEntityService.cpp @@ -441,6 +441,8 @@ void WebCustomEntityService::publish(const bool force) { } } + Mqtt::add_ha_uom(config.as(), entityItem.value_type, entityItem.uom); // add uom + Mqtt::add_ha_sections_to_doc("custom", stat_t, config, !ha_created, val_cond); ha_created |= Mqtt::queue_ha(topic, config.as()); diff --git a/src/web/WebCustomEntityService.h b/src/web/WebCustomEntityService.h index 7b81c3c31..f044dcb03 100644 --- a/src/web/WebCustomEntityService.h +++ b/src/web/WebCustomEntityService.h @@ -32,7 +32,7 @@ class CustomEntityItem { uint16_t type_id; uint8_t offset; int8_t value_type; - uint8_t uom; + uint8_t uom; // DeviceValueUOM std::string name; double factor; bool writeable; From 6d6291e6597d40d7913cf31bf630ec598fc0d472 Mon Sep 17 00:00:00 2001 From: Proddy Date: Sat, 10 Feb 2024 15:42:14 +0100 Subject: [PATCH 09/54] remove feature as its not used, and speed up web loading slightly --- interface/src/App.tsx | 5 +-- interface/src/SignIn.tsx | 4 --- interface/src/api/features.ts | 5 --- .../src/contexts/features/FeaturesLoader.tsx | 25 --------------- interface/src/contexts/features/context.ts | 10 ------ interface/src/contexts/features/index.ts | 2 -- .../src/framework/system/SystemStatusForm.tsx | 5 +-- interface/src/types/index.ts | 1 - lib/framework/AuthenticationService.cpp | 4 --- lib/framework/AuthenticationService.h | 4 --- lib/framework/ESP8266React.cpp | 7 ++-- lib/framework/ESP8266React.h | 2 -- lib/framework/Features.h | 4 --- lib/framework/FeaturesService.cpp | 19 ----------- lib/framework/FeaturesService.h | 22 ------------- lib/framework/SecuritySettingsService.cpp | 32 ------------------- lib/framework/SecuritySettingsService.h | 21 ++---------- lib_standalone/Features.h | 2 -- lib_standalone/SecurityManager.h | 2 -- lib_standalone/SecuritySettingsService.cpp | 32 ------------------- lib_standalone/SecuritySettingsService.h | 3 -- 21 files changed, 7 insertions(+), 204 deletions(-) delete mode 100644 interface/src/api/features.ts delete mode 100644 interface/src/contexts/features/FeaturesLoader.tsx delete mode 100644 interface/src/contexts/features/context.ts delete mode 100644 interface/src/contexts/features/index.ts delete mode 100644 lib/framework/FeaturesService.cpp delete mode 100644 lib/framework/FeaturesService.h diff --git a/interface/src/App.tsx b/interface/src/App.tsx index f69032319..77f79e41d 100644 --- a/interface/src/App.tsx +++ b/interface/src/App.tsx @@ -4,7 +4,6 @@ import { ToastContainer, Slide } from 'react-toastify'; import 'react-toastify/dist/ReactToastify.min.css'; import { localStorageDetector } from 'typesafe-i18n/detectors'; -import { FeaturesLoader } from './contexts/features'; import type { FC } from 'react'; import AppRouting from 'AppRouting'; import CustomTheme from 'CustomTheme'; @@ -27,9 +26,7 @@ const App: FC = () => { return ( - - - + { const { LL, setLocale, locale } = useContext(I18nContext); - const { features } = useContext(FeaturesContext); - const [signInRequest, setSignInRequest] = useState({ username: '', password: '' @@ -112,7 +109,6 @@ const SignIn: FC = () => { })} > {PROJECT_NAME} - {features.version} diff --git a/interface/src/api/features.ts b/interface/src/api/features.ts deleted file mode 100644 index c0dd66e4f..000000000 --- a/interface/src/api/features.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { alovaInstance } from './endpoints'; - -import type { Features } from 'types'; - -export const readFeatures = () => alovaInstance.Get('/rest/features'); diff --git a/interface/src/contexts/features/FeaturesLoader.tsx b/interface/src/contexts/features/FeaturesLoader.tsx deleted file mode 100644 index 38e5e0196..000000000 --- a/interface/src/contexts/features/FeaturesLoader.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import { useRequest } from 'alova'; - -import { FeaturesContext } from '.'; -import type { FC } from 'react'; - -import type { RequiredChildrenProps } from 'utils'; -import * as FeaturesApi from 'api/features'; - -const FeaturesLoader: FC = (props) => { - const { data: features } = useRequest(FeaturesApi.readFeatures); - - if (features) { - return ( - - {props.children} - - ); - } -}; - -export default FeaturesLoader; diff --git a/interface/src/contexts/features/context.ts b/interface/src/contexts/features/context.ts deleted file mode 100644 index 78a8f1ec2..000000000 --- a/interface/src/contexts/features/context.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { createContext } from 'react'; - -import type { Features } from 'types'; - -export interface FeaturesContextValue { - features: Features; -} - -const FeaturesContextDefaultValue = {} as FeaturesContextValue; -export const FeaturesContext = createContext(FeaturesContextDefaultValue); diff --git a/interface/src/contexts/features/index.ts b/interface/src/contexts/features/index.ts deleted file mode 100644 index f8df83c02..000000000 --- a/interface/src/contexts/features/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './context'; -export { default as FeaturesLoader } from './FeaturesLoader'; diff --git a/interface/src/framework/system/SystemStatusForm.tsx b/interface/src/framework/system/SystemStatusForm.tsx index f6f7203cb..ba710e36e 100644 --- a/interface/src/framework/system/SystemStatusForm.tsx +++ b/interface/src/framework/system/SystemStatusForm.tsx @@ -29,7 +29,6 @@ import { import { useRequest } from 'alova'; import { useContext, useState } from 'react'; import { toast } from 'react-toastify'; -import { FeaturesContext } from '../../contexts/features'; import RestartMonitor from './RestartMonitor'; import SystemStatusVersionDialog from './SystemStatusVersionDialog'; import type { FC } from 'react'; @@ -54,8 +53,6 @@ const SystemStatusForm: FC = () => { const [restarting, setRestarting] = useState(); const [versionDialogOpen, setVersionDialogOpen] = useState(false); - const { features } = useContext(FeaturesContext); - const { send: restartCommand } = useRequest(SystemApi.restart(), { immediate: false }); @@ -355,7 +352,7 @@ const SystemStatusForm: FC = () => { open={versionDialogOpen} onClose={() => setVersionDialogOpen(false)} version={data.emsesp_version} - platform={features.platform} + platform={data.esp_platform} /> )} diff --git a/interface/src/types/index.ts b/interface/src/types/index.ts index 632d8907b..420f7e2bf 100644 --- a/interface/src/types/index.ts +++ b/interface/src/types/index.ts @@ -1,5 +1,4 @@ export * from './ap'; -export * from './features'; export * from './me'; export * from './mqtt'; export * from './ntp'; diff --git a/lib/framework/AuthenticationService.cpp b/lib/framework/AuthenticationService.cpp index fd316a87c..f0fc92dbb 100644 --- a/lib/framework/AuthenticationService.cpp +++ b/lib/framework/AuthenticationService.cpp @@ -2,8 +2,6 @@ using namespace std::placeholders; // for `_1` etc -#if FT_ENABLED(FT_SECURITY) - AuthenticationService::AuthenticationService(AsyncWebServer * server, SecurityManager * securityManager) : _securityManager(securityManager) , _signInHandler(SIGN_IN_PATH, std::bind(&AuthenticationService::signIn, this, _1, _2)) { @@ -43,5 +41,3 @@ void AuthenticationService::signIn(AsyncWebServerRequest * request, JsonVariant AsyncWebServerResponse * response = request->beginResponse(401); request->send(response); } - -#endif diff --git a/lib/framework/AuthenticationService.h b/lib/framework/AuthenticationService.h index d8a823485..c7ca70646 100644 --- a/lib/framework/AuthenticationService.h +++ b/lib/framework/AuthenticationService.h @@ -10,8 +10,6 @@ #define MAX_AUTHENTICATION_SIZE 256 -#if FT_ENABLED(FT_SECURITY) - class AuthenticationService { public: AuthenticationService(AsyncWebServer * server, SecurityManager * securityManager); @@ -26,5 +24,3 @@ class AuthenticationService { }; #endif - -#endif diff --git a/lib/framework/ESP8266React.cpp b/lib/framework/ESP8266React.cpp index 8fd7719da..94a3b78fd 100644 --- a/lib/framework/ESP8266React.cpp +++ b/lib/framework/ESP8266React.cpp @@ -3,8 +3,7 @@ #include ESP8266React::ESP8266React(AsyncWebServer * server, FS * fs) - : _featureService(server) - , _securitySettingsService(server, fs) + : _securitySettingsService(server, fs) , _networkSettingsService(server, fs, &_securitySettingsService) , _wifiScanner(server, &_securitySettingsService) , _networkStatus(server, &_securitySettingsService) @@ -20,12 +19,12 @@ ESP8266React::ESP8266React(AsyncWebServer * server, FS * fs) , _restartService(server, &_securitySettingsService) , _factoryResetService(server, fs, &_securitySettingsService) , _systemStatus(server, &_securitySettingsService) { - // Serve static resources from PROGMEM + // Serve static resources WWWData::registerRoutes([server, this](const String & uri, const String & contentType, const uint8_t * content, size_t len) { ArRequestHandlerFunction requestHandler = [contentType, content, len](AsyncWebServerRequest * request) { AsyncWebServerResponse * response = request->beginResponse_P(200, contentType, content, len); response->addHeader("Content-Encoding", "gzip"); - // response->addHeader("Cache-Control", "public, immutable, max-age=31536000"); + response->addHeader("Cache-Control", "public, immutable, max-age=31536000"); // response->addHeader("Content-Encoding", "br"); // only works over HTTPS request->send(response); }; diff --git a/lib/framework/ESP8266React.h b/lib/framework/ESP8266React.h index 2bab9e190..2a86019e1 100644 --- a/lib/framework/ESP8266React.h +++ b/lib/framework/ESP8266React.h @@ -6,7 +6,6 @@ #include #include -#include #include #include #include @@ -72,7 +71,6 @@ class ESP8266React { } private: - FeaturesService _featureService; SecuritySettingsService _securitySettingsService; NetworkSettingsService _networkSettingsService; WiFiScanner _wifiScanner; diff --git a/lib/framework/Features.h b/lib/framework/Features.h index 204caaa18..1629b39ef 100644 --- a/lib/framework/Features.h +++ b/lib/framework/Features.h @@ -1,10 +1,6 @@ #ifndef Features_h #define Features_h -// modified by Proddy - -#define FT_ENABLED(feature) feature - // project feature on by default #ifndef FT_PROJECT #define FT_PROJECT 1 diff --git a/lib/framework/FeaturesService.cpp b/lib/framework/FeaturesService.cpp deleted file mode 100644 index cddb85586..000000000 --- a/lib/framework/FeaturesService.cpp +++ /dev/null @@ -1,19 +0,0 @@ -#include -#include "../../src/emsesp_stub.hpp" - -using namespace std::placeholders; // for `_1` etc - -FeaturesService::FeaturesService(AsyncWebServer * server) { - server->on(FEATURES_SERVICE_PATH, HTTP_GET, std::bind(&FeaturesService::features, this, _1)); -} - -void FeaturesService::features(AsyncWebServerRequest * request) { - AsyncJsonResponse * response = new AsyncJsonResponse(false); - JsonObject root = response->getRoot(); - - root["version"] = EMSESP_APP_VERSION; - root["platform"] = EMSESP_PLATFORM; - - response->setLength(); - request->send(response); -} diff --git a/lib/framework/FeaturesService.h b/lib/framework/FeaturesService.h deleted file mode 100644 index dc64a8b3d..000000000 --- a/lib/framework/FeaturesService.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef FeaturesService_h -#define FeaturesService_h - -#include - -#include -#include -#include -#include - -// #define MAX_FEATURES_SIZE 256 -#define FEATURES_SERVICE_PATH "/rest/features" - -class FeaturesService { - public: - FeaturesService(AsyncWebServer * server); - - private: - void features(AsyncWebServerRequest * request); -}; - -#endif diff --git a/lib/framework/SecuritySettingsService.cpp b/lib/framework/SecuritySettingsService.cpp index 9b5ab85c6..2a83e34b6 100644 --- a/lib/framework/SecuritySettingsService.cpp +++ b/lib/framework/SecuritySettingsService.cpp @@ -1,7 +1,5 @@ #include -#if FT_ENABLED(FT_SECURITY) - #include "../../src/emsesp_stub.hpp" SecuritySettingsService::SecuritySettingsService(AsyncWebServer * server, FS * fs) @@ -125,33 +123,3 @@ void SecuritySettingsService::generateToken(AsyncWebServerRequest * request) { } request->send(401); } - -#else - -User ADMIN_USER = User(FACTORY_ADMIN_USERNAME, FACTORY_ADMIN_PASSWORD, true); - -SecuritySettingsService::SecuritySettingsService(AsyncWebServer * server, FS * fs) - : SecurityManager() { -} -SecuritySettingsService::~SecuritySettingsService() { -} - -ArRequestFilterFunction SecuritySettingsService::filterRequest(AuthenticationPredicate predicate) { - return [this, predicate](AsyncWebServerRequest * request) { return true; }; -} - -// Return the admin user on all request - disabling security features -Authentication SecuritySettingsService::authenticateRequest(AsyncWebServerRequest * request) { - return Authentication(ADMIN_USER); -} - -// Return the function unwrapped -ArRequestHandlerFunction SecuritySettingsService::wrapRequest(ArRequestHandlerFunction onRequest, AuthenticationPredicate predicate) { - return onRequest; -} - -ArJsonRequestHandlerFunction SecuritySettingsService::wrapCallback(ArJsonRequestHandlerFunction onRequest, AuthenticationPredicate predicate) { - return onRequest; -} - -#endif diff --git a/lib/framework/SecuritySettingsService.h b/lib/framework/SecuritySettingsService.h index f122d0ba2..3ec8dd755 100644 --- a/lib/framework/SecuritySettingsService.h +++ b/lib/framework/SecuritySettingsService.h @@ -28,11 +28,9 @@ #define GENERATE_TOKEN_SIZE 512 #define GENERATE_TOKEN_PATH "/rest/generateToken" -#if FT_ENABLED(FT_SECURITY) - class SecuritySettings { public: - String jwtSecret; + String jwtSecret; std::vector users; // std::list users; @@ -102,19 +100,4 @@ class SecuritySettingsService : public StatefulService, public boolean validatePayload(JsonObject parsedPayload, User * user); }; -#else - -class SecuritySettingsService : public SecurityManager { - public: - SecuritySettingsService(AsyncWebServer * server, FS * fs); - ~SecuritySettingsService(); - - // minimal set of functions to support framework with security settings disabled - Authentication authenticateRequest(AsyncWebServerRequest * request); - ArRequestFilterFunction filterRequest(AuthenticationPredicate predicate); - ArRequestHandlerFunction wrapRequest(ArRequestHandlerFunction onRequest, AuthenticationPredicate predicate); - ArJsonRequestHandlerFunction wrapCallback(ArJsonRequestHandlerFunction onRequest, AuthenticationPredicate predicate); -}; - -#endif -#endif +#endif \ No newline at end of file diff --git a/lib_standalone/Features.h b/lib_standalone/Features.h index 28cd6d551..526806569 100644 --- a/lib_standalone/Features.h +++ b/lib_standalone/Features.h @@ -1,8 +1,6 @@ #ifndef Features_h #define Features_h -#define FT_ENABLED(feature) feature - // project feature off by default #ifndef FT_PROJECT #define FT_PROJECT 0 diff --git a/lib_standalone/SecurityManager.h b/lib_standalone/SecurityManager.h index cebff2229..d9e73e68c 100644 --- a/lib_standalone/SecurityManager.h +++ b/lib_standalone/SecurityManager.h @@ -69,10 +69,8 @@ class AuthenticationPredicates { class SecurityManager { public: -#if FT_ENABLED(FT_SECURITY) virtual Authentication authenticate(const String & username, const String & password) = 0; virtual String generateJWT(User * user) = 0; -#endif virtual Authentication authenticateRequest(AsyncWebServerRequest * request) = 0; virtual ArRequestFilterFunction filterRequest(AuthenticationPredicate predicate) = 0; diff --git a/lib_standalone/SecuritySettingsService.cpp b/lib_standalone/SecuritySettingsService.cpp index 7cc393418..97e7d9223 100644 --- a/lib_standalone/SecuritySettingsService.cpp +++ b/lib_standalone/SecuritySettingsService.cpp @@ -2,8 +2,6 @@ #include -#if FT_ENABLED(FT_SECURITY) - #include "../../src/emsesp_stub.h" // proddy added SecuritySettingsService::SecuritySettingsService(AsyncWebServer * server, FS * fs) @@ -110,34 +108,4 @@ ArJsonRequestHandlerFunction SecuritySettingsService::wrapCallback(ArJsonRequest }; } -#else - -User ADMIN_USER = User(FACTORY_ADMIN_USERNAME, FACTORY_ADMIN_PASSWORD, true); - -SecuritySettingsService::SecuritySettingsService(AsyncWebServer * server, FS * fs) - : SecurityManager() { -} -SecuritySettingsService::~SecuritySettingsService() { -} - -ArRequestFilterFunction SecuritySettingsService::filterRequest(AuthenticationPredicate predicate) { - return [this, predicate](AsyncWebServerRequest * request) { return true; }; -} - -// Return the admin user on all request - disabling security features -Authentication SecuritySettingsService::authenticateRequest(AsyncWebServerRequest * request) { - return Authentication(ADMIN_USER); -} - -// Return the function unwrapped -ArRequestHandlerFunction SecuritySettingsService::wrapRequest(ArRequestHandlerFunction onRequest, AuthenticationPredicate predicate) { - return onRequest; -} - -ArJsonRequestHandlerFunction SecuritySettingsService::wrapCallback(ArJsonRequestHandlerFunction onRequest, AuthenticationPredicate predicate) { - return onRequest; -} - -#endif - #endif \ No newline at end of file diff --git a/lib_standalone/SecuritySettingsService.h b/lib_standalone/SecuritySettingsService.h index a283854e0..4195cf1e6 100644 --- a/lib_standalone/SecuritySettingsService.h +++ b/lib_standalone/SecuritySettingsService.h @@ -25,8 +25,6 @@ #define SECURITY_SETTINGS_FILE "/config/securitySettings.json" #define SECURITY_SETTINGS_PATH "/rest/securitySettings" -#if FT_ENABLED(FT_SECURITY) - class SecuritySettings { public: String jwtSecret; @@ -103,4 +101,3 @@ class SecuritySettingsService : public SecurityManager { }; #endif -#endif From 55672cc9dea637b6879b86a1f5187011811a558f Mon Sep 17 00:00:00 2001 From: Proddy Date: Sat, 10 Feb 2024 15:43:03 +0100 Subject: [PATCH 10/54] don't show bus scanning, so orange warning doesn't render on refresh --- interface/src/project/DashboardDevices.tsx | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/interface/src/project/DashboardDevices.tsx b/interface/src/project/DashboardDevices.tsx index f59047e3f..d95bc9f3a 100644 --- a/interface/src/project/DashboardDevices.tsx +++ b/interface/src/project/DashboardDevices.tsx @@ -94,8 +94,14 @@ const DashboardDevices: FC = () => { }, []); const leftOffset = () => { - const left = document.getElementById('devices-window')?.getBoundingClientRect().left; - const right = document.getElementById('devices-window')?.getBoundingClientRect().right; + const devicesWindow = document.getElementById('devices-window'); + if (!devicesWindow) { + return 0; + } + + const clientRect = devicesWindow.getBoundingClientRect(); + const left = clientRect.left; + const right = clientRect.right; if (!left || !right) { return 0; @@ -416,11 +422,11 @@ const DashboardDevices: FC = () => { const renderCoreData = () => ( {!coreData.connected && } - {coreData.connected && coreData.devices.length === 0 && ( + {/* {coreData.connected && coreData.devices.length === 0 && ( - )} + )} */} - {coreData.devices.length !== 0 && ( + {coreData.connected && ( {(tableList: any) => ( <> From fe5a6fb568a55cdade487ca7625eb550e5f69a81 Mon Sep 17 00:00:00 2001 From: Proddy Date: Sat, 10 Feb 2024 15:43:19 +0100 Subject: [PATCH 11/54] added missing data points --- mock-api/handler.ts | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/mock-api/handler.ts b/mock-api/handler.ts index 87e02c773..692c55b5c 100644 --- a/mock-api/handler.ts +++ b/mock-api/handler.ts @@ -363,7 +363,6 @@ const mqtt_status = { }; // SYSTEM -const FEATURES_ENDPOINT = REST_ENDPOINT_ROOT + 'features'; const VERIFY_AUTHORIZATION_ENDPOINT = REST_ENDPOINT_ROOT + 'verifyAuthorization'; const SYSTEM_STATUS_ENDPOINT = REST_ENDPOINT_ROOT + 'systemStatus'; const SECURITY_SETTINGS_ENDPOINT = REST_ENDPOINT_ROOT + 'securitySettings'; @@ -375,6 +374,9 @@ const GENERATE_TOKEN_ENDPOINT = REST_ENDPOINT_ROOT + 'generateToken'; const system_status = { emsesp_version: '3.6-demo', esp_platform: 'ESP32', + cpu_type: 'ESP32-S3', + cpu_rev: '0', + cpu_cores: 2, max_alloc_heap: 89, psram_size: 0, free_psram: 0, @@ -385,9 +387,11 @@ const system_status = { flash_chip_speed: 40000000, fs_used: 40, fs_free: 24, + partition: 'app0', app_used: 1863, app_free: 121, - uptime: '000+00:15:42.707' + uptime: '000+00:15:42.707', + arduino_version: 'ESP32 Arduino v2.0.14' }; let security_settings = { jwt_secret: 'naughty!', @@ -396,17 +400,7 @@ let security_settings = { { username: 'guest', password: 'guest', admin: false } ] }; -const features = { - project: true, - security: true, - mqtt: true, - ntp: true, - ota: true, - upload_firmware: true, - version: 'v3.6-demo', - // platform: 'ESP32' - platform: 'ESP32-S3' -}; + const verify_authentication = { access_token: '1234' }; const signin = { access_token: @@ -2377,7 +2371,6 @@ router security_settings = await request.json(); return new Response('OK', { status: 200 }); }) - .get(FEATURES_ENDPOINT, () => new Response(JSON.stringify(features), { headers })) .get(VERIFY_AUTHORIZATION_ENDPOINT, () => new Response(JSON.stringify(verify_authentication), { headers })) .post(RESTART_ENDPOINT, () => new Response('OK', { status: 200 })) .post(FACTORY_RESET_ENDPOINT, () => new Response('OK', { status: 200 })) From fc8eea91eb61424953f6ed75494d49499e8798d7 Mon Sep 17 00:00:00 2001 From: Proddy Date: Sat, 10 Feb 2024 15:43:35 +0100 Subject: [PATCH 12/54] scope optimization --- src/mqtt.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mqtt.cpp b/src/mqtt.cpp index 0930109f7..df7f77bc2 100644 --- a/src/mqtt.cpp +++ b/src/mqtt.cpp @@ -1046,13 +1046,13 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev } void Mqtt::add_ha_uom(JsonObject doc, const uint8_t type, const uint8_t uom, const char * entity) { - const char * dc_ha = "dev_cla"; // device class - const char * sc_ha = "stat_cla"; // state class - const char * uom_ha = "unit_of_meas"; // unit of measure + const char * dc_ha = "dev_cla"; // device class + const char * sc_ha = "stat_cla"; // state class // set icon, except for booleans // using HA specific codes from https://github.com/home-assistant/core/blob/dev/homeassistant/const.py if (type != DeviceValueType::BOOL) { + const char * uom_ha = "unit_of_meas"; // unit of measure if (uom == DeviceValueUOM::HOURS) { doc[uom_ha] = "h"; } else if (uom == DeviceValueUOM::MINUTES) { From 52479c408f301fbab9ace076a00bfa894bb07e17 Mon Sep 17 00:00:00 2001 From: Proddy Date: Sat, 10 Feb 2024 15:43:49 +0100 Subject: [PATCH 13/54] added comment for refactor reminder --- lib/framework/NetworkSettingsService.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/lib/framework/NetworkSettingsService.cpp b/lib/framework/NetworkSettingsService.cpp index ad2cf0e9c..09369efb4 100644 --- a/lib/framework/NetworkSettingsService.cpp +++ b/lib/framework/NetworkSettingsService.cpp @@ -26,7 +26,6 @@ void NetworkSettingsService::begin() { // WiFi.setScanMethod(WIFI_ALL_CHANNEL_SCAN); // default is FAST_SCAN, connect issues in 2.0.14 // WiFi.setSortMethod(WIFI_CONNECT_AP_BY_SIGNAL); // is default, no need to set - _fsPersistence.readFromFS(); // reconfigureWiFiConnection(); } @@ -36,6 +35,7 @@ void NetworkSettingsService::reconfigureWiFiConnection() { if (WiFi.isConnected() && _state.ssid.length() == 0) { return; } + // disconnect and de-configure wifi if (WiFi.disconnect(true)) { _stopping = true; @@ -84,15 +84,16 @@ void NetworkSettingsService::manageSTA() { WiFi.begin(_state.ssid.c_str(), _state.password.c_str()); } // set power after wifi is startet, fixed value for C3_V1 - if (WiFi.isConnected()) { + // if (WiFi.isConnected()) { #ifdef BOARD_C3_MINI_V1 - // v1 needs this value, see https://github.com/emsesp/EMS-ESP32/pull/620#discussion_r993173979 - WiFi.setTxPower(WIFI_POWER_8_5dBm); // https://www.wemos.cc/en/latest/c3/c3_mini_1_0_0.html#about-wifi + // v1 needs this value, see https://github.com/emsesp/EMS-ESP32/pull/620#discussion_r993173979 + WiFi.setTxPower(WIFI_POWER_8_5dBm); // https://www.wemos.cc/en/latest/c3/c3_mini_1_0_0.html#about-wifi #else - // esp_wifi_set_max_tx_power(_state.tx_power * 4); - WiFi.setTxPower((wifi_power_t)(_state.tx_power * 4)); + // esp_wifi_set_max_tx_power(_state.tx_power * 4); + // TODO make it dynamic + WiFi.setTxPower((wifi_power_t)(_state.tx_power * 4)); #endif - } + // } } else { // not connected but STA-mode active => disconnect reconfigureWiFiConnection(); } From 303e86a5ebb902b5cc5a2476b44f68229b577606 Mon Sep 17 00:00:00 2001 From: Proddy Date: Sat, 10 Feb 2024 15:43:59 +0100 Subject: [PATCH 14/54] remove unused comments --- lib/framework/APStatus.h | 1 - lib/framework/HttpEndpoint.h | 1 - lib/framework/MqttStatus.h | 1 - lib/framework/NTPStatus.h | 1 - lib/framework/SecurityManager.h | 5 ----- lib/framework/SystemStatus.h | 1 - lib/framework/WiFiScanner.h | 2 -- 7 files changed, 12 deletions(-) diff --git a/lib/framework/APStatus.h b/lib/framework/APStatus.h index 2b7d35a04..addda2a25 100644 --- a/lib/framework/APStatus.h +++ b/lib/framework/APStatus.h @@ -10,7 +10,6 @@ #include #include -// #define MAX_AP_STATUS_SIZE 1024 #define AP_STATUS_SERVICE_PATH "/rest/apStatus" class APStatus { diff --git a/lib/framework/HttpEndpoint.h b/lib/framework/HttpEndpoint.h index a2c18b23b..ba57c7caf 100644 --- a/lib/framework/HttpEndpoint.h +++ b/lib/framework/HttpEndpoint.h @@ -57,7 +57,6 @@ class HttpEndpoint { request->send(400); // error return; } else if (outcome == StateUpdateResult::CHANGED_RESTART) { - // TODO check if works request->send(205); // reboot required return; } else if (outcome == StateUpdateResult::CHANGED) { diff --git a/lib/framework/MqttStatus.h b/lib/framework/MqttStatus.h index f8260bd54..eb7ba980b 100644 --- a/lib/framework/MqttStatus.h +++ b/lib/framework/MqttStatus.h @@ -7,7 +7,6 @@ #include #include -// #define MAX_MQTT_STATUS_SIZE 1024 #define MQTT_STATUS_SERVICE_PATH "/rest/mqttStatus" class MqttStatus { diff --git a/lib/framework/NTPStatus.h b/lib/framework/NTPStatus.h index 152933fe3..2dec0a9f4 100644 --- a/lib/framework/NTPStatus.h +++ b/lib/framework/NTPStatus.h @@ -11,7 +11,6 @@ #include #include -// #define MAX_NTP_STATUS_SIZE 1024 #define NTP_STATUS_SERVICE_PATH "/rest/ntpStatus" class NTPStatus { diff --git a/lib/framework/SecurityManager.h b/lib/framework/SecurityManager.h index 6bc1257ac..2f1610588 100644 --- a/lib/framework/SecurityManager.h +++ b/lib/framework/SecurityManager.h @@ -18,8 +18,6 @@ #define AUTHORIZATION_HEADER_PREFIX "Bearer " #define AUTHORIZATION_HEADER_PREFIX_LEN 7 -// #define MAX_JWT_SIZE 128 - class User { public: String username; @@ -70,7 +68,6 @@ class AuthenticationPredicates { class SecurityManager { public: -#if FT_ENABLED(FT_SECURITY) /* * Authenticate, returning the user if found */ @@ -81,8 +78,6 @@ class SecurityManager { */ virtual String generateJWT(User * user) = 0; -#endif - /* * Check the request header for the Authorization token */ diff --git a/lib/framework/SystemStatus.h b/lib/framework/SystemStatus.h index 3f5c456be..4970e81b9 100644 --- a/lib/framework/SystemStatus.h +++ b/lib/framework/SystemStatus.h @@ -10,7 +10,6 @@ #include #include -// #define MAX_ESP_STATUS_SIZE 1024 #define SYSTEM_STATUS_SERVICE_PATH "/rest/systemStatus" class SystemStatus { diff --git a/lib/framework/WiFiScanner.h b/lib/framework/WiFiScanner.h index f73097477..e73a2e669 100644 --- a/lib/framework/WiFiScanner.h +++ b/lib/framework/WiFiScanner.h @@ -11,8 +11,6 @@ #define SCAN_NETWORKS_SERVICE_PATH "/rest/scanNetworks" #define LIST_NETWORKS_SERVICE_PATH "/rest/listNetworks" -// #define MAX_WIFI_SCANNER_SIZE 1024 - class WiFiScanner { public: WiFiScanner(AsyncWebServer * server, SecurityManager * securityManager); From 12f0120afd59194edb88bdca282c37bfbf788941 Mon Sep 17 00:00:00 2001 From: Proddy Date: Sat, 10 Feb 2024 16:17:40 +0100 Subject: [PATCH 15/54] fix standalone compiling --- lib_standalone/SecurityManager.h | 3 - lib_standalone/SecuritySettingsService.cpp | 104 +++------------------ lib_standalone/SecuritySettingsService.h | 63 ------------- platformio.ini | 5 +- 4 files changed, 15 insertions(+), 160 deletions(-) diff --git a/lib_standalone/SecurityManager.h b/lib_standalone/SecurityManager.h index d9e73e68c..80f83d049 100644 --- a/lib_standalone/SecurityManager.h +++ b/lib_standalone/SecurityManager.h @@ -69,9 +69,6 @@ class AuthenticationPredicates { class SecurityManager { public: - virtual Authentication authenticate(const String & username, const String & password) = 0; - virtual String generateJWT(User * user) = 0; - virtual Authentication authenticateRequest(AsyncWebServerRequest * request) = 0; virtual ArRequestFilterFunction filterRequest(AuthenticationPredicate predicate) = 0; virtual ArRequestHandlerFunction wrapRequest(ArRequestHandlerFunction onRequest, AuthenticationPredicate predicate) = 0; diff --git a/lib_standalone/SecuritySettingsService.cpp b/lib_standalone/SecuritySettingsService.cpp index 97e7d9223..58b894995 100644 --- a/lib_standalone/SecuritySettingsService.cpp +++ b/lib_standalone/SecuritySettingsService.cpp @@ -2,110 +2,30 @@ #include -#include "../../src/emsesp_stub.h" // proddy added +User ADMIN_USER = User(FACTORY_ADMIN_USERNAME, FACTORY_ADMIN_PASSWORD, true); SecuritySettingsService::SecuritySettingsService(AsyncWebServer * server, FS * fs) - : _httpEndpoint(SecuritySettings::read, SecuritySettings::update, this, server, SECURITY_SETTINGS_PATH, this) - , _fsPersistence(SecuritySettings::read, SecuritySettings::update, this, fs, SECURITY_SETTINGS_FILE) - , _jwtHandler(FACTORY_JWT_SECRET) { - addUpdateHandler([&](const String & originId) { configureJWTHandler(); }, false); + : SecurityManager() { } - -void SecuritySettingsService::begin() { - _fsPersistence.readFromFS(); - configureJWTHandler(); -} - -Authentication SecuritySettingsService::authenticateRequest(AsyncWebServerRequest * request) { - AsyncWebHeader * authorizationHeader = request->getHeader(AUTHORIZATION_HEADER); - if (authorizationHeader) { - String value = authorizationHeader->value(); - if (value.startsWith(AUTHORIZATION_HEADER_PREFIX)) { - value = value.substring(AUTHORIZATION_HEADER_PREFIX_LEN); - return authenticateJWT(value); - } - } else if (request->hasParam(ACCESS_TOKEN_PARAMATER)) { - AsyncWebParameter * tokenParamater = request->getParam(ACCESS_TOKEN_PARAMATER); - String value = tokenParamater->value(); - return authenticateJWT(value); - } - return Authentication(); -} - -void SecuritySettingsService::configureJWTHandler() { - _jwtHandler.setSecret(_state.jwtSecret); -} - -Authentication SecuritySettingsService::authenticateJWT(String & jwt) { - JsonDocument payloadDocument; - _jwtHandler.parseJWT(jwt, payloadDocument); - if (payloadDocument.is()) { - JsonObject parsedPayload = payloadDocument.as(); - String username = parsedPayload["username"]; - for (User _user : _state.users) { - if (_user.username == username && validatePayload(parsedPayload, &_user)) { - return Authentication(_user); - } - } - } - return Authentication(); -} - -Authentication SecuritySettingsService::authenticate(const String & username, const String & password) { - for (User _user : _state.users) { - if (_user.username == username && _user.password == password) { - return Authentication(_user); - } - } - return Authentication(); -} - -inline void populateJWTPayload(JsonObject payload, User * user) { - payload["username"] = user->username; - payload["admin"] = user->admin; -} - -boolean SecuritySettingsService::validatePayload(JsonObject parsedPayload, User * user) { - JsonDocument jsonDocument; - JsonObject payload = jsonDocument.to(); - populateJWTPayload(payload, user); - return payload == parsedPayload; -} - -String SecuritySettingsService::generateJWT(User * user) { - JsonDocument jsonDocument; - JsonObject payload = jsonDocument.to(); - populateJWTPayload(payload, user); - return _jwtHandler.buildJWT(payload); +SecuritySettingsService::~SecuritySettingsService() { } ArRequestFilterFunction SecuritySettingsService::filterRequest(AuthenticationPredicate predicate) { - return [this, predicate](AsyncWebServerRequest * request) { - Authentication authentication = authenticateRequest(request); - return predicate(authentication); - }; + return [this, predicate](AsyncWebServerRequest * request) { return true; }; } +// Return the admin user on all request - disabling security features +Authentication SecuritySettingsService::authenticateRequest(AsyncWebServerRequest * request) { + return Authentication(ADMIN_USER); +} + +// Return the function unwrapped ArRequestHandlerFunction SecuritySettingsService::wrapRequest(ArRequestHandlerFunction onRequest, AuthenticationPredicate predicate) { - return [this, onRequest, predicate](AsyncWebServerRequest * request) { - Authentication authentication = authenticateRequest(request); - if (!predicate(authentication)) { - request->send(401); - return; - } - onRequest(request); - }; + return onRequest; } ArJsonRequestHandlerFunction SecuritySettingsService::wrapCallback(ArJsonRequestHandlerFunction onRequest, AuthenticationPredicate predicate) { - return [this, onRequest, predicate](AsyncWebServerRequest * request, JsonVariant json) { - Authentication authentication = authenticateRequest(request); - if (!predicate(authentication)) { - request->send(401); - return; - } - onRequest(request, json); - }; + return onRequest; } #endif \ No newline at end of file diff --git a/lib_standalone/SecuritySettingsService.h b/lib_standalone/SecuritySettingsService.h index 4195cf1e6..cf8dca1d9 100644 --- a/lib_standalone/SecuritySettingsService.h +++ b/lib_standalone/SecuritySettingsService.h @@ -25,69 +25,6 @@ #define SECURITY_SETTINGS_FILE "/config/securitySettings.json" #define SECURITY_SETTINGS_PATH "/rest/securitySettings" -class SecuritySettings { - public: - String jwtSecret; - std::list users; - - static void read(SecuritySettings & settings, JsonObject root) { - // secret - root["jwt_secret"] = settings.jwtSecret; - - // users - JsonArray users = root["users"].to(); - for (User user : settings.users) { - JsonObject userRoot = users.add(); - userRoot["username"] = user.username; - userRoot["password"] = user.password; - userRoot["admin"] = user.admin; - } - } - - static StateUpdateResult update(JsonObject root, SecuritySettings & settings) { - // secret - settings.jwtSecret = root["jwt_secret"] | FACTORY_JWT_SECRET; - - // users - settings.users.clear(); - if (root["users"].is()) { - for (JsonVariant user : root["users"].as()) { - settings.users.push_back(User(user["username"], user["password"], user["admin"])); - } - } else { - settings.users.push_back(User(FACTORY_ADMIN_USERNAME, FACTORY_ADMIN_PASSWORD, true)); - settings.users.push_back(User(FACTORY_GUEST_USERNAME, FACTORY_GUEST_PASSWORD, false)); - } - return StateUpdateResult::CHANGED; - } -}; - -class SecuritySettingsService : public StatefulService, public SecurityManager { - public: - SecuritySettingsService(AsyncWebServer * server, FS * fs); - - void begin(); - - // Functions to implement SecurityManager - Authentication authenticate(const String & username, const String & password); - Authentication authenticateRequest(AsyncWebServerRequest * request); - String generateJWT(User * user); - ArRequestFilterFunction filterRequest(AuthenticationPredicate predicate); - ArRequestHandlerFunction wrapRequest(ArRequestHandlerFunction onRequest, AuthenticationPredicate predicate); - ArJsonRequestHandlerFunction wrapCallback(ArJsonRequestHandlerFunction callback, AuthenticationPredicate predicate); - - private: - HttpEndpoint _httpEndpoint; - FSPersistence _fsPersistence; - ArduinoJsonJWT _jwtHandler; - - void configureJWTHandler(); - Authentication authenticateJWT(String & jwt); - boolean validatePayload(JsonObject parsedPayload, User * user); -}; - -#else - class SecuritySettingsService : public SecurityManager { public: SecuritySettingsService(AsyncWebServer * server, FS * fs); diff --git a/platformio.ini b/platformio.ini index c515f2765..a0345adf2 100644 --- a/platformio.ini +++ b/platformio.ini @@ -174,8 +174,9 @@ build_flags = -lpthread -std=gnu++11 -Og -ggdb build_src_flags = - -Wall -Wextra -Werror -Wswitch-enum -Wno-unused-parameter -Wno-inconsistent-missing-override -Wno-unused-lambda-capture -Wno-sign-compare - -Wno-missing-braces + -Wall -Wextra -Werror + -Wno-unused-parameter -Wno-sign-compare + ; -Wswitch-enum -Wno-unused-parameter -Wno-inconsistent-missing-override -Wno-unused-lambda-capture -Wno-missing-braces -I./lib_standalone -I./lib/ArduinoJson/src -I./lib/uuid-common/src From fea63b0d52cdddd08df44b02165bc87f857ef041 Mon Sep 17 00:00:00 2001 From: proddy Date: Sun, 11 Feb 2024 10:32:33 +0100 Subject: [PATCH 16/54] #1614 - WiFi Tx Power --- CHANGELOG_LATEST.md | 4 + .../framework/network/NetworkSettingsForm.tsx | 31 +- interface/src/validators/network.ts | 6 +- lib/ESPAsyncWebServer/library.properties | 10 - lib/framework/NetworkSettingsService.cpp | 290 ++++++++++++++++-- lib/framework/NetworkSettingsService.h | 51 ++- lib/framework/NetworkStatus.h | 6 +- lib_standalone/ESP8266React.h | 31 +- mock-api/handler.ts | 2 +- mock-api/server.js | 2 +- src/emsdevice.cpp | 1 + src/system.cpp | 15 +- src/web/WebStatusService.cpp | 194 ------------ src/web/WebStatusService.h | 7 +- .../emsesp_settings.json | 2 +- 15 files changed, 377 insertions(+), 275 deletions(-) delete mode 100644 lib/ESPAsyncWebServer/library.properties diff --git a/CHANGELOG_LATEST.md b/CHANGELOG_LATEST.md index ff6c5a5d5..6590348ee 100644 --- a/CHANGELOG_LATEST.md +++ b/CHANGELOG_LATEST.md @@ -4,6 +4,8 @@ ## **IMPORTANT! BREAKING CHANGES** +- The Wifi Tx Power setting in Network Settings will be reset to Auto + ## Added - thermostat boost mode and boost time [#1446](https://github.com/emsesp/EMS-ESP32/issues/1446) @@ -28,6 +30,8 @@ - MQTT autodiscovery in Domoticz not working [#1360](https://github.com/emsesp/EMS-ESP32/issues/1528) - dhw comfort for new ems+, [#1495](https://github.com/emsesp/EMS-ESP32/issues/1495) - added writeable icon to Web's Custom Entity page for each entity shown in the table +- Wifi Tx Power not adjusted [#1614](https://github.com/emsesp/EMS-ESP32/issues/1614) +- MQTT discovery of custom entity doesn't consider type of data [#1587](https://github.com/emsesp/EMS-ESP32/issues/1587) ## Changed diff --git a/interface/src/framework/network/NetworkSettingsForm.tsx b/interface/src/framework/network/NetworkSettingsForm.tsx index fe4c574a5..20387fcf6 100644 --- a/interface/src/framework/network/NetworkSettingsForm.tsx +++ b/interface/src/framework/network/NetworkSettingsForm.tsx @@ -15,8 +15,8 @@ import { ListItemSecondaryAction, ListItemText, Typography, - InputAdornment, - TextField + TextField, + MenuItem } from '@mui/material'; // eslint-disable-next-line import/named import { updateState, useRequest } from 'alova'; @@ -43,7 +43,7 @@ import { } from 'components'; import { useI18nContext } from 'i18n/i18n-react'; -import { numberValue, updateValueDirty, useRest } from 'utils'; +import { updateValueDirty, useRest } from 'utils'; import { validate } from 'validators'; import { createNetworkSettingsValidator } from 'validators/network'; @@ -88,7 +88,7 @@ const WiFiSettingsForm: FC = () => { static_ip_config: false, enableIPv6: false, bandwidth20: false, - tx_power: 20, + tx_power: 0, nosleep: false, enableMDNS: true, enableCORS: false, @@ -196,20 +196,27 @@ const WiFiSettingsForm: FC = () => { margin="normal" /> )} - dBm - }} fullWidth variant="outlined" - value={numberValue(data.tx_power)} + value={data.tx_power} onChange={updateFormValue} - type="number" margin="normal" - /> + select + > + Auto + 19.5 dBm + 19 dBm + 18.5 dBm + 17 dBm + 15 dBm + 13 dBm + 11 dBm + 8.5 dBm + 7 dBm + } label={LL.NETWORK_DISABLE_SLEEP()} diff --git a/interface/src/validators/network.ts b/interface/src/validators/network.ts index 66f92a3cd..7582d7af7 100644 --- a/interface/src/validators/network.ts +++ b/interface/src/validators/network.ts @@ -14,9 +14,5 @@ export const createNetworkSettingsValidator = (networkSettings: NetworkSettings) subnet_mask: [{ required: true, message: 'Subnet mask is required' }, IP_ADDRESS_VALIDATOR], dns_ip_1: IP_ADDRESS_VALIDATOR, dns_ip_2: IP_ADDRESS_VALIDATOR - }), - tx_power: [ - { required: true, message: 'Tx Power is required' }, - { type: 'number', min: 0, max: 20, message: 'Tx Power must be between 0 and 20dBm' } - ] + }) }); diff --git a/lib/ESPAsyncWebServer/library.properties b/lib/ESPAsyncWebServer/library.properties deleted file mode 100644 index fda5f3fe8..000000000 --- a/lib/ESPAsyncWebServer/library.properties +++ /dev/null @@ -1,10 +0,0 @@ -name=ESP Async WebServer -version=2.6.1 -author=Me-No-Dev -maintainer=Mathieu Carbou -sentence=Asynchronous HTTP and WebSocket Server Library for ESP32 -paragraph=Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc -category=Other -url=https://github.com/mathieucarbou/ESPAsyncWebServer -architectures=esp32 -license=LGPL-3.0 diff --git a/lib/framework/NetworkSettingsService.cpp b/lib/framework/NetworkSettingsService.cpp index 09369efb4..f726c996b 100644 --- a/lib/framework/NetworkSettingsService.cpp +++ b/lib/framework/NetworkSettingsService.cpp @@ -1,5 +1,7 @@ #include +#include "../../src/emsesp_stub.hpp" + using namespace std::placeholders; // for `_1` etc NetworkSettingsService::NetworkSettingsService(AsyncWebServer * server, FS * fs, SecurityManager * securityManager) @@ -7,7 +9,8 @@ NetworkSettingsService::NetworkSettingsService(AsyncWebServer * server, FS * fs, , _fsPersistence(NetworkSettings::read, NetworkSettings::update, this, fs, NETWORK_SETTINGS_FILE) , _lastConnectionAttempt(0) { addUpdateHandler([&](const String & originId) { reconfigureWiFiConnection(); }, false); - WiFi.onEvent(std::bind(&NetworkSettingsService::WiFiEvent, this, _1)); + // wifi event callbacks + WiFi.onEvent(std::bind(&NetworkSettingsService::WiFiEvent, this, _1, _2)); } void NetworkSettingsService::begin() { @@ -83,31 +86,282 @@ void NetworkSettingsService::manageSTA() { } else { WiFi.begin(_state.ssid.c_str(), _state.password.c_str()); } - // set power after wifi is startet, fixed value for C3_V1 - // if (WiFi.isConnected()) { -#ifdef BOARD_C3_MINI_V1 - // v1 needs this value, see https://github.com/emsesp/EMS-ESP32/pull/620#discussion_r993173979 - WiFi.setTxPower(WIFI_POWER_8_5dBm); // https://www.wemos.cc/en/latest/c3/c3_mini_1_0_0.html#about-wifi -#else - // esp_wifi_set_max_tx_power(_state.tx_power * 4); - // TODO make it dynamic - WiFi.setTxPower((wifi_power_t)(_state.tx_power * 4)); -#endif - // } + // Set thw Wifi Tx power + setWiFiPower(); } else { // not connected but STA-mode active => disconnect reconfigureWiFiConnection(); } } -// handles if wifi stopped -void NetworkSettingsService::WiFiEvent(WiFiEvent_t event) { - if (event == ARDUINO_EVENT_WIFI_STA_STOP) { +// set the Tx WiFi power +// based of RSSI (signal strength) and copied from Tasmota's WiFiSetTXpowerBasedOnRssi() function with is copied from espEasy +void NetworkSettingsService::setWiFiPower() { +// hardcode Tx power for Wemos CS Mini v1 +// v1 needs this value, see https://github.com/emsesp/EMS-ESP32/pull/620#discussion_r993173979 +// https://www.wemos.cc/en/latest/c3/c3_mini_1_0_0.html#about-wifi +#ifdef BOARD_C3_MINI_V1 + WiFi.setTxPower(WIFI_POWER_8_5dBm); + return; +#endif + + auto set_power = _state.tx_power; // get user settings. 0 means auto + + // If Auto set the TxPower based on the RSSI (signal strength) + if (set_power == 0) { + // Range ESP32 : 2dBm - 20dBm + // 802.11b - wifi1 + // 802.11a - wifi2 + // 802.11g - wifi3 + // 802.11n - wifi4 + // 802.11ac - wifi5 + // 802.11ax - wifi6 + int max_tx_pwr = MAX_TX_PWR_DBM_n; // assume wifi4 + int threshold = WIFI_SENSITIVITY_n; + threshold += 30; // Margin in dBm * 10 on top of threshold + + // Assume AP sends with max set by ETSI standard. + // 2.4 GHz: 100 mWatt (20 dBm) + // US and some other countries allow 1000 mW (30 dBm) + int rssi = WiFi.RSSI() * 10; + int newrssi = rssi - 200; // We cannot send with over 20 dBm, thus it makes no sense to force higher TX power all the time. + + int min_tx_pwr = 0; + if (newrssi < threshold) { + min_tx_pwr = threshold - newrssi; + } + if (min_tx_pwr > max_tx_pwr) { + min_tx_pwr = max_tx_pwr; + } + + set_power = min_tx_pwr / 10; // this is the recommended power setting to use + } + + // use the user setting, which is a value from WiFIGeneric.h + // WIFI_POWER_19_5dBm = 78,// 19.5dBm + // WIFI_POWER_19dBm = 76,// 19dBm + // WIFI_POWER_18_5dBm = 74,// 18.5dBm + // WIFI_POWER_17dBm = 68,// 17dBm + // WIFI_POWER_15dBm = 60,// 15dBm + // WIFI_POWER_13dBm = 52,// 13dBm + // WIFI_POWER_11dBm = 44,// 11dBm + // WIFI_POWER_8_5dBm = 34,// 8.5dBm + // WIFI_POWER_7dBm = 28,// 7dBm + // WIFI_POWER_5dBm = 20,// 5dBm + // WIFI_POWER_2dBm = 8,// 2dBm + // WIFI_POWER_MINUS_1dBm = -4// -1dBm + wifi_power_t p = WIFI_POWER_2dBm; + if (set_power > 19) + p = WIFI_POWER_19_5dBm; + else if (set_power > 18) + p = WIFI_POWER_18_5dBm; + else if (set_power >= 17) + p = WIFI_POWER_17dBm; + else if (set_power >= 15) + p = WIFI_POWER_15dBm; + else if (set_power >= 13) + p = WIFI_POWER_13dBm; + else if (set_power >= 11) + p = WIFI_POWER_11dBm; + else if (set_power >= 8) + p = WIFI_POWER_8_5dBm; + else if (set_power >= 7) + p = WIFI_POWER_7dBm; + else if (set_power >= 5) + p = WIFI_POWER_5dBm; + + WiFi.setTxPower(p); +} + +// start the multicast UDP service so EMS-ESP is discoverable via .local +void NetworkSettingsService::mDNS_start() const { +#ifndef EMSESP_STANDALONE + MDNS.end(); + + if (_state.enableMDNS) { + if (!MDNS.begin(emsesp::EMSESP::system_.hostname().c_str())) { + emsesp::EMSESP::logger().warning("Failed to start mDNS responder service"); + return; + } + + std::string address_s = emsesp::EMSESP::system_.hostname() + ".local"; + + MDNS.addService("http", "tcp", 80); // add our web server and rest API + MDNS.addService("telnet", "tcp", 23); // add our telnet console + + MDNS.addServiceTxt("http", "tcp", "version", EMSESP_APP_VERSION); + MDNS.addServiceTxt("http", "tcp", "address", address_s.c_str()); + + emsesp::EMSESP::logger().info("mDNS responder service started"); + } +#else + if (_state.enableMDNS) { + EMSESP::logger().info("mDNS responder service started"); + } +#endif +} + +const char * NetworkSettingsService::disconnectReason(uint8_t code) { +#ifndef EMSESP_STANDALONE + switch (code) { + case WIFI_REASON_UNSPECIFIED: // = 1, + return "unspecified"; + case WIFI_REASON_AUTH_EXPIRE: // = 2, + return "auth expire"; + case WIFI_REASON_AUTH_LEAVE: // = 3, + return "auth leave"; + case WIFI_REASON_ASSOC_EXPIRE: // = 4, + return "assoc expired"; + case WIFI_REASON_ASSOC_TOOMANY: // = 5, + return "assoc too many"; + case WIFI_REASON_NOT_AUTHED: // = 6, + return "not authenticated"; + case WIFI_REASON_NOT_ASSOCED: // = 7, + return "not assoc"; + case WIFI_REASON_ASSOC_LEAVE: // = 8, + return "assoc leave"; + case WIFI_REASON_ASSOC_NOT_AUTHED: // = 9, + return "assoc not authed"; + case WIFI_REASON_DISASSOC_PWRCAP_BAD: // = 10, + return "disassoc powerCAP bad"; + case WIFI_REASON_DISASSOC_SUPCHAN_BAD: // = 11, + return "disassoc supchan bad"; + case WIFI_REASON_IE_INVALID: // = 13, + return "IE invalid"; + case WIFI_REASON_MIC_FAILURE: // = 14, + return "MIC failure"; + case WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT: // = 15, + return "4way handshake timeout"; + case WIFI_REASON_GROUP_KEY_UPDATE_TIMEOUT: // = 16, + return "group key-update timeout"; + case WIFI_REASON_IE_IN_4WAY_DIFFERS: // = 17, + return "IE in 4way differs"; + case WIFI_REASON_GROUP_CIPHER_INVALID: // = 18, + return "group cipher invalid"; + case WIFI_REASON_PAIRWISE_CIPHER_INVALID: // = 19, + return "pairwise cipher invalid"; + case WIFI_REASON_AKMP_INVALID: // = 20, + return "AKMP invalid"; + case WIFI_REASON_UNSUPP_RSN_IE_VERSION: // = 21, + return "unsupported RSN_IE version"; + case WIFI_REASON_INVALID_RSN_IE_CAP: // = 22, + return "invalid RSN_IE_CAP"; + case WIFI_REASON_802_1X_AUTH_FAILED: // = 23, + return "802 X1 auth failed"; + case WIFI_REASON_CIPHER_SUITE_REJECTED: // = 24, + return "cipher suite rejected"; + case WIFI_REASON_BEACON_TIMEOUT: // = 200, + return "beacon timeout"; + case WIFI_REASON_NO_AP_FOUND: // = 201, + return "no AP found"; + case WIFI_REASON_AUTH_FAIL: // = 202, + return "auth fail"; + case WIFI_REASON_ASSOC_FAIL: // = 203, + return "assoc fail"; + case WIFI_REASON_HANDSHAKE_TIMEOUT: // = 204, + return "handshake timeout"; + case WIFI_REASON_CONNECTION_FAIL: // 205, + return "connection fail"; + case WIFI_REASON_AP_TSF_RESET: // 206, + return "AP tsf reset"; + case WIFI_REASON_ROAMING: // 207, + return "roaming"; + case WIFI_REASON_ASSOC_COMEBACK_TIME_TOO_LONG: // 208, + return "assoc comeback time too long"; + case WIFI_REASON_SA_QUERY_TIMEOUT: // 209, + return "sa query timeout"; + default: + return "unknown"; + } +#endif + + return ""; +} + +// handles both WiFI and Ethernet +void NetworkSettingsService::WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info) { +#ifndef EMSESP_STANDALONE + + switch (event) { + case ARDUINO_EVENT_WIFI_STA_STOP: if (_stopping) { _lastConnectionAttempt = 0; _stopping = false; } + break; + + case ARDUINO_EVENT_WIFI_STA_DISCONNECTED: + emsesp::EMSESP::logger().warning("WiFi disconnected. Reason: %s (%d)", + disconnectReason(info.wifi_sta_disconnected.reason), + info.wifi_sta_disconnected.reason); // IDF 4.0 + emsesp::EMSESP::system_.has_ipv6(false); + break; + + case ARDUINO_EVENT_WIFI_STA_GOT_IP: + char result[10]; + emsesp::EMSESP::logger().info("WiFi connected with IP=%s, hostname=%s, TxPower=%s", + WiFi.localIP().toString().c_str(), + WiFi.getHostname(), + emsesp::Helpers::render_value(result, (double)(WiFi.getTxPower() / 4), 1)); + + mDNS_start(); + break; + + case ARDUINO_EVENT_ETH_START: + ETH.setHostname(emsesp::EMSESP::system_.hostname().c_str()); + + // configure for static IP + if (_state.staticIPConfig) { + ETH.config(_state.localIP, _state.gatewayIP, _state.subnetMask, _state.dnsIP1, _state.dnsIP2); + } + break; + + case ARDUINO_EVENT_ETH_GOT_IP: + // prevent double calls + if (!emsesp::EMSESP::system_.ethernet_connected()) { + emsesp::EMSESP::logger().info("Ethernet connected with IP=%s, speed %d Mbps", ETH.localIP().toString().c_str(), ETH.linkSpeed()); + emsesp::EMSESP::system_.ethernet_connected(true); + mDNS_start(); + } + break; + + case ARDUINO_EVENT_ETH_DISCONNECTED: + emsesp::EMSESP::logger().warning("Ethernet disconnected"); + emsesp::EMSESP::system_.ethernet_connected(false); + emsesp::EMSESP::system_.has_ipv6(false); + break; + + case ARDUINO_EVENT_ETH_STOP: + emsesp::EMSESP::logger().info("Ethernet stopped"); + emsesp::EMSESP::system_.ethernet_connected(false); + emsesp::EMSESP::system_.has_ipv6(false); + break; + + case ARDUINO_EVENT_WIFI_STA_CONNECTED: + if (_state.enableIPv6) { + WiFi.enableIpV6(); + } + break; + + case ARDUINO_EVENT_ETH_CONNECTED: + if (_state.enableIPv6) { + ETH.enableIpV6(); + } + break; + + // IPv6 specific + case ARDUINO_EVENT_WIFI_STA_GOT_IP6: + case ARDUINO_EVENT_ETH_GOT_IP6: + if (emsesp::EMSESP::system_.ethernet_connected()) { + emsesp::EMSESP::logger().info("Ethernet connected with IPv6=%s, speed %d Mbps", ETH.localIPv6().toString().c_str(), ETH.linkSpeed()); + } else { + emsesp::EMSESP::logger().info("WiFi connected with IPv6=%s, hostname=%s", WiFi.localIPv6().toString().c_str(), WiFi.getHostname()); + } + mDNS_start(); + emsesp::EMSESP::system_.has_ipv6(true); + break; + + default: + break; } - // if (!_stopping && (event == ARDUINO_EVENT_WIFI_STA_LOST_IP || event == ARDUINO_EVENT_WIFI_STA_DISCONNECTED)) { - // reconfigureWiFiConnection(); - // } +#endif } diff --git a/lib/framework/NetworkSettingsService.h b/lib/framework/NetworkSettingsService.h index 96a9b116c..70e7a9430 100644 --- a/lib/framework/NetworkSettingsService.h +++ b/lib/framework/NetworkSettingsService.h @@ -9,8 +9,13 @@ #ifndef EMSESP_STANDALONE #include #include +#include +#include +#include #endif +#include + #define NETWORK_SETTINGS_FILE "/config/networkSettings.json" #define NETWORK_SETTINGS_SERVICE_PATH "/rest/networkSettings" #define WIFI_RECONNECTION_DELAY 1000 * 3 @@ -27,6 +32,37 @@ #define FACTORY_WIFI_HOSTNAME "" #endif + +#if CONFIG_IDF_TARGET_ESP32S2 +#define MAX_TX_PWR_DBM_11b 195 +#define MAX_TX_PWR_DBM_54g 150 +#define MAX_TX_PWR_DBM_n 130 +#define WIFI_SENSITIVITY_11b -880 +#define WIFI_SENSITIVITY_54g -750 +#define WIFI_SENSITIVITY_n -720 +#elif CONFIG_IDF_TARGET_ESP32S3 +#define MAX_TX_PWR_DBM_11b 210 +#define MAX_TX_PWR_DBM_54g 190 +#define MAX_TX_PWR_DBM_n 185 +#define WIFI_SENSITIVITY_11b -880 +#define WIFI_SENSITIVITY_54g -760 +#define WIFI_SENSITIVITY_n -720 +#elif CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 +#define MAX_TX_PWR_DBM_11b 210 +#define MAX_TX_PWR_DBM_54g 190 +#define MAX_TX_PWR_DBM_n 185 +#define WIFI_SENSITIVITY_11b -880 +#define WIFI_SENSITIVITY_54g -760 +#define WIFI_SENSITIVITY_n -730 +#else +#define MAX_TX_PWR_DBM_11b 195 +#define MAX_TX_PWR_DBM_54g 160 +#define MAX_TX_PWR_DBM_n 140 +#define WIFI_SENSITIVITY_11b -880 +#define WIFI_SENSITIVITY_54g -750 +#define WIFI_SENSITIVITY_n -700 +#endif + class NetworkSettings { public: // core wifi configuration @@ -84,7 +120,7 @@ class NetworkSettings { settings.staticIPConfig = root["static_ip_config"] | false; settings.enableIPv6 = root["enableIPv6"] | false; settings.bandwidth20 = root["bandwidth20"] | false; - settings.tx_power = root["tx_power"] | 20; + settings.tx_power = root["tx_power"] | 0; settings.nosleep = root["nosleep"] | false; settings.enableMDNS = root["enableMDNS"] | true; settings.enableCORS = root["enableCORS"] | false; @@ -127,13 +163,16 @@ class NetworkSettingsService : public StatefulService { private: HttpEndpoint _httpEndpoint; FSPersistence _fsPersistence; - unsigned long _lastConnectionAttempt; - bool _stopping; - void WiFiEvent(WiFiEvent_t event); + unsigned long _lastConnectionAttempt; + bool _stopping; - void reconfigureWiFiConnection(); - void manageSTA(); + void WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info); + void mDNS_start() const; + const char * disconnectReason(uint8_t code); + void reconfigureWiFiConnection(); + void manageSTA(); + void setWiFiPower(); }; #endif diff --git a/lib/framework/NetworkStatus.h b/lib/framework/NetworkStatus.h index 1e73439e9..f31630e25 100644 --- a/lib/framework/NetworkStatus.h +++ b/lib/framework/NetworkStatus.h @@ -1,15 +1,11 @@ #ifndef NetworkStatus_h #define NetworkStatus_h -#include -#include - -#include - #include #include #include #include + #include #define MAX_NETWORK_STATUS_SIZE 1024 diff --git a/lib_standalone/ESP8266React.h b/lib_standalone/ESP8266React.h index 68174ea61..ea1b198e0 100644 --- a/lib_standalone/ESP8266React.h +++ b/lib_standalone/ESP8266React.h @@ -59,21 +59,22 @@ class DummySettings { uint16_t publish_time_sensor = 10; uint16_t publish_time_heartbeat = 60; - String hostname = "ems-esp"; - String jwtSecret = "ems-esp"; - String ssid = "ems-esp"; - String password = "ems-esp"; - String bssid = ""; - String localIP = ""; - String gatewayIP = ""; - String subnetMask = ""; - bool staticIPConfig = false; - String dnsIP1 = ""; - String dnsIP2 = ""; - bool enableIPv6 = false; - bool enableMDNS = true; - bool enableCORS = false; - String CORSOrigin = "*"; + String hostname = "ems-esp"; + String jwtSecret = "ems-esp"; + String ssid = "ems-esp"; + String password = "ems-esp"; + String bssid = ""; + String localIP = ""; + String gatewayIP = ""; + String subnetMask = ""; + bool staticIPConfig = false; + String dnsIP1 = ""; + String dnsIP2 = ""; + bool enableIPv6 = false; + bool enableMDNS = true; + bool enableCORS = false; + String CORSOrigin = "*"; + uint8_t tx_power = 0; static void read(DummySettings & settings, JsonObject root){}; static void read(DummySettings & settings){}; diff --git a/mock-api/handler.ts b/mock-api/handler.ts index 692c55b5c..b3522e695 100644 --- a/mock-api/handler.ts +++ b/mock-api/handler.ts @@ -225,7 +225,7 @@ let network_settings = { password: 'myPassword', hostname: 'ems-esp', nosleep: true, - tx_power: 20, + tx_power: 0, bandwidth20: false, static_ip_config: false, enableMDNS: true, diff --git a/mock-api/server.js b/mock-api/server.js index ba672486f..72e93d791 100644 --- a/mock-api/server.js +++ b/mock-api/server.js @@ -155,7 +155,7 @@ network_settings = { password: 'myPassword', hostname: 'ems-esp', nosleep: true, - tx_power: 20, + tx_power: 0, bandwidth20: false, static_ip_config: false, enableMDNS: true, diff --git a/src/emsdevice.cpp b/src/emsdevice.cpp index 1ad7a1832..9426f44f6 100644 --- a/src/emsdevice.cpp +++ b/src/emsdevice.cpp @@ -1748,6 +1748,7 @@ void EMSdevice::mqtt_ha_entity_config_create() { } } + // TODO remove CMD - see https://github.com/emsesp/EMS-ESP32/issues/1605 if (!dv.has_state(DeviceValueState::DV_HA_CONFIG_CREATED) && (dv.type != DeviceValueType::CMD) && dv.has_state(DeviceValueState::DV_ACTIVE) && !dv.has_state(DeviceValueState::DV_API_MQTT_EXCLUDE)) { // create_device_config is only done once for the EMS device. It can added to any entity, so we take the first diff --git a/src/system.cpp b/src/system.cpp index a268aec16..cf5123b78 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -1131,7 +1131,7 @@ bool System::check_upgrade(bool factory_settings) { // if we're coming from 3.4.4 or 3.5.0b14 which had no version stored then we need to apply new settings if (missing_version) { - LOG_DEBUG("Setting MQTT Entity ID format to v3.4 format"); + LOG_INFO("Setting MQTT Entity ID format to v3.4 format"); EMSESP::esp8266React.getMqttSettingsService()->update( [&](MqttSettings & mqttSettings) { mqttSettings.entity_format = 0; // use old Entity ID format from v3.4 @@ -1139,6 +1139,19 @@ bool System::check_upgrade(bool factory_settings) { }, "local"); } + + // Network Settings Wifi tx_power is now using the value * 4. + EMSESP::esp8266React.getNetworkSettingsService()->update( + [&](NetworkSettings & networkSettings) { + if (networkSettings.tx_power == 20) { + networkSettings.tx_power = 0; // use Auto + LOG_INFO("Setting WiFi TX Power to Auto"); + return StateUpdateResult::CHANGED; + } + return StateUpdateResult::UNCHANGED; + }, + "local"); + } else if (this_version < settings_version) { // need downgrade LOG_NOTICE("Downgrading to version %d.%d.%d-%s", this_version.major(), this_version.minor(), this_version.patch(), this_version.prerelease().c_str()); diff --git a/src/web/WebStatusService.cpp b/src/web/WebStatusService.cpp index 08cd42b60..773d73927 100644 --- a/src/web/WebStatusService.cpp +++ b/src/web/WebStatusService.cpp @@ -23,95 +23,9 @@ using namespace std::placeholders; // for `_1` etc namespace emsesp { WebStatusService::WebStatusService(AsyncWebServer * server, SecurityManager * securityManager) { - // rest endpoint for web page server->on(EMSESP_STATUS_SERVICE_PATH, HTTP_GET, securityManager->wrapRequest(std::bind(&WebStatusService::webStatusService, this, _1), AuthenticationPredicates::IS_AUTHENTICATED)); - WiFi.onEvent(std::bind(&WebStatusService::WiFiEvent, this, _1, _2)); -} - -// handles both WiFI and Ethernet -void WebStatusService::WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info) { -#ifndef EMSESP_STANDALONE - - switch (event) { - case ARDUINO_EVENT_WIFI_STA_DISCONNECTED: - EMSESP::logger().warning("WiFi disconnected. Reason: %s (%d)", - disconnectReason(info.wifi_sta_disconnected.reason), - info.wifi_sta_disconnected.reason); // IDF 4.0 - EMSESP::system_.has_ipv6(false); - break; - - case ARDUINO_EVENT_WIFI_STA_GOT_IP: - EMSESP::logger().info("WiFi connected with IP=%s, hostname=%s", WiFi.localIP().toString().c_str(), WiFi.getHostname()); - mDNS_start(); - break; - - case ARDUINO_EVENT_ETH_START: - // EMSESP::logger().info("Ethernet initialized"); - ETH.setHostname(EMSESP::system_.hostname().c_str()); - - // configure for static IP - EMSESP::esp8266React.getNetworkSettingsService()->read([&](NetworkSettings & networkSettings) { - if (networkSettings.staticIPConfig) { - ETH.config(networkSettings.localIP, networkSettings.gatewayIP, networkSettings.subnetMask, networkSettings.dnsIP1, networkSettings.dnsIP2); - } - }); - - break; - - case ARDUINO_EVENT_ETH_GOT_IP: - // prevent double calls - if (!EMSESP::system_.ethernet_connected()) { - EMSESP::logger().info("Ethernet connected with IP=%s, speed %d Mbps", ETH.localIP().toString().c_str(), ETH.linkSpeed()); - EMSESP::system_.ethernet_connected(true); - mDNS_start(); - } - break; - - case ARDUINO_EVENT_ETH_DISCONNECTED: - EMSESP::logger().warning("Ethernet disconnected"); - EMSESP::system_.ethernet_connected(false); - EMSESP::system_.has_ipv6(false); - break; - - case ARDUINO_EVENT_ETH_STOP: - EMSESP::logger().info("Ethernet stopped"); - EMSESP::system_.ethernet_connected(false); - EMSESP::system_.has_ipv6(false); - break; - - case ARDUINO_EVENT_WIFI_STA_CONNECTED: - EMSESP::esp8266React.getNetworkSettingsService()->read([&](NetworkSettings & networkSettings) { - if (networkSettings.enableIPv6) { - WiFi.enableIpV6(); - } - }); - break; - - case ARDUINO_EVENT_ETH_CONNECTED: - EMSESP::esp8266React.getNetworkSettingsService()->read([&](NetworkSettings & networkSettings) { - if (networkSettings.enableIPv6) { - ETH.enableIpV6(); - } - }); - break; - - case ARDUINO_EVENT_WIFI_STA_GOT_IP6: - case ARDUINO_EVENT_ETH_GOT_IP6: - if (EMSESP::system_.ethernet_connected()) { - EMSESP::logger().info("Ethernet connected with IPv6=%s, speed %d Mbps", ETH.localIPv6().toString().c_str(), ETH.linkSpeed()); - } else { - EMSESP::logger().info("WiFi connected with IPv6=%s, hostname=%s", WiFi.localIPv6().toString().c_str(), WiFi.getHostname()); - } - mDNS_start(); - EMSESP::system_.has_ipv6(true); - break; - - default: - break; - } -#endif } void WebStatusService::webStatusService(AsyncWebServerRequest * request) { @@ -193,112 +107,4 @@ void WebStatusService::webStatusService(AsyncWebServerRequest * request) { request->send(response); } -// start the multicast UDP service so EMS-ESP is discoverable via .local -void WebStatusService::mDNS_start() const { -#ifndef EMSESP_STANDALONE - MDNS.end(); - EMSESP::esp8266React.getNetworkSettingsService()->read([&](NetworkSettings & networkSettings) { - if (networkSettings.enableMDNS) { - if (!MDNS.begin(EMSESP::system_.hostname().c_str())) { - EMSESP::logger().warning("Failed to start mDNS responder service"); - return; - } - - std::string address_s = EMSESP::system_.hostname() + ".local"; - - MDNS.addService("http", "tcp", 80); // add our web server and rest API - MDNS.addService("telnet", "tcp", 23); // add our telnet console - - MDNS.addServiceTxt("http", "tcp", "version", EMSESP_APP_VERSION); - MDNS.addServiceTxt("http", "tcp", "address", address_s.c_str()); - - EMSESP::logger().info("mDNS responder service started"); - } - }); -#else - EMSESP::esp8266React.getNetworkSettingsService()->read([&](NetworkSettings & networkSettings) { - if (networkSettings.enableMDNS) { - EMSESP::logger().info("mDNS responder service started"); - } - }); -#endif -} - -const char * WebStatusService::disconnectReason(uint8_t code) { -#ifndef EMSESP_STANDALONE - switch (code) { - case WIFI_REASON_UNSPECIFIED: // = 1, - return "unspecified"; - case WIFI_REASON_AUTH_EXPIRE: // = 2, - return "auth expire"; - case WIFI_REASON_AUTH_LEAVE: // = 3, - return "auth leave"; - case WIFI_REASON_ASSOC_EXPIRE: // = 4, - return "assoc expired"; - case WIFI_REASON_ASSOC_TOOMANY: // = 5, - return "assoc too many"; - case WIFI_REASON_NOT_AUTHED: // = 6, - return "not authenticated"; - case WIFI_REASON_NOT_ASSOCED: // = 7, - return "not assoc"; - case WIFI_REASON_ASSOC_LEAVE: // = 8, - return "assoc leave"; - case WIFI_REASON_ASSOC_NOT_AUTHED: // = 9, - return "assoc not authed"; - case WIFI_REASON_DISASSOC_PWRCAP_BAD: // = 10, - return "disassoc powerCAP bad"; - case WIFI_REASON_DISASSOC_SUPCHAN_BAD: // = 11, - return "disassoc supchan bad"; - case WIFI_REASON_IE_INVALID: // = 13, - return "IE invalid"; - case WIFI_REASON_MIC_FAILURE: // = 14, - return "MIC failure"; - case WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT: // = 15, - return "4way handshake timeout"; - case WIFI_REASON_GROUP_KEY_UPDATE_TIMEOUT: // = 16, - return "group key-update timeout"; - case WIFI_REASON_IE_IN_4WAY_DIFFERS: // = 17, - return "IE in 4way differs"; - case WIFI_REASON_GROUP_CIPHER_INVALID: // = 18, - return "group cipher invalid"; - case WIFI_REASON_PAIRWISE_CIPHER_INVALID: // = 19, - return "pairwise cipher invalid"; - case WIFI_REASON_AKMP_INVALID: // = 20, - return "AKMP invalid"; - case WIFI_REASON_UNSUPP_RSN_IE_VERSION: // = 21, - return "unsupported RSN_IE version"; - case WIFI_REASON_INVALID_RSN_IE_CAP: // = 22, - return "invalid RSN_IE_CAP"; - case WIFI_REASON_802_1X_AUTH_FAILED: // = 23, - return "802 X1 auth failed"; - case WIFI_REASON_CIPHER_SUITE_REJECTED: // = 24, - return "cipher suite rejected"; - case WIFI_REASON_BEACON_TIMEOUT: // = 200, - return "beacon timeout"; - case WIFI_REASON_NO_AP_FOUND: // = 201, - return "no AP found"; - case WIFI_REASON_AUTH_FAIL: // = 202, - return "auth fail"; - case WIFI_REASON_ASSOC_FAIL: // = 203, - return "assoc fail"; - case WIFI_REASON_HANDSHAKE_TIMEOUT: // = 204, - return "handshake timeout"; - case WIFI_REASON_CONNECTION_FAIL: // 205, - return "connection fail"; - case WIFI_REASON_AP_TSF_RESET: // 206, - return "AP tsf reset"; - case WIFI_REASON_ROAMING: // 207, - return "roaming"; - case WIFI_REASON_ASSOC_COMEBACK_TIME_TOO_LONG: // 208, - return "assoc comeback time too long"; - case WIFI_REASON_SA_QUERY_TIMEOUT: // 209, - return "sa query timeout"; - default: - return "unknown"; - } -#endif - - return ""; -} - } // namespace emsesp \ No newline at end of file diff --git a/src/web/WebStatusService.h b/src/web/WebStatusService.h index 48551aac0..97109b82b 100644 --- a/src/web/WebStatusService.h +++ b/src/web/WebStatusService.h @@ -19,8 +19,6 @@ #ifndef WebStatusService_h #define WebStatusService_h -#include - #define EMSESP_STATUS_SERVICE_PATH "/rest/status" namespace emsesp { @@ -30,10 +28,7 @@ class WebStatusService { WebStatusService(AsyncWebServer * server, SecurityManager * securityManager); private: - void webStatusService(AsyncWebServerRequest * request); - void WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info); - void mDNS_start() const; - const char * disconnectReason(uint8_t code); + void webStatusService(AsyncWebServerRequest * request); }; } // namespace emsesp diff --git a/test/standalone_file_export/emsesp_settings.json b/test/standalone_file_export/emsesp_settings.json index 43eaecc5d..1ea7eef3c 100644 --- a/test/standalone_file_export/emsesp_settings.json +++ b/test/standalone_file_export/emsesp_settings.json @@ -11,7 +11,7 @@ "static_ip_config": false, "enableIPv6": false, "bandwidth20": false, - "tx_power": 20, + "tx_power": 0, "nosleep": false, "enableMDNS": true, "enableCORS": false, From 3d715c45e0be7625ced84f59e9ceff55f4c6f766 Mon Sep 17 00:00:00 2001 From: Proddy Date: Sun, 11 Feb 2024 14:21:51 +0100 Subject: [PATCH 17/54] Wifi Tx Power not adjusted #1614 --- lib/framework/APSettingsService.cpp | 41 ++++++++++ lib/framework/APSettingsService.h | 41 +--------- lib/framework/HttpEndpoint.h | 10 ++- lib/framework/NTPSettingsService.cpp | 15 ++++ lib/framework/NTPSettingsService.h | 16 +--- lib/framework/NetworkSettingsService.cpp | 93 ++++++++++++++++++++-- lib/framework/NetworkSettingsService.h | 96 ++++------------------- lib/framework/OTASettingsService.cpp | 13 +++ lib/framework/OTASettingsService.h | 14 +--- lib/framework/SecuritySettingsService.cpp | 31 ++++++++ lib/framework/SecuritySettingsService.h | 33 +------- lib/framework/SystemStatus.cpp | 10 ++- src/emsesp_stub.hpp | 1 + src/locale_translations.h | 2 +- src/system.cpp | 21 ++--- src/test/test.cpp | 10 ++- 16 files changed, 247 insertions(+), 200 deletions(-) diff --git a/lib/framework/APSettingsService.cpp b/lib/framework/APSettingsService.cpp index acd602fc2..658570880 100644 --- a/lib/framework/APSettingsService.cpp +++ b/lib/framework/APSettingsService.cpp @@ -113,3 +113,44 @@ APNetworkStatus APSettingsService::getAPNetworkStatus() { } return apActive ? APNetworkStatus::ACTIVE : APNetworkStatus::INACTIVE; } + + +void APSettings::read(APSettings & settings, JsonObject root) { + root["provision_mode"] = settings.provisionMode; + root["ssid"] = settings.ssid; + root["password"] = settings.password; + root["channel"] = settings.channel; + root["ssid_hidden"] = settings.ssidHidden; + root["max_clients"] = settings.maxClients; + root["local_ip"] = settings.localIP.toString(); + root["gateway_ip"] = settings.gatewayIP.toString(); + root["subnet_mask"] = settings.subnetMask.toString(); +} + +StateUpdateResult APSettings::update(JsonObject root, APSettings & settings) { + APSettings newSettings = {}; + newSettings.provisionMode = root["provision_mode"] | FACTORY_AP_PROVISION_MODE; + switch (settings.provisionMode) { + case AP_MODE_ALWAYS: + case AP_MODE_DISCONNECTED: + case AP_MODE_NEVER: + break; + default: + newSettings.provisionMode = AP_MODE_ALWAYS; + } + newSettings.ssid = root["ssid"] | FACTORY_AP_SSID; + newSettings.password = root["password"] | FACTORY_AP_PASSWORD; + newSettings.channel = root["channel"] | FACTORY_AP_CHANNEL; + newSettings.ssidHidden = root["ssid_hidden"] | FACTORY_AP_SSID_HIDDEN; + newSettings.maxClients = root["max_clients"] | FACTORY_AP_MAX_CLIENTS; + + JsonUtils::readIP(root, "local_ip", newSettings.localIP, FACTORY_AP_LOCAL_IP); + JsonUtils::readIP(root, "gateway_ip", newSettings.gatewayIP, FACTORY_AP_GATEWAY_IP); + JsonUtils::readIP(root, "subnet_mask", newSettings.subnetMask, FACTORY_AP_SUBNET_MASK); + + if (newSettings == settings) { + return StateUpdateResult::UNCHANGED; + } + settings = newSettings; + return StateUpdateResult::CHANGED; +} diff --git a/lib/framework/APSettingsService.h b/lib/framework/APSettingsService.h index c2eacd084..8857c4f99 100644 --- a/lib/framework/APSettingsService.h +++ b/lib/framework/APSettingsService.h @@ -75,45 +75,8 @@ class APSettings { && subnetMask == settings.subnetMask; } - static void read(APSettings & settings, JsonObject root) { - root["provision_mode"] = settings.provisionMode; - root["ssid"] = settings.ssid; - root["password"] = settings.password; - root["channel"] = settings.channel; - root["ssid_hidden"] = settings.ssidHidden; - root["max_clients"] = settings.maxClients; - root["local_ip"] = settings.localIP.toString(); - root["gateway_ip"] = settings.gatewayIP.toString(); - root["subnet_mask"] = settings.subnetMask.toString(); - } - - static StateUpdateResult update(JsonObject root, APSettings & settings) { - APSettings newSettings = {}; - newSettings.provisionMode = root["provision_mode"] | FACTORY_AP_PROVISION_MODE; - switch (settings.provisionMode) { - case AP_MODE_ALWAYS: - case AP_MODE_DISCONNECTED: - case AP_MODE_NEVER: - break; - default: - newSettings.provisionMode = AP_MODE_ALWAYS; - } - newSettings.ssid = root["ssid"] | FACTORY_AP_SSID; - newSettings.password = root["password"] | FACTORY_AP_PASSWORD; - newSettings.channel = root["channel"] | FACTORY_AP_CHANNEL; - newSettings.ssidHidden = root["ssid_hidden"] | FACTORY_AP_SSID_HIDDEN; - newSettings.maxClients = root["max_clients"] | FACTORY_AP_MAX_CLIENTS; - - JsonUtils::readIP(root, "local_ip", newSettings.localIP, FACTORY_AP_LOCAL_IP); - JsonUtils::readIP(root, "gateway_ip", newSettings.gatewayIP, FACTORY_AP_GATEWAY_IP); - JsonUtils::readIP(root, "subnet_mask", newSettings.subnetMask, FACTORY_AP_SUBNET_MASK); - - if (newSettings == settings) { - return StateUpdateResult::UNCHANGED; - } - settings = newSettings; - return StateUpdateResult::CHANGED; - } + static void read(APSettings & settings, JsonObject root); + static StateUpdateResult update(JsonObject root, APSettings & settings); }; class APSettingsService : public StatefulService { diff --git a/lib/framework/HttpEndpoint.h b/lib/framework/HttpEndpoint.h index ba57c7caf..b3f43b8ea 100644 --- a/lib/framework/HttpEndpoint.h +++ b/lib/framework/HttpEndpoint.h @@ -56,11 +56,13 @@ class HttpEndpoint { if (outcome == StateUpdateResult::ERROR) { request->send(400); // error return; - } else if (outcome == StateUpdateResult::CHANGED_RESTART) { - request->send(205); // reboot required - return; - } else if (outcome == StateUpdateResult::CHANGED) { + } else if (outcome == StateUpdateResult::CHANGED || outcome == StateUpdateResult::CHANGED_RESTART) { + // persist changes request->onDisconnect([this]() { _statefulService->callUpdateHandlers(HTTP_ENDPOINT_ORIGIN_ID); }); + if (outcome == StateUpdateResult::CHANGED_RESTART) { + request->send(205); // reboot required + return; + } } } diff --git a/lib/framework/NTPSettingsService.cpp b/lib/framework/NTPSettingsService.cpp index e1a4aa1c5..d4095d913 100644 --- a/lib/framework/NTPSettingsService.cpp +++ b/lib/framework/NTPSettingsService.cpp @@ -85,3 +85,18 @@ void NTPSettingsService::ntp_received(struct timeval * tv) { // emsesp::EMSESP::logger().info("NTP sync to %d sec", tv->tv_sec); emsesp::EMSESP::system_.ntp_connected(true); } + +void NTPSettings::read(NTPSettings & settings, JsonObject root) { + root["enabled"] = settings.enabled; + root["server"] = settings.server; + root["tz_label"] = settings.tzLabel; + root["tz_format"] = settings.tzFormat; +} + +StateUpdateResult NTPSettings::update(JsonObject root, NTPSettings & settings) { + settings.enabled = root["enabled"] | FACTORY_NTP_ENABLED; + settings.server = root["server"] | FACTORY_NTP_SERVER; + settings.tzLabel = root["tz_label"] | FACTORY_NTP_TIME_ZONE_LABEL; + settings.tzFormat = root["tz_format"] | FACTORY_NTP_TIME_ZONE_FORMAT; + return StateUpdateResult::CHANGED; +} diff --git a/lib/framework/NTPSettingsService.h b/lib/framework/NTPSettingsService.h index e18800fa1..976d29d70 100644 --- a/lib/framework/NTPSettingsService.h +++ b/lib/framework/NTPSettingsService.h @@ -36,20 +36,8 @@ class NTPSettings { String tzFormat; String server; - static void read(NTPSettings & settings, JsonObject root) { - root["enabled"] = settings.enabled; - root["server"] = settings.server; - root["tz_label"] = settings.tzLabel; - root["tz_format"] = settings.tzFormat; - } - - static StateUpdateResult update(JsonObject root, NTPSettings & settings) { - settings.enabled = root["enabled"] | FACTORY_NTP_ENABLED; - settings.server = root["server"] | FACTORY_NTP_SERVER; - settings.tzLabel = root["tz_label"] | FACTORY_NTP_TIME_ZONE_LABEL; - settings.tzFormat = root["tz_format"] | FACTORY_NTP_TIME_ZONE_FORMAT; - return StateUpdateResult::CHANGED; - } + static void read(NTPSettings & settings, JsonObject root); + static StateUpdateResult update(JsonObject root, NTPSettings & settings); }; class NTPSettingsService : public StatefulService { diff --git a/lib/framework/NetworkSettingsService.cpp b/lib/framework/NetworkSettingsService.cpp index f726c996b..177899c81 100644 --- a/lib/framework/NetworkSettingsService.cpp +++ b/lib/framework/NetworkSettingsService.cpp @@ -86,15 +86,20 @@ void NetworkSettingsService::manageSTA() { } else { WiFi.begin(_state.ssid.c_str(), _state.password.c_str()); } - // Set thw Wifi Tx power - setWiFiPower(); + +#ifdef BOARD_C3_MINI_V1 + // hardcode Tx power for Wemos CS Mini v1 + // v1 needs this value, see https://github.com/emsesp/EMS-ESP32/pull/620#discussion_r993173979 + // https://www.wemos.cc/en/latest/c3/c3_mini_1_0_0.html#about-wifi + WiFi.setTxPower(WIFI_POWER_8_5dBm); + return; +#endif } else { // not connected but STA-mode active => disconnect reconfigureWiFiConnection(); } } // set the Tx WiFi power -// based of RSSI (signal strength) and copied from Tasmota's WiFiSetTXpowerBasedOnRssi() function with is copied from espEasy void NetworkSettingsService::setWiFiPower() { // hardcode Tx power for Wemos CS Mini v1 // v1 needs this value, see https://github.com/emsesp/EMS-ESP32/pull/620#discussion_r993173979 @@ -106,7 +111,8 @@ void NetworkSettingsService::setWiFiPower() { auto set_power = _state.tx_power; // get user settings. 0 means auto - // If Auto set the TxPower based on the RSSI (signal strength) + // If Auto set the TxPower based on the RSSI (signal strength), picking the lowest value + // based of RSSI (signal strength) and copied from Tasmota's WiFiSetTXpowerBasedOnRssi() which is copied ESPEasy's ESPEasyWifi.SetWiFiTXpower() function if (set_power == 0) { // Range ESP32 : 2dBm - 20dBm // 802.11b - wifi1 @@ -134,6 +140,9 @@ void NetworkSettingsService::setWiFiPower() { } set_power = min_tx_pwr / 10; // this is the recommended power setting to use +#ifdef EMSESP_DEBUG + emsesp::EMSESP::logger().debug("Recommended set WiFi Tx Power (set_power %d, rssi %d, threshold %d", set_power, rssi, threshold); +#endif } // use the user setting, which is a value from WiFIGeneric.h @@ -298,7 +307,7 @@ void NetworkSettingsService::WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info) case ARDUINO_EVENT_WIFI_STA_GOT_IP: char result[10]; - emsesp::EMSESP::logger().info("WiFi connected with IP=%s, hostname=%s, TxPower=%s", + emsesp::EMSESP::logger().info("WiFi connected with IP=%s, hostname=%s, TxPower=%s dBm", WiFi.localIP().toString().c_str(), WiFi.getHostname(), emsesp::Helpers::render_value(result, (double)(WiFi.getTxPower() / 4), 1)); @@ -337,6 +346,8 @@ void NetworkSettingsService::WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info) break; case ARDUINO_EVENT_WIFI_STA_CONNECTED: + // Set the TxPower after the connection is established + setWiFiPower(); if (_state.enableIPv6) { WiFi.enableIpV6(); } @@ -365,3 +376,75 @@ void NetworkSettingsService::WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info) } #endif } + +void NetworkSettings::read(NetworkSettings & settings, JsonObject root) { + // connection settings + root["ssid"] = settings.ssid; + root["bssid"] = settings.bssid; + root["password"] = settings.password; + root["hostname"] = settings.hostname; + root["static_ip_config"] = settings.staticIPConfig; + root["enableIPv6"] = settings.enableIPv6; + root["bandwidth20"] = settings.bandwidth20; + root["tx_power"] = settings.tx_power; + root["nosleep"] = settings.nosleep; + root["enableMDNS"] = settings.enableMDNS; + root["enableCORS"] = settings.enableCORS; + root["CORSOrigin"] = settings.CORSOrigin; + + // extended settings + JsonUtils::writeIP(root, "local_ip", settings.localIP); + JsonUtils::writeIP(root, "gateway_ip", settings.gatewayIP); + JsonUtils::writeIP(root, "subnet_mask", settings.subnetMask); + JsonUtils::writeIP(root, "dns_ip_1", settings.dnsIP1); + JsonUtils::writeIP(root, "dns_ip_2", settings.dnsIP2); +} + +StateUpdateResult NetworkSettings::update(JsonObject root, NetworkSettings & settings) { + // keep copy of original settings + auto enableCORS = settings.enableCORS; + auto CORSOrigin = settings.CORSOrigin; + auto ssid = settings.ssid; + auto tx_power = settings.tx_power; + + settings.ssid = root["ssid"] | FACTORY_WIFI_SSID; + settings.bssid = root["bssid"] | ""; + settings.password = root["password"] | FACTORY_WIFI_PASSWORD; + settings.hostname = root["hostname"] | FACTORY_WIFI_HOSTNAME; + settings.staticIPConfig = root["static_ip_config"] | false; + settings.enableIPv6 = root["enableIPv6"] | false; + settings.bandwidth20 = root["bandwidth20"] | false; + settings.tx_power = root["tx_power"] | 0; + settings.nosleep = root["nosleep"] | false; + settings.enableMDNS = root["enableMDNS"] | true; + settings.enableCORS = root["enableCORS"] | false; + settings.CORSOrigin = root["CORSOrigin"] | "*"; + + // extended settings + JsonUtils::readIP(root, "local_ip", settings.localIP); + JsonUtils::readIP(root, "gateway_ip", settings.gatewayIP); + JsonUtils::readIP(root, "subnet_mask", settings.subnetMask); + JsonUtils::readIP(root, "dns_ip_1", settings.dnsIP1); + JsonUtils::readIP(root, "dns_ip_2", settings.dnsIP2); + + // Swap around the dns servers if 2 is populated but 1 is not + if (IPUtils::isNotSet(settings.dnsIP1) && IPUtils::isSet(settings.dnsIP2)) { + settings.dnsIP1 = settings.dnsIP2; + settings.dnsIP2 = INADDR_NONE; + } + + // Turning off static ip config if we don't meet the minimum requirements + // of ipAddress, gateway and subnet. This may change to static ip only + // as sensible defaults can be assumed for gateway and subnet + if (settings.staticIPConfig && (IPUtils::isNotSet(settings.localIP) || IPUtils::isNotSet(settings.gatewayIP) || IPUtils::isNotSet(settings.subnetMask))) { + settings.staticIPConfig = false; + } + + // see if we need to inform the user of a restart + if (tx_power != settings.tx_power || enableCORS != settings.enableCORS || CORSOrigin != settings.CORSOrigin + || (ssid != settings.ssid && settings.ssid == "")) { + return StateUpdateResult::CHANGED_RESTART; // tell WebUI that a restart is needed + } + + return StateUpdateResult::CHANGED; +} \ No newline at end of file diff --git a/lib/framework/NetworkSettingsService.h b/lib/framework/NetworkSettingsService.h index 70e7a9430..e7e558b79 100644 --- a/lib/framework/NetworkSettingsService.h +++ b/lib/framework/NetworkSettingsService.h @@ -14,8 +14,6 @@ #include #endif -#include - #define NETWORK_SETTINGS_FILE "/config/networkSettings.json" #define NETWORK_SETTINGS_SERVICE_PATH "/rest/networkSettings" #define WIFI_RECONNECTION_DELAY 1000 * 3 @@ -32,7 +30,7 @@ #define FACTORY_WIFI_HOSTNAME "" #endif - +// copied from Tasmota #if CONFIG_IDF_TARGET_ESP32S2 #define MAX_TX_PWR_DBM_11b 195 #define MAX_TX_PWR_DBM_54g 150 @@ -66,18 +64,18 @@ class NetworkSettings { public: // core wifi configuration - String ssid; - String bssid; - String password; - String hostname; - bool staticIPConfig; - bool enableIPv6; - bool bandwidth20; - int8_t tx_power; - bool nosleep; - bool enableMDNS; - bool enableCORS; - String CORSOrigin; + String ssid; + String bssid; + String password; + String hostname; + bool staticIPConfig; + bool enableIPv6; + bool bandwidth20; + uint8_t tx_power; + bool nosleep; + bool enableMDNS; + bool enableCORS; + String CORSOrigin; // optional configuration for static IP address IPAddress localIP; @@ -86,73 +84,11 @@ class NetworkSettings { IPAddress dnsIP1; IPAddress dnsIP2; - static void read(NetworkSettings & settings, JsonObject root) { - // connection settings - root["ssid"] = settings.ssid; - root["bssid"] = settings.bssid; - root["password"] = settings.password; - root["hostname"] = settings.hostname; - root["static_ip_config"] = settings.staticIPConfig; - root["enableIPv6"] = settings.enableIPv6; - root["bandwidth20"] = settings.bandwidth20; - root["tx_power"] = settings.tx_power; - root["nosleep"] = settings.nosleep; - root["enableMDNS"] = settings.enableMDNS; - root["enableCORS"] = settings.enableCORS; - root["CORSOrigin"] = settings.CORSOrigin; - - // extended settings - JsonUtils::writeIP(root, "local_ip", settings.localIP); - JsonUtils::writeIP(root, "gateway_ip", settings.gatewayIP); - JsonUtils::writeIP(root, "subnet_mask", settings.subnetMask); - JsonUtils::writeIP(root, "dns_ip_1", settings.dnsIP1); - JsonUtils::writeIP(root, "dns_ip_2", settings.dnsIP2); - } - - static StateUpdateResult update(JsonObject root, NetworkSettings & settings) { - auto enableCORS = settings.enableCORS; - auto CORSOrigin = settings.CORSOrigin; - auto ssid = settings.ssid; - settings.ssid = root["ssid"] | FACTORY_WIFI_SSID; - settings.bssid = root["bssid"] | ""; - settings.password = root["password"] | FACTORY_WIFI_PASSWORD; - settings.hostname = root["hostname"] | FACTORY_WIFI_HOSTNAME; - settings.staticIPConfig = root["static_ip_config"] | false; - settings.enableIPv6 = root["enableIPv6"] | false; - settings.bandwidth20 = root["bandwidth20"] | false; - settings.tx_power = root["tx_power"] | 0; - settings.nosleep = root["nosleep"] | false; - settings.enableMDNS = root["enableMDNS"] | true; - settings.enableCORS = root["enableCORS"] | false; - settings.CORSOrigin = root["CORSOrigin"] | "*"; - - // extended settings - JsonUtils::readIP(root, "local_ip", settings.localIP); - JsonUtils::readIP(root, "gateway_ip", settings.gatewayIP); - JsonUtils::readIP(root, "subnet_mask", settings.subnetMask); - JsonUtils::readIP(root, "dns_ip_1", settings.dnsIP1); - JsonUtils::readIP(root, "dns_ip_2", settings.dnsIP2); - - // Swap around the dns servers if 2 is populated but 1 is not - if (IPUtils::isNotSet(settings.dnsIP1) && IPUtils::isSet(settings.dnsIP2)) { - settings.dnsIP1 = settings.dnsIP2; - settings.dnsIP2 = INADDR_NONE; - } - - // Turning off static ip config if we don't meet the minimum requirements - // of ipAddress, gateway and subnet. This may change to static ip only - // as sensible defaults can be assumed for gateway and subnet - if (settings.staticIPConfig && (IPUtils::isNotSet(settings.localIP) || IPUtils::isNotSet(settings.gatewayIP) || IPUtils::isNotSet(settings.subnetMask))) { - settings.staticIPConfig = false; - } - if (enableCORS != settings.enableCORS || CORSOrigin != settings.CORSOrigin || (ssid != settings.ssid && settings.ssid == "")) { - return StateUpdateResult::CHANGED_RESTART; // tell WebUI that a restart is needed - } - - return StateUpdateResult::CHANGED; - } + static void read(NetworkSettings & settings, JsonObject root); + static StateUpdateResult update(JsonObject root, NetworkSettings & settings); }; + class NetworkSettingsService : public StatefulService { public: NetworkSettingsService(AsyncWebServer * server, FS * fs, SecurityManager * securityManager); diff --git a/lib/framework/OTASettingsService.cpp b/lib/framework/OTASettingsService.cpp index c20f4cadd..66a157d46 100644 --- a/lib/framework/OTASettingsService.cpp +++ b/lib/framework/OTASettingsService.cpp @@ -74,3 +74,16 @@ void OTASettingsService::WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info) { break; } } + +void OTASettings::read(OTASettings & settings, JsonObject root) { + root["enabled"] = settings.enabled; + root["port"] = settings.port; + root["password"] = settings.password; +} + +StateUpdateResult OTASettings::update(JsonObject root, OTASettings & settings) { + settings.enabled = root["enabled"] | FACTORY_OTA_ENABLED; + settings.port = root["port"] | FACTORY_OTA_PORT; + settings.password = root["password"] | FACTORY_OTA_PASSWORD; + return StateUpdateResult::CHANGED; +} \ No newline at end of file diff --git a/lib/framework/OTASettingsService.h b/lib/framework/OTASettingsService.h index 12818c07e..72ed4581a 100644 --- a/lib/framework/OTASettingsService.h +++ b/lib/framework/OTASettingsService.h @@ -28,18 +28,8 @@ class OTASettings { int port; String password; - static void read(OTASettings & settings, JsonObject root) { - root["enabled"] = settings.enabled; - root["port"] = settings.port; - root["password"] = settings.password; - } - - static StateUpdateResult update(JsonObject root, OTASettings & settings) { - settings.enabled = root["enabled"] | FACTORY_OTA_ENABLED; - settings.port = root["port"] | FACTORY_OTA_PORT; - settings.password = root["password"] | FACTORY_OTA_PASSWORD; - return StateUpdateResult::CHANGED; - } + static void read(OTASettings & settings, JsonObject root); + static StateUpdateResult update(JsonObject root, OTASettings & settings); }; class OTASettingsService : public StatefulService { diff --git a/lib/framework/SecuritySettingsService.cpp b/lib/framework/SecuritySettingsService.cpp index 2a83e34b6..593e8084e 100644 --- a/lib/framework/SecuritySettingsService.cpp +++ b/lib/framework/SecuritySettingsService.cpp @@ -123,3 +123,34 @@ void SecuritySettingsService::generateToken(AsyncWebServerRequest * request) { } request->send(401); } + +void SecuritySettings::read(SecuritySettings & settings, JsonObject root) { + // secret + root["jwt_secret"] = settings.jwtSecret; + + // users + JsonArray users = root["users"].to(); + for (User user : settings.users) { + JsonObject userRoot = users.add(); + userRoot["username"] = user.username; + userRoot["password"] = user.password; + userRoot["admin"] = user.admin; + } +} + +StateUpdateResult SecuritySettings::update(JsonObject root, SecuritySettings & settings) { + // secret + settings.jwtSecret = root["jwt_secret"] | FACTORY_JWT_SECRET; + + // users + settings.users.clear(); + if (root["users"].is()) { + for (JsonVariant user : root["users"].as()) { + settings.users.push_back(User(user["username"], user["password"], user["admin"])); + } + } else { + settings.users.push_back(User(FACTORY_ADMIN_USERNAME, FACTORY_ADMIN_PASSWORD, true)); + settings.users.push_back(User(FACTORY_GUEST_USERNAME, FACTORY_GUEST_PASSWORD, false)); + } + return StateUpdateResult::CHANGED; +} diff --git a/lib/framework/SecuritySettingsService.h b/lib/framework/SecuritySettingsService.h index 3ec8dd755..82aedf6ef 100644 --- a/lib/framework/SecuritySettingsService.h +++ b/lib/framework/SecuritySettingsService.h @@ -32,38 +32,9 @@ class SecuritySettings { public: String jwtSecret; std::vector users; - // std::list users; - static void read(SecuritySettings & settings, JsonObject root) { - // secret - root["jwt_secret"] = settings.jwtSecret; - - // users - JsonArray users = root["users"].to(); - for (User user : settings.users) { - JsonObject userRoot = users.add(); - userRoot["username"] = user.username; - userRoot["password"] = user.password; - userRoot["admin"] = user.admin; - } - } - - static StateUpdateResult update(JsonObject root, SecuritySettings & settings) { - // secret - settings.jwtSecret = root["jwt_secret"] | FACTORY_JWT_SECRET; - - // users - settings.users.clear(); - if (root["users"].is()) { - for (JsonVariant user : root["users"].as()) { - settings.users.push_back(User(user["username"], user["password"], user["admin"])); - } - } else { - settings.users.push_back(User(FACTORY_ADMIN_USERNAME, FACTORY_ADMIN_PASSWORD, true)); - settings.users.push_back(User(FACTORY_GUEST_USERNAME, FACTORY_GUEST_PASSWORD, false)); - } - return StateUpdateResult::CHANGED; - } + static void read(SecuritySettings & settings, JsonObject root); + static StateUpdateResult update(JsonObject root, SecuritySettings & settings); }; class SecuritySettingsService : public StatefulService, public SecurityManager { diff --git a/lib/framework/SystemStatus.cpp b/lib/framework/SystemStatus.cpp index 845583763..d82cb8326 100644 --- a/lib/framework/SystemStatus.cpp +++ b/lib/framework/SystemStatus.cpp @@ -17,7 +17,15 @@ void SystemStatus::systemStatus(AsyncWebServerRequest * request) { AsyncJsonResponse * response = new AsyncJsonResponse(false); JsonObject root = response->getRoot(); - root["emsesp_version"] = EMSESP_APP_VERSION; +#ifdef EMSESP_DEBUG + root["emsesp_version"] = std::string(EMSESP_APP_VERSION) + " (DEBUG)"; +#else +#ifdef EMSESP_TEST + root["emsesp_version"] = std::string(EMSESP_APP_VERSION) + " (TEST)"; +#else + root["emsesp_version"] = EMSESP_APP_VERSION; +#endif +#endif root["esp_platform"] = EMSESP_PLATFORM; root["cpu_type"] = ESP.getChipModel(); root["cpu_rev"] = ESP.getChipRevision(); diff --git a/src/emsesp_stub.hpp b/src/emsesp_stub.hpp index 0df912ef1..2f8eb0535 100644 --- a/src/emsesp_stub.hpp +++ b/src/emsesp_stub.hpp @@ -23,6 +23,7 @@ #include "temperaturesensor.h" #include "version.h" #include "default_settings.h" +#include "helpers.h" #include diff --git a/src/locale_translations.h b/src/locale_translations.h index 957a9eec7..824d0703a 100644 --- a/src/locale_translations.h +++ b/src/locale_translations.h @@ -68,7 +68,7 @@ MAKE_WORD_TRANSLATION(fetch_cmd, "refresh all EMS values", "Lese alle EMS-Werte MAKE_WORD_TRANSLATION(restart_cmd, "restart EMS-ESP", "Neustart", "opnieuw opstarten", "", "uruchom ponownie EMS-ESP", "restart EMS-ESP", "redémarrer EMS-ESP", "EMS-ESPyi yeniden başlat", "riavvia EMS-ESP", "reštart EMS-ESP") // TODO translate MAKE_WORD_TRANSLATION(watch_cmd, "watch incoming telegrams", "Watch auf eingehende Telegramme", "inkomende telegrammen bekijken", "", "obserwuj przyczodzące telegramy", "se innkommende telegrammer", "", "Gelen telegramları", "guardare i telegrammi in arrivo", "sledovať prichádzajúce telegramy") // TODO translate MAKE_WORD_TRANSLATION(publish_cmd, "publish all to MQTT", "Publiziere MQTT", "publiceer alles naar MQTT", "", "opublikuj wszystko na MQTT", "Publiser alt til MQTT", "", "Hepsini MQTTye gönder", "pubblica tutto su MQTT", "zverejniť všetko na MQTT") // TODO translate -MAKE_WORD_TRANSLATION(system_info_cmd, "show system status", "Zeige System-Status", "toon systeemstatus", "", "pokaż status systemu", "vis system status", "", "Sistem Durumunu Göster", "visualizza stati di sistema", "zobraziť stav systému") // TODO translate +MAKE_WORD_TRANSLATION(system_info_cmd, "show system info", "Zeige System-Status", "toon systeemstatus", "", "pokaż status systemu", "vis system status", "", "Sistem Durumunu Göster", "visualizza stati di sistema", "zobraziť stav systému") // TODO translate MAKE_WORD_TRANSLATION(schedule_cmd, "enable schedule item", "Aktiviere Zeitplan", "activeer tijdschema item", "", "aktywuj wybrany harmonogram", "", "", "program öğesini etkinleştir", "abilitare l'elemento programmato", "povoliť položku plánu") // TODO translate MAKE_WORD_TRANSLATION(entity_cmd, "set custom value on ems", "Sende eigene Entitäten zu EMS", "verstuur custom waarde naar EMS", "", "wyślij własną wartość na EMS", "", "", "emp üzerinde özel değer ayarla", "imposta valori personalizzati su EMS", "nastaviť vlastnú hodnotu na ems") // TODO translate MAKE_WORD_TRANSLATION(commands_response, "get response", "Hole Antwort", "Verzoek om antwoord", "", "uzyskaj odpowiedź", "", "", "gelen cevap", "", "získať odpoveď") // TODO translate diff --git a/src/system.cpp b/src/system.cpp index cf5123b78..71e6bbf84 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -274,10 +274,11 @@ void System::system_restart() { // saves all settings void System::wifi_reconnect() { - LOG_INFO("WiFi reconnecting..."); + EMSESP::esp8266React.getNetworkSettingsService()->read( + [](NetworkSettings & networkSettings) { LOG_INFO("WiFi reconnecting to SSID '%s'...", networkSettings.ssid.c_str()); }); Shell::loop_all(); delay(1000); // wait a second - EMSESP::webSettingsService.save(); // local settings + EMSESP::webSettingsService.save(); // save local settings EMSESP::esp8266React.getNetworkSettingsService()->callUpdateHandlers("local"); // in case we've changed ssid or password } @@ -468,7 +469,7 @@ void System::start() { // button single click void System::button_OnClick(PButton & b) { - LOG_DEBUG("Button pressed - single click"); + LOG_NOTICE("Button pressed - single click - show settings folders"); #if defined(EMSESP_TEST) #ifndef EMSESP_STANDALONE @@ -479,20 +480,19 @@ void System::button_OnClick(PButton & b) { // button double click void System::button_OnDblClick(PButton & b) { - LOG_DEBUG("Button pressed - double click - reconnect"); + LOG_NOTICE("Button pressed - double click - wifi reconnect"); EMSESP::system_.wifi_reconnect(); } // button long press void System::button_OnLongPress(PButton & b) { - LOG_DEBUG("Button pressed - long press"); + LOG_NOTICE("Button pressed - long press"); } // button indefinite press void System::button_OnVLongPress(PButton & b) { - LOG_DEBUG("Button pressed - very long press"); + LOG_NOTICE("Button pressed - very long press - factory reset"); #ifndef EMSESP_STANDALONE - LOG_WARNING("Performing factory reset..."); EMSESP::esp8266React.factoryReset(); #endif } @@ -973,6 +973,8 @@ void System::show_system(uuid::console::Shell & shell) { shell.printfln(" SSID: %s", WiFi.SSID().c_str()); shell.printfln(" BSSID: %s", WiFi.BSSIDstr().c_str()); shell.printfln(" RSSI: %d dBm (%d %%)", WiFi.RSSI(), wifi_quality(WiFi.RSSI())); + char result[10]; + shell.printfln(" TxPower: %s dBm", emsesp::Helpers::render_value(result, (double)(WiFi.getTxPower() / 4), 1)); shell.printfln(" MAC address: %s", WiFi.macAddress().c_str()); shell.printfln(" Hostname: %s", WiFi.getHostname()); shell.printfln(" IPv4 address: %s/%s", uuid::printable_to_string(WiFi.localIP()).c_str(), uuid::printable_to_string(WiFi.subnetMask()).c_str()); @@ -1108,7 +1110,7 @@ bool System::check_upgrade(bool factory_settings) { #if defined(EMSESP_DEBUG) if (!missing_version) { - LOG_INFO("Checking version (settings has %d.%d.%d-%s)...", + LOG_INFO("Checking version (settings file is v%d.%d.%d-%s)...", settings_version.major(), settings_version.minor(), settings_version.patch(), @@ -1144,7 +1146,7 @@ bool System::check_upgrade(bool factory_settings) { EMSESP::esp8266React.getNetworkSettingsService()->update( [&](NetworkSettings & networkSettings) { if (networkSettings.tx_power == 20) { - networkSettings.tx_power = 0; // use Auto + networkSettings.tx_power = WIFI_POWER_19_5dBm; // use 19.5 as we don't have 20 anymore LOG_INFO("Setting WiFi TX Power to Auto"); return StateUpdateResult::CHANGED; } @@ -1266,6 +1268,7 @@ bool System::command_info(const char * value, const int8_t id, JsonObject output if (WiFi.status() == WL_CONNECTED && !settings.bssid.isEmpty()) { node["BSSID"] = "set"; } + node["TxPower setting"] = settings.tx_power; node["static ip config"] = settings.staticIPConfig; node["enable IPv6"] = settings.enableIPv6; node["low bandwidth"] = settings.bandwidth20; diff --git a/src/test/test.cpp b/src/test/test.cpp index 2d39fbd47..da2fdd791 100644 --- a/src/test/test.cpp +++ b/src/test/test.cpp @@ -1978,20 +1978,22 @@ void Test::listDir(fs::FS & fs, const char * dirname, uint8_t levels) { File file = root.openNextFile(); while (file) { if (file.isDirectory()) { - Serial.print(" DIR : "); + Serial.print(" DIR: "); Serial.println(file.name()); if (levels) { listDir(fs, file.name(), levels - 1); } Serial.println(); } else { - Serial.print(" FILE: "); + Serial.print(" "); Serial.print(file.name()); - Serial.print("\tSIZE: "); - Serial.println(file.size()); + Serial.print(" ("); + Serial.print(file.size()); + Serial.println(" bytes)"); } file = root.openNextFile(); } + Serial.println(); } #endif #endif From 23cfdd9b341786b9ff47f9958c24ae96fbd1054c Mon Sep 17 00:00:00 2001 From: proddy Date: Sun, 11 Feb 2024 21:54:08 +0100 Subject: [PATCH 18/54] remove cmd --- scripts/upload_fw.py | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100755 scripts/upload_fw.py diff --git a/scripts/upload_fw.py b/scripts/upload_fw.py deleted file mode 100755 index 0de980efe..000000000 --- a/scripts/upload_fw.py +++ /dev/null @@ -1,10 +0,0 @@ -# for calling dos upload from Window WSL2 Linux, because serial ports are not mapped yet -# example file -Import('env') -from subprocess import call - -def upload(source, target, env): - print("bin file: " + str(target[0])) - call(["cmd.exe", "/c", "c:\\Users\\paul\\OneDrive\\Desktop\\ems-esp32.bat"]) - -env.AddPostAction("$BUILD_DIR/${PROGNAME}.bin", [upload]) From 7c97aaf735038771da7b3d7d8fec0ab03726e1a8 Mon Sep 17 00:00:00 2001 From: proddy Date: Sun, 11 Feb 2024 21:54:31 +0100 Subject: [PATCH 19/54] try out etags instead of immutable cache --- interface/progmem-generator.js | 20 +++++++++++++++++--- lib/framework/ESP8266React.cpp | 25 +++++++++++++++++++++---- lib_standalone/Network.h | 15 +++++++++++++++ 3 files changed, 53 insertions(+), 7 deletions(-) diff --git a/interface/progmem-generator.js b/interface/progmem-generator.js index e68e047b6..c50c565d1 100644 --- a/interface/progmem-generator.js +++ b/interface/progmem-generator.js @@ -2,6 +2,7 @@ import { readdirSync, existsSync, unlinkSync, readFileSync, createWriteStream } import { resolve, relative, sep } from 'path'; import zlib from 'zlib'; import mime from 'mime-types'; +import crypto from 'crypto'; const ARDUINO_INCLUDES = '#include \n\n'; const INDENT = ' '; @@ -11,14 +12,17 @@ const bytesPerLine = 20; var totalSize = 0; const generateWWWClass = () => - `typedef std::function RouteRegistrationHandler; + `typedef std::function RouteRegistrationHandler; // Total size is ${totalSize} bytes class WWWData { ${indent}public: ${indent.repeat(2)}static void registerRoutes(RouteRegistrationHandler handler) { ${fileInfo - .map((file) => `${indent.repeat(3)}handler("${file.uri}", "${file.mimeType}", ${file.variable}, ${file.size});`) + .map( + (file) => + `${indent.repeat(3)}handler("${file.uri}", "${file.mimeType}", ${file.variable}, ${file.size}, "${file.hash}");` + ) .join('\n')} ${indent.repeat(2)}} }; @@ -50,6 +54,12 @@ const writeFile = (relativeFilePath, buffer) => { writeStream.write('const uint8_t ' + variable + '[] = {'); // const zipBuffer = zlib.brotliCompressSync(buffer, { quality: 1 }); const zipBuffer = zlib.gzipSync(buffer, { level: 9 }); + + // create sha + const hashSum = crypto.createHash('sha256'); + hashSum.update(zipBuffer); + const hash = hashSum.digest('hex'); + zipBuffer.forEach((b) => { if (!(size % bytesPerLine)) { writeStream.write('\n'); @@ -58,15 +68,19 @@ const writeFile = (relativeFilePath, buffer) => { writeStream.write('0x' + ('00' + b.toString(16).toUpperCase()).slice(-2) + ','); size++; }); + if (size % bytesPerLine) { writeStream.write('\n'); } + writeStream.write('};\n\n'); + fileInfo.push({ uri: '/' + relativeFilePath.replace(sep, '/'), mimeType, variable, - size + size, + hash }); // console.log(relativeFilePath + ' (size ' + size + ' bytes)'); diff --git a/lib/framework/ESP8266React.cpp b/lib/framework/ESP8266React.cpp index 94a3b78fd..6250a378f 100644 --- a/lib/framework/ESP8266React.cpp +++ b/lib/framework/ESP8266React.cpp @@ -19,15 +19,32 @@ ESP8266React::ESP8266React(AsyncWebServer * server, FS * fs) , _restartService(server, &_securitySettingsService) , _factoryResetService(server, fs, &_securitySettingsService) , _systemStatus(server, &_securitySettingsService) { - // Serve static resources - WWWData::registerRoutes([server, this](const String & uri, const String & contentType, const uint8_t * content, size_t len) { - ArRequestHandlerFunction requestHandler = [contentType, content, len](AsyncWebServerRequest * request) { + // + // Serve static web resources + // + + // Populate the last modification date based on build datetime + static char last_modified[50]; + sprintf(last_modified, "%s %s CET", __DATE__, __TIME__); + + WWWData::registerRoutes([server, this](const String & uri, const String & contentType, const uint8_t * content, size_t len, const String & hash) { + ArRequestHandlerFunction requestHandler = [contentType, content, len, hash](AsyncWebServerRequest * request) { + // Check if the client already has the same version and respond with a 304 (Not modified) + if (request->header("If-Modified-Since").indexOf(last_modified) > 0) { + return request->send(304); + } else if (request->header("If-None-Match").equals(hash)) { + return request->send(304); + } + AsyncWebServerResponse * response = request->beginResponse_P(200, contentType, content, len); response->addHeader("Content-Encoding", "gzip"); - response->addHeader("Cache-Control", "public, immutable, max-age=31536000"); + // response->addHeader("Cache-Control", "public, immutable, max-age=31536000"); + response->addHeader("Last-Modified", last_modified); + response->addHeader("ETag", hash); // response->addHeader("Content-Encoding", "br"); // only works over HTTPS request->send(response); }; + server->on(uri.c_str(), HTTP_GET, requestHandler); // Serving non matching get requests with "/index.html" // OPTIONS get a straight up 200 response diff --git a/lib_standalone/Network.h b/lib_standalone/Network.h index 6fa63c151..c7a750180 100644 --- a/lib_standalone/Network.h +++ b/lib_standalone/Network.h @@ -11,6 +11,21 @@ #define WIFI_AP WIFI_MODE_AP #define WIFI_AP_STA WIFI_MODE_APSTA +typedef enum { + WIFI_POWER_19_5dBm = 78, // 19.5dBm + WIFI_POWER_19dBm = 76, // 19dBm + WIFI_POWER_18_5dBm = 74, // 18.5dBm + WIFI_POWER_17dBm = 68, // 17dBm + WIFI_POWER_15dBm = 60, // 15dBm + WIFI_POWER_13dBm = 52, // 13dBm + WIFI_POWER_11dBm = 44, // 11dBm + WIFI_POWER_8_5dBm = 34, // 8.5dBm + WIFI_POWER_7dBm = 28, // 7dBm + WIFI_POWER_5dBm = 20, // 5dBm + WIFI_POWER_2dBm = 8, // 2dBm + WIFI_POWER_MINUS_1dBm = -4 // -1dBm +} wifi_power_t; + typedef enum { ETH_CLOCK_GPIO0_IN = 0, /*!< RMII clock input to GPIO0 */ ETH_CLOCK_GPIO0_OUT = 1, /*!< RMII clock output from GPIO0 */ From 65cf8005a46766da056837fba52b97eb6a558703 Mon Sep 17 00:00:00 2001 From: Proddy Date: Sun, 11 Feb 2024 23:01:32 +0100 Subject: [PATCH 20/54] fixes for txPower --- lib/framework/ESP8266React.cpp | 3 +- lib/framework/NetworkSettingsService.cpp | 87 ++++++++++++------------ lib/framework/NetworkSettingsService.h | 2 +- 3 files changed, 46 insertions(+), 46 deletions(-) diff --git a/lib/framework/ESP8266React.cpp b/lib/framework/ESP8266React.cpp index 6250a378f..20e936a0c 100644 --- a/lib/framework/ESP8266React.cpp +++ b/lib/framework/ESP8266React.cpp @@ -38,10 +38,11 @@ ESP8266React::ESP8266React(AsyncWebServer * server, FS * fs) AsyncWebServerResponse * response = request->beginResponse_P(200, contentType, content, len); response->addHeader("Content-Encoding", "gzip"); + // response->addHeader("Content-Encoding", "br"); // only works over HTTPS // response->addHeader("Cache-Control", "public, immutable, max-age=31536000"); response->addHeader("Last-Modified", last_modified); response->addHeader("ETag", hash); - // response->addHeader("Content-Encoding", "br"); // only works over HTTPS + request->send(response); }; diff --git a/lib/framework/NetworkSettingsService.cpp b/lib/framework/NetworkSettingsService.cpp index 177899c81..d2ccf9985 100644 --- a/lib/framework/NetworkSettingsService.cpp +++ b/lib/framework/NetworkSettingsService.cpp @@ -88,64 +88,53 @@ void NetworkSettingsService::manageSTA() { } #ifdef BOARD_C3_MINI_V1 - // hardcode Tx power for Wemos CS Mini v1 + // always hardcode Tx power for Wemos CS Mini v1 // v1 needs this value, see https://github.com/emsesp/EMS-ESP32/pull/620#discussion_r993173979 // https://www.wemos.cc/en/latest/c3/c3_mini_1_0_0.html#about-wifi WiFi.setTxPower(WIFI_POWER_8_5dBm); return; +#else + if (_state.tx_power != 0) { + // if not set to Auto (0) set the Tx power now + WiFi.setTxPower((wifi_power_t)_state.tx_power); + } #endif } else { // not connected but STA-mode active => disconnect reconfigureWiFiConnection(); } } -// set the Tx WiFi power -void NetworkSettingsService::setWiFiPower() { -// hardcode Tx power for Wemos CS Mini v1 -// v1 needs this value, see https://github.com/emsesp/EMS-ESP32/pull/620#discussion_r993173979 -// https://www.wemos.cc/en/latest/c3/c3_mini_1_0_0.html#about-wifi -#ifdef BOARD_C3_MINI_V1 - WiFi.setTxPower(WIFI_POWER_8_5dBm); - return; -#endif +// set the TxPower based on the RSSI (signal strength), picking the lowest value +// code is based of RSSI (signal strength) and copied from Tasmota's WiFiSetTXpowerBasedOnRssi() which is copied ESPEasy's ESPEasyWifi.SetWiFiTXpower() function +void NetworkSettingsService::setWiFiPowerOnRSSI() { + // Range ESP32 : 2dBm - 20dBm + // 802.11b - wifi1 + // 802.11a - wifi2 + // 802.11g - wifi3 + // 802.11n - wifi4 + // 802.11ac - wifi5 + // 802.11ax - wifi6 - auto set_power = _state.tx_power; // get user settings. 0 means auto + int max_tx_pwr = MAX_TX_PWR_DBM_n; // assume wifi4 + int threshold = WIFI_SENSITIVITY_n + 30; // Margin in dBm * 10 on top of threshold - // If Auto set the TxPower based on the RSSI (signal strength), picking the lowest value - // based of RSSI (signal strength) and copied from Tasmota's WiFiSetTXpowerBasedOnRssi() which is copied ESPEasy's ESPEasyWifi.SetWiFiTXpower() function - if (set_power == 0) { - // Range ESP32 : 2dBm - 20dBm - // 802.11b - wifi1 - // 802.11a - wifi2 - // 802.11g - wifi3 - // 802.11n - wifi4 - // 802.11ac - wifi5 - // 802.11ax - wifi6 - int max_tx_pwr = MAX_TX_PWR_DBM_n; // assume wifi4 - int threshold = WIFI_SENSITIVITY_n; - threshold += 30; // Margin in dBm * 10 on top of threshold + // Assume AP sends with max set by ETSI standard. + // 2.4 GHz: 100 mWatt (20 dBm) + // US and some other countries allow 1000 mW (30 dBm) + int rssi = WiFi.RSSI() * 10; + int newrssi = rssi - 200; // We cannot send with over 20 dBm, thus it makes no sense to force higher TX power all the time. - // Assume AP sends with max set by ETSI standard. - // 2.4 GHz: 100 mWatt (20 dBm) - // US and some other countries allow 1000 mW (30 dBm) - int rssi = WiFi.RSSI() * 10; - int newrssi = rssi - 200; // We cannot send with over 20 dBm, thus it makes no sense to force higher TX power all the time. - - int min_tx_pwr = 0; - if (newrssi < threshold) { - min_tx_pwr = threshold - newrssi; - } - if (min_tx_pwr > max_tx_pwr) { - min_tx_pwr = max_tx_pwr; - } - - set_power = min_tx_pwr / 10; // this is the recommended power setting to use -#ifdef EMSESP_DEBUG - emsesp::EMSESP::logger().debug("Recommended set WiFi Tx Power (set_power %d, rssi %d, threshold %d", set_power, rssi, threshold); -#endif + int min_tx_pwr = 0; + if (newrssi < threshold) { + min_tx_pwr = threshold - newrssi; + } + if (min_tx_pwr > max_tx_pwr) { + min_tx_pwr = max_tx_pwr; } - // use the user setting, which is a value from WiFIGeneric.h + uint8_t set_power = min_tx_pwr / 10; // this is the recommended power setting to use + + // from WiFIGeneric.h use: // WIFI_POWER_19_5dBm = 78,// 19.5dBm // WIFI_POWER_19dBm = 76,// 19dBm // WIFI_POWER_18_5dBm = 74,// 18.5dBm @@ -178,6 +167,13 @@ void NetworkSettingsService::setWiFiPower() { else if (set_power >= 5) p = WIFI_POWER_5dBm; +#ifdef EMSESP_DEBUG + emsesp::EMSESP::logger().debug("Recommended set WiFi Tx Power (set_power %d, new power %d, rssi %d, threshold %d", set_power, p, rssi, threshold); +#else + char result[10]; + emsesp::EMSESP::logger().info("Setting WiFi Tx Power to %s dBm", emsesp::Helpers::render_value(result, (double)(p / 4), 1)); +#endif + WiFi.setTxPower(p); } @@ -347,7 +343,10 @@ void NetworkSettingsService::WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info) case ARDUINO_EVENT_WIFI_STA_CONNECTED: // Set the TxPower after the connection is established - setWiFiPower(); + // if we're using TxPower = 0 (Auto) + if (_state.tx_power == 0) { + setWiFiPowerOnRSSI(); + } if (_state.enableIPv6) { WiFi.enableIpV6(); } diff --git a/lib/framework/NetworkSettingsService.h b/lib/framework/NetworkSettingsService.h index e7e558b79..6b5551802 100644 --- a/lib/framework/NetworkSettingsService.h +++ b/lib/framework/NetworkSettingsService.h @@ -108,7 +108,7 @@ class NetworkSettingsService : public StatefulService { const char * disconnectReason(uint8_t code); void reconfigureWiFiConnection(); void manageSTA(); - void setWiFiPower(); + void setWiFiPowerOnRSSI(); }; #endif From 1f7c968d0d989da4b752cd0a50e5600dbad971ba Mon Sep 17 00:00:00 2001 From: Proddy Date: Mon, 12 Feb 2024 11:22:07 +0100 Subject: [PATCH 21/54] remove OriginID from state service --- lib/framework/FSPersistence.h | 2 +- lib/framework/HttpEndpoint.h | 2 +- lib/framework/MqttSettingsService.cpp | 2 +- lib/framework/NTPSettingsService.cpp | 2 +- lib/framework/NetworkSettingsService.cpp | 18 ++-- lib/framework/OTASettingsService.cpp | 6 +- lib/framework/SecuritySettingsService.cpp | 2 +- lib/framework/StatefulService.h | 36 +++---- lib_standalone/FSPersistence.h | 2 +- lib_standalone/StatefulService.h | 16 +-- src/analogsensor.cpp | 108 +++++++++---------- src/console.cpp | 72 ++++++------- src/devices/solar.cpp | 10 +- src/system.cpp | 74 ++++--------- src/temperaturesensor.cpp | 46 ++++---- src/web/WebCustomEntityService.cpp | 84 ++++++++------- src/web/WebCustomizationService.cpp | 122 +++++++++++----------- src/web/WebLogService.cpp | 30 +++--- src/web/WebSchedulerService.cpp | 32 +++--- src/web/WebSettingsService.cpp | 2 +- 20 files changed, 302 insertions(+), 366 deletions(-) diff --git a/lib/framework/FSPersistence.h b/lib/framework/FSPersistence.h index ec38aec37..5a7639c13 100644 --- a/lib/framework/FSPersistence.h +++ b/lib/framework/FSPersistence.h @@ -80,7 +80,7 @@ class FSPersistence { void enableUpdateHandler() { if (!_updateHandlerId) { - _updateHandlerId = _statefulService->addUpdateHandler([&](const String & originId) { writeToFS(); }); + _updateHandlerId = _statefulService->addUpdateHandler([&] { writeToFS(); }); } } diff --git a/lib/framework/HttpEndpoint.h b/lib/framework/HttpEndpoint.h index b3f43b8ea..a8dac9119 100644 --- a/lib/framework/HttpEndpoint.h +++ b/lib/framework/HttpEndpoint.h @@ -58,7 +58,7 @@ class HttpEndpoint { return; } else if (outcome == StateUpdateResult::CHANGED || outcome == StateUpdateResult::CHANGED_RESTART) { // persist changes - request->onDisconnect([this]() { _statefulService->callUpdateHandlers(HTTP_ENDPOINT_ORIGIN_ID); }); + request->onDisconnect([this] { _statefulService->callUpdateHandlers(); }); if (outcome == StateUpdateResult::CHANGED_RESTART) { request->send(205); // reboot required return; diff --git a/lib/framework/MqttSettingsService.cpp b/lib/framework/MqttSettingsService.cpp index 5c28d88a3..3e69c1b92 100644 --- a/lib/framework/MqttSettingsService.cpp +++ b/lib/framework/MqttSettingsService.cpp @@ -36,7 +36,7 @@ MqttSettingsService::MqttSettingsService(AsyncWebServer * server, FS * fs, Secur , _disconnectReason(espMqttClientTypes::DisconnectReason::TCP_DISCONNECTED) , _mqttClient(nullptr) { WiFi.onEvent(std::bind(&MqttSettingsService::WiFiEvent, this, _1, _2)); - addUpdateHandler([&](const String & originId) { onConfigUpdated(); }, false); + addUpdateHandler([&] { onConfigUpdated(); }, false); } MqttSettingsService::~MqttSettingsService() { diff --git a/lib/framework/NTPSettingsService.cpp b/lib/framework/NTPSettingsService.cpp index d4095d913..212d9d3ae 100644 --- a/lib/framework/NTPSettingsService.cpp +++ b/lib/framework/NTPSettingsService.cpp @@ -14,7 +14,7 @@ NTPSettingsService::NTPSettingsService(AsyncWebServer * server, FS * fs, Securit WiFi.onEvent(std::bind(&NTPSettingsService::WiFiEvent, this, _1)); - addUpdateHandler([&](const String & originId) { configureNTP(); }, false); + addUpdateHandler([&] { configureNTP(); }, false); } void NTPSettingsService::begin() { diff --git a/lib/framework/NetworkSettingsService.cpp b/lib/framework/NetworkSettingsService.cpp index d2ccf9985..1bb03be27 100644 --- a/lib/framework/NetworkSettingsService.cpp +++ b/lib/framework/NetworkSettingsService.cpp @@ -8,7 +8,7 @@ NetworkSettingsService::NetworkSettingsService(AsyncWebServer * server, FS * fs, : _httpEndpoint(NetworkSettings::read, NetworkSettings::update, this, server, NETWORK_SETTINGS_SERVICE_PATH, securityManager) , _fsPersistence(NetworkSettings::read, NetworkSettings::update, this, fs, NETWORK_SETTINGS_FILE) , _lastConnectionAttempt(0) { - addUpdateHandler([&](const String & originId) { reconfigureWiFiConnection(); }, false); + addUpdateHandler([&] { reconfigureWiFiConnection(); }, false); // wifi event callbacks WiFi.onEvent(std::bind(&NetworkSettingsService::WiFiEvent, this, _1, _2)); } @@ -75,6 +75,7 @@ void NetworkSettingsService::manageSTA() { if (_state.nosleep) { WiFi.setSleep(false); // turn off sleep - WIFI_PS_NONE } + // attempt to connect to the network uint mac[6]; if (!_state.bssid.isEmpty() && sscanf(_state.bssid.c_str(), "%X:%X:%X:%X:%X:%X", &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]) == 6) { @@ -92,11 +93,12 @@ void NetworkSettingsService::manageSTA() { // v1 needs this value, see https://github.com/emsesp/EMS-ESP32/pull/620#discussion_r993173979 // https://www.wemos.cc/en/latest/c3/c3_mini_1_0_0.html#about-wifi WiFi.setTxPower(WIFI_POWER_8_5dBm); - return; #else if (_state.tx_power != 0) { // if not set to Auto (0) set the Tx power now - WiFi.setTxPower((wifi_power_t)_state.tx_power); + if (!WiFi.setTxPower((wifi_power_t)_state.tx_power)) { + emsesp::EMSESP::logger().warning("Failed to set WiFi Tx Power"); + } } #endif } else { // not connected but STA-mode active => disconnect @@ -174,7 +176,9 @@ void NetworkSettingsService::setWiFiPowerOnRSSI() { emsesp::EMSESP::logger().info("Setting WiFi Tx Power to %s dBm", emsesp::Helpers::render_value(result, (double)(p / 4), 1)); #endif - WiFi.setTxPower(p); + if (!WiFi.setTxPower(p)) { + emsesp::EMSESP::logger().warning("Failed to set WiFi Tx Power"); + } } // start the multicast UDP service so EMS-ESP is discoverable via .local @@ -184,7 +188,7 @@ void NetworkSettingsService::mDNS_start() const { if (_state.enableMDNS) { if (!MDNS.begin(emsesp::EMSESP::system_.hostname().c_str())) { - emsesp::EMSESP::logger().warning("Failed to start mDNS responder service"); + emsesp::EMSESP::logger().warning("Failed to start mDNS Responder service"); return; } @@ -196,11 +200,11 @@ void NetworkSettingsService::mDNS_start() const { MDNS.addServiceTxt("http", "tcp", "version", EMSESP_APP_VERSION); MDNS.addServiceTxt("http", "tcp", "address", address_s.c_str()); - emsesp::EMSESP::logger().info("mDNS responder service started"); + emsesp::EMSESP::logger().info("mDNS Responder service started"); } #else if (_state.enableMDNS) { - EMSESP::logger().info("mDNS responder service started"); + EMSESP::logger().info("mDNS Responder service started"); } #endif } diff --git a/lib/framework/OTASettingsService.cpp b/lib/framework/OTASettingsService.cpp index 66a157d46..ecf18a1da 100644 --- a/lib/framework/OTASettingsService.cpp +++ b/lib/framework/OTASettingsService.cpp @@ -9,7 +9,7 @@ OTASettingsService::OTASettingsService(AsyncWebServer * server, FS * fs, Securit , _fsPersistence(OTASettings::read, OTASettings::update, this, fs, OTA_SETTINGS_FILE) , _arduinoOTA(nullptr) { WiFi.onEvent(std::bind(&OTASettingsService::WiFiEvent, this, _1, _2)); - addUpdateHandler([&](const String & originId) { configureArduinoOTA(); }, false); + addUpdateHandler([&] { configureArduinoOTA(); }, false); } void OTASettingsService::begin() { @@ -35,8 +35,8 @@ void OTASettingsService::configureArduinoOTA() { _arduinoOTA->setPort(_state.port); _arduinoOTA->setPassword(_state.password.c_str()); - _arduinoOTA->onStart([]() { emsesp::EMSESP::system_.upload_status(true); }); - _arduinoOTA->onEnd([]() { emsesp::EMSESP::system_.upload_status(false); }); + _arduinoOTA->onStart([] { emsesp::EMSESP::system_.upload_status(true); }); + _arduinoOTA->onEnd([] { emsesp::EMSESP::system_.upload_status(false); }); _arduinoOTA->onProgress([](unsigned int progress, unsigned int total) { // Serial.printf("Progress: %u%%\r\n", (progress / (total / 100))); diff --git a/lib/framework/SecuritySettingsService.cpp b/lib/framework/SecuritySettingsService.cpp index 593e8084e..2b4d13636 100644 --- a/lib/framework/SecuritySettingsService.cpp +++ b/lib/framework/SecuritySettingsService.cpp @@ -6,7 +6,7 @@ SecuritySettingsService::SecuritySettingsService(AsyncWebServer * server, FS * f : _httpEndpoint(SecuritySettings::read, SecuritySettings::update, this, server, SECURITY_SETTINGS_PATH, this) , _fsPersistence(SecuritySettings::read, SecuritySettings::update, this, fs, SECURITY_SETTINGS_FILE) , _jwtHandler(FACTORY_JWT_SECRET) { - addUpdateHandler([&](const String & originId) { configureJWTHandler(); }, false); + addUpdateHandler([&] { configureJWTHandler(); }, false); server->on(GENERATE_TOKEN_PATH, HTTP_GET, wrapRequest(std::bind(&SecuritySettingsService::generateToken, this, std::placeholders::_1), AuthenticationPredicates::IS_ADMIN)); diff --git a/lib/framework/StatefulService.h b/lib/framework/StatefulService.h index 80fa5f84e..f87d96841 100644 --- a/lib/framework/StatefulService.h +++ b/lib/framework/StatefulService.h @@ -23,8 +23,8 @@ using JsonStateUpdater = std::function using JsonStateReader = std::function; -typedef size_t update_handler_id_t; -typedef std::function StateUpdateCallback; +typedef size_t update_handler_id_t; +typedef std::function StateUpdateCallback; typedef struct StateUpdateHandlerInfo { static update_handler_id_t currentUpdatedHandlerId; @@ -33,7 +33,7 @@ typedef struct StateUpdateHandlerInfo { bool _allowRemove; StateUpdateHandlerInfo(StateUpdateCallback cb, bool allowRemove) : _id(++currentUpdatedHandlerId) - , _cb(cb) + , _cb(std::move(cb)) , _allowRemove(allowRemove){}; } StateUpdateHandlerInfo_t; @@ -41,7 +41,7 @@ template class StatefulService { public: template - StatefulService(Args &&... args) + explicit StatefulService(Args &&... args) : _state(std::forward(args)...) , _accessMutex(xSemaphoreCreateRecursiveMutex()) { } @@ -50,27 +50,28 @@ class StatefulService { if (!cb) { return 0; } - StateUpdateHandlerInfo_t updateHandler(cb, allowRemove); - _updateHandlers.push_back(updateHandler); + StateUpdateHandlerInfo_t updateHandler(std::move(cb), allowRemove); + _updateHandlers.push_back(std::move(updateHandler)); return updateHandler._id; } void removeUpdateHandler(update_handler_id_t id) { - for (auto i = _updateHandlers.begin(); i != _updateHandlers.end();) { - if ((*i)._allowRemove && (*i)._id == id) { - i = _updateHandlers.erase(i); + for (auto it = _updateHandlers.begin(); it != _updateHandlers.end();) { + auto & elem = *it; + if (elem._allowRemove && elem._id == id) { + it = _updateHandlers.erase(it); } else { - ++i; + ++it; } } } - StateUpdateResult update(std::function stateUpdater, const String & originId) { + StateUpdateResult update(std::function stateUpdater) { beginTransaction(); StateUpdateResult result = stateUpdater(_state); endTransaction(); if (result == StateUpdateResult::CHANGED) { - callUpdateHandlers(originId); + callUpdateHandlers(); } return result; } @@ -82,12 +83,12 @@ class StatefulService { return result; } - StateUpdateResult update(JsonObject jsonObject, JsonStateUpdater stateUpdater, const String & originId) { + StateUpdateResult update(JsonObject jsonObject, JsonStateUpdater stateUpdater) { beginTransaction(); StateUpdateResult result = stateUpdater(jsonObject, _state); endTransaction(); if (result == StateUpdateResult::CHANGED) { - callUpdateHandlers(originId); + callUpdateHandlers(); } return result; } @@ -111,9 +112,9 @@ class StatefulService { endTransaction(); } - void callUpdateHandlers(const String & originId) { + void callUpdateHandlers() { for (const StateUpdateHandlerInfo_t & updateHandler : _updateHandlers) { - updateHandler._cb(originId); + updateHandler._cb(); } } @@ -129,9 +130,8 @@ class StatefulService { } private: - SemaphoreHandle_t _accessMutex; + SemaphoreHandle_t _accessMutex; std::vector _updateHandlers; - // std::list _updateHandlers; }; #endif diff --git a/lib_standalone/FSPersistence.h b/lib_standalone/FSPersistence.h index 1b8a68c49..9d943d711 100644 --- a/lib_standalone/FSPersistence.h +++ b/lib_standalone/FSPersistence.h @@ -40,7 +40,7 @@ class FSPersistence { void enableUpdateHandler() { if (!_updateHandlerId) { - _updateHandlerId = _statefulService->addUpdateHandler([&](const String & originId) { writeToFS(); }); + _updateHandlerId = _statefulService->addUpdateHandler([&]() { writeToFS(); }); } } diff --git a/lib_standalone/StatefulService.h b/lib_standalone/StatefulService.h index 577b51fbb..0210bc1b3 100644 --- a/lib_standalone/StatefulService.h +++ b/lib_standalone/StatefulService.h @@ -20,8 +20,8 @@ using JsonStateUpdater = std::function using JsonStateReader = std::function; -typedef size_t update_handler_id_t; -typedef std::function StateUpdateCallback; +typedef size_t update_handler_id_t; +typedef std::function StateUpdateCallback; typedef struct StateUpdateHandlerInfo { static update_handler_id_t currentUpdatedHandlerId; @@ -68,12 +68,12 @@ class StatefulService { } } - StateUpdateResult update(std::function stateUpdater, const String & originId) { + StateUpdateResult update(std::function stateUpdater, ) { beginTransaction(); StateUpdateResult result = stateUpdater(_state); endTransaction(); if (result == StateUpdateResult::CHANGED) { - callUpdateHandlers(originId); + callUpdateHandlers(); } return result; } @@ -85,12 +85,12 @@ class StatefulService { return result; } - StateUpdateResult update(JsonObject jsonObject, JsonStateUpdater stateUpdater, const String & originId) { + StateUpdateResult update(JsonObject jsonObject, JsonStateUpdater stateUpdater, ) { beginTransaction(); StateUpdateResult result = stateUpdater(jsonObject, _state); endTransaction(); if (result == StateUpdateResult::CHANGED) { - callUpdateHandlers(originId); + callUpdateHandlers(); } return result; } @@ -114,9 +114,9 @@ class StatefulService { endTransaction(); } - void callUpdateHandlers(const String & originId) { + void callUpdateHandlers() { for (const StateUpdateHandlerInfo_t & updateHandler : _updateHandlers) { - updateHandler._cb(originId); + updateHandler._cb(); } } diff --git a/src/analogsensor.cpp b/src/analogsensor.cpp index 987f8d709..13a31130e 100644 --- a/src/analogsensor.cpp +++ b/src/analogsensor.cpp @@ -321,37 +321,35 @@ void AnalogSensor::loop() { bool AnalogSensor::update(uint8_t gpio, const std::string & name, double offset, double factor, uint8_t uom, int8_t type, bool deleted) { // first see if we can find the sensor in our customization list bool found_sensor = false; - EMSESP::webCustomizationService.update( - [&](WebCustomization & settings) { - for (auto & AnalogCustomization : settings.analogCustomizations) { - if (AnalogCustomization.type == AnalogType::COUNTER || AnalogCustomization.type >= AnalogType::DIGITAL_OUT) { - Command::erase_command(EMSdevice::DeviceType::ANALOGSENSOR, AnalogCustomization.name.c_str()); - } - if (AnalogCustomization.gpio == gpio) { - found_sensor = true; // found the record - // see if it's marked for deletion - if (deleted) { - EMSESP::nvs_.remove(AnalogCustomization.name.c_str()); - LOG_DEBUG("Removing analog sensor GPIO %02d", gpio); - settings.analogCustomizations.remove(AnalogCustomization); - } else { - // update existing record - if (name != AnalogCustomization.name) { - EMSESP::nvs_.remove(AnalogCustomization.name.c_str()); - } - AnalogCustomization.name = name; - AnalogCustomization.offset = offset; - AnalogCustomization.factor = factor; - AnalogCustomization.uom = uom; - AnalogCustomization.type = type; - LOG_DEBUG("Customizing existing analog GPIO %02d", gpio); - } - return StateUpdateResult::CHANGED; // persist the change - } + EMSESP::webCustomizationService.update([&](WebCustomization & settings) { + for (auto & AnalogCustomization : settings.analogCustomizations) { + if (AnalogCustomization.type == AnalogType::COUNTER || AnalogCustomization.type >= AnalogType::DIGITAL_OUT) { + Command::erase_command(EMSdevice::DeviceType::ANALOGSENSOR, AnalogCustomization.name.c_str()); } - return StateUpdateResult::UNCHANGED; - }, - "local"); + if (AnalogCustomization.gpio == gpio) { + found_sensor = true; // found the record + // see if it's marked for deletion + if (deleted) { + EMSESP::nvs_.remove(AnalogCustomization.name.c_str()); + LOG_DEBUG("Removing analog sensor GPIO %02d", gpio); + settings.analogCustomizations.remove(AnalogCustomization); + } else { + // update existing record + if (name != AnalogCustomization.name) { + EMSESP::nvs_.remove(AnalogCustomization.name.c_str()); + } + AnalogCustomization.name = name; + AnalogCustomization.offset = offset; + AnalogCustomization.factor = factor; + AnalogCustomization.uom = uom; + AnalogCustomization.type = type; + LOG_DEBUG("Customizing existing analog GPIO %02d", gpio); + } + return StateUpdateResult::CHANGED; // persist the change + } + } + return StateUpdateResult::UNCHANGED; + }); // if the sensor exists and we're using HA, delete the old HA record if (found_sensor && Mqtt::ha_enabled()) { @@ -360,20 +358,18 @@ bool AnalogSensor::update(uint8_t gpio, const std::string & name, double offset, // we didn't find it, it's new, so create and store it in the customization list if (!found_sensor) { - EMSESP::webCustomizationService.update( - [&](WebCustomization & settings) { - auto newSensor = AnalogCustomization(); - newSensor.gpio = gpio; - newSensor.name = name; - newSensor.offset = offset; - newSensor.factor = factor; - newSensor.uom = uom; - newSensor.type = type; - settings.analogCustomizations.push_back(newSensor); - LOG_DEBUG("Adding new customization for analog sensor GPIO %02d", gpio); - return StateUpdateResult::CHANGED; // persist the change - }, - "local"); + EMSESP::webCustomizationService.update([&](WebCustomization & settings) { + auto newSensor = AnalogCustomization(); + newSensor.gpio = gpio; + newSensor.name = name; + newSensor.offset = offset; + newSensor.factor = factor; + newSensor.uom = uom; + newSensor.type = type; + settings.analogCustomizations.push_back(newSensor); + LOG_DEBUG("Adding new customization for analog sensor GPIO %02d", gpio); + return StateUpdateResult::CHANGED; // persist the change + }); } // reloads the sensors in the customizations file into the sensors list @@ -818,20 +814,18 @@ bool AnalogSensor::command_setvalue(const char * value, const int8_t gpio) { return false; } if (oldoffset != sensor.offset()) { - EMSESP::webCustomizationService.update( - [&](WebCustomization & settings) { - for (auto & AnalogCustomization : settings.analogCustomizations) { - if (AnalogCustomization.gpio == sensor.gpio() && AnalogCustomization.type == sensor.type()) { - AnalogCustomization.offset = sensor.offset(); - } + EMSESP::webCustomizationService.update([&](WebCustomization & settings) { + for (auto & AnalogCustomization : settings.analogCustomizations) { + if (AnalogCustomization.gpio == sensor.gpio() && AnalogCustomization.type == sensor.type()) { + AnalogCustomization.offset = sensor.offset(); } - if (sensor.type() == AnalogType::COUNTER || (sensor.type() == AnalogType::DIGITAL_OUT && sensor.uom() > 0)) { - return StateUpdateResult::UNCHANGED; // temporary change - } else { - return StateUpdateResult::CHANGED; // persist the change - } - }, - "local"); + } + if (sensor.type() == AnalogType::COUNTER || (sensor.type() == AnalogType::DIGITAL_OUT && sensor.uom() > 0)) { + return StateUpdateResult::UNCHANGED; // temporary change + } else { + return StateUpdateResult::CHANGED; // persist the change + } + }); publish_sensor(sensor); changed_ = true; } diff --git a/src/console.cpp b/src/console.cpp index 9d2748d96..24933e8a0 100644 --- a/src/console.cpp +++ b/src/console.cpp @@ -184,12 +184,10 @@ static void setup_commands(std::shared_ptr & commands) { shell.enter_password(F_(new_password_prompt2), [password1](Shell & shell, bool completed, const std::string & password2) { if (completed) { if (password1 == password2) { - to_app(shell).esp8266React.getSecuritySettingsService()->update( - [&](SecuritySettings & securitySettings) { - securitySettings.jwtSecret = password2.c_str(); - return StateUpdateResult::CHANGED; - }, - "local"); + to_app(shell).esp8266React.getSecuritySettingsService()->update([&](SecuritySettings & securitySettings) { + securitySettings.jwtSecret = password2.c_str(); + return StateUpdateResult::CHANGED; + }); shell.println("Admin password updated"); } else { shell.println("Passwords do not match"); @@ -258,12 +256,10 @@ static void setup_commands(std::shared_ptr & commands) { shell.println("The network connection will be reset..."); Shell::loop_all(); delay(1000); // wait a second - to_app(shell).esp8266React.getNetworkSettingsService()->update( - [&](NetworkSettings & networkSettings) { - networkSettings.hostname = arguments.front().c_str(); - return StateUpdateResult::CHANGED; - }, - "local"); + to_app(shell).esp8266React.getNetworkSettingsService()->update([&](NetworkSettings & networkSettings) { + networkSettings.hostname = arguments.front().c_str(); + return StateUpdateResult::CHANGED; + }); }); commands->add_command(ShellContext::MAIN, @@ -293,21 +289,19 @@ static void setup_commands(std::shared_ptr & commands) { if (arguments.size() == 2 && Helpers::toLower(arguments.back()) == "nvs") { to_app(shell).nvs_.putString("boot", board_profile.c_str()); } - to_app(shell).webSettingsService.update( - [&](WebSettings & settings) { - settings.board_profile = board_profile.c_str(); - settings.led_gpio = data[0]; - settings.dallas_gpio = data[1]; - settings.rx_gpio = data[2]; - settings.tx_gpio = data[3]; - settings.pbutton_gpio = data[4]; - settings.phy_type = data[5]; - settings.eth_power = data[6]; // can be -1 - settings.eth_phy_addr = data[7]; - settings.eth_clock_mode = data[8]; - return StateUpdateResult::CHANGED; - }, - "local"); + to_app(shell).webSettingsService.update([&](WebSettings & settings) { + settings.board_profile = board_profile.c_str(); + settings.led_gpio = data[0]; + settings.dallas_gpio = data[1]; + settings.rx_gpio = data[2]; + settings.tx_gpio = data[3]; + settings.pbutton_gpio = data[4]; + settings.phy_type = data[5]; + settings.eth_power = data[6]; // can be -1 + settings.eth_phy_addr = data[7]; + settings.eth_clock_mode = data[8]; + return StateUpdateResult::CHANGED; + }); shell.printfln("Loaded board profile %s", board_profile.c_str()); to_app(shell).system_.network_init(true); }); @@ -320,13 +314,11 @@ static void setup_commands(std::shared_ptr & commands) { [](Shell & shell, const std::vector & arguments) { uint8_t device_id = Helpers::hextoint(arguments.front().c_str()); if ((device_id == 0x0B) || (device_id == 0x0D) || (device_id == 0x0A) || (device_id == 0x0F) || (device_id == 0x12)) { - to_app(shell).webSettingsService.update( - [&](WebSettings & settings) { - settings.ems_bus_id = device_id; - shell.printfln(F_(bus_id_fmt), settings.ems_bus_id); - return StateUpdateResult::CHANGED; - }, - "local"); + to_app(shell).webSettingsService.update([&](WebSettings & settings) { + settings.ems_bus_id = device_id; + shell.printfln(F_(bus_id_fmt), settings.ems_bus_id); + return StateUpdateResult::CHANGED; + }); } else { shell.println("Must be 0B, 0D, 0A, 0E, 0F, or 48 - 4D"); } @@ -342,13 +334,11 @@ static void setup_commands(std::shared_ptr & commands) { [](Shell & shell, const std::vector & arguments) { uint8_t tx_mode = std::strtol(arguments[0].c_str(), nullptr, 10); // save the tx_mode - to_app(shell).webSettingsService.update( - [&](WebSettings & settings) { - settings.tx_mode = tx_mode; - shell.printfln(F_(tx_mode_fmt), settings.tx_mode); - return StateUpdateResult::CHANGED; - }, - "local"); + to_app(shell).webSettingsService.update([&](WebSettings & settings) { + settings.tx_mode = tx_mode; + shell.printfln(F_(tx_mode_fmt), settings.tx_mode); + return StateUpdateResult::CHANGED; + }); to_app(shell).uart_init(); }); diff --git a/src/devices/solar.cpp b/src/devices/solar.cpp index 409533b50..2c405aca2 100644 --- a/src/devices/solar.cpp +++ b/src/devices/solar.cpp @@ -1047,12 +1047,10 @@ bool Solar::set_SM10MaxFlow(const char * value, const int8_t id) { return false; } maxFlow_ = (flow * 10); - EMSESP::webSettingsService.update( - [&](WebSettings & settings) { - settings.solar_maxflow = maxFlow_; - return StateUpdateResult::CHANGED; - }, - "local"); + EMSESP::webSettingsService.update([&](WebSettings & settings) { + settings.solar_maxflow = maxFlow_; + return StateUpdateResult::CHANGED; + }); return true; } diff --git a/src/system.cpp b/src/system.cpp index 71e6bbf84..5a1752943 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -208,8 +208,7 @@ bool System::command_syslog_level(const char * value, const int8_t id) { changed = true; } return StateUpdateResult::CHANGED; - }, - "local"); + }); if (changed) { EMSESP::system_.syslog_init(); } @@ -277,9 +276,9 @@ void System::wifi_reconnect() { EMSESP::esp8266React.getNetworkSettingsService()->read( [](NetworkSettings & networkSettings) { LOG_INFO("WiFi reconnecting to SSID '%s'...", networkSettings.ssid.c_str()); }); Shell::loop_all(); - delay(1000); // wait a second - EMSESP::webSettingsService.save(); // save local settings - EMSESP::esp8266React.getNetworkSettingsService()->callUpdateHandlers("local"); // in case we've changed ssid or password + delay(1000); // wait a second + EMSESP::webSettingsService.save(); // save local settings + EMSESP::esp8266React.getNetworkSettingsService()->callUpdateHandlers(); // in case we've changed ssid or password } // format the FS. Wipes everything. @@ -386,33 +385,6 @@ void System::reload_settings() { }); } -// adjust WiFi settings -// this for problem solving mesh and connection issues, and also get EMS bus-powered more stable by lowering power -void System::wifi_tweak() { -#if defined(EMSESP_WIFI_TWEAK) - // Default Tx Power is 80 = 20dBm <-- default - // WIFI_POWER_19_5dBm = 78,// 19.5dBm - // WIFI_POWER_19dBm = 76,// 19dBm - // WIFI_POWER_18_5dBm = 74,// 18.5dBm - // WIFI_POWER_17dBm = 68,// 17dBm - // WIFI_POWER_15dBm = 60,// 15dBm - // WIFI_POWER_13dBm = 52,// 13dBm - // WIFI_POWER_11dBm = 44,// 11dBm - // WIFI_POWER_8_5dBm = 34,// 8.5dBm - // WIFI_POWER_7dBm = 28,// 7dBm - // WIFI_POWER_5dBm = 20,// 5dBm - // WIFI_POWER_2dBm = 8,// 2dBm - // WIFI_POWER_MINUS_1dBm = -4// -1dBm - wifi_power_t p1 = WiFi.getTxPower(); - (void)WiFi.setTxPower(WIFI_POWER_17dBm); - wifi_power_t p2 = WiFi.getTxPower(); - bool s1 = WiFi.getSleep(); - WiFi.setSleep(false); // turn off sleep - WIFI_PS_NONE - bool s2 = WiFi.getSleep(); - LOG_DEBUG("Adjusting WiFi - Tx power %d->%d, Sleep %d->%d", p1, p2, s1, s2); -#endif -} - // check for valid ESP32 pins. This is very dependent on which ESP32 board is being used. // Typically you can't use 1, 6-11, 20, 24, 28-31 and 40+ // we allow 0 as it has a special function on the NodeMCU apparently @@ -1134,25 +1106,21 @@ bool System::check_upgrade(bool factory_settings) { // if we're coming from 3.4.4 or 3.5.0b14 which had no version stored then we need to apply new settings if (missing_version) { LOG_INFO("Setting MQTT Entity ID format to v3.4 format"); - EMSESP::esp8266React.getMqttSettingsService()->update( - [&](MqttSettings & mqttSettings) { - mqttSettings.entity_format = 0; // use old Entity ID format from v3.4 - return StateUpdateResult::CHANGED; - }, - "local"); + EMSESP::esp8266React.getMqttSettingsService()->update([&](MqttSettings & mqttSettings) { + mqttSettings.entity_format = 0; // use old Entity ID format from v3.4 + return StateUpdateResult::CHANGED; + }); } // Network Settings Wifi tx_power is now using the value * 4. - EMSESP::esp8266React.getNetworkSettingsService()->update( - [&](NetworkSettings & networkSettings) { - if (networkSettings.tx_power == 20) { - networkSettings.tx_power = WIFI_POWER_19_5dBm; // use 19.5 as we don't have 20 anymore - LOG_INFO("Setting WiFi TX Power to Auto"); - return StateUpdateResult::CHANGED; - } - return StateUpdateResult::UNCHANGED; - }, - "local"); + EMSESP::esp8266React.getNetworkSettingsService()->update([&](NetworkSettings & networkSettings) { + if (networkSettings.tx_power == 20) { + networkSettings.tx_power = WIFI_POWER_19_5dBm; // use 19.5 as we don't have 20 anymore + LOG_INFO("Setting WiFi TX Power to Auto"); + return StateUpdateResult::CHANGED; + } + return StateUpdateResult::UNCHANGED; + }); } else if (this_version < settings_version) { // need downgrade @@ -1164,12 +1132,10 @@ bool System::check_upgrade(bool factory_settings) { // if we did a change, set the new version and reboot if (save_version) { - EMSESP::webSettingsService.update( - [&](WebSettings & settings) { - settings.version = EMSESP_APP_VERSION; - return StateUpdateResult::CHANGED; - }, - "local"); + EMSESP::webSettingsService.update([&](WebSettings & settings) { + settings.version = EMSESP_APP_VERSION; + return StateUpdateResult::CHANGED; + }); return true; // need reboot } diff --git a/src/temperaturesensor.cpp b/src/temperaturesensor.cpp index 8f464cd8e..d07a478a5 100644 --- a/src/temperaturesensor.cpp +++ b/src/temperaturesensor.cpp @@ -302,31 +302,29 @@ bool TemperatureSensor::update(const std::string & id, const std::string & name, sensor.set_offset(offset); // store the new name and offset in our configuration - EMSESP::webCustomizationService.update( - [&](WebCustomization & settings) { - // look it up to see if it exists - bool found = false; - for (auto & SensorCustomization : settings.sensorCustomizations) { - if (SensorCustomization.id == id) { - SensorCustomization.name = name; - SensorCustomization.offset = offset; - found = true; - LOG_DEBUG("Customizing existing sensor ID %s", id.c_str()); - break; - } + EMSESP::webCustomizationService.update([&](WebCustomization & settings) { + // look it up to see if it exists + bool found = false; + for (auto & SensorCustomization : settings.sensorCustomizations) { + if (SensorCustomization.id == id) { + SensorCustomization.name = name; + SensorCustomization.offset = offset; + found = true; + LOG_DEBUG("Customizing existing sensor ID %s", id.c_str()); + break; } - if (!found) { - SensorCustomization newSensor = SensorCustomization(); - newSensor.id = id; - newSensor.name = name; - newSensor.offset = offset; - settings.sensorCustomizations.push_back(newSensor); - LOG_DEBUG("Adding new customization for sensor ID %s", id.c_str()); - } - sensor.ha_registered = false; // it's changed so we may need to recreate the HA config - return StateUpdateResult::CHANGED; - }, - "local"); + } + if (!found) { + SensorCustomization newSensor = SensorCustomization(); + newSensor.id = id; + newSensor.name = name; + newSensor.offset = offset; + settings.sensorCustomizations.push_back(newSensor); + LOG_DEBUG("Adding new customization for sensor ID %s", id.c_str()); + } + sensor.ha_registered = false; // it's changed so we may need to recreate the HA config + return StateUpdateResult::CHANGED; + }); return true; } } diff --git a/src/web/WebCustomEntityService.cpp b/src/web/WebCustomEntityService.cpp index 0a3019f7c..998faa611 100644 --- a/src/web/WebCustomEntityService.cpp +++ b/src/web/WebCustomEntityService.cpp @@ -628,52 +628,50 @@ bool WebCustomEntityService::get_value(std::shared_ptr telegram) // hard coded tests #ifdef EMSESP_TEST void WebCustomEntityService::test() { - update( - [&](WebCustomEntity & webCustomEntity) { - webCustomEntity.customEntityItems.clear(); - // test 1 - auto entityItem = CustomEntityItem(); - entityItem.ram = 0; - entityItem.device_id = 8; - entityItem.type_id = 24; - entityItem.offset = 0; - entityItem.factor = 1; - entityItem.name = "test_custom"; - entityItem.uom = 1; - entityItem.value_type = 1; - entityItem.writeable = true; - entityItem.data = "70"; - webCustomEntity.customEntityItems.push_back(entityItem); + update([&](WebCustomEntity & webCustomEntity) { + webCustomEntity.customEntityItems.clear(); + // test 1 + auto entityItem = CustomEntityItem(); + entityItem.ram = 0; + entityItem.device_id = 8; + entityItem.type_id = 24; + entityItem.offset = 0; + entityItem.factor = 1; + entityItem.name = "test_custom"; + entityItem.uom = 1; + entityItem.value_type = 1; + entityItem.writeable = true; + entityItem.data = "70"; + webCustomEntity.customEntityItems.push_back(entityItem); - // test 2 - entityItem.ram = 0; - entityItem.device_id = 24; - entityItem.type_id = 677; - entityItem.offset = 3; - entityItem.factor = 1; - entityItem.name = "test_read_only"; - entityItem.uom = 0; - entityItem.value_type = 2; - entityItem.writeable = false; - entityItem.data = "48"; - webCustomEntity.customEntityItems.push_back(entityItem); + // test 2 + entityItem.ram = 0; + entityItem.device_id = 24; + entityItem.type_id = 677; + entityItem.offset = 3; + entityItem.factor = 1; + entityItem.name = "test_read_only"; + entityItem.uom = 0; + entityItem.value_type = 2; + entityItem.writeable = false; + entityItem.data = "48"; + webCustomEntity.customEntityItems.push_back(entityItem); - // test 2 - entityItem.ram = 1; - entityItem.device_id = 0; - entityItem.type_id = 0; - entityItem.offset = 0; - entityItem.factor = 1; - entityItem.name = "test_ram"; - entityItem.uom = 0; - entityItem.value_type = 8; - entityItem.writeable = true; - entityItem.data = "14"; - webCustomEntity.customEntityItems.push_back(entityItem); + // test 2 + entityItem.ram = 1; + entityItem.device_id = 0; + entityItem.type_id = 0; + entityItem.offset = 0; + entityItem.factor = 1; + entityItem.name = "test_ram"; + entityItem.uom = 0; + entityItem.value_type = 8; + entityItem.writeable = true; + entityItem.data = "14"; + webCustomEntity.customEntityItems.push_back(entityItem); - return StateUpdateResult::CHANGED; // persist the changes - }, - "local"); + return StateUpdateResult::CHANGED; // persist the changes + }); } #endif diff --git a/src/web/WebCustomizationService.cpp b/src/web/WebCustomizationService.cpp index 5e96f1ba2..62b8839bf 100644 --- a/src/web/WebCustomizationService.cpp +++ b/src/web/WebCustomizationService.cpp @@ -276,30 +276,28 @@ void WebCustomizationService::customization_entities(AsyncWebServerRequest * req emsdevice->getCustomizationEntities(entity_ids); // Save the list to the customization file - update( - [&](WebCustomization & settings) { - // see if we already have a mask list for this device, if so remove it - for (auto it = settings.entityCustomizations.begin(); it != settings.entityCustomizations.end();) { - if ((*it).product_id == product_id && (*it).device_id == device_id) { - it = settings.entityCustomizations.erase(it); - break; - } else { - ++it; - } + update([&](WebCustomization & settings) { + // see if we already have a mask list for this device, if so remove it + for (auto it = settings.entityCustomizations.begin(); it != settings.entityCustomizations.end();) { + if ((*it).product_id == product_id && (*it).device_id == device_id) { + it = settings.entityCustomizations.erase(it); + break; + } else { + ++it; } + } - // create a new entry for this device if there are values - EntityCustomization new_entry; - new_entry.product_id = product_id; - new_entry.device_id = device_id; + // create a new entry for this device if there are values + EntityCustomization new_entry; + new_entry.product_id = product_id; + new_entry.device_id = device_id; - new_entry.entity_ids = entity_ids; + new_entry.entity_ids = entity_ids; - // add the record and save - settings.entityCustomizations.push_back(new_entry); - return StateUpdateResult::CHANGED; - }, - "local"); + // add the record and save + settings.entityCustomizations.push_back(new_entry); + return StateUpdateResult::CHANGED; + }); break; } @@ -320,54 +318,52 @@ void WebCustomizationService::begin() { // hard coded tests #ifdef EMSESP_TEST void WebCustomizationService::test() { - update( - [&](WebCustomization & webCustomization) { - // Temperature sensors - webCustomization.sensorCustomizations.clear(); - auto sensor = SensorCustomization(); - sensor.id = "01-0203-0405-0607"; - sensor.name = "test_sensor1"; - sensor.offset = 0; - webCustomization.sensorCustomizations.push_back(sensor); + update([&](WebCustomization & webCustomization) { + // Temperature sensors + webCustomization.sensorCustomizations.clear(); + auto sensor = SensorCustomization(); + sensor.id = "01-0203-0405-0607"; + sensor.name = "test_sensor1"; + sensor.offset = 0; + webCustomization.sensorCustomizations.push_back(sensor); - sensor = SensorCustomization(); - sensor.id = "0B-0C0D-0E0F-1011"; - sensor.name = "test_sensor2"; - sensor.offset = 4; - webCustomization.sensorCustomizations.push_back(sensor); + sensor = SensorCustomization(); + sensor.id = "0B-0C0D-0E0F-1011"; + sensor.name = "test_sensor2"; + sensor.offset = 4; + webCustomization.sensorCustomizations.push_back(sensor); - // Analog sensors - // This actually adds the sensors as we use customizations to store them - webCustomization.analogCustomizations.clear(); - auto analog = AnalogCustomization(); - analog.gpio = 36; - analog.name = "test_analog1"; - analog.offset = 0; - analog.factor = 0.1; - analog.uom = 17; - analog.type = 3; - webCustomization.analogCustomizations.push_back(analog); + // Analog sensors + // This actually adds the sensors as we use customizations to store them + webCustomization.analogCustomizations.clear(); + auto analog = AnalogCustomization(); + analog.gpio = 36; + analog.name = "test_analog1"; + analog.offset = 0; + analog.factor = 0.1; + analog.uom = 17; + analog.type = 3; + webCustomization.analogCustomizations.push_back(analog); - analog = AnalogCustomization(); - analog.gpio = 37; - analog.name = "test_analog2"; - analog.offset = 0; - analog.factor = 1; - analog.uom = 0; - analog.type = 1; - webCustomization.analogCustomizations.push_back(analog); + analog = AnalogCustomization(); + analog.gpio = 37; + analog.name = "test_analog2"; + analog.offset = 0; + analog.factor = 1; + analog.uom = 0; + analog.type = 1; + webCustomization.analogCustomizations.push_back(analog); - // EMS entities - webCustomization.entityCustomizations.clear(); - auto emsEntity = EntityCustomization(); - emsEntity.product_id = 123; - emsEntity.device_id = 8; - emsEntity.entity_ids.push_back("08heatingactive|is my heating on?"); - webCustomization.entityCustomizations.push_back(emsEntity); + // EMS entities + webCustomization.entityCustomizations.clear(); + auto emsEntity = EntityCustomization(); + emsEntity.product_id = 123; + emsEntity.device_id = 8; + emsEntity.entity_ids.push_back("08heatingactive|is my heating on?"); + webCustomization.entityCustomizations.push_back(emsEntity); - return StateUpdateResult::CHANGED; // persist the changes - }, - "local"); + return StateUpdateResult::CHANGED; // persist the changes + }); EMSESP::analogsensor_.reload(); // this is needed to active the analog sensors } diff --git a/src/web/WebLogService.cpp b/src/web/WebLogService.cpp index 703b2d9a3..0558f1a26 100644 --- a/src/web/WebLogService.cpp +++ b/src/web/WebLogService.cpp @@ -59,12 +59,10 @@ uuid::log::Level WebLogService::log_level() const { } void WebLogService::log_level(uuid::log::Level level) { - EMSESP::webSettingsService.update( - [&](WebSettings & settings) { - settings.weblog_level = level; - return StateUpdateResult::CHANGED; - }, - "local"); + EMSESP::webSettingsService.update([&](WebSettings & settings) { + settings.weblog_level = level; + return StateUpdateResult::CHANGED; + }); uuid::log::Logger::register_handler(this, level); if (level == uuid::log::Level::OFF) { log_messages_.clear(); @@ -87,12 +85,10 @@ void WebLogService::maximum_log_messages(size_t count) { while (log_messages_.size() > maximum_log_messages_) { log_messages_.pop_front(); } - EMSESP::webSettingsService.update( - [&](WebSettings & settings) { - settings.weblog_buffer = count; - return StateUpdateResult::CHANGED; - }, - "local"); + EMSESP::webSettingsService.update([&](WebSettings & settings) { + settings.weblog_buffer = count; + return StateUpdateResult::CHANGED; + }); } bool WebLogService::compact() const { @@ -101,12 +97,10 @@ bool WebLogService::compact() const { void WebLogService::compact(bool compact) { compact_ = compact; - EMSESP::webSettingsService.update( - [&](WebSettings & settings) { - settings.weblog_compact = compact; - return StateUpdateResult::CHANGED; - }, - "local"); + EMSESP::webSettingsService.update([&](WebSettings & settings) { + settings.weblog_compact = compact; + return StateUpdateResult::CHANGED; + }); } WebLogService::QueuedLogMessage::QueuedLogMessage(unsigned long id, std::shared_ptr && content) diff --git a/src/web/WebSchedulerService.cpp b/src/web/WebSchedulerService.cpp index f06361559..a5d3e527b 100644 --- a/src/web/WebSchedulerService.cpp +++ b/src/web/WebSchedulerService.cpp @@ -432,25 +432,23 @@ void WebSchedulerService::loop() { // hard coded tests #if defined(EMSESP_TEST) void WebSchedulerService::test() { - update( - [&](WebScheduler & webScheduler) { - webScheduler.scheduleItems.clear(); - // test 1 - auto si = ScheduleItem(); - si.active = true; - si.flags = 1; - si.time = "12:00"; - si.cmd = "system/fetch"; - si.value = "10"; - si.name = "test_scheduler"; - si.elapsed_min = 0; - si.retry_cnt = 0xFF; // no startup retries + update([&](WebScheduler & webScheduler) { + webScheduler.scheduleItems.clear(); + // test 1 + auto si = ScheduleItem(); + si.active = true; + si.flags = 1; + si.time = "12:00"; + si.cmd = "system/fetch"; + si.value = "10"; + si.name = "test_scheduler"; + si.elapsed_min = 0; + si.retry_cnt = 0xFF; // no startup retries - webScheduler.scheduleItems.push_back(si); + webScheduler.scheduleItems.push_back(si); - return StateUpdateResult::CHANGED; // persist the changes - }, - "local"); + return StateUpdateResult::CHANGED; // persist the changes + }); } #endif diff --git a/src/web/WebSettingsService.cpp b/src/web/WebSettingsService.cpp index 436f5d23e..04ce8f8eb 100644 --- a/src/web/WebSettingsService.cpp +++ b/src/web/WebSettingsService.cpp @@ -32,7 +32,7 @@ WebSettingsService::WebSettingsService(AsyncWebServer * server, FS * fs, Securit HTTP_GET, securityManager->wrapRequest(std::bind(&WebSettingsService::board_profile, this, _1), AuthenticationPredicates::IS_ADMIN)); - addUpdateHandler([&](const String & originId) { onUpdate(); }, false); + addUpdateHandler([&] { onUpdate(); }, false); } void WebSettings::read(WebSettings & settings, JsonObject root) { From df1109ea39237fe6b564c58d8e8d6c73dc059b94 Mon Sep 17 00:00:00 2001 From: Proddy Date: Mon, 12 Feb 2024 11:22:21 +0100 Subject: [PATCH 22/54] remove wifi_tweak --- pio_local.ini_example | 1 - src/system.h | 1 - 2 files changed, 2 deletions(-) diff --git a/pio_local.ini_example b/pio_local.ini_example index 9e25f8543..451ef3d5d 100644 --- a/pio_local.ini_example +++ b/pio_local.ini_example @@ -2,7 +2,6 @@ [common] ; custom build flags to use in my_build_flags -; -DEMSESP_WIFI_TWEAK ; experimental WiFi tweaks for stability ; -DEMSESP_UART_DEBUG ; debugging UART ; -DEMSESP_DEBUG ; enables DEBUG to the log. Will generate a lot of extra traffic on Console and Syslog ; -DEMSESP_DEFAULT_BOARD_PROFILE=\"NODEMCU\" ; hard code the default board name diff --git a/src/system.h b/src/system.h index ccff2ae71..b7dea5c9a 100644 --- a/src/system.h +++ b/src/system.h @@ -75,7 +75,6 @@ class System { bool upload_status(); void show_mem(const char * note); void reload_settings(); - void wifi_tweak(); void syslog_init(); bool check_upgrade(bool factory_settings); bool check_restore(); From ed5f0bc6d54d9a9a2325dc00ad08dd4675f74b55 Mon Sep 17 00:00:00 2001 From: Proddy Date: Mon, 12 Feb 2024 11:22:56 +0100 Subject: [PATCH 23/54] start logging service sooner so weblog captures setup like network, mqtt etc --- src/emsesp.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/emsesp.cpp b/src/emsesp.cpp index 646eb61a6..08271d021 100644 --- a/src/emsesp.cpp +++ b/src/emsesp.cpp @@ -1484,8 +1484,10 @@ void EMSESP::start() { bool factory_settings = false; #endif - esp8266React.begin(); // loads core system services settings (network, mqtt, ap, ntp etc) webLogService.begin(); // start web log service. now we can start capturing logs to the web log + + esp8266React.begin(); // loads core system services settings (network, mqtt, ap, ntp etc) + nvs_.begin("ems-esp", false, "nvs"); LOG_INFO("Starting EMS-ESP version %s", EMSESP_APP_VERSION); // welcome message From 80a3007f8b75db4e80d822624198d9990c678f03 Mon Sep 17 00:00:00 2001 From: Proddy Date: Mon, 12 Feb 2024 14:21:30 +0100 Subject: [PATCH 24/54] refactoring --- lib/framework/APSettingsService.cpp | 23 +++-- lib/framework/APSettingsService.h | 8 +- lib/framework/APStatus.cpp | 10 +- lib/framework/APStatus.h | 5 +- lib/framework/ArduinoJsonJWT.cpp | 113 ++++++++++++---------- lib/framework/ArduinoJsonJWT.h | 29 +++--- lib/framework/AuthenticationService.cpp | 16 ++- lib/framework/AuthenticationService.h | 5 +- lib/framework/ESP8266React.cpp | 15 +-- lib/framework/ESP8266React.h | 35 ++++--- lib/framework/ESPUtils.h | 4 +- lib/framework/FSPersistence.h | 10 +- lib/framework/FactoryResetService.cpp | 10 +- lib/framework/FactoryResetService.h | 8 +- lib/framework/HttpEndpoint.h | 27 +++--- lib/framework/IPUtils.h | 14 ++- lib/framework/JsonUtils.h | 5 +- lib/framework/MqttSettingsService.cpp | 83 ++++++++++------ lib/framework/MqttSettingsService.h | 12 ++- lib/framework/MqttStatus.cpp | 10 +- lib/framework/MqttStatus.h | 5 +- lib/framework/NTPSettingsService.cpp | 29 +++--- lib/framework/NTPSettingsService.h | 8 +- lib/framework/NTPStatus.cpp | 30 ++++-- lib/framework/NTPStatus.h | 8 +- lib/framework/NetworkSettingsService.cpp | 50 +++++----- lib/framework/NetworkSettingsService.h | 10 +- lib/framework/NetworkStatus.cpp | 12 +-- lib/framework/NetworkStatus.h | 4 +- lib/framework/OTASettingsService.cpp | 12 +-- lib/framework/OTASettingsService.h | 6 +- lib/framework/RestartService.cpp | 21 ++-- lib/framework/RestartService.h | 10 +- lib/framework/SecurityManager.h | 35 +++---- lib/framework/SecuritySettingsService.cpp | 63 +++--------- lib/framework/SecuritySettingsService.h | 56 ++++++++--- lib/framework/StatefulService.cpp | 2 +- lib/framework/SystemStatus.cpp | 15 ++- lib/framework/SystemStatus.h | 4 +- lib/framework/UploadFileService.cpp | 101 ++++++++++--------- lib/framework/UploadFileService.h | 27 +++--- lib/framework/WiFiScanner.cpp | 20 ++-- lib/framework/WiFiScanner.h | 4 +- lib_standalone/StatefulService.h | 4 +- src/emsesp.h | 3 +- src/emsesp_stub.hpp | 3 +- src/telegram.h | 5 +- src/version.h | 2 +- src/web/WebAPIService.cpp | 23 +++-- src/web/WebCustomEntityService.cpp | 2 - src/web/WebCustomizationService.cpp | 11 +-- src/web/WebDataService.cpp | 21 ++-- src/web/WebLogService.cpp | 9 +- src/web/WebSchedulerService.cpp | 2 - src/web/WebSettingsService.cpp | 8 +- src/web/WebStatusService.cpp | 4 +- 56 files changed, 555 insertions(+), 516 deletions(-) diff --git a/lib/framework/APSettingsService.cpp b/lib/framework/APSettingsService.cpp index 658570880..cff6d3818 100644 --- a/lib/framework/APSettingsService.cpp +++ b/lib/framework/APSettingsService.cpp @@ -1,4 +1,4 @@ -#include +#include "APSettingsService.h" #include "../../src/emsesp_stub.hpp" @@ -9,8 +9,8 @@ APSettingsService::APSettingsService(AsyncWebServer * server, FS * fs, SecurityM , _lastManaged(0) , _reconfigureAp(false) , _connected(0) { - addUpdateHandler([&](const String & originId) { reconfigureAP(); }, false); - WiFi.onEvent(std::bind(&APSettingsService::WiFiEvent, this, _1)); + addUpdateHandler([this] { reconfigureAP(); }, false); + WiFi.onEvent([this](WiFiEvent_t event, WiFiEventInfo_t info) { WiFiEvent(event); }); } void APSettingsService::begin() { @@ -53,7 +53,7 @@ void APSettingsService::reconfigureAP() { void APSettingsService::loop() { unsigned long currentMillis = uuid::get_uptime(); - unsigned long manageElapsed = (uint32_t)(currentMillis - _lastManaged); + unsigned long manageElapsed = static_cast(currentMillis - _lastManaged); if (manageElapsed >= MANAGE_NETWORK_DELAY) { _lastManaged = currentMillis; manageAP(); @@ -76,7 +76,7 @@ void APSettingsService::manageAP() { void APSettingsService::startAP() { WiFi.softAPConfig(_state.localIP, _state.gatewayIP, _state.subnetMask); - esp_wifi_set_bandwidth((wifi_interface_t)ESP_IF_WIFI_AP, WIFI_BW_HT20); + esp_wifi_set_bandwidth(static_cast(ESP_IF_WIFI_AP), WIFI_BW_HT20); WiFi.softAP(_state.ssid.c_str(), _state.password.c_str(), _state.channel, _state.ssidHidden, _state.maxClients); #if CONFIG_IDF_TARGET_ESP32C3 WiFi.setTxPower(WIFI_POWER_8_5dBm); // https://www.wemos.cc/en/latest/c3/c3_mini_1_0_0.html#about-wifi @@ -108,14 +108,16 @@ void APSettingsService::handleDNS() { APNetworkStatus APSettingsService::getAPNetworkStatus() { WiFiMode_t currentWiFiMode = WiFi.getMode(); bool apActive = currentWiFiMode == WIFI_AP || currentWiFiMode == WIFI_AP_STA; + if (apActive && _state.provisionMode != AP_MODE_ALWAYS && WiFi.status() == WL_CONNECTED) { return APNetworkStatus::LINGERING; } + return apActive ? APNetworkStatus::ACTIVE : APNetworkStatus::INACTIVE; } -void APSettings::read(APSettings & settings, JsonObject root) { +void APSettings::read(const APSettings & settings, JsonObject root) { root["provision_mode"] = settings.provisionMode; root["ssid"] = settings.ssid; root["password"] = settings.password; @@ -129,7 +131,8 @@ void APSettings::read(APSettings & settings, JsonObject root) { StateUpdateResult APSettings::update(JsonObject root, APSettings & settings) { APSettings newSettings = {}; - newSettings.provisionMode = root["provision_mode"] | FACTORY_AP_PROVISION_MODE; + newSettings.provisionMode = static_cast(root["provision_mode"] | FACTORY_AP_PROVISION_MODE); + switch (settings.provisionMode) { case AP_MODE_ALWAYS: case AP_MODE_DISCONNECTED: @@ -138,11 +141,12 @@ StateUpdateResult APSettings::update(JsonObject root, APSettings & settings) { default: newSettings.provisionMode = AP_MODE_ALWAYS; } + newSettings.ssid = root["ssid"] | FACTORY_AP_SSID; newSettings.password = root["password"] | FACTORY_AP_PASSWORD; - newSettings.channel = root["channel"] | FACTORY_AP_CHANNEL; + newSettings.channel = static_cast(root["channel"] | FACTORY_AP_CHANNEL); newSettings.ssidHidden = root["ssid_hidden"] | FACTORY_AP_SSID_HIDDEN; - newSettings.maxClients = root["max_clients"] | FACTORY_AP_MAX_CLIENTS; + newSettings.maxClients = static_cast(root["max_clients"] | FACTORY_AP_MAX_CLIENTS); JsonUtils::readIP(root, "local_ip", newSettings.localIP, FACTORY_AP_LOCAL_IP); JsonUtils::readIP(root, "gateway_ip", newSettings.gatewayIP, FACTORY_AP_GATEWAY_IP); @@ -151,6 +155,7 @@ StateUpdateResult APSettings::update(JsonObject root, APSettings & settings) { if (newSettings == settings) { return StateUpdateResult::UNCHANGED; } + settings = newSettings; return StateUpdateResult::CHANGED; } diff --git a/lib/framework/APSettingsService.h b/lib/framework/APSettingsService.h index 8857c4f99..3c76feeb5 100644 --- a/lib/framework/APSettingsService.h +++ b/lib/framework/APSettingsService.h @@ -1,9 +1,9 @@ #ifndef APSettingsConfig_h #define APSettingsConfig_h -#include -#include -#include +#include "HttpEndpoint.h" +#include "FSPersistence.h" +#include "JsonUtils.h" #include #include @@ -75,7 +75,7 @@ class APSettings { && subnetMask == settings.subnetMask; } - static void read(APSettings & settings, JsonObject root); + static void read(const APSettings & settings, JsonObject root); static StateUpdateResult update(JsonObject root, APSettings & settings); }; diff --git a/lib/framework/APStatus.cpp b/lib/framework/APStatus.cpp index d4595fefe..47ec3c8fa 100644 --- a/lib/framework/APStatus.cpp +++ b/lib/framework/APStatus.cpp @@ -1,17 +1,15 @@ -#include - -using namespace std::placeholders; // for `_1` etc +#include "APStatus.h" APStatus::APStatus(AsyncWebServer * server, SecurityManager * securityManager, APSettingsService * apSettingsService) : _apSettingsService(apSettingsService) { server->on(AP_STATUS_SERVICE_PATH, HTTP_GET, - securityManager->wrapRequest(std::bind(&APStatus::apStatus, this, _1), AuthenticationPredicates::IS_AUTHENTICATED)); + securityManager->wrapRequest([this](AsyncWebServerRequest * request) { apStatus(request); }, AuthenticationPredicates::IS_AUTHENTICATED)); } void APStatus::apStatus(AsyncWebServerRequest * request) { - AsyncJsonResponse * response = new AsyncJsonResponse(false); - JsonObject root = response->getRoot(); + auto * response = new AsyncJsonResponse(false); + JsonObject root = response->getRoot(); root["status"] = _apSettingsService->getAPNetworkStatus(); root["ip_address"] = WiFi.softAPIP().toString(); diff --git a/lib/framework/APStatus.h b/lib/framework/APStatus.h index addda2a25..23ee79305 100644 --- a/lib/framework/APStatus.h +++ b/lib/framework/APStatus.h @@ -7,8 +7,9 @@ #include #include #include -#include -#include + +#include "SecurityManager.h" +#include "APSettingsService.h" #define AP_STATUS_SERVICE_PATH "/rest/apStatus" diff --git a/lib/framework/ArduinoJsonJWT.cpp b/lib/framework/ArduinoJsonJWT.cpp index 595166ec5..eb8dce2d0 100644 --- a/lib/framework/ArduinoJsonJWT.cpp +++ b/lib/framework/ArduinoJsonJWT.cpp @@ -1,47 +1,27 @@ #include "ArduinoJsonJWT.h" +#include + ArduinoJsonJWT::ArduinoJsonJWT(String secret) - : _secret(secret) { + : _secret(std::move(secret)) { } void ArduinoJsonJWT::setSecret(String secret) { - _secret = secret; + _secret = std::move(secret); } String ArduinoJsonJWT::getSecret() { return _secret; } -/* - * ESP32 uses mbedtls, ESP2866 uses bearssl. - * - * Both come with decent HMAC implementations supporting sha256, as well as others. - * - * No need to pull in additional crypto libraries - lets use what we already have. - */ -String ArduinoJsonJWT::sign(String & payload) { - unsigned char hmacResult[32]; - { - mbedtls_md_context_t ctx; - mbedtls_md_type_t md_type = MBEDTLS_MD_SHA256; - mbedtls_md_init(&ctx); - mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(md_type), 1); - mbedtls_md_hmac_starts(&ctx, (unsigned char *)_secret.c_str(), _secret.length()); - mbedtls_md_hmac_update(&ctx, (unsigned char *)payload.c_str(), payload.length()); - mbedtls_md_hmac_finish(&ctx, hmacResult); - mbedtls_md_free(&ctx); - } - return encode((char *)hmacResult, 32); -} - String ArduinoJsonJWT::buildJWT(JsonObject payload) { // serialize, then encode payload String jwt; serializeJson(payload, jwt); - jwt = encode(jwt.c_str(), jwt.length()); + jwt = encode(jwt.c_str(), static_cast(jwt.length())); // add the header to payload - jwt = JWT_HEADER + '.' + jwt; + jwt = getJWTHeader() + '.' + jwt; // add signature jwt += '.' + sign(jwt); @@ -53,65 +33,88 @@ void ArduinoJsonJWT::parseJWT(String jwt, JsonDocument & jsonDocument) { // clear json document before we begin, jsonDocument wil be null on failure jsonDocument.clear(); + const String & jwt_header = getJWTHeader(); + const unsigned int jwt_header_size = jwt_header.length(); + // must have the correct header and delimiter - if (!jwt.startsWith(JWT_HEADER) || jwt.indexOf('.') != JWT_HEADER_SIZE) { + if (!jwt.startsWith(jwt_header) || jwt.indexOf('.') != static_cast(jwt_header_size)) { return; } // check there is a signature delimieter - int signatureDelimiterIndex = jwt.lastIndexOf('.'); - if (signatureDelimiterIndex == JWT_HEADER_SIZE) { + const int signatureDelimiterIndex = jwt.lastIndexOf('.'); + if (signatureDelimiterIndex == static_cast(jwt_header_size)) { return; } // check the signature is valid - String signature = jwt.substring(signatureDelimiterIndex + 1); - jwt = jwt.substring(0, signatureDelimiterIndex); + const String signature = jwt.substring(static_cast(signatureDelimiterIndex) + 1); + jwt = jwt.substring(0, static_cast(signatureDelimiterIndex)); if (sign(jwt) != signature) { return; } // decode payload - jwt = jwt.substring(JWT_HEADER_SIZE + 1); + jwt = jwt.substring(jwt_header_size + 1); jwt = decode(jwt); // parse payload, clearing json document after failure - DeserializationError error = deserializeJson(jsonDocument, jwt); + const DeserializationError error = deserializeJson(jsonDocument, jwt); if (error != DeserializationError::Ok || !jsonDocument.is()) { jsonDocument.clear(); } } +/* + * ESP32 uses mbedtls, ESP2866 uses bearssl. + * + * Both come with decent HMAC implementations supporting sha256, as well as others. + * + * No need to pull in additional crypto libraries - lets use what we already have. + */ +String ArduinoJsonJWT::sign(String & payload) { + std::array hmacResult{}; + { + mbedtls_md_context_t ctx; + mbedtls_md_type_t md_type = MBEDTLS_MD_SHA256; + mbedtls_md_init(&ctx); + mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(md_type), 1); + mbedtls_md_hmac_starts(&ctx, reinterpret_cast(_secret.c_str()), _secret.length()); + mbedtls_md_hmac_update(&ctx, reinterpret_cast(payload.c_str()), payload.length()); + mbedtls_md_hmac_finish(&ctx, hmacResult.data()); + mbedtls_md_free(&ctx); + } + return encode(reinterpret_cast(hmacResult.data()), hmacResult.size()); +} + String ArduinoJsonJWT::encode(const char * cstr, int inputLen) { // prepare encoder base64_encodestate _state; base64_init_encodestate(&_state); - size_t encodedLength = base64_encode_expected_len(inputLen) + 1; - // prepare buffer of correct length, returning an empty string on failure - char * buffer = (char *)malloc(encodedLength * sizeof(char)); - if (buffer == nullptr) { - return ""; - } + + // prepare buffer of correct length + const auto bufferLength = static_cast(base64_encode_expected_len(inputLen)) + 1; + auto * buffer = new char[bufferLength]; // encode to buffer int len = base64_encode_block(cstr, inputLen, &buffer[0], &_state); len += base64_encode_blockend(&buffer[len], &_state); - buffer[len] = 0; + buffer[len] = '\0'; // convert to arduino string, freeing buffer - String value = String(buffer); - free(buffer); + auto result = String(buffer); + delete[] buffer; buffer = nullptr; // remove padding and convert to URL safe form - while (value.length() > 0 && value.charAt(value.length() - 1) == '=') { - value.remove(value.length() - 1); + while (result.length() > 0 && result.charAt(result.length() - 1) == '=') { + result.remove(result.length() - 1); } - value.replace('+', '-'); - value.replace('/', '_'); + result.replace('+', '-'); + result.replace('/', '_'); // return as string - return value; + return result; } String ArduinoJsonJWT::decode(String value) { @@ -120,12 +123,18 @@ String ArduinoJsonJWT::decode(String value) { value.replace('_', '/'); // prepare buffer of correct length - char buffer[base64_decode_expected_len(value.length()) + 1]; + const auto bufferLength = static_cast(base64_decode_expected_len(value.length()) + 1); + auto * buffer = new char[bufferLength]; // decode - int len = base64_decode_chars(value.c_str(), value.length(), &buffer[0]); - buffer[len] = 0; + const int len = base64_decode_chars(value.c_str(), static_cast(value.length()), &buffer[0]); + buffer[len] = '\0'; + + // convert to arduino string, freeing buffer + auto result = String(buffer); + delete[] buffer; + buffer = nullptr; // return as string - return String(buffer); -} + return result; +} \ No newline at end of file diff --git a/lib/framework/ArduinoJsonJWT.h b/lib/framework/ArduinoJsonJWT.h index cd13d5fa4..dc9a28da6 100644 --- a/lib/framework/ArduinoJsonJWT.h +++ b/lib/framework/ArduinoJsonJWT.h @@ -3,30 +3,33 @@ #include #include + #include #include #include class ArduinoJsonJWT { - private: - String _secret; - - const String JWT_HEADER = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9"; - const int JWT_HEADER_SIZE = JWT_HEADER.length(); - - String sign(String & value); - - static String encode(const char * cstr, int len); - static String decode(String value); - public: - ArduinoJsonJWT(String secret); + explicit ArduinoJsonJWT(String secret); void setSecret(String secret); String getSecret(); String buildJWT(JsonObject payload); void parseJWT(String jwt, JsonDocument & jsonDocument); + + private: + String _secret; + + String sign(String & value); + + static String encode(const char * cstr, int len); + static String decode(String value); + + static const String & getJWTHeader() { + static const String JWT_HEADER = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9"; + return JWT_HEADER; + } }; -#endif +#endif \ No newline at end of file diff --git a/lib/framework/AuthenticationService.cpp b/lib/framework/AuthenticationService.cpp index f0fc92dbb..241e912c9 100644 --- a/lib/framework/AuthenticationService.cpp +++ b/lib/framework/AuthenticationService.cpp @@ -1,11 +1,9 @@ -#include - -using namespace std::placeholders; // for `_1` etc +#include "AuthenticationService.h" AuthenticationService::AuthenticationService(AsyncWebServer * server, SecurityManager * securityManager) : _securityManager(securityManager) - , _signInHandler(SIGN_IN_PATH, std::bind(&AuthenticationService::signIn, this, _1, _2)) { - server->on(VERIFY_AUTHORIZATION_PATH, HTTP_GET, std::bind(&AuthenticationService::verifyAuthorization, this, _1)); + , _signInHandler(SIGN_IN_PATH, [this](AsyncWebServerRequest * request, JsonVariant json) { signIn(request, json); }) { + server->on(VERIFY_AUTHORIZATION_PATH, HTTP_GET, [this](AsyncWebServerRequest * request) { verifyAuthorization(request); }); _signInHandler.setMethod(HTTP_POST); _signInHandler.setMaxContentLength(MAX_AUTHENTICATION_SIZE); server->addHandler(&_signInHandler); @@ -29,10 +27,10 @@ void AuthenticationService::signIn(AsyncWebServerRequest * request, JsonVariant String password = json["password"]; Authentication authentication = _securityManager->authenticate(username, password); if (authentication.authenticated) { - User * user = authentication.user; - AsyncJsonResponse * response = new AsyncJsonResponse(false); - JsonObject jsonObject = response->getRoot(); - jsonObject["access_token"] = _securityManager->generateJWT(user); + User * user = authentication.user; + auto * response = new AsyncJsonResponse(false); + JsonObject jsonObject = response->getRoot(); + jsonObject["access_token"] = _securityManager->generateJWT(user); response->setLength(); request->send(response); return; diff --git a/lib/framework/AuthenticationService.h b/lib/framework/AuthenticationService.h index c7ca70646..b4b7eac23 100644 --- a/lib/framework/AuthenticationService.h +++ b/lib/framework/AuthenticationService.h @@ -1,9 +1,10 @@ #ifndef AuthenticationService_H_ #define AuthenticationService_H_ -#include +#include "Features.h" +#include "SecurityManager.h" + #include -#include #define VERIFY_AUTHORIZATION_PATH "/rest/verifyAuthorization" #define SIGN_IN_PATH "/rest/signIn" diff --git a/lib/framework/ESP8266React.cpp b/lib/framework/ESP8266React.cpp index 20e936a0c..d81fe7b83 100644 --- a/lib/framework/ESP8266React.cpp +++ b/lib/framework/ESP8266React.cpp @@ -1,6 +1,6 @@ -#include +#include "ESP8266React.h" -#include +#include "WWWData.h" ESP8266React::ESP8266React(AsyncWebServer * server, FS * fs) : _securitySettingsService(server, fs) @@ -27,7 +27,7 @@ ESP8266React::ESP8266React(AsyncWebServer * server, FS * fs) static char last_modified[50]; sprintf(last_modified, "%s %s CET", __DATE__, __TIME__); - WWWData::registerRoutes([server, this](const String & uri, const String & contentType, const uint8_t * content, size_t len, const String & hash) { + WWWData::registerRoutes([server](const String & uri, const String & contentType, const uint8_t * content, size_t len, const String & hash) { ArRequestHandlerFunction requestHandler = [contentType, content, len, hash](AsyncWebServerRequest * request) { // Check if the client already has the same version and respond with a 304 (Not modified) if (request->header("If-Modified-Since").indexOf(last_modified) > 0) { @@ -66,12 +66,13 @@ ESP8266React::ESP8266React(AsyncWebServer * server, FS * fs) void ESP8266React::begin() { _networkSettingsService.begin(); _networkSettingsService.read([&](NetworkSettings & networkSettings) { + DefaultHeaders & defaultHeaders = DefaultHeaders::Instance(); if (networkSettings.enableCORS) { - DefaultHeaders::Instance().addHeader("Access-Control-Allow-Origin", networkSettings.CORSOrigin); - DefaultHeaders::Instance().addHeader("Access-Control-Allow-Headers", "Accept, Content-Type, Authorization"); - DefaultHeaders::Instance().addHeader("Access-Control-Allow-Credentials", "true"); + defaultHeaders.addHeader("Access-Control-Allow-Origin", networkSettings.CORSOrigin); + defaultHeaders.addHeader("Access-Control-Allow-Headers", "Accept, Content-Type, Authorization"); + defaultHeaders.addHeader("Access-Control-Allow-Credentials", "true"); } - DefaultHeaders::Instance().addHeader("Server", networkSettings.hostname); + defaultHeaders.addHeader("Server", networkSettings.hostname); }); _apSettingsService.begin(); _ntpSettingsService.begin(); diff --git a/lib/framework/ESP8266React.h b/lib/framework/ESP8266React.h index 2a86019e1..589369f33 100644 --- a/lib/framework/ESP8266React.h +++ b/lib/framework/ESP8266React.h @@ -1,28 +1,27 @@ #ifndef ESP8266React_h #define ESP8266React_h -#include +#include "APSettingsService.h" +#include "APStatus.h" +#include "AuthenticationService.h" +#include "FactoryResetService.h" +#include "MqttSettingsService.h" +#include "MqttStatus.h" +#include "NTPSettingsService.h" +#include "NTPStatus.h" +#include "OTASettingsService.h" +#include "UploadFileService.h" +#include "RestartService.h" +#include "SecuritySettingsService.h" +#include "SystemStatus.h" +#include "WiFiScanner.h" +#include "NetworkSettingsService.h" +#include "NetworkStatus.h" +#include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - class ESP8266React { public: ESP8266React(AsyncWebServer * server, FS * fs); diff --git a/lib/framework/ESPUtils.h b/lib/framework/ESPUtils.h index 0c5861628..490514f45 100644 --- a/lib/framework/ESPUtils.h +++ b/lib/framework/ESPUtils.h @@ -5,8 +5,8 @@ class ESPUtils { public: - static String defaultDeviceValue(String prefix = "") { - return prefix + String((uint32_t)ESP.getEfuseMac(), HEX); + static String defaultDeviceValue(const String & prefix = "") { + return prefix + String(static_cast(ESP.getEfuseMac()), HEX); } }; diff --git a/lib/framework/FSPersistence.h b/lib/framework/FSPersistence.h index 5a7639c13..ff2205aeb 100644 --- a/lib/framework/FSPersistence.h +++ b/lib/framework/FSPersistence.h @@ -1,8 +1,8 @@ #ifndef FSPersistence_h #define FSPersistence_h -#include -#include +#include "StatefulService.h" +#include "FS.h" template class FSPersistence { @@ -47,8 +47,8 @@ class FSPersistence { // make directories if required, for new IDF4.2 & LittleFS String path(_filePath); int index = 0; - while ((index = path.indexOf('/', index + 1)) != -1) { - String segment = path.substring(0, index); + while ((index = path.indexOf('/', static_cast(index) + 1)) != -1) { + String segment = path.substring(0, static_cast(index)); if (!_fs->exists(segment)) { _fs->mkdir(segment); } @@ -80,7 +80,7 @@ class FSPersistence { void enableUpdateHandler() { if (!_updateHandlerId) { - _updateHandlerId = _statefulService->addUpdateHandler([&] { writeToFS(); }); + _updateHandlerId = _statefulService->addUpdateHandler([this] { writeToFS(); }); } } diff --git a/lib/framework/FactoryResetService.cpp b/lib/framework/FactoryResetService.cpp index 6bb631b02..c7f4ee0d1 100644 --- a/lib/framework/FactoryResetService.cpp +++ b/lib/framework/FactoryResetService.cpp @@ -1,16 +1,14 @@ -#include - -using namespace std::placeholders; +#include "FactoryResetService.h" FactoryResetService::FactoryResetService(AsyncWebServer * server, FS * fs, SecurityManager * securityManager) : fs(fs) { server->on(FACTORY_RESET_SERVICE_PATH, HTTP_POST, - securityManager->wrapRequest(std::bind(&FactoryResetService::handleRequest, this, _1), AuthenticationPredicates::IS_ADMIN)); + securityManager->wrapRequest([this](AsyncWebServerRequest * request) { handleRequest(request); }, AuthenticationPredicates::IS_ADMIN)); } void FactoryResetService::handleRequest(AsyncWebServerRequest * request) { - request->onDisconnect(std::bind(&FactoryResetService::factoryReset, this)); + request->onDisconnect([this]() { factoryReset(); }); request->send(200); } @@ -21,7 +19,7 @@ void FactoryResetService::factoryReset() { // TODO To replaced with fs.rmdir(FS_CONFIG_DIRECTORY) now we're using IDF 4.2 File root = fs->open(FS_CONFIG_DIRECTORY); File file; - while (file = root.openNextFile()) { + while ((file = root.openNextFile())) { String path = file.path(); file.close(); fs->remove(path); diff --git a/lib/framework/FactoryResetService.h b/lib/framework/FactoryResetService.h index a6a4bee12..2a53c3122 100644 --- a/lib/framework/FactoryResetService.h +++ b/lib/framework/FactoryResetService.h @@ -3,22 +3,22 @@ #include #include -#include -#include #include +#include "SecurityManager.h" +#include "RestartService.h" + #define FS_CONFIG_DIRECTORY "/config" #define FACTORY_RESET_SERVICE_PATH "/rest/factoryReset" class FactoryResetService { - FS * fs; - public: FactoryResetService(AsyncWebServer * server, FS * fs, SecurityManager * securityManager); void factoryReset(); private: + FS * fs; void handleRequest(AsyncWebServerRequest * request); }; diff --git a/lib/framework/HttpEndpoint.h b/lib/framework/HttpEndpoint.h index a8dac9119..db33394b0 100644 --- a/lib/framework/HttpEndpoint.h +++ b/lib/framework/HttpEndpoint.h @@ -2,15 +2,13 @@ #define HttpEndpoint_h #include - #include -#include -#include +#include "SecurityManager.h" +#include "StatefulService.h" #define HTTP_ENDPOINT_ORIGIN_ID "http" - -using namespace std::placeholders; // for `_1` etc +#define HTTPS_ENDPOINT_ORIGIN_ID "https" template class HttpEndpoint { @@ -19,8 +17,7 @@ class HttpEndpoint { JsonStateUpdater _stateUpdater; StatefulService * _statefulService; - AsyncCallbackWebHandler * GEThandler; - AsyncCallbackJsonWebHandler * POSThandler; + AsyncCallbackJsonWebHandler * handler; public: HttpEndpoint(JsonStateReader stateReader, @@ -33,12 +30,12 @@ class HttpEndpoint { : _stateReader(stateReader) , _stateUpdater(stateUpdater) , _statefulService(statefulService) { - // Create the GET and POST endpoints - POSThandler = new AsyncCallbackJsonWebHandler(servicePath, - securityManager->wrapCallback([this](AsyncWebServerRequest * request, - JsonVariant json) { handleRequest(request, json); }, - authenticationPredicate)); - server->addHandler(POSThandler); + // Create hander for both GET and POST endpoints + handler = new AsyncCallbackJsonWebHandler(servicePath, + securityManager->wrapCallback([this](AsyncWebServerRequest * request, + JsonVariant json) { handleRequest(request, json); }, + authenticationPredicate)); + server->addHandler(handler); } protected: @@ -66,8 +63,8 @@ class HttpEndpoint { } } - AsyncJsonResponse * response = new AsyncJsonResponse(false); - JsonObject jsonObject = response->getRoot().to(); + auto * response = new AsyncJsonResponse(false); + JsonObject jsonObject = response->getRoot().to(); _statefulService->read(jsonObject, _stateReader); response->setLength(); request->send(response); diff --git a/lib/framework/IPUtils.h b/lib/framework/IPUtils.h index 5c211d6c0..528c36494 100644 --- a/lib/framework/IPUtils.h +++ b/lib/framework/IPUtils.h @@ -3,16 +3,20 @@ #include -const IPAddress IP_NOT_SET = IPAddress(INADDR_NONE); - class IPUtils { public: static bool isSet(const IPAddress & ip) { - return ip != IP_NOT_SET; + return ip != getNotSetIP(); } static bool isNotSet(const IPAddress & ip) { - return ip == IP_NOT_SET; + return ip == getNotSetIP(); + } + + private: + static const IPAddress & getNotSetIP() { + static const IPAddress IP_NOT_SET = IPAddress(INADDR_NONE); + return IP_NOT_SET; } }; -#endif +#endif \ No newline at end of file diff --git a/lib/framework/JsonUtils.h b/lib/framework/JsonUtils.h index 29a72bd6a..0d2ff9fa5 100644 --- a/lib/framework/JsonUtils.h +++ b/lib/framework/JsonUtils.h @@ -2,9 +2,10 @@ #define JsonUtils_h #include -#include -#include #include +#include + +#include "IPUtils.h" class JsonUtils { public: diff --git a/lib/framework/MqttSettingsService.cpp b/lib/framework/MqttSettingsService.cpp index 3e69c1b92..d8f98d9b3 100644 --- a/lib/framework/MqttSettingsService.cpp +++ b/lib/framework/MqttSettingsService.cpp @@ -1,22 +1,23 @@ -#include - +#include "MqttSettingsService.h" #include "../../src/emsesp_stub.hpp" -using namespace std::placeholders; // for `_1` etc - /** * Retains a copy of the cstr provided in the pointer provided using dynamic allocation. * * Frees the pointer before allocation and leaves it as nullptr if cstr == nullptr. */ static char * retainCstr(const char * cstr, char ** ptr) { + if (ptr == nullptr || *ptr == nullptr) { + return nullptr; + } + // free up previously retained value if exists - free(*ptr); + delete[] *ptr; *ptr = nullptr; // dynamically allocate and copy cstr (if non null) if (cstr != nullptr) { - *ptr = (char *)malloc(strlen(cstr) + 1); + *ptr = new char[strlen(cstr) + 1]; strcpy(*ptr, cstr); } @@ -31,15 +32,22 @@ MqttSettingsService::MqttSettingsService(AsyncWebServer * server, FS * fs, Secur , _retainedClientId(nullptr) , _retainedUsername(nullptr) , _retainedPassword(nullptr) + , _retainedRootCA(nullptr) , _reconfigureMqtt(false) , _disconnectedAt(0) , _disconnectReason(espMqttClientTypes::DisconnectReason::TCP_DISCONNECTED) , _mqttClient(nullptr) { - WiFi.onEvent(std::bind(&MqttSettingsService::WiFiEvent, this, _1, _2)); - addUpdateHandler([&] { onConfigUpdated(); }, false); + WiFi.onEvent([this](WiFiEvent_t event, WiFiEventInfo_t info) { WiFiEvent(event); }); + addUpdateHandler([this]() { onConfigUpdated(); }, false); } MqttSettingsService::~MqttSettingsService() { + delete _mqttClient; + retainCstr(nullptr, &_retainedHost); + retainCstr(nullptr, &_retainedClientId); + retainCstr(nullptr, &_retainedUsername); + retainCstr(nullptr, &_retainedPassword); + retainCstr(nullptr, &_retainedRootCA); } void MqttSettingsService::begin() { @@ -55,32 +63,41 @@ void MqttSettingsService::startClient() { return; } delete _mqttClient; + _mqttClient = nullptr; } #if CONFIG_IDF_TARGET_ESP32S3 if (_state.enableTLS) { isSecure = true; - _mqttClient = static_cast(new espMqttClientSecure(espMqttClientTypes::UseInternalTask::NO)); + _mqttClient = new espMqttClientSecure(espMqttClientTypes::UseInternalTask::NO); if (_state.rootCA == "insecure") { static_cast(_mqttClient)->setInsecure(); } else { String certificate = "-----BEGIN CERTIFICATE-----\n" + _state.rootCA + "\n-----END CERTIFICATE-----\n"; static_cast(_mqttClient)->setCACert(retainCstr(certificate.c_str(), &_retainedRootCA)); } - static_cast(_mqttClient)->onConnect(std::bind(&MqttSettingsService::onMqttConnect, this, _1)); - static_cast(_mqttClient)->onDisconnect(std::bind(&MqttSettingsService::onMqttDisconnect, this, _1)); - static_cast(_mqttClient)->onMessage(std::bind(&MqttSettingsService::onMqttMessage, this, _1, _2, _3, _4, _5, _6)); + static_cast(_mqttClient)->onConnect([this](bool sessionPresent) { onMqttConnect(sessionPresent); }); + static_cast(_mqttClient)->onDisconnect([this](espMqttClientTypes::DisconnectReason reason) { onMqttDisconnect(reason); }); + static_cast(_mqttClient) + ->onMessage( + [this](const espMqttClientTypes::MessageProperties & properties, const char * topic, const uint8_t * payload, size_t len, size_t index, size_t total) { + onMqttMessage(properties, topic, payload, len, index, total); + }); return; } #endif isSecure = false; - _mqttClient = static_cast(new espMqttClient(espMqttClientTypes::UseInternalTask::NO)); - static_cast(_mqttClient)->onConnect(std::bind(&MqttSettingsService::onMqttConnect, this, _1)); - static_cast(_mqttClient)->onDisconnect(std::bind(&MqttSettingsService::onMqttDisconnect, this, _1)); - static_cast(_mqttClient)->onMessage(std::bind(&MqttSettingsService::onMqttMessage, this, _1, _2, _3, _4, _5, _6)); + _mqttClient = new espMqttClient(espMqttClientTypes::UseInternalTask::NO); + static_cast(_mqttClient)->onConnect([this](bool sessionPresent) { onMqttConnect(sessionPresent); }); + static_cast(_mqttClient)->onDisconnect([this](espMqttClientTypes::DisconnectReason reason) { onMqttDisconnect(reason); }); + static_cast(_mqttClient) + ->onMessage( + [this](const espMqttClientTypes::MessageProperties & properties, const char * topic, const uint8_t * payload, size_t len, size_t index, size_t total) { + onMqttMessage(properties, topic, payload, len, index, total); + }); } void MqttSettingsService::loop() { - if (_reconfigureMqtt || (_disconnectedAt && (uint32_t)(uuid::get_uptime() - _disconnectedAt) >= MQTT_RECONNECTION_DELAY)) { + if (_reconfigureMqtt || (_disconnectedAt && static_cast(uuid::get_uptime() - _disconnectedAt) >= MQTT_RECONNECTION_DELAY)) { // reconfigure MQTT client _disconnectedAt = configureMqtt() ? 0 : uuid::get_uptime(); _reconfigureMqtt = false; @@ -116,6 +133,9 @@ void MqttSettingsService::onMqttMessage(const espMqttClientTypes::MessagePropert size_t len, size_t index, size_t total) { + (void)properties; + (void)index; + (void)total; emsesp::EMSESP::mqtt_.on_message(topic, payload, len); } @@ -128,6 +148,7 @@ MqttClient * MqttSettingsService::getMqttClient() { } void MqttSettingsService::onMqttConnect(bool sessionPresent) { + (void)sessionPresent; // _disconnectedAt = 0; emsesp::EMSESP::mqtt_.on_connect(); // emsesp::EMSESP::logger().info("Connected to MQTT, %s", (sessionPresent) ? ("with persistent session") : ("without persistent session")); @@ -149,7 +170,7 @@ void MqttSettingsService::onConfigUpdated() { emsesp::EMSESP::mqtt_.start(); // reload EMS-ESP MQTT settings } -void MqttSettingsService::WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info) { +void MqttSettingsService::WiFiEvent(WiFiEvent_t event) { switch (event) { case ARDUINO_EVENT_WIFI_STA_GOT_IP: case ARDUINO_EVENT_ETH_GOT_IP: @@ -264,32 +285,32 @@ StateUpdateResult MqttSettings::update(JsonObject root, MqttSettings & settings) #endif newSettings.enabled = root["enabled"] | FACTORY_MQTT_ENABLED; newSettings.host = root["host"] | FACTORY_MQTT_HOST; - newSettings.port = root["port"] | FACTORY_MQTT_PORT; + newSettings.port = static_cast(root["port"] | FACTORY_MQTT_PORT); newSettings.base = root["base"] | FACTORY_MQTT_BASE; newSettings.username = root["username"] | FACTORY_MQTT_USERNAME; newSettings.password = root["password"] | FACTORY_MQTT_PASSWORD; newSettings.clientId = root["client_id"] | FACTORY_MQTT_CLIENT_ID; - newSettings.keepAlive = root["keep_alive"] | FACTORY_MQTT_KEEP_ALIVE; + newSettings.keepAlive = static_cast(root["keep_alive"] | FACTORY_MQTT_KEEP_ALIVE); newSettings.cleanSession = root["clean_session"] | FACTORY_MQTT_CLEAN_SESSION; - newSettings.mqtt_qos = root["mqtt_qos"] | EMSESP_DEFAULT_MQTT_QOS; + newSettings.mqtt_qos = static_cast(root["mqtt_qos"] | EMSESP_DEFAULT_MQTT_QOS); newSettings.mqtt_retain = root["mqtt_retain"] | EMSESP_DEFAULT_MQTT_RETAIN; - newSettings.publish_time_boiler = root["publish_time_boiler"] | EMSESP_DEFAULT_PUBLISH_TIME; - newSettings.publish_time_thermostat = root["publish_time_thermostat"] | EMSESP_DEFAULT_PUBLISH_TIME; - newSettings.publish_time_solar = root["publish_time_solar"] | EMSESP_DEFAULT_PUBLISH_TIME; - newSettings.publish_time_mixer = root["publish_time_mixer"] | EMSESP_DEFAULT_PUBLISH_TIME; - newSettings.publish_time_other = root["publish_time_other"] | EMSESP_DEFAULT_PUBLISH_TIME; - newSettings.publish_time_sensor = root["publish_time_sensor"] | EMSESP_DEFAULT_PUBLISH_TIME; - newSettings.publish_time_heartbeat = root["publish_time_heartbeat"] | EMSESP_DEFAULT_PUBLISH_HEARTBEAT; + newSettings.publish_time_boiler = static_cast(root["publish_time_boiler"] | EMSESP_DEFAULT_PUBLISH_TIME); + newSettings.publish_time_thermostat = static_cast(root["publish_time_thermostat"] | EMSESP_DEFAULT_PUBLISH_TIME); + newSettings.publish_time_solar = static_cast(root["publish_time_solar"] | EMSESP_DEFAULT_PUBLISH_TIME); + newSettings.publish_time_mixer = static_cast(root["publish_time_mixer"] | EMSESP_DEFAULT_PUBLISH_TIME); + newSettings.publish_time_other = static_cast(root["publish_time_other"] | EMSESP_DEFAULT_PUBLISH_TIME); + newSettings.publish_time_sensor = static_cast(root["publish_time_sensor"] | EMSESP_DEFAULT_PUBLISH_TIME); + newSettings.publish_time_heartbeat = static_cast(root["publish_time_heartbeat"] | EMSESP_DEFAULT_PUBLISH_HEARTBEAT); newSettings.ha_enabled = root["ha_enabled"] | EMSESP_DEFAULT_HA_ENABLED; - newSettings.nested_format = root["nested_format"] | EMSESP_DEFAULT_NESTED_FORMAT; + newSettings.nested_format = static_cast(root["nested_format"] | EMSESP_DEFAULT_NESTED_FORMAT); newSettings.discovery_prefix = root["discovery_prefix"] | EMSESP_DEFAULT_DISCOVERY_PREFIX; - newSettings.discovery_type = root["discovery_type"] | EMSESP_DEFAULT_DISCOVERY_TYPE; + newSettings.discovery_type = static_cast(root["discovery_type"] | EMSESP_DEFAULT_DISCOVERY_TYPE); newSettings.publish_single = root["publish_single"] | EMSESP_DEFAULT_PUBLISH_SINGLE; newSettings.publish_single2cmd = root["publish_single2cmd"] | EMSESP_DEFAULT_PUBLISH_SINGLE2CMD; newSettings.send_response = root["send_response"] | EMSESP_DEFAULT_SEND_RESPONSE; - newSettings.entity_format = root["entity_format"] | EMSESP_DEFAULT_ENTITY_FORMAT; + newSettings.entity_format = static_cast(root["entity_format"] | EMSESP_DEFAULT_ENTITY_FORMAT); if (newSettings.enabled != settings.enabled) { changed = true; diff --git a/lib/framework/MqttSettingsService.h b/lib/framework/MqttSettingsService.h index 93bd0d163..335070780 100644 --- a/lib/framework/MqttSettingsService.h +++ b/lib/framework/MqttSettingsService.h @@ -1,11 +1,12 @@ #ifndef MqttSettingsService_h #define MqttSettingsService_h -#include -#include -#include +#include "StatefulService.h" +#include "HttpEndpoint.h" +#include "FSPersistence.h" +#include "ESPUtils.h" + #include -#include #include @@ -141,11 +142,12 @@ class MqttSettingsService : public StatefulService { // the MQTT client instance MqttClient * _mqttClient; - void WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info); + void WiFiEvent(WiFiEvent_t event); void onMqttConnect(bool sessionPresent); void onMqttDisconnect(espMqttClientTypes::DisconnectReason reason); void onMqttMessage(const espMqttClientTypes::MessageProperties & properties, const char * topic, const uint8_t * payload, size_t len, size_t index, size_t total); + bool configureMqtt(); }; diff --git a/lib/framework/MqttStatus.cpp b/lib/framework/MqttStatus.cpp index c62ba99e1..c1c66d5ab 100644 --- a/lib/framework/MqttStatus.cpp +++ b/lib/framework/MqttStatus.cpp @@ -1,19 +1,17 @@ -#include +#include "MqttStatus.h" #include "../../src/emsesp_stub.hpp" -using namespace std::placeholders; // for `_1` etc - MqttStatus::MqttStatus(AsyncWebServer * server, MqttSettingsService * mqttSettingsService, SecurityManager * securityManager) : _mqttSettingsService(mqttSettingsService) { server->on(MQTT_STATUS_SERVICE_PATH, HTTP_GET, - securityManager->wrapRequest(std::bind(&MqttStatus::mqttStatus, this, _1), AuthenticationPredicates::IS_AUTHENTICATED)); + securityManager->wrapRequest([this](AsyncWebServerRequest * request) { mqttStatus(request); }, AuthenticationPredicates::IS_AUTHENTICATED)); } void MqttStatus::mqttStatus(AsyncWebServerRequest * request) { - AsyncJsonResponse * response = new AsyncJsonResponse(false); - JsonObject root = response->getRoot(); + auto * response = new AsyncJsonResponse(false); + JsonObject root = response->getRoot(); root["enabled"] = _mqttSettingsService->isEnabled(); root["connected"] = _mqttSettingsService->isConnected(); diff --git a/lib/framework/MqttStatus.h b/lib/framework/MqttStatus.h index eb7ba980b..87fa18616 100644 --- a/lib/framework/MqttStatus.h +++ b/lib/framework/MqttStatus.h @@ -2,10 +2,11 @@ #define MqttStatus_h #include -#include #include #include -#include + +#include "MqttSettingsService.h" +#include "SecurityManager.h" #define MQTT_STATUS_SERVICE_PATH "/rest/mqttStatus" diff --git a/lib/framework/NTPSettingsService.cpp b/lib/framework/NTPSettingsService.cpp index 212d9d3ae..6c7e75e2b 100644 --- a/lib/framework/NTPSettingsService.cpp +++ b/lib/framework/NTPSettingsService.cpp @@ -1,20 +1,20 @@ -#include +#include "NTPSettingsService.h" #include "../../src/emsesp_stub.hpp" -using namespace std::placeholders; // for `_1` etc - NTPSettingsService::NTPSettingsService(AsyncWebServer * server, FS * fs, SecurityManager * securityManager) : _httpEndpoint(NTPSettings::read, NTPSettings::update, this, server, NTP_SETTINGS_SERVICE_PATH, securityManager) , _fsPersistence(NTPSettings::read, NTPSettings::update, this, fs, NTP_SETTINGS_FILE) - , _timeHandler(TIME_PATH, securityManager->wrapCallback(std::bind(&NTPSettingsService::configureTime, this, _1, _2), AuthenticationPredicates::IS_ADMIN)) { + , _timeHandler(TIME_PATH, + securityManager->wrapCallback([this](AsyncWebServerRequest * request, JsonVariant json) { configureTime(request, json); }, + AuthenticationPredicates::IS_ADMIN)) + , _connected(false) { _timeHandler.setMethod(HTTP_POST); _timeHandler.setMaxContentLength(MAX_TIME_SIZE); server->addHandler(&_timeHandler); - WiFi.onEvent(std::bind(&NTPSettingsService::WiFiEvent, this, _1)); - - addUpdateHandler([&] { configureNTP(); }, false); + WiFi.onEvent([this](WiFiEvent_t event, WiFiEventInfo_t info) { WiFiEvent(event); }); + addUpdateHandler([this] { configureNTP(); }, false); } void NTPSettingsService::begin() { @@ -27,9 +27,9 @@ void NTPSettingsService::WiFiEvent(WiFiEvent_t event) { switch (event) { case ARDUINO_EVENT_WIFI_STA_DISCONNECTED: case ARDUINO_EVENT_ETH_DISCONNECTED: - if (connected_) { + if (_connected) { emsesp::EMSESP::logger().info("WiFi connection dropped, stopping NTP"); - connected_ = false; + _connected = false; configureNTP(); } break; @@ -37,7 +37,7 @@ void NTPSettingsService::WiFiEvent(WiFiEvent_t event) { case ARDUINO_EVENT_WIFI_STA_GOT_IP: case ARDUINO_EVENT_ETH_GOT_IP: // emsesp::EMSESP::logger().info("Got IP address, starting NTP synchronization"); - connected_ = true; + _connected = true; configureNTP(); break; @@ -49,7 +49,7 @@ void NTPSettingsService::WiFiEvent(WiFiEvent_t event) { // https://werner.rothschopf.net/microcontroller/202103_arduino_esp32_ntp_en.htm void NTPSettingsService::configureNTP() { emsesp::EMSESP::system_.ntp_connected(false); - if (connected_ && _state.enabled) { + if (_connected && _state.enabled) { emsesp::EMSESP::logger().info("Starting NTP service"); esp_sntp_set_sync_interval(3600000); // one hour esp_sntp_set_time_sync_notification_cb(ntp_received); @@ -63,13 +63,13 @@ void NTPSettingsService::configureNTP() { void NTPSettingsService::configureTime(AsyncWebServerRequest * request, JsonVariant json) { if (json.is()) { - struct tm tm = {0}; + struct tm tm = {}; String timeLocal = json["local_time"]; char * s = strptime(timeLocal.c_str(), "%Y-%m-%dT%H:%M:%S", &tm); if (s != nullptr) { tm.tm_isdst = -1; // not set by strptime, tells mktime to determine daylightsaving time_t time = mktime(&tm); - struct timeval now = {.tv_sec = time}; + struct timeval now = {.tv_sec = time, .tv_usec = {}}; settimeofday(&now, nullptr); AsyncWebServerResponse * response = request->beginResponse(200); request->send(response); @@ -82,6 +82,7 @@ void NTPSettingsService::configureTime(AsyncWebServerRequest * request, JsonVari } void NTPSettingsService::ntp_received(struct timeval * tv) { + (void)tv; // emsesp::EMSESP::logger().info("NTP sync to %d sec", tv->tv_sec); emsesp::EMSESP::system_.ntp_connected(true); } @@ -99,4 +100,4 @@ StateUpdateResult NTPSettings::update(JsonObject root, NTPSettings & settings) { settings.tzLabel = root["tz_label"] | FACTORY_NTP_TIME_ZONE_LABEL; settings.tzFormat = root["tz_format"] | FACTORY_NTP_TIME_ZONE_FORMAT; return StateUpdateResult::CHANGED; -} +} \ No newline at end of file diff --git a/lib/framework/NTPSettingsService.h b/lib/framework/NTPSettingsService.h index 976d29d70..9e1c503ac 100644 --- a/lib/framework/NTPSettingsService.h +++ b/lib/framework/NTPSettingsService.h @@ -1,10 +1,10 @@ #ifndef NTPSettingsService_h #define NTPSettingsService_h -#include -#include +#include "HttpEndpoint.h" +#include "FSPersistence.h" -#include +#include #include #ifndef FACTORY_NTP_ENABLED @@ -51,8 +51,8 @@ class NTPSettingsService : public StatefulService { HttpEndpoint _httpEndpoint; FSPersistence _fsPersistence; AsyncCallbackJsonWebHandler _timeHandler; + bool _connected; - bool connected_ = false; void WiFiEvent(WiFiEvent_t event); void configureNTP(); void configureTime(AsyncWebServerRequest * request, JsonVariant json); diff --git a/lib/framework/NTPStatus.cpp b/lib/framework/NTPStatus.cpp index ddb6bbc2d..95b9c32a6 100644 --- a/lib/framework/NTPStatus.cpp +++ b/lib/framework/NTPStatus.cpp @@ -1,12 +1,13 @@ -#include +#include "NTPStatus.h" + #include "../../src/emsesp_stub.hpp" -using namespace std::placeholders; // for `_1` etc +#include NTPStatus::NTPStatus(AsyncWebServer * server, SecurityManager * securityManager) { server->on(NTP_STATUS_SERVICE_PATH, HTTP_GET, - securityManager->wrapRequest(std::bind(&NTPStatus::ntpStatus, this, _1), AuthenticationPredicates::IS_AUTHENTICATED)); + securityManager->wrapRequest([this](AsyncWebServerRequest * request) { ntpStatus(request); }, AuthenticationPredicates::IS_AUTHENTICATED)); } /* @@ -15,9 +16,9 @@ NTPStatus::NTPStatus(AsyncWebServer * server, SecurityManager * securityManager) * Uses a 25 byte buffer, large enough to fit an ISO time string with offset. */ String formatTime(tm * time, const char * format) { - char time_string[25]; - strftime(time_string, 25, format, time); - return String(time_string); + std::array time_string{}; + strftime(time_string.data(), time_string.size(), format, time); + return {time_string.data()}; } String toUTCTimeString(tm * time) { @@ -29,14 +30,23 @@ String toLocalTimeString(tm * time) { } void NTPStatus::ntpStatus(AsyncWebServerRequest * request) { - AsyncJsonResponse * response = new AsyncJsonResponse(false); - JsonObject root = response->getRoot(); + auto * response = new AsyncJsonResponse(false); + JsonObject root = response->getRoot(); // grab the current instant in unix seconds time_t now = time(nullptr); // only provide enabled/disabled status for now - root["status"] = esp_sntp_enabled() ? emsesp::EMSESP::system_.ntp_connected() ? 2 : 1 : 0; + root["status"] = []() { + if (esp_sntp_enabled()) { + if (emsesp::EMSESP::system_.ntp_connected()) { + return 2; + } else { + return 1; + } + } + return 0; + }(); // the current time in UTC root["utc_time"] = toUTCTimeString(gmtime(&now)); @@ -49,4 +59,4 @@ void NTPStatus::ntpStatus(AsyncWebServerRequest * request) { response->setLength(); request->send(response); -} +} \ No newline at end of file diff --git a/lib/framework/NTPStatus.h b/lib/framework/NTPStatus.h index 2dec0a9f4..e9aa7d766 100644 --- a/lib/framework/NTPStatus.h +++ b/lib/framework/NTPStatus.h @@ -1,14 +1,14 @@ #ifndef NTPStatus_h #define NTPStatus_h -#include - +#include #include #include - #include #include -#include + +#include "SecurityManager.h" + #include #define NTP_STATUS_SERVICE_PATH "/rest/ntpStatus" diff --git a/lib/framework/NetworkSettingsService.cpp b/lib/framework/NetworkSettingsService.cpp index 1bb03be27..83cd8b0c2 100644 --- a/lib/framework/NetworkSettingsService.cpp +++ b/lib/framework/NetworkSettingsService.cpp @@ -1,16 +1,25 @@ -#include +#include "NetworkSettingsService.h" #include "../../src/emsesp_stub.hpp" -using namespace std::placeholders; // for `_1` etc - NetworkSettingsService::NetworkSettingsService(AsyncWebServer * server, FS * fs, SecurityManager * securityManager) : _httpEndpoint(NetworkSettings::read, NetworkSettings::update, this, server, NETWORK_SETTINGS_SERVICE_PATH, securityManager) , _fsPersistence(NetworkSettings::read, NetworkSettings::update, this, fs, NETWORK_SETTINGS_FILE) - , _lastConnectionAttempt(0) { - addUpdateHandler([&] { reconfigureWiFiConnection(); }, false); - // wifi event callbacks - WiFi.onEvent(std::bind(&NetworkSettingsService::WiFiEvent, this, _1, _2)); + , _lastConnectionAttempt(0) + , _stopping(false) { + addUpdateHandler([this]() { reconfigureWiFiConnection(); }, false); + WiFi.onEvent([this](WiFiEvent_t event, WiFiEventInfo_t info) { WiFiEvent(event, info); }); +} + +static bool formatBssid(const String & bssid, uint8_t (&mac)[6]) { + uint tmp[6]; + if (bssid.isEmpty() || sscanf(bssid.c_str(), "%X:%X:%X:%X:%X:%X", &tmp[0], &tmp[1], &tmp[2], &tmp[3], &tmp[4], &tmp[5]) != 6) { + return false; + } + for (uint8_t i = 0; i < 6; i++) { + mac[i] = static_cast(tmp[i]); + } + return true; } void NetworkSettingsService::begin() { @@ -47,7 +56,7 @@ void NetworkSettingsService::reconfigureWiFiConnection() { void NetworkSettingsService::loop() { unsigned long currentMillis = millis(); - if (!_lastConnectionAttempt || (uint32_t)(currentMillis - _lastConnectionAttempt) >= WIFI_RECONNECTION_DELAY) { + if (!_lastConnectionAttempt || static_cast(currentMillis - _lastConnectionAttempt) >= WIFI_RECONNECTION_DELAY) { _lastConnectionAttempt = currentMillis; manageSTA(); } @@ -68,22 +77,18 @@ void NetworkSettingsService::manageSTA() { // www.esp32.com/viewtopic.php?t=12055 if (_state.bandwidth20) { - esp_wifi_set_bandwidth((wifi_interface_t)ESP_IF_WIFI_STA, WIFI_BW_HT20); + esp_wifi_set_bandwidth(static_cast(ESP_IF_WIFI_STA), WIFI_BW_HT20); } else { - esp_wifi_set_bandwidth((wifi_interface_t)ESP_IF_WIFI_STA, WIFI_BW_HT40); + esp_wifi_set_bandwidth(static_cast(ESP_IF_WIFI_STA), WIFI_BW_HT40); } if (_state.nosleep) { WiFi.setSleep(false); // turn off sleep - WIFI_PS_NONE } // attempt to connect to the network - uint mac[6]; - if (!_state.bssid.isEmpty() && sscanf(_state.bssid.c_str(), "%X:%X:%X:%X:%X:%X", &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]) == 6) { - uint8_t mac1[6]; - for (uint8_t i = 0; i < 6; i++) { - mac1[i] = (uint8_t)mac[i]; - } - WiFi.begin(_state.ssid.c_str(), _state.password.c_str(), 0, mac1); + uint8_t bssid[6]; + if (formatBssid(_state.bssid, bssid)) { + WiFi.begin(_state.ssid.c_str(), _state.password.c_str(), 0, bssid); } else { WiFi.begin(_state.ssid.c_str(), _state.password.c_str()); } @@ -96,7 +101,7 @@ void NetworkSettingsService::manageSTA() { #else if (_state.tx_power != 0) { // if not set to Auto (0) set the Tx power now - if (!WiFi.setTxPower((wifi_power_t)_state.tx_power)) { + if (!WiFi.setTxPower(static_cast(_state.tx_power))) { emsesp::EMSESP::logger().warning("Failed to set WiFi Tx Power"); } } @@ -173,7 +178,7 @@ void NetworkSettingsService::setWiFiPowerOnRSSI() { emsesp::EMSESP::logger().debug("Recommended set WiFi Tx Power (set_power %d, new power %d, rssi %d, threshold %d", set_power, p, rssi, threshold); #else char result[10]; - emsesp::EMSESP::logger().info("Setting WiFi Tx Power to %s dBm", emsesp::Helpers::render_value(result, (double)(p / 4), 1)); + emsesp::EMSESP::logger().info("Setting WiFi Tx Power to %s dBm", emsesp::Helpers::render_value(result, ((double)(p) / 4), 1)); #endif if (!WiFi.setTxPower(p)) { @@ -310,7 +315,7 @@ void NetworkSettingsService::WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info) emsesp::EMSESP::logger().info("WiFi connected with IP=%s, hostname=%s, TxPower=%s dBm", WiFi.localIP().toString().c_str(), WiFi.getHostname(), - emsesp::Helpers::render_value(result, (double)(WiFi.getTxPower() / 4), 1)); + emsesp::Helpers::render_value(result, ((double)(WiFi.getTxPower()) / 4), 1)); mDNS_start(); break; @@ -389,7 +394,6 @@ void NetworkSettings::read(NetworkSettings & settings, JsonObject root) { root["static_ip_config"] = settings.staticIPConfig; root["enableIPv6"] = settings.enableIPv6; root["bandwidth20"] = settings.bandwidth20; - root["tx_power"] = settings.tx_power; root["nosleep"] = settings.nosleep; root["enableMDNS"] = settings.enableMDNS; root["enableCORS"] = settings.enableCORS; @@ -417,7 +421,7 @@ StateUpdateResult NetworkSettings::update(JsonObject root, NetworkSettings & set settings.staticIPConfig = root["static_ip_config"] | false; settings.enableIPv6 = root["enableIPv6"] | false; settings.bandwidth20 = root["bandwidth20"] | false; - settings.tx_power = root["tx_power"] | 0; + settings.tx_power = static_cast(root["tx_power"] | 0); settings.nosleep = root["nosleep"] | false; settings.enableMDNS = root["enableMDNS"] | true; settings.enableCORS = root["enableCORS"] | false; @@ -445,7 +449,7 @@ StateUpdateResult NetworkSettings::update(JsonObject root, NetworkSettings & set // see if we need to inform the user of a restart if (tx_power != settings.tx_power || enableCORS != settings.enableCORS || CORSOrigin != settings.CORSOrigin - || (ssid != settings.ssid && settings.ssid == "")) { + || (ssid != settings.ssid && settings.ssid.isEmpty())) { return StateUpdateResult::CHANGED_RESTART; // tell WebUI that a restart is needed } diff --git a/lib/framework/NetworkSettingsService.h b/lib/framework/NetworkSettingsService.h index 6b5551802..e27af0e01 100644 --- a/lib/framework/NetworkSettingsService.h +++ b/lib/framework/NetworkSettingsService.h @@ -1,10 +1,10 @@ #ifndef NetworkSettingsService_h #define NetworkSettingsService_h -#include -#include -#include -#include +#include "StatefulService.h" +#include "FSPersistence.h" +#include "HttpEndpoint.h" +#include "JsonUtils.h" #ifndef EMSESP_STANDALONE #include @@ -16,7 +16,7 @@ #define NETWORK_SETTINGS_FILE "/config/networkSettings.json" #define NETWORK_SETTINGS_SERVICE_PATH "/rest/networkSettings" -#define WIFI_RECONNECTION_DELAY 1000 * 3 +#define WIFI_RECONNECTION_DELAY (1000 * 3) #ifndef FACTORY_WIFI_SSID #define FACTORY_WIFI_SSID "" diff --git a/lib/framework/NetworkStatus.cpp b/lib/framework/NetworkStatus.cpp index 64e0cd604..27c37cee7 100644 --- a/lib/framework/NetworkStatus.cpp +++ b/lib/framework/NetworkStatus.cpp @@ -1,18 +1,16 @@ -#include +#include "NetworkStatus.h" #include "../../src/emsesp_stub.hpp" -using namespace std::placeholders; // for `_1` etc - NetworkStatus::NetworkStatus(AsyncWebServer * server, SecurityManager * securityManager) { server->on(NETWORK_STATUS_SERVICE_PATH, HTTP_GET, - securityManager->wrapRequest(std::bind(&NetworkStatus::networkStatus, this, _1), AuthenticationPredicates::IS_AUTHENTICATED)); + securityManager->wrapRequest([this](AsyncWebServerRequest * request) { networkStatus(request); }, AuthenticationPredicates::IS_AUTHENTICATED)); } void NetworkStatus::networkStatus(AsyncWebServerRequest * request) { - AsyncJsonResponse * response = new AsyncJsonResponse(false); - JsonObject root = response->getRoot(); + auto * response = new AsyncJsonResponse(false); + JsonObject root = response->getRoot(); bool ethernet_connected = emsesp::EMSESP::system_.ethernet_connected(); wl_status_t wifi_status = WiFi.status(); @@ -22,7 +20,7 @@ void NetworkStatus::networkStatus(AsyncWebServerRequest * request) { root["status"] = 10; // custom code #10 - ETHERNET_STATUS_CONNECTED root["hostname"] = ETH.getHostname(); } else { - root["status"] = (uint8_t)wifi_status; + root["status"] = static_cast(wifi_status); root["hostname"] = WiFi.getHostname(); } diff --git a/lib/framework/NetworkStatus.h b/lib/framework/NetworkStatus.h index f31630e25..6c5524169 100644 --- a/lib/framework/NetworkStatus.h +++ b/lib/framework/NetworkStatus.h @@ -4,9 +4,9 @@ #include #include #include -#include -#include +#include "IPUtils.h" +#include "SecurityManager.h" #define MAX_NETWORK_STATUS_SIZE 1024 #define NETWORK_STATUS_SERVICE_PATH "/rest/networkStatus" diff --git a/lib/framework/OTASettingsService.cpp b/lib/framework/OTASettingsService.cpp index ecf18a1da..61673092c 100644 --- a/lib/framework/OTASettingsService.cpp +++ b/lib/framework/OTASettingsService.cpp @@ -1,15 +1,13 @@ -#include +#include "OTASettingsService.h" #include "../../src/emsesp_stub.hpp" -using namespace std::placeholders; // for `_1` etc - OTASettingsService::OTASettingsService(AsyncWebServer * server, FS * fs, SecurityManager * securityManager) : _httpEndpoint(OTASettings::read, OTASettings::update, this, server, OTA_SETTINGS_SERVICE_PATH, securityManager) , _fsPersistence(OTASettings::read, OTASettings::update, this, fs, OTA_SETTINGS_FILE) , _arduinoOTA(nullptr) { - WiFi.onEvent(std::bind(&OTASettingsService::WiFiEvent, this, _1, _2)); - addUpdateHandler([&] { configureArduinoOTA(); }, false); + WiFi.onEvent([this](WiFiEvent_t event, WiFiEventInfo_t info) { WiFiEvent(event); }); + addUpdateHandler([this] { configureArduinoOTA(); }, false); } void OTASettingsService::begin() { @@ -32,7 +30,7 @@ void OTASettingsService::configureArduinoOTA() { if (_state.enabled) { _arduinoOTA = new ArduinoOTAClass; - _arduinoOTA->setPort(_state.port); + _arduinoOTA->setPort(static_cast(_state.port)); _arduinoOTA->setPassword(_state.password.c_str()); _arduinoOTA->onStart([] { emsesp::EMSESP::system_.upload_status(true); }); @@ -64,7 +62,7 @@ void OTASettingsService::configureArduinoOTA() { } } -void OTASettingsService::WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info) { +void OTASettingsService::WiFiEvent(WiFiEvent_t event) { switch (event) { case ARDUINO_EVENT_WIFI_STA_GOT_IP: case ARDUINO_EVENT_ETH_GOT_IP: diff --git a/lib/framework/OTASettingsService.h b/lib/framework/OTASettingsService.h index 72ed4581a..41183dac6 100644 --- a/lib/framework/OTASettingsService.h +++ b/lib/framework/OTASettingsService.h @@ -1,8 +1,8 @@ #ifndef OTASettingsService_h #define OTASettingsService_h -#include -#include +#include "HttpEndpoint.h" +#include "FSPersistence.h" #include #include @@ -45,7 +45,7 @@ class OTASettingsService : public StatefulService { ArduinoOTAClass * _arduinoOTA; void configureArduinoOTA(); - void WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info); + void WiFiEvent(WiFiEvent_t event); }; #endif diff --git a/lib/framework/RestartService.cpp b/lib/framework/RestartService.cpp index b767b9cf0..b56232408 100644 --- a/lib/framework/RestartService.cpp +++ b/lib/framework/RestartService.cpp @@ -1,15 +1,22 @@ -#include +#include "RestartService.h" + #include #include "../../src/emsesp_stub.hpp" -using namespace std::placeholders; // for `_1` etc - RestartService::RestartService(AsyncWebServer * server, SecurityManager * securityManager) { - server->on(RESTART_SERVICE_PATH, HTTP_POST, securityManager->wrapRequest(std::bind(&RestartService::restart, this, _1), AuthenticationPredicates::IS_ADMIN)); + server->on(RESTART_SERVICE_PATH, + HTTP_POST, + securityManager->wrapRequest([this](AsyncWebServerRequest * request) { restart(request); }, AuthenticationPredicates::IS_ADMIN)); server->on(PARTITION_SERVICE_PATH, HTTP_POST, - securityManager->wrapRequest(std::bind(&RestartService::partition, this, _1), AuthenticationPredicates::IS_ADMIN)); + securityManager->wrapRequest([this](AsyncWebServerRequest * request) { partition(request); }, AuthenticationPredicates::IS_ADMIN)); +} + +void RestartService::restartNow() { + WiFi.disconnect(true); + delay(500); + ESP.restart(); } void RestartService::restart(AsyncWebServerRequest * request) { @@ -19,7 +26,7 @@ void RestartService::restart(AsyncWebServerRequest * request) { } void RestartService::partition(AsyncWebServerRequest * request) { - const esp_partition_t * factory_partition = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_FACTORY, NULL); + const esp_partition_t * factory_partition = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_FACTORY, nullptr); if (factory_partition) { esp_ota_set_boot_partition(factory_partition); emsesp::EMSESP::system_.store_nvs_values(); @@ -27,7 +34,7 @@ void RestartService::partition(AsyncWebServerRequest * request) { request->send(200); return; } - const esp_partition_t * ota_partition = esp_ota_get_next_update_partition(NULL); + const esp_partition_t * ota_partition = esp_ota_get_next_update_partition(nullptr); if (!ota_partition) { request->send(400); // bad request return; diff --git a/lib/framework/RestartService.h b/lib/framework/RestartService.h index 8a010716f..55c0b25d1 100644 --- a/lib/framework/RestartService.h +++ b/lib/framework/RestartService.h @@ -3,9 +3,9 @@ #include #include - #include -#include + +#include "SecurityManager.h" #define RESTART_SERVICE_PATH "/rest/restart" #define PARTITION_SERVICE_PATH "/rest/partition" @@ -14,11 +14,7 @@ class RestartService { public: RestartService(AsyncWebServer * server, SecurityManager * securityManager); - static void restartNow() { - WiFi.disconnect(true); - delay(500); - ESP.restart(); - } + static void restartNow(); private: void restart(AsyncWebServerRequest * request); diff --git a/lib/framework/SecurityManager.h b/lib/framework/SecurityManager.h index 2f1610588..1e9bec21b 100644 --- a/lib/framework/SecurityManager.h +++ b/lib/framework/SecurityManager.h @@ -1,10 +1,11 @@ #ifndef SecurityManager_h #define SecurityManager_h -#include -#include +#include "Features.h" +#include "ArduinoJsonJWT.h" +#include "ESPUtils.h" + #include -#include #include #include @@ -26,28 +27,27 @@ class User { public: User(String username, String password, bool admin) - : username(username) - , password(password) + : username(std::move(username)) + , password(std::move(password)) , admin(admin) { } }; class Authentication { public: - User * user; - boolean authenticated; + User * user = nullptr; + boolean authenticated = false; public: - Authentication(User & user) + explicit Authentication(const User & user) : user(new User(user)) , authenticated(true) { } - Authentication() - : user(nullptr) - , authenticated(false) { - } + + Authentication() = default; + ~Authentication() { - delete (user); + delete user; } }; @@ -55,13 +55,14 @@ typedef std::function AuthenticationPr class AuthenticationPredicates { public: - static bool NONE_REQUIRED(Authentication & authentication) { + static bool NONE_REQUIRED(const Authentication & authentication) { + (void)authentication; return true; }; - static bool IS_AUTHENTICATED(Authentication & authentication) { + static bool IS_AUTHENTICATED(const Authentication & authentication) { return authentication.authenticated; }; - static bool IS_ADMIN(Authentication & authentication) { + static bool IS_ADMIN(const Authentication & authentication) { return authentication.authenticated && authentication.user->admin; }; }; @@ -76,7 +77,7 @@ class SecurityManager { /* * Generate a JWT for the user provided */ - virtual String generateJWT(User * user) = 0; + virtual String generateJWT(const User * user) = 0; /* * Check the request header for the Authorization token diff --git a/lib/framework/SecuritySettingsService.cpp b/lib/framework/SecuritySettingsService.cpp index 2b4d13636..195be6a1a 100644 --- a/lib/framework/SecuritySettingsService.cpp +++ b/lib/framework/SecuritySettingsService.cpp @@ -1,15 +1,13 @@ -#include - -#include "../../src/emsesp_stub.hpp" +#include "SecuritySettingsService.h" SecuritySettingsService::SecuritySettingsService(AsyncWebServer * server, FS * fs) : _httpEndpoint(SecuritySettings::read, SecuritySettings::update, this, server, SECURITY_SETTINGS_PATH, this) , _fsPersistence(SecuritySettings::read, SecuritySettings::update, this, fs, SECURITY_SETTINGS_FILE) , _jwtHandler(FACTORY_JWT_SECRET) { - addUpdateHandler([&] { configureJWTHandler(); }, false); + addUpdateHandler([this] { configureJWTHandler(); }, false); server->on(GENERATE_TOKEN_PATH, HTTP_GET, - wrapRequest(std::bind(&SecuritySettingsService::generateToken, this, std::placeholders::_1), AuthenticationPredicates::IS_ADMIN)); + SecuritySettingsService::wrapRequest([this](AsyncWebServerRequest * request) { generateToken(request); }, AuthenticationPredicates::IS_ADMIN)); } void SecuritySettingsService::begin() { @@ -30,7 +28,7 @@ Authentication SecuritySettingsService::authenticateRequest(AsyncWebServerReques String value = tokenParamater->value(); return authenticateJWT(value); } - return Authentication(); + return {}; } void SecuritySettingsService::configureJWTHandler() { @@ -43,37 +41,37 @@ Authentication SecuritySettingsService::authenticateJWT(String & jwt) { if (payloadDocument.is()) { JsonObject parsedPayload = payloadDocument.as(); String username = parsedPayload["username"]; - for (User _user : _state.users) { + for (const User & _user : _state.users) { if (_user.username == username && validatePayload(parsedPayload, &_user)) { return Authentication(_user); } } } - return Authentication(); + return {}; } Authentication SecuritySettingsService::authenticate(const String & username, const String & password) { - for (User _user : _state.users) { + for (const User & _user : _state.users) { if (_user.username == username && _user.password == password) { return Authentication(_user); } } - return Authentication(); + return {}; } -inline void populateJWTPayload(JsonObject payload, User * user) { +inline void populateJWTPayload(JsonObject payload, const User * user) { payload["username"] = user->username; payload["admin"] = user->admin; } -boolean SecuritySettingsService::validatePayload(JsonObject parsedPayload, User * user) { +boolean SecuritySettingsService::validatePayload(JsonObject parsedPayload, const User * user) { JsonDocument jsonDocument; JsonObject payload = jsonDocument.to(); populateJWTPayload(payload, user); return payload == parsedPayload; } -String SecuritySettingsService::generateJWT(User * user) { +String SecuritySettingsService::generateJWT(const User * user) { JsonDocument jsonDocument; JsonObject payload = jsonDocument.to(); populateJWTPayload(payload, user); @@ -111,11 +109,11 @@ ArJsonRequestHandlerFunction SecuritySettingsService::wrapCallback(ArJsonRequest void SecuritySettingsService::generateToken(AsyncWebServerRequest * request) { AsyncWebParameter * usernameParam = request->getParam("username"); - for (User _user : _state.users) { + for (const User & _user : _state.users) { if (_user.username == usernameParam->value()) { - AsyncJsonResponse * response = new AsyncJsonResponse(false); - JsonObject root = response->getRoot(); - root["token"] = generateJWT(&_user); + auto * response = new AsyncJsonResponse(false); + JsonObject root = response->getRoot(); + root["token"] = generateJWT(&_user); response->setLength(); request->send(response); return; @@ -123,34 +121,3 @@ void SecuritySettingsService::generateToken(AsyncWebServerRequest * request) { } request->send(401); } - -void SecuritySettings::read(SecuritySettings & settings, JsonObject root) { - // secret - root["jwt_secret"] = settings.jwtSecret; - - // users - JsonArray users = root["users"].to(); - for (User user : settings.users) { - JsonObject userRoot = users.add(); - userRoot["username"] = user.username; - userRoot["password"] = user.password; - userRoot["admin"] = user.admin; - } -} - -StateUpdateResult SecuritySettings::update(JsonObject root, SecuritySettings & settings) { - // secret - settings.jwtSecret = root["jwt_secret"] | FACTORY_JWT_SECRET; - - // users - settings.users.clear(); - if (root["users"].is()) { - for (JsonVariant user : root["users"].as()) { - settings.users.push_back(User(user["username"], user["password"], user["admin"])); - } - } else { - settings.users.push_back(User(FACTORY_ADMIN_USERNAME, FACTORY_ADMIN_PASSWORD, true)); - settings.users.push_back(User(FACTORY_GUEST_USERNAME, FACTORY_GUEST_PASSWORD, false)); - } - return StateUpdateResult::CHANGED; -} diff --git a/lib/framework/SecuritySettingsService.h b/lib/framework/SecuritySettingsService.h index 82aedf6ef..91f3f4b3b 100644 --- a/lib/framework/SecuritySettingsService.h +++ b/lib/framework/SecuritySettingsService.h @@ -1,10 +1,10 @@ #ifndef SecuritySettingsService_h #define SecuritySettingsService_h -#include -#include -#include -#include +#include "Features.h" +#include "SecurityManager.h" +#include "HttpEndpoint.h" +#include "FSPersistence.h" #ifndef FACTORY_ADMIN_USERNAME #define FACTORY_ADMIN_USERNAME "admin" @@ -33,23 +33,51 @@ class SecuritySettings { String jwtSecret; std::vector users; - static void read(SecuritySettings & settings, JsonObject root); - static StateUpdateResult update(JsonObject root, SecuritySettings & settings); + static void read(SecuritySettings & settings, JsonObject root) { + // secret + root["jwt_secret"] = settings.jwtSecret; + + // users + JsonArray users = root["users"].to(); + for (const User & user : settings.users) { + JsonObject userRoot = users.add(); + userRoot["username"] = user.username; + userRoot["password"] = user.password; + userRoot["admin"] = user.admin; + } + } + + static StateUpdateResult update(JsonObject root, SecuritySettings & settings) { + // secret + settings.jwtSecret = root["jwt_secret"] | FACTORY_JWT_SECRET; + + // users + settings.users.clear(); + if (root["users"].is()) { + for (JsonVariant user : root["users"].as()) { + settings.users.emplace_back(user["username"], user["password"], user["admin"]); + } + } else { + settings.users.emplace_back(FACTORY_ADMIN_USERNAME, FACTORY_ADMIN_PASSWORD, true); + settings.users.emplace_back(FACTORY_GUEST_USERNAME, FACTORY_GUEST_PASSWORD, false); + } + return StateUpdateResult::CHANGED; + } }; -class SecuritySettingsService : public StatefulService, public SecurityManager { +class SecuritySettingsService final : public StatefulService, public SecurityManager { public: SecuritySettingsService(AsyncWebServer * server, FS * fs); void begin(); // Functions to implement SecurityManager - Authentication authenticate(const String & username, const String & password); - Authentication authenticateRequest(AsyncWebServerRequest * request); - String generateJWT(User * user); - ArRequestFilterFunction filterRequest(AuthenticationPredicate predicate); - ArRequestHandlerFunction wrapRequest(ArRequestHandlerFunction onRequest, AuthenticationPredicate predicate); - ArJsonRequestHandlerFunction wrapCallback(ArJsonRequestHandlerFunction callback, AuthenticationPredicate predicate); + Authentication authenticate(const String & username, const String & password) override; + Authentication authenticateRequest(AsyncWebServerRequest * request) override; + String generateJWT(const User * user) override; + ArRequestFilterFunction filterRequest(AuthenticationPredicate predicate) override; + ArRequestHandlerFunction wrapRequest(ArRequestHandlerFunction onRequest, AuthenticationPredicate predicate) override; + ArJsonRequestHandlerFunction wrapCallback(ArJsonRequestHandlerFunction callback, AuthenticationPredicate predicate) override; private: HttpEndpoint _httpEndpoint; @@ -68,7 +96,7 @@ class SecuritySettingsService : public StatefulService, public /* * Verify the payload is correct */ - boolean validatePayload(JsonObject parsedPayload, User * user); + boolean validatePayload(JsonObject parsedPayload, const User * user); }; #endif \ No newline at end of file diff --git a/lib/framework/StatefulService.cpp b/lib/framework/StatefulService.cpp index ece6b1fb3..d5f847aba 100644 --- a/lib/framework/StatefulService.cpp +++ b/lib/framework/StatefulService.cpp @@ -1,3 +1,3 @@ -#include +#include "StatefulService.h" update_handler_id_t StateUpdateHandlerInfo::currentUpdatedHandlerId = 0; diff --git a/lib/framework/SystemStatus.cpp b/lib/framework/SystemStatus.cpp index d82cb8326..b90ef7c38 100644 --- a/lib/framework/SystemStatus.cpp +++ b/lib/framework/SystemStatus.cpp @@ -1,21 +1,20 @@ -#include +#include "SystemStatus.h" + #include #include "../../src/emsesp_stub.hpp" -using namespace std::placeholders; // for `_1` etc - SystemStatus::SystemStatus(AsyncWebServer * server, SecurityManager * securityManager) { server->on(SYSTEM_STATUS_SERVICE_PATH, HTTP_GET, - securityManager->wrapRequest(std::bind(&SystemStatus::systemStatus, this, _1), AuthenticationPredicates::IS_AUTHENTICATED)); + securityManager->wrapRequest([this](AsyncWebServerRequest * request) { systemStatus(request); }, AuthenticationPredicates::IS_AUTHENTICATED)); } void SystemStatus::systemStatus(AsyncWebServerRequest * request) { emsesp::EMSESP::system_.refreshHeapMem(); // refresh free heap and max alloc heap - AsyncJsonResponse * response = new AsyncJsonResponse(false); - JsonObject root = response->getRoot(); + auto * response = new AsyncJsonResponse(false); + JsonObject root = response->getRoot(); #ifdef EMSESP_DEBUG root["emsesp_version"] = std::string(EMSESP_APP_VERSION) + " (DEBUG)"; @@ -49,11 +48,11 @@ void SystemStatus::systemStatus(AsyncWebServerRequest * request) { root["psram_size"] = emsesp::EMSESP::system_.PSram(); root["free_psram"] = ESP.getFreePsram() / 1024; } - const esp_partition_t * partition = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_FACTORY, NULL); + const esp_partition_t * partition = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_FACTORY, nullptr); if (partition != NULL) { // factory partition found root["has_loader"] = true; } else { // check for not empty, smaller OTA partition - partition = esp_ota_get_next_update_partition(NULL); + partition = esp_ota_get_next_update_partition(nullptr); if (partition) { uint64_t buffer; esp_partition_read(partition, 0, &buffer, 8); diff --git a/lib/framework/SystemStatus.h b/lib/framework/SystemStatus.h index 4970e81b9..bd2d7ebf6 100644 --- a/lib/framework/SystemStatus.h +++ b/lib/framework/SystemStatus.h @@ -5,10 +5,10 @@ #include #include #include - #include #include -#include + +#include "SecurityManager.h" #define SYSTEM_STATUS_SERVICE_PATH "/rest/systemStatus" diff --git a/lib/framework/UploadFileService.cpp b/lib/framework/UploadFileService.cpp index 58bedf83f..ee818b4d6 100644 --- a/lib/framework/UploadFileService.cpp +++ b/lib/framework/UploadFileService.cpp @@ -1,20 +1,27 @@ -#include -#include -#include - +#include "UploadFileService.h" #include "../../src/emsesp_stub.hpp" -using namespace std::placeholders; // for `_1` etc +#include -static bool is_firmware = false; -static char md5[33] = "\0"; +static String getFilenameExtension(const String & filename) { + const auto pos = filename.lastIndexOf('.'); + if (pos != -1) { + return filename.substring(static_cast(pos) + 1); + } + return {}; +} UploadFileService::UploadFileService(AsyncWebServer * server, SecurityManager * securityManager) - : _securityManager(securityManager) { - server->on(UPLOAD_FILE_PATH, - HTTP_POST, - std::bind(&UploadFileService::uploadComplete, this, _1), - std::bind(&UploadFileService::handleUpload, this, _1, _2, _3, _4, _5, _6)); + : _securityManager(securityManager) + , _is_firmware(false) + , _md5() { + server->on( + UPLOAD_FILE_PATH, + HTTP_POST, + [this](AsyncWebServerRequest * request) { uploadComplete(request); }, + [this](AsyncWebServerRequest * request, const String & filename, size_t index, uint8_t * data, size_t len, bool final) { + handleUpload(request, filename, index, data, len, final); + }); } void UploadFileService::handleUpload(AsyncWebServerRequest * request, const String & filename, size_t index, uint8_t * data, size_t len, bool final) { @@ -28,29 +35,27 @@ void UploadFileService::handleUpload(AsyncWebServerRequest * request, const Stri // at init if (!index) { // check details of the file, to see if its a valid bin or json file - std::string fname(filename.c_str()); - auto position = fname.find_last_of("."); - std::string extension = fname.substr(position + 1); - size_t fsize = request->contentLength(); + const String extension = getFilenameExtension(filename); + const std::size_t filesize = request->contentLength(); - is_firmware = false; - if ((extension == "bin") && (fsize > 1000000)) { - is_firmware = true; + _is_firmware = false; + if ((extension == "bin") && (filesize > 1000000)) { + _is_firmware = true; } else if (extension == "json") { - md5[0] = '\0'; // clear md5 + _md5[0] = '\0'; // clear md5 } else if (extension == "md5") { - if (len == 32) { - memcpy(md5, data, 32); - md5[32] = '\0'; + if (len == _md5.size() - 1) { + std::memcpy(_md5.data(), data, _md5.size() - 1); + _md5.back() = '\0'; } return; } else { - md5[0] = '\0'; + _md5.front() = '\0'; handleError(request, 406); // Not Acceptable - unsupported file type return; } - if (is_firmware) { + if (_is_firmware) { // Check firmware header, 0xE9 magic offset 0 indicates esp bin, chip offset 12: esp32:0, S2:2, C3:5 #if CONFIG_IDF_TARGET_ESP32 // ESP32/PICO-D4 if (len > 12 && (data[0] != 0xE9 || data[12] != 0)) { @@ -74,12 +79,12 @@ void UploadFileService::handleUpload(AsyncWebServerRequest * request, const Stri } #endif // it's firmware - initialize the ArduinoOTA updater - if (Update.begin(fsize - sizeof(esp_image_header_t))) { - if (strlen(md5) == 32) { - Update.setMD5(md5); - md5[0] = '\0'; + if (Update.begin(filesize - sizeof(esp_image_header_t))) { + if (strlen(_md5.data()) == _md5.size() - 1) { + Update.setMD5(_md5.data()); + _md5.front() = '\0'; } - request->onDisconnect(UploadFileService::handleEarlyDisconnect); // success, let's make sure we end the update if the client hangs up + request->onDisconnect([this]() { handleEarlyDisconnect(); }); // success, let's make sure we end the update if the client hangs up } else { handleError(request, 507); // failed to begin, send an error response Insufficient Storage return; @@ -90,23 +95,17 @@ void UploadFileService::handleUpload(AsyncWebServerRequest * request, const Stri } } - if (!is_firmware) { - if (len) { - if (len != request->_tempFile.write(data, len)) { // stream the incoming chunk to the opened file - handleError(request, 507); // 507-Insufficient Storage - } + if (!_is_firmware) { + if (len && len != request->_tempFile.write(data, len)) { // stream the incoming chunk to the opened file + handleError(request, 507); // 507-Insufficient Storage } - } else { - // if we haven't delt with an error, continue with the firmware update - if (!request->_tempObject) { - if (Update.write(data, len) != len) { - handleError(request, 500); - } - if (final) { - if (!Update.end(true)) { - handleError(request, 500); - } - } + } else if (!request->_tempObject) { // if we haven't delt with an error, continue with the firmware update + if (Update.write(data, len) != len) { + handleError(request, 500); + return; + } + if (final && !Update.end(true)) { + handleError(request, 500); } } } @@ -124,7 +123,7 @@ void UploadFileService::uploadComplete(AsyncWebServerRequest * request) { // check if it was a firmware upgrade // if no error, send the success response as a JSON - if (is_firmware && !request->_tempObject) { + if (_is_firmware && !request->_tempObject) { emsesp::EMSESP::system_.store_nvs_values(); request->onDisconnect(RestartService::restartNow); AsyncWebServerResponse * response = request->beginResponse(200); @@ -132,10 +131,10 @@ void UploadFileService::uploadComplete(AsyncWebServerRequest * request) { return; } - if (strlen(md5) == 32) { + if (strlen(_md5.data()) == _md5.size() - 1) { auto * response = new AsyncJsonResponse(false); JsonObject root = response->getRoot(); - root["md5"] = md5; + root["md5"] = _md5.data(); response->setLength(); request->send(response); return; @@ -163,6 +162,6 @@ void UploadFileService::handleError(AsyncWebServerRequest * request, int code) { } void UploadFileService::handleEarlyDisconnect() { - is_firmware = false; + _is_firmware = false; Update.abort(); -} +} \ No newline at end of file diff --git a/lib/framework/UploadFileService.h b/lib/framework/UploadFileService.h index 4abcdf7ce..0885805fa 100644 --- a/lib/framework/UploadFileService.h +++ b/lib/framework/UploadFileService.h @@ -1,16 +1,16 @@ #ifndef UploadFileService_h #define UploadFileService_h -#include +#include "RestartService.h" +#include "SecurityManager.h" +#include +#include +#include #include #include -#include - -#include -#include -#include +#include #define UPLOAD_FILE_PATH "/rest/uploadFile" #define TEMP_FILENAME_PATH "/tmp_upload" @@ -20,11 +20,14 @@ class UploadFileService { UploadFileService(AsyncWebServer * server, SecurityManager * securityManager); private: - SecurityManager * _securityManager; - void handleUpload(AsyncWebServerRequest * request, const String & filename, size_t index, uint8_t * data, size_t len, bool final); - void uploadComplete(AsyncWebServerRequest * request); - void handleError(AsyncWebServerRequest * request, int code); - static void handleEarlyDisconnect(); + SecurityManager * _securityManager; + bool _is_firmware; + std::array _md5; + + void handleUpload(AsyncWebServerRequest * request, const String & filename, size_t index, uint8_t * data, size_t len, bool final); + void uploadComplete(AsyncWebServerRequest * request); + void handleError(AsyncWebServerRequest * request, int code); + void handleEarlyDisconnect(); }; -#endif +#endif \ No newline at end of file diff --git a/lib/framework/WiFiScanner.cpp b/lib/framework/WiFiScanner.cpp index 51fd74bc1..c4e698361 100644 --- a/lib/framework/WiFiScanner.cpp +++ b/lib/framework/WiFiScanner.cpp @@ -1,14 +1,12 @@ -#include - -using namespace std::placeholders; // for `_1` etc +#include "WiFiScanner.h" WiFiScanner::WiFiScanner(AsyncWebServer * server, SecurityManager * securityManager) { server->on(SCAN_NETWORKS_SERVICE_PATH, HTTP_GET, - securityManager->wrapRequest(std::bind(&WiFiScanner::scanNetworks, this, _1), AuthenticationPredicates::IS_ADMIN)); + securityManager->wrapRequest([this](AsyncWebServerRequest * request) { scanNetworks(request); }, AuthenticationPredicates::IS_ADMIN)); server->on(LIST_NETWORKS_SERVICE_PATH, HTTP_GET, - securityManager->wrapRequest(std::bind(&WiFiScanner::listNetworks, this, _1), AuthenticationPredicates::IS_ADMIN)); + securityManager->wrapRequest([this](AsyncWebServerRequest * request) { listNetworks(request); }, AuthenticationPredicates::IS_ADMIN)); }; void WiFiScanner::scanNetworks(AsyncWebServerRequest * request) { @@ -21,18 +19,18 @@ void WiFiScanner::scanNetworks(AsyncWebServerRequest * request) { } void WiFiScanner::listNetworks(AsyncWebServerRequest * request) { - int numNetworks = WiFi.scanComplete(); + const int numNetworks = WiFi.scanComplete(); if (numNetworks > -1) { - AsyncJsonResponse * response = new AsyncJsonResponse(false); - JsonObject root = response->getRoot(); - JsonArray networks = root["networks"].to(); - for (int i = 0; i < numNetworks; i++) { + auto * response = new AsyncJsonResponse(false); + JsonObject root = response->getRoot(); + JsonArray networks = root["networks"].to(); + for (uint8_t i = 0; i < numNetworks; i++) { JsonObject network = networks.add(); network["rssi"] = WiFi.RSSI(i); network["ssid"] = WiFi.SSID(i); network["bssid"] = WiFi.BSSIDstr(i); network["channel"] = WiFi.channel(i); - network["encryption_type"] = (uint8_t)WiFi.encryptionType(i); + network["encryption_type"] = static_cast(WiFi.encryptionType(i)); } response->setLength(); request->send(response); diff --git a/lib/framework/WiFiScanner.h b/lib/framework/WiFiScanner.h index e73a2e669..7c76bdb15 100644 --- a/lib/framework/WiFiScanner.h +++ b/lib/framework/WiFiScanner.h @@ -3,10 +3,10 @@ #include #include - #include #include -#include + +#include "SecurityManager.h" #define SCAN_NETWORKS_SERVICE_PATH "/rest/scanNetworks" #define LIST_NETWORKS_SERVICE_PATH "/rest/listNetworks" diff --git a/lib_standalone/StatefulService.h b/lib_standalone/StatefulService.h index 0210bc1b3..ceb2ae965 100644 --- a/lib_standalone/StatefulService.h +++ b/lib_standalone/StatefulService.h @@ -68,7 +68,7 @@ class StatefulService { } } - StateUpdateResult update(std::function stateUpdater, ) { + StateUpdateResult update(std::function stateUpdater) { beginTransaction(); StateUpdateResult result = stateUpdater(_state); endTransaction(); @@ -85,7 +85,7 @@ class StatefulService { return result; } - StateUpdateResult update(JsonObject jsonObject, JsonStateUpdater stateUpdater, ) { + StateUpdateResult update(JsonObject jsonObject, JsonStateUpdater stateUpdater) { beginTransaction(); StateUpdateResult result = stateUpdater(jsonObject, _state); endTransaction(); diff --git a/src/emsesp.h b/src/emsesp.h index 324ed9ad5..427476e41 100644 --- a/src/emsesp.h +++ b/src/emsesp.h @@ -38,8 +38,7 @@ #endif #include -#include - +#include "ESP8266React.h" #include "web/WebStatusService.h" #include "web/WebDataService.h" #include "web/WebSettingsService.h" diff --git a/src/emsesp_stub.hpp b/src/emsesp_stub.hpp index 2f8eb0535..d028b30ec 100644 --- a/src/emsesp_stub.hpp +++ b/src/emsesp_stub.hpp @@ -24,8 +24,7 @@ #include "version.h" #include "default_settings.h" #include "helpers.h" - -#include +#include "ESP8266React.h" #include diff --git a/src/telegram.h b/src/telegram.h index fb047823d..aba93af64 100644 --- a/src/telegram.h +++ b/src/telegram.h @@ -21,16 +21,15 @@ #include #include +#include // UART drivers #if defined(ESP32) #include "uart/emsuart_esp32.h" #elif defined(EMSESP_STANDALONE) -#include +#include "emsuart_standalone.h" #endif -#include - #include "helpers.h" #define MAX_RX_TELEGRAMS 10 // size of Rx queue diff --git a/src/version.h b/src/version.h index 259e9ea01..2caf6b5af 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define EMSESP_APP_VERSION "3.6.5-dev.13" +#define EMSESP_APP_VERSION "3.6.5-dev.14" diff --git a/src/web/WebAPIService.cpp b/src/web/WebAPIService.cpp index f997cd5f8..be53e9f4c 100644 --- a/src/web/WebAPIService.cpp +++ b/src/web/WebAPIService.cpp @@ -18,8 +18,6 @@ #include "emsesp.h" -using namespace std::placeholders; // for `_1` etc - namespace emsesp { uint32_t WebAPIService::api_count_ = 0; @@ -27,17 +25,26 @@ uint16_t WebAPIService::api_fails_ = 0; WebAPIService::WebAPIService(AsyncWebServer * server, SecurityManager * securityManager) : _securityManager(securityManager) - , _apiHandler("/api", std::bind(&WebAPIService::webAPIService_post, this, _1, _2)) { // for POSTS, must use 'Content-Type: application/json' in header - server->on("/api", HTTP_GET, std::bind(&WebAPIService::webAPIService_get, this, _1)); // for GETS + , _apiHandler(EMSESP_API_SERVICE_PATH, [this](AsyncWebServerRequest * request, JsonVariant json) { webAPIService_post(request, json); }) { // for POSTs + server->on(EMSESP_API_SERVICE_PATH, HTTP_GET, [this](AsyncWebServerRequest * request) { webAPIService_get(request); }); // for GETs server->addHandler(&_apiHandler); // for settings - server->on(GET_SETTINGS_PATH, HTTP_GET, securityManager->wrapRequest(std::bind(&WebAPIService::getSettings, this, _1), AuthenticationPredicates::IS_ADMIN)); + server->on(GET_SETTINGS_PATH, + HTTP_GET, + securityManager->wrapRequest([this](AsyncWebServerRequest * request) { getSettings(request); }, AuthenticationPredicates::IS_ADMIN)); + server->on(GET_CUSTOMIZATIONS_PATH, HTTP_GET, - securityManager->wrapRequest(std::bind(&WebAPIService::getCustomizations, this, _1), AuthenticationPredicates::IS_ADMIN)); - server->on(GET_SCHEDULE_PATH, HTTP_GET, securityManager->wrapRequest(std::bind(&WebAPIService::getSchedule, this, _1), AuthenticationPredicates::IS_ADMIN)); - server->on(GET_ENTITIES_PATH, HTTP_GET, securityManager->wrapRequest(std::bind(&WebAPIService::getEntities, this, _1), AuthenticationPredicates::IS_ADMIN)); + securityManager->wrapRequest([this](AsyncWebServerRequest * request) { getCustomizations(request); }, AuthenticationPredicates::IS_ADMIN)); + + server->on(GET_SCHEDULE_PATH, + HTTP_GET, + securityManager->wrapRequest([this](AsyncWebServerRequest * request) { getSchedule(request); }, AuthenticationPredicates::IS_ADMIN)); + + server->on(GET_ENTITIES_PATH, + HTTP_GET, + securityManager->wrapRequest([this](AsyncWebServerRequest * request) { getEntities(request); }, AuthenticationPredicates::IS_ADMIN)); } // HTTP GET diff --git a/src/web/WebCustomEntityService.cpp b/src/web/WebCustomEntityService.cpp index 998faa611..7cbc1b7a0 100644 --- a/src/web/WebCustomEntityService.cpp +++ b/src/web/WebCustomEntityService.cpp @@ -20,8 +20,6 @@ namespace emsesp { -using namespace std::placeholders; // for `_1` etc - WebCustomEntityService::WebCustomEntityService(AsyncWebServer * server, FS * fs, SecurityManager * securityManager) : _httpEndpoint(WebCustomEntity::read, WebCustomEntity::update, diff --git a/src/web/WebCustomizationService.cpp b/src/web/WebCustomizationService.cpp index 62b8839bf..1181190e4 100644 --- a/src/web/WebCustomizationService.cpp +++ b/src/web/WebCustomizationService.cpp @@ -20,27 +20,24 @@ namespace emsesp { -using namespace std::placeholders; // for `_1` etc - bool WebCustomization::_start = true; WebCustomizationService::WebCustomizationService(AsyncWebServer * server, FS * fs, SecurityManager * securityManager) : _fsPersistence(WebCustomization::read, WebCustomization::update, this, fs, EMSESP_CUSTOMIZATION_FILE) , _masked_entities_handler(CUSTOMIZATION_ENTITIES_PATH, - securityManager->wrapCallback(std::bind(&WebCustomizationService::customization_entities, this, _1, _2), + securityManager->wrapCallback([this](AsyncWebServerRequest * request, JsonVariant json) { customization_entities(request, json); }, AuthenticationPredicates::IS_AUTHENTICATED)) { server->on(DEVICE_ENTITIES_PATH, HTTP_GET, - securityManager->wrapRequest(std::bind(&WebCustomizationService::device_entities, this, _1), AuthenticationPredicates::IS_AUTHENTICATED)); - + securityManager->wrapRequest([this](AsyncWebServerRequest * request) { device_entities(request); }, AuthenticationPredicates::IS_AUTHENTICATED)); server->on(DEVICES_SERVICE_PATH, HTTP_GET, - securityManager->wrapRequest(std::bind(&WebCustomizationService::devices, this, _1), AuthenticationPredicates::IS_AUTHENTICATED)); + securityManager->wrapRequest([this](AsyncWebServerRequest * request) { devices(request); }, AuthenticationPredicates::IS_AUTHENTICATED)); server->on(RESET_CUSTOMIZATION_SERVICE_PATH, HTTP_POST, - securityManager->wrapRequest(std::bind(&WebCustomizationService::reset_customization, this, _1), AuthenticationPredicates::IS_ADMIN)); + securityManager->wrapRequest([this](AsyncWebServerRequest * request) { reset_customization(request); }, AuthenticationPredicates::IS_ADMIN)); _masked_entities_handler.setMethod(HTTP_POST); _masked_entities_handler.setMaxContentLength(2048); diff --git a/src/web/WebDataService.cpp b/src/web/WebDataService.cpp index 4fba68a1f..2fb7f624b 100644 --- a/src/web/WebDataService.cpp +++ b/src/web/WebDataService.cpp @@ -20,33 +20,36 @@ namespace emsesp { -using namespace std::placeholders; // for `_1` etc - WebDataService::WebDataService(AsyncWebServer * server, SecurityManager * securityManager) : _write_value_handler(WRITE_DEVICE_VALUE_SERVICE_PATH, - securityManager->wrapCallback(std::bind(&WebDataService::write_device_value, this, _1, _2), AuthenticationPredicates::IS_ADMIN)) + securityManager->wrapCallback([this](AsyncWebServerRequest * request, JsonVariant json) { write_device_value(request, json); }, + AuthenticationPredicates::IS_ADMIN)) , _write_temperature_handler(WRITE_TEMPERATURE_SENSOR_SERVICE_PATH, - securityManager->wrapCallback(std::bind(&WebDataService::write_temperature_sensor, this, _1, _2), + securityManager->wrapCallback([this](AsyncWebServerRequest * request, + JsonVariant json) { write_temperature_sensor(request, json); }, AuthenticationPredicates::IS_ADMIN)) , _write_analog_handler(WRITE_ANALOG_SENSOR_SERVICE_PATH, - securityManager->wrapCallback(std::bind(&WebDataService::write_analog_sensor, this, _1, _2), AuthenticationPredicates::IS_ADMIN)) { + securityManager->wrapCallback([this](AsyncWebServerRequest * request, JsonVariant json) { write_analog_sensor(request, json); }, + AuthenticationPredicates::IS_ADMIN)) { // GET's server->on(DEVICE_DATA_SERVICE_PATH, HTTP_GET, - securityManager->wrapRequest(std::bind(&WebDataService::device_data, this, _1), AuthenticationPredicates::IS_AUTHENTICATED)); + securityManager->wrapRequest([this](AsyncWebServerRequest * request) { device_data(request); }, AuthenticationPredicates::IS_AUTHENTICATED)); + server->on(CORE_DATA_SERVICE_PATH, HTTP_GET, - securityManager->wrapRequest(std::bind(&WebDataService::core_data, this, _1), AuthenticationPredicates::IS_AUTHENTICATED)); + securityManager->wrapRequest([this](AsyncWebServerRequest * request) { core_data(request); }, AuthenticationPredicates::IS_AUTHENTICATED)); server->on(SENSOR_DATA_SERVICE_PATH, HTTP_GET, - securityManager->wrapRequest(std::bind(&WebDataService::sensor_data, this, _1), AuthenticationPredicates::IS_AUTHENTICATED)); + securityManager->wrapRequest([this](AsyncWebServerRequest * request) { sensor_data(request); }, AuthenticationPredicates::IS_AUTHENTICATED)); // POST's server->on(SCAN_DEVICES_SERVICE_PATH, HTTP_POST, - securityManager->wrapRequest(std::bind(&WebDataService::scan_devices, this, _1), AuthenticationPredicates::IS_ADMIN)); + securityManager->wrapRequest([this](AsyncWebServerRequest * request) { scan_devices(request); }, AuthenticationPredicates::IS_ADMIN)); + _write_value_handler.setMethod(HTTP_POST); _write_value_handler.setMaxContentLength(256); diff --git a/src/web/WebLogService.cpp b/src/web/WebLogService.cpp index 0558f1a26..634c728b5 100644 --- a/src/web/WebLogService.cpp +++ b/src/web/WebLogService.cpp @@ -18,19 +18,18 @@ #include "emsesp.h" -using namespace std::placeholders; - namespace emsesp { WebLogService::WebLogService(AsyncWebServer * server, SecurityManager * securityManager) : events_(EVENT_SOURCE_LOG_PATH) - , setValues_(LOG_SETTINGS_PATH, std::bind(&WebLogService::setValues, this, _1, _2)) { + , setValues_(LOG_SETTINGS_PATH, [this](AsyncWebServerRequest * request, JsonVariant json) { setValues(request, json); }) { events_.setFilter(securityManager->filterRequest(AuthenticationPredicates::IS_ADMIN)); - server->on(LOG_SETTINGS_PATH, HTTP_GET, std::bind(&WebLogService::getValues, this, _1)); // get settings + // get settings + server->on(LOG_SETTINGS_PATH, HTTP_POST, [this](AsyncWebServerRequest * request) { getValues(request); }); // for bring back the whole log - is a command, hence a POST - server->on(FETCH_LOG_PATH, HTTP_POST, std::bind(&WebLogService::fetchLog, this, _1)); + server->on(FETCH_LOG_PATH, HTTP_POST, [this](AsyncWebServerRequest * request) { fetchLog(request); }); server->addHandler(&setValues_); server->addHandler(&events_); diff --git a/src/web/WebSchedulerService.cpp b/src/web/WebSchedulerService.cpp index a5d3e527b..52665811a 100644 --- a/src/web/WebSchedulerService.cpp +++ b/src/web/WebSchedulerService.cpp @@ -21,8 +21,6 @@ namespace emsesp { -using namespace std::placeholders; // for `_1` etc - WebSchedulerService::WebSchedulerService(AsyncWebServer * server, FS * fs, SecurityManager * securityManager) : _httpEndpoint(WebScheduler::read, WebScheduler::update, this, server, EMSESP_SCHEDULER_SERVICE_PATH, securityManager, AuthenticationPredicates::IS_AUTHENTICATED) , _fsPersistence(WebScheduler::read, WebScheduler::update, this, fs, EMSESP_SCHEDULER_FILE) { diff --git a/src/web/WebSettingsService.cpp b/src/web/WebSettingsService.cpp index 04ce8f8eb..16f1015ea 100644 --- a/src/web/WebSettingsService.cpp +++ b/src/web/WebSettingsService.cpp @@ -22,17 +22,13 @@ namespace emsesp { uint8_t WebSettings::flags_ = 0; -using namespace std::placeholders; // for `_1` etc - WebSettingsService::WebSettingsService(AsyncWebServer * server, FS * fs, SecurityManager * securityManager) : _httpEndpoint(WebSettings::read, WebSettings::update, this, server, EMSESP_SETTINGS_SERVICE_PATH, securityManager) , _fsPersistence(WebSettings::read, WebSettings::update, this, fs, EMSESP_SETTINGS_FILE) { - // GET server->on(EMSESP_BOARD_PROFILE_SERVICE_PATH, HTTP_GET, - securityManager->wrapRequest(std::bind(&WebSettingsService::board_profile, this, _1), AuthenticationPredicates::IS_ADMIN)); - - addUpdateHandler([&] { onUpdate(); }, false); + securityManager->wrapRequest([this](AsyncWebServerRequest * request) { board_profile(request); }, AuthenticationPredicates::IS_AUTHENTICATED)); + addUpdateHandler([this] { onUpdate(); }, false); } void WebSettings::read(WebSettings & settings, JsonObject root) { diff --git a/src/web/WebStatusService.cpp b/src/web/WebStatusService.cpp index 773d73927..9fab268c9 100644 --- a/src/web/WebStatusService.cpp +++ b/src/web/WebStatusService.cpp @@ -18,14 +18,12 @@ #include "emsesp.h" -using namespace std::placeholders; // for `_1` etc - namespace emsesp { WebStatusService::WebStatusService(AsyncWebServer * server, SecurityManager * securityManager) { server->on(EMSESP_STATUS_SERVICE_PATH, HTTP_GET, - securityManager->wrapRequest(std::bind(&WebStatusService::webStatusService, this, _1), AuthenticationPredicates::IS_AUTHENTICATED)); + securityManager->wrapRequest([this](AsyncWebServerRequest * request) { webStatusService(request); }, AuthenticationPredicates::IS_AUTHENTICATED)); } void WebStatusService::webStatusService(AsyncWebServerRequest * request) { From 6cd9dfc68545d3adeca7cc6a2e27504355c38856 Mon Sep 17 00:00:00 2001 From: Proddy Date: Mon, 12 Feb 2024 14:25:21 +0100 Subject: [PATCH 25/54] fixes for #1615 --- lib/framework/NetworkSettingsService.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/lib/framework/NetworkSettingsService.cpp b/lib/framework/NetworkSettingsService.cpp index 83cd8b0c2..8761e9564 100644 --- a/lib/framework/NetworkSettingsService.cpp +++ b/lib/framework/NetworkSettingsService.cpp @@ -123,7 +123,7 @@ void NetworkSettingsService::setWiFiPowerOnRSSI() { // 802.11ax - wifi6 int max_tx_pwr = MAX_TX_PWR_DBM_n; // assume wifi4 - int threshold = WIFI_SENSITIVITY_n + 30; // Margin in dBm * 10 on top of threshold + int threshold = WIFI_SENSITIVITY_n + 70; // Margin in dBm * 10 on top of threshold // Assume AP sends with max set by ETSI standard. // 2.4 GHz: 100 mWatt (20 dBm) @@ -155,27 +155,27 @@ void NetworkSettingsService::setWiFiPowerOnRSSI() { // WIFI_POWER_2dBm = 8,// 2dBm // WIFI_POWER_MINUS_1dBm = -4// -1dBm wifi_power_t p = WIFI_POWER_2dBm; - if (set_power > 19) + if (min_tx_pwr > 185) p = WIFI_POWER_19_5dBm; - else if (set_power > 18) + else if (min_tx_pwr > 170) p = WIFI_POWER_18_5dBm; - else if (set_power >= 17) + else if (min_tx_pwr > 150) p = WIFI_POWER_17dBm; - else if (set_power >= 15) + else if (min_tx_pwr > 130) p = WIFI_POWER_15dBm; - else if (set_power >= 13) + else if (min_tx_pwr > 110) p = WIFI_POWER_13dBm; - else if (set_power >= 11) + else if (min_tx_pwr > 85) p = WIFI_POWER_11dBm; - else if (set_power >= 8) + else if (min_tx_pwr > 70) p = WIFI_POWER_8_5dBm; - else if (set_power >= 7) + else if (min_tx_pwr > 50) p = WIFI_POWER_7dBm; - else if (set_power >= 5) + else if (min_tx_pwr > 20) p = WIFI_POWER_5dBm; #ifdef EMSESP_DEBUG - emsesp::EMSESP::logger().debug("Recommended set WiFi Tx Power (set_power %d, new power %d, rssi %d, threshold %d", set_power, p, rssi, threshold); + emsesp::EMSESP::logger().debug("Recommended set WiFi Tx Power (set_power %d, new power %d, rssi %d, threshold %d)", set_power, p, rssi, threshold); #else char result[10]; emsesp::EMSESP::logger().info("Setting WiFi Tx Power to %s dBm", emsesp::Helpers::render_value(result, ((double)(p) / 4), 1)); From a8a875f9d5ccb410afbd5a80ebda0bf356ed8ffe Mon Sep 17 00:00:00 2001 From: Proddy Date: Mon, 12 Feb 2024 14:40:08 +0100 Subject: [PATCH 26/54] add missing tx_power --- lib/framework/NetworkSettingsService.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/framework/NetworkSettingsService.cpp b/lib/framework/NetworkSettingsService.cpp index 8761e9564..28ef6c880 100644 --- a/lib/framework/NetworkSettingsService.cpp +++ b/lib/framework/NetworkSettingsService.cpp @@ -398,6 +398,7 @@ void NetworkSettings::read(NetworkSettings & settings, JsonObject root) { root["enableMDNS"] = settings.enableMDNS; root["enableCORS"] = settings.enableCORS; root["CORSOrigin"] = settings.CORSOrigin; + root["tx_power"] = settings.tx_power; // extended settings JsonUtils::writeIP(root, "local_ip", settings.localIP); From 644907e58b76b709e6892ef7e3e14f6aec9534e8 Mon Sep 17 00:00:00 2001 From: Proddy Date: Mon, 12 Feb 2024 14:51:10 +0100 Subject: [PATCH 27/54] fix error in event log --- src/web/WebLogService.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/web/WebLogService.cpp b/src/web/WebLogService.cpp index 634c728b5..f4132b79d 100644 --- a/src/web/WebLogService.cpp +++ b/src/web/WebLogService.cpp @@ -26,7 +26,7 @@ WebLogService::WebLogService(AsyncWebServer * server, SecurityManager * security events_.setFilter(securityManager->filterRequest(AuthenticationPredicates::IS_ADMIN)); // get settings - server->on(LOG_SETTINGS_PATH, HTTP_POST, [this](AsyncWebServerRequest * request) { getValues(request); }); + server->on(LOG_SETTINGS_PATH, HTTP_GET, [this](AsyncWebServerRequest * request) { getValues(request); }); // for bring back the whole log - is a command, hence a POST server->on(FETCH_LOG_PATH, HTTP_POST, [this](AsyncWebServerRequest * request) { fetchLog(request); }); From 295b90f49cfa1a1459af0e1cab023cda4bd21e9e Mon Sep 17 00:00:00 2001 From: proddy Date: Tue, 13 Feb 2024 10:56:50 +0100 Subject: [PATCH 28/54] NTP log text --- src/system.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/system.cpp b/src/system.cpp index 5a1752943..c8f007b24 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -1557,8 +1557,8 @@ std::string System::reset_reason(uint8_t cpu) const { // set NTP status void System::ntp_connected(bool b) { - if (b != ntp_connected_) { - LOG_INFO(b ? "NTP connected" : "NTP disconnected"); // if changed report it + if (b != ntp_connected_ && !b) { + LOG_WARNING("NTP disconnected"); // if turned off report it } ntp_connected_ = b; From 12e65279ef6bb696cc20856b15488d8604eb38a3 Mon Sep 17 00:00:00 2001 From: proddy Date: Tue, 13 Feb 2024 10:56:56 +0100 Subject: [PATCH 29/54] package update --- interface/.eslintrc.json | 4 +- interface/package.json | 10 +- interface/yarn.lock | 205 ++++++++++++++------------------------- 3 files changed, 81 insertions(+), 138 deletions(-) diff --git a/interface/.eslintrc.json b/interface/.eslintrc.json index 199f83753..781a0705b 100644 --- a/interface/.eslintrc.json +++ b/interface/.eslintrc.json @@ -5,8 +5,8 @@ }, "extends": [ "eslint:recommended", - "airbnb/hooks", - "airbnb-typescript", + // "airbnb/hooks", + // "airbnb-typescript", "plugin:react/recommended", "plugin:react/jsx-runtime", "plugin:@typescript-eslint/recommended", diff --git a/interface/package.json b/interface/package.json index 14b862a2a..ecca8641b 100644 --- a/interface/package.json +++ b/interface/package.json @@ -26,8 +26,8 @@ "@babel/core": "^7.23.9", "@emotion/react": "^11.11.3", "@emotion/styled": "^11.11.0", - "@mui/icons-material": "^5.15.9", - "@mui/material": "^5.15.9", + "@mui/icons-material": "^5.15.10", + "@mui/material": "^5.15.10", "@table-library/react-table-library": "4.1.7", "@types/imagemin": "^8.0.5", "@types/lodash-es": "^4.17.12", @@ -54,12 +54,10 @@ "devDependencies": { "@preact/compat": "^17.1.2", "@preact/preset-vite": "^2.8.1", - "@typescript-eslint/eslint-plugin": "^6.21.0", - "@typescript-eslint/parser": "^6.21.0", + "@typescript-eslint/eslint-plugin": "^7.0.1", + "@typescript-eslint/parser": "^7.0.1", "concurrently": "^8.2.2", "eslint": "^8.56.0", - "eslint-config-airbnb": "^19.0.4", - "eslint-config-airbnb-typescript": "^17.1.0", "eslint-config-prettier": "^9.1.0", "eslint-import-resolver-typescript": "^3.6.1", "eslint-plugin-autofix": "^1.1.0", diff --git a/interface/yarn.lock b/interface/yarn.lock index 10b067180..8320022b6 100644 --- a/interface/yarn.lock +++ b/interface/yarn.lock @@ -1014,16 +1014,16 @@ __metadata: languageName: node linkType: hard -"@mui/core-downloads-tracker@npm:^5.15.9": - version: 5.15.9 - resolution: "@mui/core-downloads-tracker@npm:5.15.9" - checksum: 10/f0f7af8e8f6f50df29a4e41ecb59c75869f760f22df0dc534476094089c74edcd7eacb4d17e636e0b7dd06ea1f3bb6564b21dbe072f89d1b9d87373760d69e2b +"@mui/core-downloads-tracker@npm:^5.15.10": + version: 5.15.10 + resolution: "@mui/core-downloads-tracker@npm:5.15.10" + checksum: 10/aeb16b31f60c08cc03585fedadceadd54aa48dda394fb945ab885f884c1b1692efb72309465641b6ca2367bd53d5fdce15f189d4691f42b59206622ffb2d6f0f languageName: node linkType: hard -"@mui/icons-material@npm:^5.15.9": - version: 5.15.9 - resolution: "@mui/icons-material@npm:5.15.9" +"@mui/icons-material@npm:^5.15.10": + version: 5.15.10 + resolution: "@mui/icons-material@npm:5.15.10" dependencies: "@babel/runtime": "npm:^7.23.9" peerDependencies: @@ -1033,17 +1033,17 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 10/bcda24107125108569fe8252d05297f441362d33dbb96f8c32b35ac6d280a3c9a2f03548344c73d316e26c89d2d3e74057b292be6677ab1b582d94b6cf3ba100 + checksum: 10/ce22c02dc7ed960a21f8d5ea7c4d4fc03d9f71e8a26ced02f75da1ffd6c768e6fa0682a308a03be53bffc2325a5aaf68be69f9e192b0a57c6752f7548e5b9045 languageName: node linkType: hard -"@mui/material@npm:^5.15.9": - version: 5.15.9 - resolution: "@mui/material@npm:5.15.9" +"@mui/material@npm:^5.15.10": + version: 5.15.10 + resolution: "@mui/material@npm:5.15.10" dependencies: "@babel/runtime": "npm:^7.23.9" "@mui/base": "npm:5.0.0-beta.36" - "@mui/core-downloads-tracker": "npm:^5.15.9" + "@mui/core-downloads-tracker": "npm:^5.15.10" "@mui/system": "npm:^5.15.9" "@mui/types": "npm:^7.2.13" "@mui/utils": "npm:^5.15.9" @@ -1066,7 +1066,7 @@ __metadata: optional: true "@types/react": optional: true - checksum: 10/fbbb33f83520f2f0a31d7a75be02c3c038da0bd2d2a914eadbe890783f18e9a93f818ea93da21cc6a6c303352662b4da764c67094183cee5133f810ffabead07 + checksum: 10/a88ad1287a905549ed516742544c8ba32f0cd7e1b184564efc8ceba5f43060d37b5cd113db605f1bb5be6c74cbdad7321d3fd7df410ba33d55548cf7c5bbf8d0 languageName: node linkType: hard @@ -1713,15 +1713,15 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:^6.21.0": - version: 6.21.0 - resolution: "@typescript-eslint/eslint-plugin@npm:6.21.0" +"@typescript-eslint/eslint-plugin@npm:^7.0.1": + version: 7.0.1 + resolution: "@typescript-eslint/eslint-plugin@npm:7.0.1" dependencies: "@eslint-community/regexpp": "npm:^4.5.1" - "@typescript-eslint/scope-manager": "npm:6.21.0" - "@typescript-eslint/type-utils": "npm:6.21.0" - "@typescript-eslint/utils": "npm:6.21.0" - "@typescript-eslint/visitor-keys": "npm:6.21.0" + "@typescript-eslint/scope-manager": "npm:7.0.1" + "@typescript-eslint/type-utils": "npm:7.0.1" + "@typescript-eslint/utils": "npm:7.0.1" + "@typescript-eslint/visitor-keys": "npm:7.0.1" debug: "npm:^4.3.4" graphemer: "npm:^1.4.0" ignore: "npm:^5.2.4" @@ -1729,73 +1729,73 @@ __metadata: semver: "npm:^7.5.4" ts-api-utils: "npm:^1.0.1" peerDependencies: - "@typescript-eslint/parser": ^6.0.0 || ^6.0.0-alpha - eslint: ^7.0.0 || ^8.0.0 + "@typescript-eslint/parser": ^7.0.0 + eslint: ^8.56.0 peerDependenciesMeta: typescript: optional: true - checksum: 10/a57de0f630789330204cc1531f86cfc68b391cafb1ba67c8992133f1baa2a09d629df66e71260b040de4c9a3ff1252952037093c4128b0d56c4dbb37720b4c1d + checksum: 10/0862e8ec8677fcea794394fc9eab8dba11043c08452722790e0d296d4ee84713180676e1e3135be4203ace7bb73933c94159255cb9190c7bc13bf7f03a361915 languageName: node linkType: hard -"@typescript-eslint/parser@npm:^6.21.0": - version: 6.21.0 - resolution: "@typescript-eslint/parser@npm:6.21.0" +"@typescript-eslint/parser@npm:^7.0.1": + version: 7.0.1 + resolution: "@typescript-eslint/parser@npm:7.0.1" dependencies: - "@typescript-eslint/scope-manager": "npm:6.21.0" - "@typescript-eslint/types": "npm:6.21.0" - "@typescript-eslint/typescript-estree": "npm:6.21.0" - "@typescript-eslint/visitor-keys": "npm:6.21.0" + "@typescript-eslint/scope-manager": "npm:7.0.1" + "@typescript-eslint/types": "npm:7.0.1" + "@typescript-eslint/typescript-estree": "npm:7.0.1" + "@typescript-eslint/visitor-keys": "npm:7.0.1" debug: "npm:^4.3.4" peerDependencies: - eslint: ^7.0.0 || ^8.0.0 + eslint: ^8.56.0 peerDependenciesMeta: typescript: optional: true - checksum: 10/4d51cdbc170e72275efc5ef5fce48a81ec431e4edde8374f4d0213d8d370a06823e1a61ae31d502a5f1b0d1f48fc4d29a1b1b5c2dcf809d66d3872ccf6e46ac7 + checksum: 10/b4ba1743ab730268a1924139f072e4a0a56959526fb6377e1b3964518b6c6851733ae446a44d29fed1cb96669e2913cca524895ce77a6205aaed8bda00e8cd5d languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:6.21.0": - version: 6.21.0 - resolution: "@typescript-eslint/scope-manager@npm:6.21.0" +"@typescript-eslint/scope-manager@npm:7.0.1": + version: 7.0.1 + resolution: "@typescript-eslint/scope-manager@npm:7.0.1" dependencies: - "@typescript-eslint/types": "npm:6.21.0" - "@typescript-eslint/visitor-keys": "npm:6.21.0" - checksum: 10/fe91ac52ca8e09356a71dc1a2f2c326480f3cccfec6b2b6d9154c1a90651ab8ea270b07c67df5678956c3bbf0bbe7113ab68f68f21b20912ea528b1214197395 + "@typescript-eslint/types": "npm:7.0.1" + "@typescript-eslint/visitor-keys": "npm:7.0.1" + checksum: 10/dade6055bb853adb54de795cc3da5ab8550236d4186f108573fdb02e636ab7fc4300a55b506698ced4087ca43b143a5593931cb3195ab4790470b456d9ff8846 languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:6.21.0": - version: 6.21.0 - resolution: "@typescript-eslint/type-utils@npm:6.21.0" +"@typescript-eslint/type-utils@npm:7.0.1": + version: 7.0.1 + resolution: "@typescript-eslint/type-utils@npm:7.0.1" dependencies: - "@typescript-eslint/typescript-estree": "npm:6.21.0" - "@typescript-eslint/utils": "npm:6.21.0" + "@typescript-eslint/typescript-estree": "npm:7.0.1" + "@typescript-eslint/utils": "npm:7.0.1" debug: "npm:^4.3.4" ts-api-utils: "npm:^1.0.1" peerDependencies: - eslint: ^7.0.0 || ^8.0.0 + eslint: ^8.56.0 peerDependenciesMeta: typescript: optional: true - checksum: 10/d03fb3ee1caa71f3ce053505f1866268d7ed79ffb7fed18623f4a1253f5b8f2ffc92636d6fd08fcbaf5bd265a6de77bf192c53105131e4724643dfc910d705fc + checksum: 10/cf20a3c0e56121ac62467e48121e135798db6d2999bd4f96ed44edc39f2597812d12b1bd6a378adec54d6c5e7db75fa5f98a27ce399792a2c8a5bbd3649952f7 languageName: node linkType: hard -"@typescript-eslint/types@npm:6.21.0": - version: 6.21.0 - resolution: "@typescript-eslint/types@npm:6.21.0" - checksum: 10/e26da86d6f36ca5b6ef6322619f8ec55aabcd7d43c840c977ae13ae2c964c3091fc92eb33730d8be08927c9de38466c5323e78bfb270a9ff1d3611fe821046c5 +"@typescript-eslint/types@npm:7.0.1": + version: 7.0.1 + resolution: "@typescript-eslint/types@npm:7.0.1" + checksum: 10/c08b2d34bab2a877a45a1e4c2923f50d03022b682b7aaba929ae2a9a5ad32db0e46265544a6616ccb98654b434250621be0e282fc5b21b8ccaf6b78741d68f67 languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:6.21.0": - version: 6.21.0 - resolution: "@typescript-eslint/typescript-estree@npm:6.21.0" +"@typescript-eslint/typescript-estree@npm:7.0.1": + version: 7.0.1 + resolution: "@typescript-eslint/typescript-estree@npm:7.0.1" dependencies: - "@typescript-eslint/types": "npm:6.21.0" - "@typescript-eslint/visitor-keys": "npm:6.21.0" + "@typescript-eslint/types": "npm:7.0.1" + "@typescript-eslint/visitor-keys": "npm:7.0.1" debug: "npm:^4.3.4" globby: "npm:^11.1.0" is-glob: "npm:^4.0.3" @@ -1805,34 +1805,34 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 10/b32fa35fca2a229e0f5f06793e5359ff9269f63e9705e858df95d55ca2cd7fdb5b3e75b284095a992c48c5fc46a1431a1a4b6747ede2dd08929dc1cbacc589b8 + checksum: 10/b0b0adc84502d1ffcf3a0024179e0f2780be5f8b0a18328db46d430efc4e38a7965656b4392dd47d6176bbb1ee200aec6dd8581c39b606e260750574358cde9f languageName: node linkType: hard -"@typescript-eslint/utils@npm:6.21.0": - version: 6.21.0 - resolution: "@typescript-eslint/utils@npm:6.21.0" +"@typescript-eslint/utils@npm:7.0.1": + version: 7.0.1 + resolution: "@typescript-eslint/utils@npm:7.0.1" dependencies: "@eslint-community/eslint-utils": "npm:^4.4.0" "@types/json-schema": "npm:^7.0.12" "@types/semver": "npm:^7.5.0" - "@typescript-eslint/scope-manager": "npm:6.21.0" - "@typescript-eslint/types": "npm:6.21.0" - "@typescript-eslint/typescript-estree": "npm:6.21.0" + "@typescript-eslint/scope-manager": "npm:7.0.1" + "@typescript-eslint/types": "npm:7.0.1" + "@typescript-eslint/typescript-estree": "npm:7.0.1" semver: "npm:^7.5.4" peerDependencies: - eslint: ^7.0.0 || ^8.0.0 - checksum: 10/b404a2c55a425a79d054346ae123087d30c7ecf7ed7abcf680c47bf70c1de4fabadc63434f3f460b2fa63df76bc9e4a0b9fa2383bb8a9fcd62733fb5c4e4f3e3 + eslint: ^8.56.0 + checksum: 10/b7e0cb2994f73b3f416684dc175d4e1da5f8306d6c81abbad2f219fa3e4f29154063a3c9568e4a1f879a38b79c62250e596e4ed7265f7bd1ed9b3db806cb92b7 languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:6.21.0": - version: 6.21.0 - resolution: "@typescript-eslint/visitor-keys@npm:6.21.0" +"@typescript-eslint/visitor-keys@npm:7.0.1": + version: 7.0.1 + resolution: "@typescript-eslint/visitor-keys@npm:7.0.1" dependencies: - "@typescript-eslint/types": "npm:6.21.0" + "@typescript-eslint/types": "npm:7.0.1" eslint-visitor-keys: "npm:^3.4.1" - checksum: 10/30422cdc1e2ffad203df40351a031254b272f9c6f2b7e02e9bfa39e3fc2c7b1c6130333b0057412968deda17a3a68a578a78929a8139c6acef44d9d841dc72e1 + checksum: 10/915c5b19302a4c76e843cd2d04a9a2b11907e658d7018c8b55c338b090d9115d3719809aa05b8af130cc1b216c77626d210c20f705b732e83d04ceae0c112f6b languageName: node linkType: hard @@ -1851,8 +1851,8 @@ __metadata: "@babel/core": "npm:^7.23.9" "@emotion/react": "npm:^11.11.3" "@emotion/styled": "npm:^11.11.0" - "@mui/icons-material": "npm:^5.15.9" - "@mui/material": "npm:^5.15.9" + "@mui/icons-material": "npm:^5.15.10" + "@mui/material": "npm:^5.15.10" "@preact/compat": "npm:^17.1.2" "@preact/preset-vite": "npm:^2.8.1" "@table-library/react-table-library": "npm:4.1.7" @@ -1862,14 +1862,12 @@ __metadata: "@types/react": "npm:^18.2.55" "@types/react-dom": "npm:^18.2.19" "@types/react-router-dom": "npm:^5.3.3" - "@typescript-eslint/eslint-plugin": "npm:^6.21.0" - "@typescript-eslint/parser": "npm:^6.21.0" + "@typescript-eslint/eslint-plugin": "npm:^7.0.1" + "@typescript-eslint/parser": "npm:^7.0.1" alova: "npm:^2.17.0" async-validator: "npm:^4.2.5" concurrently: "npm:^8.2.2" eslint: "npm:^8.56.0" - eslint-config-airbnb: "npm:^19.0.4" - eslint-config-airbnb-typescript: "npm:^17.1.0" eslint-config-prettier: "npm:^9.1.0" eslint-import-resolver-typescript: "npm:^3.6.1" eslint-plugin-autofix: "npm:^1.1.0" @@ -2738,13 +2736,6 @@ __metadata: languageName: node linkType: hard -"confusing-browser-globals@npm:^1.0.10": - version: 1.0.11 - resolution: "confusing-browser-globals@npm:1.0.11" - checksum: 10/3afc635abd37e566477f610e7978b15753f0e84025c25d49236f1f14d480117185516bdd40d2a2167e6bed8048641a9854964b9c067e3dcdfa6b5d0ad3c3a5ef - languageName: node - linkType: hard - "console-control-strings@npm:^1.1.0": version: 1.1.0 resolution: "console-control-strings@npm:1.1.0" @@ -3790,52 +3781,6 @@ __metadata: languageName: node linkType: hard -"eslint-config-airbnb-base@npm:^15.0.0": - version: 15.0.0 - resolution: "eslint-config-airbnb-base@npm:15.0.0" - dependencies: - confusing-browser-globals: "npm:^1.0.10" - object.assign: "npm:^4.1.2" - object.entries: "npm:^1.1.5" - semver: "npm:^6.3.0" - peerDependencies: - eslint: ^7.32.0 || ^8.2.0 - eslint-plugin-import: ^2.25.2 - checksum: 10/daa68a1dcb7bff338747a952723b5fa9d159980ec3554c395a4b52a7f7d4f00a45e7b465420eb6d4d87a82cef6361e4cfd6dbb38c2f3f52f2140b6cf13654803 - languageName: node - linkType: hard - -"eslint-config-airbnb-typescript@npm:^17.1.0": - version: 17.1.0 - resolution: "eslint-config-airbnb-typescript@npm:17.1.0" - dependencies: - eslint-config-airbnb-base: "npm:^15.0.0" - peerDependencies: - "@typescript-eslint/eslint-plugin": ^5.13.0 || ^6.0.0 - "@typescript-eslint/parser": ^5.0.0 || ^6.0.0 - eslint: ^7.32.0 || ^8.2.0 - eslint-plugin-import: ^2.25.3 - checksum: 10/a2238d820909ac005704e04d29ed495cebbe024869c488330273ea108e18cbf74b6b13e09d54d22a598fe793b9ed5ae593a7e8f9bdc6ea17614d5f2add340960 - languageName: node - linkType: hard - -"eslint-config-airbnb@npm:^19.0.4": - version: 19.0.4 - resolution: "eslint-config-airbnb@npm:19.0.4" - dependencies: - eslint-config-airbnb-base: "npm:^15.0.0" - object.assign: "npm:^4.1.2" - object.entries: "npm:^1.1.5" - peerDependencies: - eslint: ^7.32.0 || ^8.2.0 - eslint-plugin-import: ^2.25.3 - eslint-plugin-jsx-a11y: ^6.5.1 - eslint-plugin-react: ^7.28.0 - eslint-plugin-react-hooks: ^4.3.0 - checksum: 10/f2086523cfd20c42fd620c757281bd028aa8ce9dadc7293c5c23ea60947a2d3ca04404ede77b40f5a65250fe3c04502acafc4f2f6946819fe6c257d76d9644e5 - languageName: node - linkType: hard - "eslint-config-prettier@npm:^9.1.0": version: 9.1.0 resolution: "eslint-config-prettier@npm:9.1.0" @@ -6603,7 +6548,7 @@ __metadata: languageName: node linkType: hard -"object.assign@npm:^4.1.2, object.assign@npm:^4.1.4": +"object.assign@npm:^4.1.4": version: 4.1.4 resolution: "object.assign@npm:4.1.4" dependencies: @@ -6615,7 +6560,7 @@ __metadata: languageName: node linkType: hard -"object.entries@npm:^1.1.5, object.entries@npm:^1.1.6, object.entries@npm:^1.1.7": +"object.entries@npm:^1.1.6, object.entries@npm:^1.1.7": version: 1.1.7 resolution: "object.entries@npm:1.1.7" dependencies: @@ -7739,7 +7684,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:^6.0.0, semver@npm:^6.3.0, semver@npm:^6.3.1": +"semver@npm:^6.0.0, semver@npm:^6.3.1": version: 6.3.1 resolution: "semver@npm:6.3.1" bin: From 62ae5332de3c18013b07ce6043bcbb8624145826 Mon Sep 17 00:00:00 2001 From: proddy Date: Tue, 13 Feb 2024 10:57:11 +0100 Subject: [PATCH 30/54] use consistent log message format --- lib/framework/NetworkSettingsService.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/lib/framework/NetworkSettingsService.cpp b/lib/framework/NetworkSettingsService.cpp index 28ef6c880..44e65eaa1 100644 --- a/lib/framework/NetworkSettingsService.cpp +++ b/lib/framework/NetworkSettingsService.cpp @@ -205,11 +205,7 @@ void NetworkSettingsService::mDNS_start() const { MDNS.addServiceTxt("http", "tcp", "version", EMSESP_APP_VERSION); MDNS.addServiceTxt("http", "tcp", "address", address_s.c_str()); - emsesp::EMSESP::logger().info("mDNS Responder service started"); - } -#else - if (_state.enableMDNS) { - EMSESP::logger().info("mDNS Responder service started"); + emsesp::EMSESP::logger().info("Starting mDNS Responder service"); } #endif } From 4bf22dd6a55e2bae55b6ccf087f92d8f48db3ed8 Mon Sep 17 00:00:00 2001 From: proddy Date: Tue, 13 Feb 2024 10:57:37 +0100 Subject: [PATCH 31/54] refresh sync to 30ms for faster display in web --- src/web/WebLogService.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/web/WebLogService.h b/src/web/WebLogService.h index 083b10fdc..a7be311fb 100644 --- a/src/web/WebLogService.h +++ b/src/web/WebLogService.h @@ -28,7 +28,7 @@ namespace emsesp { class WebLogService : public uuid::log::Handler { public: static constexpr size_t MAX_LOG_MESSAGES = 50; - static constexpr size_t REFRESH_SYNC = 50; + static constexpr size_t REFRESH_SYNC = 30; WebLogService(AsyncWebServer * server, SecurityManager * securityManager); From f40a6f20c6755fd3528fd9d88c5c20d8ed1045f2 Mon Sep 17 00:00:00 2001 From: Proddy Date: Tue, 13 Feb 2024 15:16:58 +0100 Subject: [PATCH 32/54] change log text --- lib/framework/NetworkSettingsService.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/lib/framework/NetworkSettingsService.cpp b/lib/framework/NetworkSettingsService.cpp index 44e65eaa1..cf628175a 100644 --- a/lib/framework/NetworkSettingsService.cpp +++ b/lib/framework/NetworkSettingsService.cpp @@ -308,11 +308,10 @@ void NetworkSettingsService::WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info) case ARDUINO_EVENT_WIFI_STA_GOT_IP: char result[10]; - emsesp::EMSESP::logger().info("WiFi connected with IP=%s, hostname=%s, TxPower=%s dBm", + emsesp::EMSESP::logger().info("WiFi connected (IP=%s, hostname=%s, TxPower=%s dBm)", WiFi.localIP().toString().c_str(), WiFi.getHostname(), emsesp::Helpers::render_value(result, ((double)(WiFi.getTxPower()) / 4), 1)); - mDNS_start(); break; @@ -328,7 +327,7 @@ void NetworkSettingsService::WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info) case ARDUINO_EVENT_ETH_GOT_IP: // prevent double calls if (!emsesp::EMSESP::system_.ethernet_connected()) { - emsesp::EMSESP::logger().info("Ethernet connected with IP=%s, speed %d Mbps", ETH.localIP().toString().c_str(), ETH.linkSpeed()); + emsesp::EMSESP::logger().info("Ethernet connected (IP=%s, speed %d Mbps)", ETH.localIP().toString().c_str(), ETH.linkSpeed()); emsesp::EMSESP::system_.ethernet_connected(true); mDNS_start(); } @@ -347,8 +346,7 @@ void NetworkSettingsService::WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info) break; case ARDUINO_EVENT_WIFI_STA_CONNECTED: - // Set the TxPower after the connection is established - // if we're using TxPower = 0 (Auto) + // Set the TxPower after the connection is established, if we're using TxPower = 0 (Auto) if (_state.tx_power == 0) { setWiFiPowerOnRSSI(); } @@ -367,9 +365,12 @@ void NetworkSettingsService::WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info) case ARDUINO_EVENT_WIFI_STA_GOT_IP6: case ARDUINO_EVENT_ETH_GOT_IP6: if (emsesp::EMSESP::system_.ethernet_connected()) { - emsesp::EMSESP::logger().info("Ethernet connected with IPv6=%s, speed %d Mbps", ETH.localIPv6().toString().c_str(), ETH.linkSpeed()); + emsesp::EMSESP::logger().info("Ethernet connected (IPv6=%s, speed %d Mbps)", ETH.localIPv6().toString().c_str(), ETH.linkSpeed()); } else { - emsesp::EMSESP::logger().info("WiFi connected with IPv6=%s, hostname=%s", WiFi.localIPv6().toString().c_str(), WiFi.getHostname()); + emsesp::EMSESP::logger().info("WiFi connected (IPv6=%s, hostname=%s, TxPower=%s dBm)", + WiFi.localIPv6().toString().c_str(), + WiFi.getHostname(), + emsesp::Helpers::render_value(result, ((double)(WiFi.getTxPower()) / 4), 1)); } mDNS_start(); emsesp::EMSESP::system_.has_ipv6(true); From 732ad4bc6a971240f44907420a542ad164ddaa7f Mon Sep 17 00:00:00 2001 From: Proddy Date: Tue, 13 Feb 2024 15:17:34 +0100 Subject: [PATCH 33/54] remove retainStr --- lib/framework/MqttSettingsService.cpp | 60 ++++++--------------------- 1 file changed, 13 insertions(+), 47 deletions(-) diff --git a/lib/framework/MqttSettingsService.cpp b/lib/framework/MqttSettingsService.cpp index d8f98d9b3..8f7c45738 100644 --- a/lib/framework/MqttSettingsService.cpp +++ b/lib/framework/MqttSettingsService.cpp @@ -1,30 +1,6 @@ #include "MqttSettingsService.h" #include "../../src/emsesp_stub.hpp" -/** - * Retains a copy of the cstr provided in the pointer provided using dynamic allocation. - * - * Frees the pointer before allocation and leaves it as nullptr if cstr == nullptr. - */ -static char * retainCstr(const char * cstr, char ** ptr) { - if (ptr == nullptr || *ptr == nullptr) { - return nullptr; - } - - // free up previously retained value if exists - delete[] *ptr; - *ptr = nullptr; - - // dynamically allocate and copy cstr (if non null) - if (cstr != nullptr) { - *ptr = new char[strlen(cstr) + 1]; - strcpy(*ptr, cstr); - } - - // return reference to pointer for convenience - return *ptr; -} - MqttSettingsService::MqttSettingsService(AsyncWebServer * server, FS * fs, SecurityManager * securityManager) : _httpEndpoint(MqttSettings::read, MqttSettings::update, this, server, MQTT_SETTINGS_SERVICE_PATH, securityManager) , _fsPersistence(MqttSettings::read, MqttSettings::update, this, fs, MQTT_SETTINGS_FILE) @@ -32,7 +8,6 @@ MqttSettingsService::MqttSettingsService(AsyncWebServer * server, FS * fs, Secur , _retainedClientId(nullptr) , _retainedUsername(nullptr) , _retainedPassword(nullptr) - , _retainedRootCA(nullptr) , _reconfigureMqtt(false) , _disconnectedAt(0) , _disconnectReason(espMqttClientTypes::DisconnectReason::TCP_DISCONNECTED) @@ -43,11 +18,6 @@ MqttSettingsService::MqttSettingsService(AsyncWebServer * server, FS * fs, Secur MqttSettingsService::~MqttSettingsService() { delete _mqttClient; - retainCstr(nullptr, &_retainedHost); - retainCstr(nullptr, &_retainedClientId); - retainCstr(nullptr, &_retainedUsername); - retainCstr(nullptr, &_retainedPassword); - retainCstr(nullptr, &_retainedRootCA); } void MqttSettingsService::begin() { @@ -73,7 +43,7 @@ void MqttSettingsService::startClient() { static_cast(_mqttClient)->setInsecure(); } else { String certificate = "-----BEGIN CERTIFICATE-----\n" + _state.rootCA + "\n-----END CERTIFICATE-----\n"; - static_cast(_mqttClient)->setCACert(retainCstr(certificate.c_str(), &_retainedRootCA)); + static_cast(_mqttClient)->setCACert(certificate.c_str()); } static_cast(_mqttClient)->onConnect([this](bool sessionPresent) { onMqttConnect(sessionPresent); }); static_cast(_mqttClient)->onDisconnect([this](espMqttClientTypes::DisconnectReason reason) { onMqttDisconnect(reason); }); @@ -151,7 +121,9 @@ void MqttSettingsService::onMqttConnect(bool sessionPresent) { (void)sessionPresent; // _disconnectedAt = 0; emsesp::EMSESP::mqtt_.on_connect(); - // emsesp::EMSESP::logger().info("Connected to MQTT, %s", (sessionPresent) ? ("with persistent session") : ("without persistent session")); +#ifdef EMSESP_DEBUG + emsesp::EMSESP::logger().debug("Connected to MQTT, %s", (sessionPresent) ? ("with persistent session") : ("without persistent session")); +#endif } void MqttSettingsService::onMqttDisconnect(espMqttClientTypes::DisconnectReason reason) { @@ -204,31 +176,25 @@ bool MqttSettingsService::configureMqtt() { _reconfigureMqtt = false; #if CONFIG_IDF_TARGET_ESP32S3 if (_state.enableTLS) { - // emsesp::EMSESP::logger().info("Start secure MQTT with rootCA"); - static_cast(_mqttClient)->setServer(retainCstr(_state.host.c_str(), &_retainedHost), _state.port); +#if EMSESP_DEBUG + emsesp::EMSESP::logger().debug("Start secure MQTT with rootCA"); +#endif + static_cast(_mqttClient)->setServer(_state.host.c_str(), _state.port); if (_state.username.length() > 0) { static_cast(_mqttClient) - ->setCredentials(retainCstr(_state.username.c_str(), &_retainedUsername), - retainCstr(_state.password.length() > 0 ? _state.password.c_str() : nullptr, &_retainedPassword)); - } else { - static_cast(_mqttClient)->setCredentials(retainCstr(nullptr, &_retainedUsername), retainCstr(nullptr, &_retainedPassword)); + ->setCredentials(_state.username.c_str(), _state.password.length() > 0 ? _state.password.c_str() : nullptr); } - static_cast(_mqttClient)->setClientId(retainCstr(_state.clientId.c_str(), &_retainedClientId)); + static_cast(_mqttClient)->setClientId(_state.clientId.c_str()); static_cast(_mqttClient)->setKeepAlive(_state.keepAlive); static_cast(_mqttClient)->setCleanSession(_state.cleanSession); return _mqttClient->connect(); } #endif - // emsesp::EMSESP::logger().info("Configuring MQTT client"); - static_cast(_mqttClient)->setServer(retainCstr(_state.host.c_str(), &_retainedHost), _state.port); + static_cast(_mqttClient)->setServer(_state.host.c_str(), _state.port); if (_state.username.length() > 0) { - static_cast(_mqttClient) - ->setCredentials(retainCstr(_state.username.c_str(), &_retainedUsername), - retainCstr(_state.password.length() > 0 ? _state.password.c_str() : nullptr, &_retainedPassword)); - } else { - static_cast(_mqttClient)->setCredentials(retainCstr(nullptr, &_retainedUsername), retainCstr(nullptr, &_retainedPassword)); + static_cast(_mqttClient)->setCredentials(_state.username.c_str(), _state.password.length() > 0 ? _state.password.c_str() : nullptr); } - static_cast(_mqttClient)->setClientId(retainCstr(_state.clientId.c_str(), &_retainedClientId)); + static_cast(_mqttClient)->setClientId(_state.clientId.c_str()); static_cast(_mqttClient)->setKeepAlive(_state.keepAlive); static_cast(_mqttClient)->setCleanSession(_state.cleanSession); return _mqttClient->connect(); From 16779064f49b55c50e3afff3a3ae70e43ec11fd9 Mon Sep 17 00:00:00 2001 From: Proddy Date: Tue, 13 Feb 2024 15:17:47 +0100 Subject: [PATCH 34/54] update --- .gitignore | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/.gitignore b/.gitignore index cd0cb6050..9086892e9 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,7 @@ .vscode/c_cpp_properties.json .vscode/extensions.json .vscode/launch.json -# .vscode/settings.json +.vscode/settings.json # c++ compiling .clang_complete @@ -12,11 +12,11 @@ cppcheck.out.xml # platformio .pio pio_local.ini +*_old # OS specific .DS_Store *Thumbs.db -emsesp # web specfic build/ @@ -43,7 +43,7 @@ interface/analyse.html test.sh scripts/run.sh scripts/__pycache__ -/scripts/stackdmp.txt +scripts/stackdmp.txt # i18n generated files interface/src/i18n/i18n-react.tsx @@ -57,9 +57,5 @@ interface/src/i18n/i18n-util.async.ts sonar/ bw-output/ -# entity dump results -# dump_entities.csv -# dump_entities.xls* - -*_old - +# testing +emsesp From a7d0259b306010e854122733c4d2f7695acd6306 Mon Sep 17 00:00:00 2001 From: Proddy Date: Tue, 13 Feb 2024 15:19:06 +0100 Subject: [PATCH 35/54] replace lambda [&] with [this] --- lib/framework/ESP8266React.cpp | 2 +- lib_standalone/FSPersistence.h | 2 +- src/analogsensor.cpp | 6 +++--- src/console.cpp | 2 +- src/devices/boiler.cpp | 2 +- src/devices/solar.cpp | 4 ++-- src/mqtt.cpp | 4 +++- src/shower.cpp | 4 ++-- src/system.cpp | 26 ++++++++++++-------------- src/telegram.cpp | 2 +- src/temperaturesensor.cpp | 4 ++-- src/web/WebCustomEntityService.cpp | 18 +++++++++--------- 12 files changed, 38 insertions(+), 38 deletions(-) diff --git a/lib/framework/ESP8266React.cpp b/lib/framework/ESP8266React.cpp index d81fe7b83..057cef0cb 100644 --- a/lib/framework/ESP8266React.cpp +++ b/lib/framework/ESP8266React.cpp @@ -65,7 +65,7 @@ ESP8266React::ESP8266React(AsyncWebServer * server, FS * fs) void ESP8266React::begin() { _networkSettingsService.begin(); - _networkSettingsService.read([&](NetworkSettings & networkSettings) { + _networkSettingsService.read([this](NetworkSettings & networkSettings) { DefaultHeaders & defaultHeaders = DefaultHeaders::Instance(); if (networkSettings.enableCORS) { defaultHeaders.addHeader("Access-Control-Allow-Origin", networkSettings.CORSOrigin); diff --git a/lib_standalone/FSPersistence.h b/lib_standalone/FSPersistence.h index 9d943d711..12fffd5d8 100644 --- a/lib_standalone/FSPersistence.h +++ b/lib_standalone/FSPersistence.h @@ -40,7 +40,7 @@ class FSPersistence { void enableUpdateHandler() { if (!_updateHandlerId) { - _updateHandlerId = _statefulService->addUpdateHandler([&]() { writeToFS(); }); + _updateHandlerId = _statefulService->addUpdateHandler([this] { writeToFS(); }); } } diff --git a/src/analogsensor.cpp b/src/analogsensor.cpp index 13a31130e..411c6a7bc 100644 --- a/src/analogsensor.cpp +++ b/src/analogsensor.cpp @@ -37,7 +37,7 @@ void AnalogSensor::start() { Command::add( EMSdevice::DeviceType::ANALOGSENSOR, F_(setvalue), - [&](const char * value, const int8_t id) { return command_setvalue(value, id); }, + [this](const char * value, const int8_t id) { return command_setvalue(value, id); }, FL_(setiovalue_cmd), CommandFlag::ADMIN_ONLY); @@ -48,7 +48,7 @@ void AnalogSensor::start() { // load settings from the customization file, sorts them and initializes the GPIOs void AnalogSensor::reload() { - EMSESP::webSettingsService.read([&](WebSettings & settings) { analog_enabled_ = settings.analog_enabled; }); + EMSESP::webSettingsService.read([this](WebSettings & settings) { analog_enabled_ = settings.analog_enabled; }); #if defined(EMSESP_STANDALONE) analog_enabled_ = true; // for local offline testing @@ -63,7 +63,7 @@ void AnalogSensor::reload() { } // load the list of analog sensors from the customization service // and store them locally and then activate them - EMSESP::webCustomizationService.read([&](WebCustomization & settings) { + EMSESP::webCustomizationService.read([this](WebCustomization & settings) { auto it = sensors_.begin(); for (auto & sensor_ : sensors_) { // update existing sensors diff --git a/src/console.cpp b/src/console.cpp index 24933e8a0..d3c2d32a9 100644 --- a/src/console.cpp +++ b/src/console.cpp @@ -604,7 +604,7 @@ void EMSESPShell::display_banner() { println(); // set console name - EMSESP::esp8266React.getNetworkSettingsService()->read([&](NetworkSettings & networkSettings) { console_hostname_ = networkSettings.hostname.c_str(); }); + EMSESP::esp8266React.getNetworkSettingsService()->read([this](NetworkSettings & networkSettings) { console_hostname_ = networkSettings.hostname.c_str(); }); if (console_hostname_.empty()) { console_hostname_ = "ems-esp"; } diff --git a/src/devices/boiler.cpp b/src/devices/boiler.cpp index 8a54d7429..a2fbe953c 100644 --- a/src/devices/boiler.cpp +++ b/src/devices/boiler.cpp @@ -1118,7 +1118,7 @@ void Boiler::check_active() { // check forceheatingoff option if (!Helpers::hasValue(forceHeatingOff_, EMS_VALUE_BOOL)) { - EMSESP::webSettingsService.read([&](WebSettings & settings) { forceHeatingOff_ = settings.boiler_heatingoff ? EMS_VALUE_BOOL_ON : 0; }); + EMSESP::webSettingsService.read([this](WebSettings & settings) { forceHeatingOff_ = settings.boiler_heatingoff ? EMS_VALUE_BOOL_ON : 0; }); has_update(&forceHeatingOff_); } static uint32_t lastSendHeatingOff = 0; diff --git a/src/devices/solar.cpp b/src/devices/solar.cpp index 2c405aca2..a83538bb2 100644 --- a/src/devices/solar.cpp +++ b/src/devices/solar.cpp @@ -554,7 +554,7 @@ void Solar::process_SM10Monitor(std::shared_ptr telegram) { has_update(solarPumpMod_, solarpumpmod); if (!Helpers::hasValue(maxFlow_)) { - EMSESP::webSettingsService.read([&](WebSettings & settings) { maxFlow_ = settings.solar_maxflow; }); + EMSESP::webSettingsService.read([this](WebSettings & settings) { maxFlow_ = settings.solar_maxflow; }); has_update(&maxFlow_); } @@ -1047,7 +1047,7 @@ bool Solar::set_SM10MaxFlow(const char * value, const int8_t id) { return false; } maxFlow_ = (flow * 10); - EMSESP::webSettingsService.update([&](WebSettings & settings) { + EMSESP::webSettingsService.update([this](WebSettings & settings) { settings.solar_maxflow = maxFlow_; return StateUpdateResult::CHANGED; }); diff --git a/src/mqtt.cpp b/src/mqtt.cpp index df7f77bc2..10c318b8c 100644 --- a/src/mqtt.cpp +++ b/src/mqtt.cpp @@ -195,9 +195,9 @@ void Mqtt::show_mqtt(uuid::console::Shell & shell) { for (const auto & mqtt_subfunction : mqtt_subfunctions_) { shell.printfln(" %s/%s", Mqtt::base().c_str(), mqtt_subfunction.topic_.c_str()); } - shell.println(); shell.println(); + shell.println(); } #if defined(EMSESP_TEST) @@ -451,6 +451,7 @@ void Mqtt::on_disconnect(espMqttClientTypes::DisconnectReason reason) { return; } connecting_ = false; + if (reason == espMqttClientTypes::DisconnectReason::TCP_DISCONNECTED) { LOG_WARNING("MQTT disconnected: TCP"); } else if (reason == espMqttClientTypes::DisconnectReason::MQTT_UNACCEPTABLE_PROTOCOL_VERSION) { @@ -468,6 +469,7 @@ void Mqtt::on_disconnect(espMqttClientTypes::DisconnectReason reason) { } else { LOG_WARNING("MQTT disconnected: code %d", reason); } + mqttClient_->clearQueue(true); } diff --git a/src/shower.cpp b/src/shower.cpp index 4d83c837d..fa09568c2 100644 --- a/src/shower.cpp +++ b/src/shower.cpp @@ -25,7 +25,7 @@ uuid::log::Logger Shower::logger_{F_(shower), uuid::log::Facility::CONSOLE}; static bool force_coldshot = false; void Shower::start() { - EMSESP::webSettingsService.read([&](WebSettings & settings) { + EMSESP::webSettingsService.read([this](WebSettings & settings) { shower_timer_ = settings.shower_timer; shower_alert_ = settings.shower_alert; shower_alert_trigger_ = settings.shower_alert_trigger * 60000; // convert from minutes @@ -35,7 +35,7 @@ void Shower::start() { Command::add( EMSdevice::DeviceType::BOILER, F_(coldshot), - [&](const char * value, const int8_t id, JsonObject output) { + [this](const char * value, const int8_t id, JsonObject output) { LOG_INFO("Forcing coldshot..."); if (shower_state_) { output["message"] = "OK"; diff --git a/src/system.cpp b/src/system.cpp index c8f007b24..c4659d3f0 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -202,7 +202,7 @@ bool System::command_syslog_level(const char * value, const int8_t id) { if (Helpers::value2enum(value, s, FL_(list_syslog_level))) { bool changed = false; EMSESP::webSettingsService.update( - [&](WebSettings & settings) { + [this](WebSettings & settings) { if (settings.syslog_level != (int8_t)s - 1) { settings.syslog_level = (int8_t)s - 1; changed = true; @@ -295,7 +295,7 @@ void System::format(uuid::console::Shell & shell) { } void System::syslog_init() { - EMSESP::webSettingsService.read([&](WebSettings & settings) { + EMSESP::webSettingsService.read([this](WebSettings & settings) { syslog_enabled_ = settings.syslog_enabled; syslog_level_ = settings.syslog_level; syslog_mark_interval_ = settings.syslog_mark_interval; @@ -349,7 +349,7 @@ void System::syslog_init() { // read some specific system settings to store locally for faster access void System::reload_settings() { - EMSESP::webSettingsService.read([&](WebSettings & settings) { + EMSESP::webSettingsService.read([this](WebSettings & settings) { version_ = settings.version; pbutton_gpio_ = settings.pbutton_gpio; @@ -427,7 +427,7 @@ void System::start() { refreshHeapMem(); // refresh free heap and max alloc heap #endif - EMSESP::esp8266React.getNetworkSettingsService()->read([&](NetworkSettings & networkSettings) { + EMSESP::esp8266React.getNetworkSettingsService()->read([this](NetworkSettings & networkSettings) { hostname(networkSettings.hostname.c_str()); // sets the hostname }); @@ -1080,15 +1080,13 @@ bool System::check_upgrade(bool factory_settings) { version::Semver200_version settings_version(settingsVersion); -#if defined(EMSESP_DEBUG) if (!missing_version) { - LOG_INFO("Checking version (settings file is v%d.%d.%d-%s)...", - settings_version.major(), - settings_version.minor(), - settings_version.patch(), - settings_version.prerelease().c_str()); + LOG_DEBUG("Checking version upgrade (settings file is v%d.%d.%d-%s)", + settings_version.major(), + settings_version.minor(), + settings_version.patch(), + settings_version.prerelease().c_str()); } -#endif if (factory_settings) { return false; // fresh install, do nothing @@ -1106,14 +1104,14 @@ bool System::check_upgrade(bool factory_settings) { // if we're coming from 3.4.4 or 3.5.0b14 which had no version stored then we need to apply new settings if (missing_version) { LOG_INFO("Setting MQTT Entity ID format to v3.4 format"); - EMSESP::esp8266React.getMqttSettingsService()->update([&](MqttSettings & mqttSettings) { + EMSESP::esp8266React.getMqttSettingsService()->update([this](MqttSettings & mqttSettings) { mqttSettings.entity_format = 0; // use old Entity ID format from v3.4 return StateUpdateResult::CHANGED; }); } // Network Settings Wifi tx_power is now using the value * 4. - EMSESP::esp8266React.getNetworkSettingsService()->update([&](NetworkSettings & networkSettings) { + EMSESP::esp8266React.getNetworkSettingsService()->update([this](NetworkSettings & networkSettings) { if (networkSettings.tx_power == 20) { networkSettings.tx_power = WIFI_POWER_19_5dBm; // use 19.5 as we don't have 20 anymore LOG_INFO("Setting WiFi TX Power to Auto"); @@ -1132,7 +1130,7 @@ bool System::check_upgrade(bool factory_settings) { // if we did a change, set the new version and reboot if (save_version) { - EMSESP::webSettingsService.update([&](WebSettings & settings) { + EMSESP::webSettingsService.update([this](WebSettings & settings) { settings.version = EMSESP_APP_VERSION; return StateUpdateResult::CHANGED; }); diff --git a/src/telegram.cpp b/src/telegram.cpp index 83382a457..36ffdbf04 100644 --- a/src/telegram.cpp +++ b/src/telegram.cpp @@ -243,7 +243,7 @@ void RxService::add_empty(const uint8_t src, const uint8_t dest, const uint16_t // send out request to EMS bus for all devices void TxService::start() { // grab the bus ID and tx_mode - EMSESP::webSettingsService.read([&](WebSettings & settings) { + EMSESP::webSettingsService.read([this](WebSettings & settings) { ems_bus_id(settings.ems_bus_id); tx_mode(settings.tx_mode); }); diff --git a/src/temperaturesensor.cpp b/src/temperaturesensor.cpp index d07a478a5..49b4c1f5f 100644 --- a/src/temperaturesensor.cpp +++ b/src/temperaturesensor.cpp @@ -53,7 +53,7 @@ void TemperatureSensor::start() { // load settings void TemperatureSensor::reload() { // load the service settings - EMSESP::webSettingsService.read([&](WebSettings & settings) { + EMSESP::webSettingsService.read([this](WebSettings & settings) { dallas_gpio_ = settings.dallas_gpio; parasite_ = settings.dallas_parasite; }); @@ -604,7 +604,7 @@ std::string TemperatureSensor::Sensor::name() const { // look up in customization service for a specific sensor // and set the name and offset from that entry if it exists bool TemperatureSensor::Sensor::apply_customization() { - EMSESP::webCustomizationService.read([&](WebCustomization & settings) { + EMSESP::webCustomizationService.read([this](WebCustomization & settings) { auto sensors = settings.sensorCustomizations; if (!sensors.empty()) { for (const auto & sensor : sensors) { diff --git a/src/web/WebCustomEntityService.cpp b/src/web/WebCustomEntityService.cpp index 7cbc1b7a0..26ac4f6b8 100644 --- a/src/web/WebCustomEntityService.cpp +++ b/src/web/WebCustomEntityService.cpp @@ -128,7 +128,7 @@ StateUpdateResult WebCustomEntity::update(JsonObject root, WebCustomEntity & web // set value by api command bool WebCustomEntityService::command_setvalue(const char * value, const std::string name) { - EMSESP::webCustomEntityService.read([&](WebCustomEntity & webEntity) { customEntityItems = &webEntity.customEntityItems; }); + EMSESP::webCustomEntityService.read([this](WebCustomEntity & webEntity) { customEntityItems = &webEntity.customEntityItems; }); for (CustomEntityItem & entityItem : *customEntityItems) { if (Helpers::toLower(entityItem.name) == Helpers::toLower(name)) { if (entityItem.ram == 1) { @@ -251,7 +251,7 @@ void WebCustomEntityService::show_values(JsonObject output) { // process json output for info/commands and value_info bool WebCustomEntityService::get_value_info(JsonObject output, const char * cmd) { - EMSESP::webCustomEntityService.read([&](WebCustomEntity & webEntity) { customEntityItems = &webEntity.customEntityItems; }); + EMSESP::webCustomEntityService.read([this](WebCustomEntity & webEntity) { customEntityItems = &webEntity.customEntityItems; }); // if it's commands... if (Helpers::toLower(cmd) == F_(commands)) { @@ -365,7 +365,7 @@ void WebCustomEntityService::publish(const bool force) { return; } - EMSESP::webCustomEntityService.read([&](WebCustomEntity & webEntity) { customEntityItems = &webEntity.customEntityItems; }); + EMSESP::webCustomEntityService.read([this](WebCustomEntity & webEntity) { customEntityItems = &webEntity.customEntityItems; }); if (customEntityItems->size() == 0) { return; } @@ -456,7 +456,7 @@ void WebCustomEntityService::publish(const bool force) { // count only entities with valid value or command to show in dashboard uint8_t WebCustomEntityService::count_entities() { - EMSESP::webCustomEntityService.read([&](WebCustomEntity & webEntity) { customEntityItems = &webEntity.customEntityItems; }); + EMSESP::webCustomEntityService.read([this](WebCustomEntity & webEntity) { customEntityItems = &webEntity.customEntityItems; }); if (customEntityItems->size() == 0) { return 0; } @@ -473,7 +473,7 @@ uint8_t WebCustomEntityService::count_entities() { } uint8_t WebCustomEntityService::has_commands() { - EMSESP::webCustomEntityService.read([&](WebCustomEntity & webEntity) { customEntityItems = &webEntity.customEntityItems; }); + EMSESP::webCustomEntityService.read([this](WebCustomEntity & webEntity) { customEntityItems = &webEntity.customEntityItems; }); uint8_t count = 0; for (const CustomEntityItem & entity : *customEntityItems) { count += entity.writeable ? 1 : 0; @@ -484,7 +484,7 @@ uint8_t WebCustomEntityService::has_commands() { // send to dashboard, msgpack don't like serialized, use number void WebCustomEntityService::generate_value_web(JsonObject output) { - EMSESP::webCustomEntityService.read([&](WebCustomEntity & webEntity) { customEntityItems = &webEntity.customEntityItems; }); + EMSESP::webCustomEntityService.read([this](WebCustomEntity & webEntity) { customEntityItems = &webEntity.customEntityItems; }); output["label"] = (std::string) "Custom Entities"; JsonArray data = output["data"].to(); @@ -556,7 +556,7 @@ void WebCustomEntityService::generate_value_web(JsonObject output) { // fetch telegram, called from emsesp::fetch void WebCustomEntityService::fetch() { - EMSESP::webCustomEntityService.read([&](WebCustomEntity & webEntity) { customEntityItems = &webEntity.customEntityItems; }); + EMSESP::webCustomEntityService.read([this](WebCustomEntity & webEntity) { customEntityItems = &webEntity.customEntityItems; }); const uint8_t len[] = {1, 1, 1, 2, 2, 3, 3}; for (auto & entity : *customEntityItems) { @@ -582,7 +582,7 @@ void WebCustomEntityService::fetch() { // called on process telegram, read from telegram bool WebCustomEntityService::get_value(std::shared_ptr telegram) { bool has_change = false; - EMSESP::webCustomEntityService.read([&](WebCustomEntity & webEntity) { customEntityItems = &webEntity.customEntityItems; }); + EMSESP::webCustomEntityService.read([this](WebCustomEntity & webEntity) { customEntityItems = &webEntity.customEntityItems; }); // read-length of BOOL, INT, UINT, SHORT, USHORT, ULONG, TIME const uint8_t len[] = {1, 1, 1, 2, 2, 3, 3}; for (auto & entity : *customEntityItems) { @@ -626,7 +626,7 @@ bool WebCustomEntityService::get_value(std::shared_ptr telegram) // hard coded tests #ifdef EMSESP_TEST void WebCustomEntityService::test() { - update([&](WebCustomEntity & webCustomEntity) { + update([this](WebCustomEntity & webCustomEntity) { webCustomEntity.customEntityItems.clear(); // test 1 auto entityItem = CustomEntityItem(); From b683d1dd21a560be37f6d08455fbe7484c68c113 Mon Sep 17 00:00:00 2001 From: Proddy Date: Tue, 13 Feb 2024 20:19:03 +0100 Subject: [PATCH 36/54] default mqtt will base off ESP32's chip code --- factory_settings.ini | 1 - 1 file changed, 1 deletion(-) diff --git a/factory_settings.ini b/factory_settings.ini index 469faac18..b423605ca 100644 --- a/factory_settings.ini +++ b/factory_settings.ini @@ -36,7 +36,6 @@ build_flags = -D FACTORY_MQTT_PORT=1883 -D FACTORY_MQTT_USERNAME=\"\" -D FACTORY_MQTT_PASSWORD=\"\" - -D FACTORY_MQTT_CLIENT_ID=\"ems-esp\" -D FACTORY_MQTT_KEEP_ALIVE=60 -D FACTORY_MQTT_CLEAN_SESSION=false -D FACTORY_MQTT_MAX_TOPIC_LENGTH=128 From df21c15972393f0deb1ad9387147a7f021dbb56e Mon Sep 17 00:00:00 2001 From: Proddy Date: Tue, 13 Feb 2024 20:19:21 +0100 Subject: [PATCH 37/54] code cleaning --- lib/framework/MqttSettingsService.h | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/lib/framework/MqttSettingsService.h b/lib/framework/MqttSettingsService.h index 335070780..7fd7ab69c 100644 --- a/lib/framework/MqttSettingsService.h +++ b/lib/framework/MqttSettingsService.h @@ -60,21 +60,14 @@ static String generateClientId() { class MqttSettings { public: - // host and port - if enabled bool enabled; String host; uint16_t port; String rootCA; bool enableTLS; - - // username and password - String username; - String password; - - // client id settings - String clientId; - - // connection settings + String username; + String password; + String clientId; uint16_t keepAlive; bool cleanSession; From 92a80c3aaf1d0ce8a5f13853aacffcd457ef149e Mon Sep 17 00:00:00 2001 From: Proddy Date: Tue, 13 Feb 2024 20:19:41 +0100 Subject: [PATCH 38/54] factoryReset only used with button in test mode --- lib/framework/ESP8266React.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/framework/ESP8266React.h b/lib/framework/ESP8266React.h index 589369f33..4f5988933 100644 --- a/lib/framework/ESP8266React.h +++ b/lib/framework/ESP8266React.h @@ -65,9 +65,11 @@ class ESP8266React { _mqttSettingsService.setWill(will_topic); } +#ifndef EMSESP_STANDALONE void factoryReset() { _factoryResetService.factoryReset(); } +#endif private: SecuritySettingsService _securitySettingsService; From ce3c3e0b3ea00bc908effa5ba84ca599582c8782 Mon Sep 17 00:00:00 2001 From: Proddy Date: Tue, 13 Feb 2024 20:19:58 +0100 Subject: [PATCH 39/54] tidy up lambda's --- lib/framework/ESP8266React.cpp | 2 +- lib/framework/FSPersistence.h | 2 +- lib/framework/FactoryResetService.cpp | 2 +- lib/framework/MqttSettingsService.cpp | 2 +- lib/framework/NTPStatus.cpp | 2 +- lib/framework/NetworkSettingsService.cpp | 2 +- lib/framework/UploadFileService.cpp | 2 +- src/analogsensor.cpp | 6 +++--- src/console.cpp | 2 +- src/devices/boiler.cpp | 2 +- src/devices/solar.cpp | 4 ++-- src/mqtt.cpp | 3 ++- src/shower.cpp | 4 ++-- src/system.cpp | 14 +++++++------- src/telegram.cpp | 2 +- src/temperaturesensor.cpp | 4 ++-- src/web/WebCustomEntityService.cpp | 18 +++++++++--------- 17 files changed, 37 insertions(+), 36 deletions(-) diff --git a/lib/framework/ESP8266React.cpp b/lib/framework/ESP8266React.cpp index 057cef0cb..d81fe7b83 100644 --- a/lib/framework/ESP8266React.cpp +++ b/lib/framework/ESP8266React.cpp @@ -65,7 +65,7 @@ ESP8266React::ESP8266React(AsyncWebServer * server, FS * fs) void ESP8266React::begin() { _networkSettingsService.begin(); - _networkSettingsService.read([this](NetworkSettings & networkSettings) { + _networkSettingsService.read([&](NetworkSettings & networkSettings) { DefaultHeaders & defaultHeaders = DefaultHeaders::Instance(); if (networkSettings.enableCORS) { defaultHeaders.addHeader("Access-Control-Allow-Origin", networkSettings.CORSOrigin); diff --git a/lib/framework/FSPersistence.h b/lib/framework/FSPersistence.h index ff2205aeb..1fe93c8bc 100644 --- a/lib/framework/FSPersistence.h +++ b/lib/framework/FSPersistence.h @@ -80,7 +80,7 @@ class FSPersistence { void enableUpdateHandler() { if (!_updateHandlerId) { - _updateHandlerId = _statefulService->addUpdateHandler([this] { writeToFS(); }); + _updateHandlerId = _statefulService->addUpdateHandler([&] { writeToFS(); }); } } diff --git a/lib/framework/FactoryResetService.cpp b/lib/framework/FactoryResetService.cpp index c7f4ee0d1..3a23f6a3b 100644 --- a/lib/framework/FactoryResetService.cpp +++ b/lib/framework/FactoryResetService.cpp @@ -8,7 +8,7 @@ FactoryResetService::FactoryResetService(AsyncWebServer * server, FS * fs, Secur } void FactoryResetService::handleRequest(AsyncWebServerRequest * request) { - request->onDisconnect([this]() { factoryReset(); }); + request->onDisconnect([this] { factoryReset(); }); request->send(200); } diff --git a/lib/framework/MqttSettingsService.cpp b/lib/framework/MqttSettingsService.cpp index 8f7c45738..2ac8958d1 100644 --- a/lib/framework/MqttSettingsService.cpp +++ b/lib/framework/MqttSettingsService.cpp @@ -13,7 +13,7 @@ MqttSettingsService::MqttSettingsService(AsyncWebServer * server, FS * fs, Secur , _disconnectReason(espMqttClientTypes::DisconnectReason::TCP_DISCONNECTED) , _mqttClient(nullptr) { WiFi.onEvent([this](WiFiEvent_t event, WiFiEventInfo_t info) { WiFiEvent(event); }); - addUpdateHandler([this]() { onConfigUpdated(); }, false); + addUpdateHandler([this] { onConfigUpdated(); }, false); } MqttSettingsService::~MqttSettingsService() { diff --git a/lib/framework/NTPStatus.cpp b/lib/framework/NTPStatus.cpp index 95b9c32a6..db5afdc90 100644 --- a/lib/framework/NTPStatus.cpp +++ b/lib/framework/NTPStatus.cpp @@ -37,7 +37,7 @@ void NTPStatus::ntpStatus(AsyncWebServerRequest * request) { time_t now = time(nullptr); // only provide enabled/disabled status for now - root["status"] = []() { + root["status"] = [] { if (esp_sntp_enabled()) { if (emsesp::EMSESP::system_.ntp_connected()) { return 2; diff --git a/lib/framework/NetworkSettingsService.cpp b/lib/framework/NetworkSettingsService.cpp index cf628175a..2b986a0d8 100644 --- a/lib/framework/NetworkSettingsService.cpp +++ b/lib/framework/NetworkSettingsService.cpp @@ -7,7 +7,7 @@ NetworkSettingsService::NetworkSettingsService(AsyncWebServer * server, FS * fs, , _fsPersistence(NetworkSettings::read, NetworkSettings::update, this, fs, NETWORK_SETTINGS_FILE) , _lastConnectionAttempt(0) , _stopping(false) { - addUpdateHandler([this]() { reconfigureWiFiConnection(); }, false); + addUpdateHandler([this] { reconfigureWiFiConnection(); }, false); WiFi.onEvent([this](WiFiEvent_t event, WiFiEventInfo_t info) { WiFiEvent(event, info); }); } diff --git a/lib/framework/UploadFileService.cpp b/lib/framework/UploadFileService.cpp index ee818b4d6..13a8e5a09 100644 --- a/lib/framework/UploadFileService.cpp +++ b/lib/framework/UploadFileService.cpp @@ -84,7 +84,7 @@ void UploadFileService::handleUpload(AsyncWebServerRequest * request, const Stri Update.setMD5(_md5.data()); _md5.front() = '\0'; } - request->onDisconnect([this]() { handleEarlyDisconnect(); }); // success, let's make sure we end the update if the client hangs up + request->onDisconnect([this] { handleEarlyDisconnect(); }); // success, let's make sure we end the update if the client hangs up } else { handleError(request, 507); // failed to begin, send an error response Insufficient Storage return; diff --git a/src/analogsensor.cpp b/src/analogsensor.cpp index 411c6a7bc..13a31130e 100644 --- a/src/analogsensor.cpp +++ b/src/analogsensor.cpp @@ -37,7 +37,7 @@ void AnalogSensor::start() { Command::add( EMSdevice::DeviceType::ANALOGSENSOR, F_(setvalue), - [this](const char * value, const int8_t id) { return command_setvalue(value, id); }, + [&](const char * value, const int8_t id) { return command_setvalue(value, id); }, FL_(setiovalue_cmd), CommandFlag::ADMIN_ONLY); @@ -48,7 +48,7 @@ void AnalogSensor::start() { // load settings from the customization file, sorts them and initializes the GPIOs void AnalogSensor::reload() { - EMSESP::webSettingsService.read([this](WebSettings & settings) { analog_enabled_ = settings.analog_enabled; }); + EMSESP::webSettingsService.read([&](WebSettings & settings) { analog_enabled_ = settings.analog_enabled; }); #if defined(EMSESP_STANDALONE) analog_enabled_ = true; // for local offline testing @@ -63,7 +63,7 @@ void AnalogSensor::reload() { } // load the list of analog sensors from the customization service // and store them locally and then activate them - EMSESP::webCustomizationService.read([this](WebCustomization & settings) { + EMSESP::webCustomizationService.read([&](WebCustomization & settings) { auto it = sensors_.begin(); for (auto & sensor_ : sensors_) { // update existing sensors diff --git a/src/console.cpp b/src/console.cpp index d3c2d32a9..24933e8a0 100644 --- a/src/console.cpp +++ b/src/console.cpp @@ -604,7 +604,7 @@ void EMSESPShell::display_banner() { println(); // set console name - EMSESP::esp8266React.getNetworkSettingsService()->read([this](NetworkSettings & networkSettings) { console_hostname_ = networkSettings.hostname.c_str(); }); + EMSESP::esp8266React.getNetworkSettingsService()->read([&](NetworkSettings & networkSettings) { console_hostname_ = networkSettings.hostname.c_str(); }); if (console_hostname_.empty()) { console_hostname_ = "ems-esp"; } diff --git a/src/devices/boiler.cpp b/src/devices/boiler.cpp index a2fbe953c..8a54d7429 100644 --- a/src/devices/boiler.cpp +++ b/src/devices/boiler.cpp @@ -1118,7 +1118,7 @@ void Boiler::check_active() { // check forceheatingoff option if (!Helpers::hasValue(forceHeatingOff_, EMS_VALUE_BOOL)) { - EMSESP::webSettingsService.read([this](WebSettings & settings) { forceHeatingOff_ = settings.boiler_heatingoff ? EMS_VALUE_BOOL_ON : 0; }); + EMSESP::webSettingsService.read([&](WebSettings & settings) { forceHeatingOff_ = settings.boiler_heatingoff ? EMS_VALUE_BOOL_ON : 0; }); has_update(&forceHeatingOff_); } static uint32_t lastSendHeatingOff = 0; diff --git a/src/devices/solar.cpp b/src/devices/solar.cpp index a83538bb2..2c405aca2 100644 --- a/src/devices/solar.cpp +++ b/src/devices/solar.cpp @@ -554,7 +554,7 @@ void Solar::process_SM10Monitor(std::shared_ptr telegram) { has_update(solarPumpMod_, solarpumpmod); if (!Helpers::hasValue(maxFlow_)) { - EMSESP::webSettingsService.read([this](WebSettings & settings) { maxFlow_ = settings.solar_maxflow; }); + EMSESP::webSettingsService.read([&](WebSettings & settings) { maxFlow_ = settings.solar_maxflow; }); has_update(&maxFlow_); } @@ -1047,7 +1047,7 @@ bool Solar::set_SM10MaxFlow(const char * value, const int8_t id) { return false; } maxFlow_ = (flow * 10); - EMSESP::webSettingsService.update([this](WebSettings & settings) { + EMSESP::webSettingsService.update([&](WebSettings & settings) { settings.solar_maxflow = maxFlow_; return StateUpdateResult::CHANGED; }); diff --git a/src/mqtt.cpp b/src/mqtt.cpp index 10c318b8c..6bca33d74 100644 --- a/src/mqtt.cpp +++ b/src/mqtt.cpp @@ -20,6 +20,7 @@ #include "emsesp.h" #include "version.h" #include "emsdevice.h" +#include namespace emsesp { @@ -381,7 +382,7 @@ void Mqtt::start() { // add the 'publish' command ('call system publish' in console or via API) Command::add(EMSdevice::DeviceType::SYSTEM, F_(publish), System::command_publish, FL_(publish_cmd)); - // create last will topic with the base prefixed. It has to be static because asyncmqttclient destroys the reference + // create last will topic with the base prefixed. It has to be static because the client destroys the reference static char will_topic[MQTT_TOPIC_MAX_SIZE]; if (!Mqtt::base().empty()) { snprintf(will_topic, MQTT_TOPIC_MAX_SIZE, "%s/status", Mqtt::base().c_str()); diff --git a/src/shower.cpp b/src/shower.cpp index fa09568c2..4d83c837d 100644 --- a/src/shower.cpp +++ b/src/shower.cpp @@ -25,7 +25,7 @@ uuid::log::Logger Shower::logger_{F_(shower), uuid::log::Facility::CONSOLE}; static bool force_coldshot = false; void Shower::start() { - EMSESP::webSettingsService.read([this](WebSettings & settings) { + EMSESP::webSettingsService.read([&](WebSettings & settings) { shower_timer_ = settings.shower_timer; shower_alert_ = settings.shower_alert; shower_alert_trigger_ = settings.shower_alert_trigger * 60000; // convert from minutes @@ -35,7 +35,7 @@ void Shower::start() { Command::add( EMSdevice::DeviceType::BOILER, F_(coldshot), - [this](const char * value, const int8_t id, JsonObject output) { + [&](const char * value, const int8_t id, JsonObject output) { LOG_INFO("Forcing coldshot..."); if (shower_state_) { output["message"] = "OK"; diff --git a/src/system.cpp b/src/system.cpp index c4659d3f0..926acef97 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -202,7 +202,7 @@ bool System::command_syslog_level(const char * value, const int8_t id) { if (Helpers::value2enum(value, s, FL_(list_syslog_level))) { bool changed = false; EMSESP::webSettingsService.update( - [this](WebSettings & settings) { + [&](WebSettings & settings) { if (settings.syslog_level != (int8_t)s - 1) { settings.syslog_level = (int8_t)s - 1; changed = true; @@ -295,7 +295,7 @@ void System::format(uuid::console::Shell & shell) { } void System::syslog_init() { - EMSESP::webSettingsService.read([this](WebSettings & settings) { + EMSESP::webSettingsService.read([&](WebSettings & settings) { syslog_enabled_ = settings.syslog_enabled; syslog_level_ = settings.syslog_level; syslog_mark_interval_ = settings.syslog_mark_interval; @@ -349,7 +349,7 @@ void System::syslog_init() { // read some specific system settings to store locally for faster access void System::reload_settings() { - EMSESP::webSettingsService.read([this](WebSettings & settings) { + EMSESP::webSettingsService.read([&](WebSettings & settings) { version_ = settings.version; pbutton_gpio_ = settings.pbutton_gpio; @@ -427,7 +427,7 @@ void System::start() { refreshHeapMem(); // refresh free heap and max alloc heap #endif - EMSESP::esp8266React.getNetworkSettingsService()->read([this](NetworkSettings & networkSettings) { + EMSESP::esp8266React.getNetworkSettingsService()->read([&](NetworkSettings & networkSettings) { hostname(networkSettings.hostname.c_str()); // sets the hostname }); @@ -1104,14 +1104,14 @@ bool System::check_upgrade(bool factory_settings) { // if we're coming from 3.4.4 or 3.5.0b14 which had no version stored then we need to apply new settings if (missing_version) { LOG_INFO("Setting MQTT Entity ID format to v3.4 format"); - EMSESP::esp8266React.getMqttSettingsService()->update([this](MqttSettings & mqttSettings) { + EMSESP::esp8266React.getMqttSettingsService()->update([&](MqttSettings & mqttSettings) { mqttSettings.entity_format = 0; // use old Entity ID format from v3.4 return StateUpdateResult::CHANGED; }); } // Network Settings Wifi tx_power is now using the value * 4. - EMSESP::esp8266React.getNetworkSettingsService()->update([this](NetworkSettings & networkSettings) { + EMSESP::esp8266React.getNetworkSettingsService()->update([&](NetworkSettings & networkSettings) { if (networkSettings.tx_power == 20) { networkSettings.tx_power = WIFI_POWER_19_5dBm; // use 19.5 as we don't have 20 anymore LOG_INFO("Setting WiFi TX Power to Auto"); @@ -1130,7 +1130,7 @@ bool System::check_upgrade(bool factory_settings) { // if we did a change, set the new version and reboot if (save_version) { - EMSESP::webSettingsService.update([this](WebSettings & settings) { + EMSESP::webSettingsService.update([&](WebSettings & settings) { settings.version = EMSESP_APP_VERSION; return StateUpdateResult::CHANGED; }); diff --git a/src/telegram.cpp b/src/telegram.cpp index 36ffdbf04..83382a457 100644 --- a/src/telegram.cpp +++ b/src/telegram.cpp @@ -243,7 +243,7 @@ void RxService::add_empty(const uint8_t src, const uint8_t dest, const uint16_t // send out request to EMS bus for all devices void TxService::start() { // grab the bus ID and tx_mode - EMSESP::webSettingsService.read([this](WebSettings & settings) { + EMSESP::webSettingsService.read([&](WebSettings & settings) { ems_bus_id(settings.ems_bus_id); tx_mode(settings.tx_mode); }); diff --git a/src/temperaturesensor.cpp b/src/temperaturesensor.cpp index 49b4c1f5f..d07a478a5 100644 --- a/src/temperaturesensor.cpp +++ b/src/temperaturesensor.cpp @@ -53,7 +53,7 @@ void TemperatureSensor::start() { // load settings void TemperatureSensor::reload() { // load the service settings - EMSESP::webSettingsService.read([this](WebSettings & settings) { + EMSESP::webSettingsService.read([&](WebSettings & settings) { dallas_gpio_ = settings.dallas_gpio; parasite_ = settings.dallas_parasite; }); @@ -604,7 +604,7 @@ std::string TemperatureSensor::Sensor::name() const { // look up in customization service for a specific sensor // and set the name and offset from that entry if it exists bool TemperatureSensor::Sensor::apply_customization() { - EMSESP::webCustomizationService.read([this](WebCustomization & settings) { + EMSESP::webCustomizationService.read([&](WebCustomization & settings) { auto sensors = settings.sensorCustomizations; if (!sensors.empty()) { for (const auto & sensor : sensors) { diff --git a/src/web/WebCustomEntityService.cpp b/src/web/WebCustomEntityService.cpp index 26ac4f6b8..7cbc1b7a0 100644 --- a/src/web/WebCustomEntityService.cpp +++ b/src/web/WebCustomEntityService.cpp @@ -128,7 +128,7 @@ StateUpdateResult WebCustomEntity::update(JsonObject root, WebCustomEntity & web // set value by api command bool WebCustomEntityService::command_setvalue(const char * value, const std::string name) { - EMSESP::webCustomEntityService.read([this](WebCustomEntity & webEntity) { customEntityItems = &webEntity.customEntityItems; }); + EMSESP::webCustomEntityService.read([&](WebCustomEntity & webEntity) { customEntityItems = &webEntity.customEntityItems; }); for (CustomEntityItem & entityItem : *customEntityItems) { if (Helpers::toLower(entityItem.name) == Helpers::toLower(name)) { if (entityItem.ram == 1) { @@ -251,7 +251,7 @@ void WebCustomEntityService::show_values(JsonObject output) { // process json output for info/commands and value_info bool WebCustomEntityService::get_value_info(JsonObject output, const char * cmd) { - EMSESP::webCustomEntityService.read([this](WebCustomEntity & webEntity) { customEntityItems = &webEntity.customEntityItems; }); + EMSESP::webCustomEntityService.read([&](WebCustomEntity & webEntity) { customEntityItems = &webEntity.customEntityItems; }); // if it's commands... if (Helpers::toLower(cmd) == F_(commands)) { @@ -365,7 +365,7 @@ void WebCustomEntityService::publish(const bool force) { return; } - EMSESP::webCustomEntityService.read([this](WebCustomEntity & webEntity) { customEntityItems = &webEntity.customEntityItems; }); + EMSESP::webCustomEntityService.read([&](WebCustomEntity & webEntity) { customEntityItems = &webEntity.customEntityItems; }); if (customEntityItems->size() == 0) { return; } @@ -456,7 +456,7 @@ void WebCustomEntityService::publish(const bool force) { // count only entities with valid value or command to show in dashboard uint8_t WebCustomEntityService::count_entities() { - EMSESP::webCustomEntityService.read([this](WebCustomEntity & webEntity) { customEntityItems = &webEntity.customEntityItems; }); + EMSESP::webCustomEntityService.read([&](WebCustomEntity & webEntity) { customEntityItems = &webEntity.customEntityItems; }); if (customEntityItems->size() == 0) { return 0; } @@ -473,7 +473,7 @@ uint8_t WebCustomEntityService::count_entities() { } uint8_t WebCustomEntityService::has_commands() { - EMSESP::webCustomEntityService.read([this](WebCustomEntity & webEntity) { customEntityItems = &webEntity.customEntityItems; }); + EMSESP::webCustomEntityService.read([&](WebCustomEntity & webEntity) { customEntityItems = &webEntity.customEntityItems; }); uint8_t count = 0; for (const CustomEntityItem & entity : *customEntityItems) { count += entity.writeable ? 1 : 0; @@ -484,7 +484,7 @@ uint8_t WebCustomEntityService::has_commands() { // send to dashboard, msgpack don't like serialized, use number void WebCustomEntityService::generate_value_web(JsonObject output) { - EMSESP::webCustomEntityService.read([this](WebCustomEntity & webEntity) { customEntityItems = &webEntity.customEntityItems; }); + EMSESP::webCustomEntityService.read([&](WebCustomEntity & webEntity) { customEntityItems = &webEntity.customEntityItems; }); output["label"] = (std::string) "Custom Entities"; JsonArray data = output["data"].to(); @@ -556,7 +556,7 @@ void WebCustomEntityService::generate_value_web(JsonObject output) { // fetch telegram, called from emsesp::fetch void WebCustomEntityService::fetch() { - EMSESP::webCustomEntityService.read([this](WebCustomEntity & webEntity) { customEntityItems = &webEntity.customEntityItems; }); + EMSESP::webCustomEntityService.read([&](WebCustomEntity & webEntity) { customEntityItems = &webEntity.customEntityItems; }); const uint8_t len[] = {1, 1, 1, 2, 2, 3, 3}; for (auto & entity : *customEntityItems) { @@ -582,7 +582,7 @@ void WebCustomEntityService::fetch() { // called on process telegram, read from telegram bool WebCustomEntityService::get_value(std::shared_ptr telegram) { bool has_change = false; - EMSESP::webCustomEntityService.read([this](WebCustomEntity & webEntity) { customEntityItems = &webEntity.customEntityItems; }); + EMSESP::webCustomEntityService.read([&](WebCustomEntity & webEntity) { customEntityItems = &webEntity.customEntityItems; }); // read-length of BOOL, INT, UINT, SHORT, USHORT, ULONG, TIME const uint8_t len[] = {1, 1, 1, 2, 2, 3, 3}; for (auto & entity : *customEntityItems) { @@ -626,7 +626,7 @@ bool WebCustomEntityService::get_value(std::shared_ptr telegram) // hard coded tests #ifdef EMSESP_TEST void WebCustomEntityService::test() { - update([this](WebCustomEntity & webCustomEntity) { + update([&](WebCustomEntity & webCustomEntity) { webCustomEntity.customEntityItems.clear(); // test 1 auto entityItem = CustomEntityItem(); From 34b7dd61cfd6551c258355605bc70840d142c144 Mon Sep 17 00:00:00 2001 From: Proddy Date: Wed, 14 Feb 2024 10:53:53 +0100 Subject: [PATCH 40/54] clean up standalone --- lib_standalone/Arduino.cpp | 7 +++--- lib_standalone/Arduino.h | 10 +++------ lib_standalone/AsyncJson.h | 4 +++- lib_standalone/AsyncTCP.h | 1 + lib_standalone/ESP8266React.h | 25 ++++++++++------------ lib_standalone/ESPAsyncWebServer.h | 2 +- lib_standalone/ESPmDNS.h | 0 lib_standalone/FS.h | 3 ++- lib_standalone/FSPersistence.h | 4 ++-- lib_standalone/HttpEndpoint.h | 8 +++---- lib_standalone/LittleFS.cpp | 6 +++--- lib_standalone/Network.h | 3 ++- lib_standalone/Print.h | 3 ++- lib_standalone/SecurityManager.h | 15 ++++++------- lib_standalone/SecuritySettingsService.cpp | 2 +- lib_standalone/SecuritySettingsService.h | 8 +++---- lib_standalone/StatefulService.cpp | 2 +- lib_standalone/StatefulService.h | 3 ++- lib_standalone/WString.cpp | 2 +- lib_standalone/WebSocketTxRx.h | 0 lib_standalone/emsuart_standalone.h | 2 +- 21 files changed, 53 insertions(+), 57 deletions(-) delete mode 100644 lib_standalone/ESPmDNS.h delete mode 100644 lib_standalone/WebSocketTxRx.h diff --git a/lib_standalone/Arduino.cpp b/lib_standalone/Arduino.cpp index 2afc4e78f..314f01601 100644 --- a/lib_standalone/Arduino.cpp +++ b/lib_standalone/Arduino.cpp @@ -17,17 +17,16 @@ #ifdef EMSESP_STANDALONE -#include + #include #include - #include #include #include - #include -#include +#include "Arduino.h" +#include "Network.h" NativeConsole Serial; diff --git a/lib_standalone/Arduino.h b/lib_standalone/Arduino.h index 83a93a166..b500609ab 100644 --- a/lib_standalone/Arduino.h +++ b/lib_standalone/Arduino.h @@ -25,16 +25,14 @@ #include #include #include - -#include // for count_if - +#include #include #include #include -#include - #include +#include "WString.h" + typedef double double_t; #define ICACHE_FLASH_ATTR @@ -188,6 +186,4 @@ void yield(void); void setup(void); void loop(void); - - #endif diff --git a/lib_standalone/AsyncJson.h b/lib_standalone/AsyncJson.h index 676062f34..e3af4f7a8 100644 --- a/lib_standalone/AsyncJson.h +++ b/lib_standalone/AsyncJson.h @@ -1,8 +1,10 @@ #ifndef ASYNC_JSON_H_ #define ASYNC_JSON_H_ + #include -#include + +#include "ESPAsyncWebServer.h" #define DYNAMIC_JSON_DOCUMENT_SIZE 1024 diff --git a/lib_standalone/AsyncTCP.h b/lib_standalone/AsyncTCP.h index c06bbd0a5..58307baab 100644 --- a/lib_standalone/AsyncTCP.h +++ b/lib_standalone/AsyncTCP.h @@ -2,6 +2,7 @@ #define ASYNCTCP_H_ #include "Arduino.h" + #include class AsyncClient; diff --git a/lib_standalone/ESP8266React.h b/lib_standalone/ESP8266React.h index ea1b198e0..ca7b194b3 100644 --- a/lib_standalone/ESP8266React.h +++ b/lib_standalone/ESP8266React.h @@ -1,21 +1,19 @@ #ifndef ESP8266React_h #define ESP8266React_h -#include - -#include -#include - -#include -#include - #include -#include -#include -#include -#include -#include +#include "Arduino.h" +#include "ArduinoJson.h" +#include "AsyncJson.h" +#include "ESPAsyncWebServer.h" +#include "FS.h" +#include "SecurityManager.h" +#include "SecuritySettingsService.h" +#include "StatefulService.h" +#include "Network.h" + +#include #define AP_SETTINGS_FILE "/config/apSettings.json" #define MQTT_SETTINGS_FILE "/config/mqttSettings.json" @@ -104,7 +102,6 @@ class ESP8266React { , _securitySettingsService(server, fs){}; void begin() { - // initialize mqtt _mqttClient = new espMqttClient(); }; void loop(){}; diff --git a/lib_standalone/ESPAsyncWebServer.h b/lib_standalone/ESPAsyncWebServer.h index 50b341849..54d431706 100644 --- a/lib_standalone/ESPAsyncWebServer.h +++ b/lib_standalone/ESPAsyncWebServer.h @@ -2,9 +2,9 @@ #define _ESPAsyncWebServer_H_ #include "Arduino.h" +#include "AsyncTCP.h" #include -#include #include class AsyncWebServer; diff --git a/lib_standalone/ESPmDNS.h b/lib_standalone/ESPmDNS.h deleted file mode 100644 index e69de29bb..000000000 diff --git a/lib_standalone/FS.h b/lib_standalone/FS.h index d85355f22..f3e3ef2e8 100644 --- a/lib_standalone/FS.h +++ b/lib_standalone/FS.h @@ -21,9 +21,10 @@ #ifndef FS_H #define FS_H +#include "Arduino.h" + #include #include -#include #include #include #include diff --git a/lib_standalone/FSPersistence.h b/lib_standalone/FSPersistence.h index 12fffd5d8..74672aa84 100644 --- a/lib_standalone/FSPersistence.h +++ b/lib_standalone/FSPersistence.h @@ -1,8 +1,8 @@ #ifndef FSPersistence_h #define FSPersistence_h -#include -#include +#include "StatefulService.h" +#include "FS.h" template class FSPersistence { diff --git a/lib_standalone/HttpEndpoint.h b/lib_standalone/HttpEndpoint.h index e3fae9ba0..e6efe4a7d 100644 --- a/lib_standalone/HttpEndpoint.h +++ b/lib_standalone/HttpEndpoint.h @@ -3,11 +3,11 @@ #include -#include -#include +#include "AsyncJson.h" +#include "ESPAsyncWebServer.h" -#include -#include +#include "SecurityManager.h" +#include "StatefulService.h" #define HTTP_ENDPOINT_ORIGIN_ID "http" diff --git a/lib_standalone/LittleFS.cpp b/lib_standalone/LittleFS.cpp index 36e635fa3..f207f88f0 100644 --- a/lib_standalone/LittleFS.cpp +++ b/lib_standalone/LittleFS.cpp @@ -17,9 +17,9 @@ */ #ifdef ENV_NATIVE -#include -#include -#include +#include "Arduino.h" +#include "FS.h" +#include "LittleFS.h" fs::LittleFSFS LittleFS; diff --git a/lib_standalone/Network.h b/lib_standalone/Network.h index c7a750180..7dad09f10 100644 --- a/lib_standalone/Network.h +++ b/lib_standalone/Network.h @@ -1,7 +1,8 @@ #ifndef Network_h #define Network_h -#include +#include "Arduino.h" + #include #include diff --git a/lib_standalone/Print.h b/lib_standalone/Print.h index 548a6fa26..d8f40e25e 100644 --- a/lib_standalone/Print.h +++ b/lib_standalone/Print.h @@ -28,7 +28,8 @@ #include #include -#include + +#include "WString.h" int vsnprintf_P(char * str, size_t size, const char * format, va_list ap); diff --git a/lib_standalone/SecurityManager.h b/lib_standalone/SecurityManager.h index 80f83d049..5f8a9e6fd 100644 --- a/lib_standalone/SecurityManager.h +++ b/lib_standalone/SecurityManager.h @@ -1,18 +1,15 @@ #ifndef SecurityManager_h #define SecurityManager_h -#include -#include -#include -#include +#include "Arduino.h" +#include "Features.h" +#include "ESPAsyncWebServer.h" +#include "AsyncJson.h" + #include -#ifndef FACTORY_JWT_SECRET -#define FACTORY_JWT_SECRET ESPUtils::defaultDeviceValue() -#endif - +#define FACTORY_JWT_SECRET "ems-esp" #define ACCESS_TOKEN_PARAMATER "access_token" - #define AUTHORIZATION_HEADER "Authorization" #define AUTHORIZATION_HEADER_PREFIX "Bearer " #define AUTHORIZATION_HEADER_PREFIX_LEN 7 diff --git a/lib_standalone/SecuritySettingsService.cpp b/lib_standalone/SecuritySettingsService.cpp index 58b894995..862adc5e3 100644 --- a/lib_standalone/SecuritySettingsService.cpp +++ b/lib_standalone/SecuritySettingsService.cpp @@ -1,6 +1,6 @@ #ifdef EMSESP_STANDALONE -#include +#include "SecuritySettingsService.h" User ADMIN_USER = User(FACTORY_ADMIN_USERNAME, FACTORY_ADMIN_PASSWORD, true); diff --git a/lib_standalone/SecuritySettingsService.h b/lib_standalone/SecuritySettingsService.h index cf8dca1d9..d4176462e 100644 --- a/lib_standalone/SecuritySettingsService.h +++ b/lib_standalone/SecuritySettingsService.h @@ -1,10 +1,10 @@ #ifndef SecuritySettingsService_h #define SecuritySettingsService_h -#include -#include -#include -#include +#include "Features.h" +#include "SecurityManager.h" +#include "HttpEndpoint.h" +#include "FSPersistence.h" #ifndef FACTORY_ADMIN_USERNAME #define FACTORY_ADMIN_USERNAME "admin" diff --git a/lib_standalone/StatefulService.cpp b/lib_standalone/StatefulService.cpp index ece6b1fb3..d5f847aba 100644 --- a/lib_standalone/StatefulService.cpp +++ b/lib_standalone/StatefulService.cpp @@ -1,3 +1,3 @@ -#include +#include "StatefulService.h" update_handler_id_t StateUpdateHandlerInfo::currentUpdatedHandlerId = 0; diff --git a/lib_standalone/StatefulService.h b/lib_standalone/StatefulService.h index ceb2ae965..2a1a04376 100644 --- a/lib_standalone/StatefulService.h +++ b/lib_standalone/StatefulService.h @@ -1,7 +1,8 @@ #ifndef StatefulService_h #define StatefulService_h -#include +#include "Arduino.h" + #include #include diff --git a/lib_standalone/WString.cpp b/lib_standalone/WString.cpp index 853c80c63..994fe9817 100644 --- a/lib_standalone/WString.cpp +++ b/lib_standalone/WString.cpp @@ -1,7 +1,7 @@ #ifdef EMSESP_STANDALONE -#include +#include "Arduino.h" #include "WString.h" /* diff --git a/lib_standalone/WebSocketTxRx.h b/lib_standalone/WebSocketTxRx.h deleted file mode 100644 index e69de29bb..000000000 diff --git a/lib_standalone/emsuart_standalone.h b/lib_standalone/emsuart_standalone.h index ab63a9a0e..844de9cae 100644 --- a/lib_standalone/emsuart_standalone.h +++ b/lib_standalone/emsuart_standalone.h @@ -19,7 +19,7 @@ #ifndef EMSESP_EMSUART_H #define EMSESP_EMSUART_H -#include +#include "Arduino.h" namespace emsesp { From 994e1fc26bbf4acfa3960f03035f5e22532e00df Mon Sep 17 00:00:00 2001 From: Proddy Date: Wed, 14 Feb 2024 10:54:16 +0100 Subject: [PATCH 41/54] remove bogus include --- src/mqtt.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/mqtt.cpp b/src/mqtt.cpp index 6bca33d74..0137c5c54 100644 --- a/src/mqtt.cpp +++ b/src/mqtt.cpp @@ -20,7 +20,6 @@ #include "emsesp.h" #include "version.h" #include "emsdevice.h" -#include namespace emsesp { From daf08e7bd946d00887ba32fbc040f4edf01f3903 Mon Sep 17 00:00:00 2001 From: Proddy Date: Wed, 14 Feb 2024 11:00:03 +0100 Subject: [PATCH 42/54] support standalone --- lib/framework/ESPUtils.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/framework/ESPUtils.h b/lib/framework/ESPUtils.h index 490514f45..f2879dd83 100644 --- a/lib/framework/ESPUtils.h +++ b/lib/framework/ESPUtils.h @@ -6,7 +6,11 @@ class ESPUtils { public: static String defaultDeviceValue(const String & prefix = "") { +#ifndef EMSESP_STANDALONE return prefix + String(static_cast(ESP.getEfuseMac()), HEX); +#else + return "ems-esp"; +#endif } }; From fdaa9a6188043a9c7d39fe87e950668f096e7005 Mon Sep 17 00:00:00 2001 From: Proddy Date: Wed, 14 Feb 2024 11:00:16 +0100 Subject: [PATCH 43/54] tidy up standalone --- platformio.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platformio.ini b/platformio.ini index a0345adf2..102e92696 100644 --- a/platformio.ini +++ b/platformio.ini @@ -169,14 +169,14 @@ build_flags = platform = native build_flags = -DARDUINOJSON_ENABLE_STD_STRING=1 -DARDUINOJSON_ENABLE_PROGMEM=1 -DARDUINOJSON_ENABLE_ARDUINO_STRING -DARDUINOJSON_USE_DOUBLE=0 - -DEMSESP_DEBUG -DEMSESP_STANDALONE -DEMSESP_TEST -D__linux__ + -DEMSESP_DEBUG -DEMSESP_STANDALONE -DEMSESP_TEST -DEMSESP_DEFAULT_LOCALE=\"en\" -DEMSESP_DEFAULT_TX_MODE=8 -DEMSESP_DEFAULT_VERSION=\"3.6.5-dev\" -DEMSESP_DEFAULT_BOARD_PROFILE=\"S32\" -lpthread + -D__linux__ -std=gnu++11 -Og -ggdb build_src_flags = -Wall -Wextra -Werror -Wno-unused-parameter -Wno-sign-compare - ; -Wswitch-enum -Wno-unused-parameter -Wno-inconsistent-missing-override -Wno-unused-lambda-capture -Wno-missing-braces -I./lib_standalone -I./lib/ArduinoJson/src -I./lib/uuid-common/src From a35486ec246503809a832b32d4f27019dc65186f Mon Sep 17 00:00:00 2001 From: Proddy Date: Wed, 14 Feb 2024 11:09:08 +0100 Subject: [PATCH 44/54] remove bogus flags --- platformio.ini | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/platformio.ini b/platformio.ini index 102e92696..575a2218b 100644 --- a/platformio.ini +++ b/platformio.ini @@ -13,8 +13,6 @@ extra_configs = [common] core_build_flags = - -D ARDUINO_ARCH_ESP32=1 - -D ESP32=1 -O2 -std=gnu++17 @@ -50,7 +48,7 @@ extra_scripts = scripts/rename_fw.py [espressi32_base_tasmota] -; use Tasmota's libary which removes some libs (like mbedtsl) and increases available heap +; use Tasmota's library which removes some libs (like mbedtsl) and increases available heap ; platform = https://github.com/tasmota/platform-espressif32.git ; latest development ; latest release with WiFi_secure.h, Arduino 2.0.14 platform = https://github.com/tasmota/platform-espressif32/releases/download/2024.01.00/platform-espressif32.zip @@ -68,11 +66,9 @@ extra_scripts = [env] monitor_speed = 115200 -monitor_filters = esp32_exception_decoder upload_speed = 921600 build_type = release lib_ldf_mode = chain+ -; board_build.flash_mode = qio check_tool = cppcheck, clangtidy check_severity = high, medium From b6accb8d0278ecc6358c3f82a5732b185f3b98b4 Mon Sep 17 00:00:00 2001 From: proddy Date: Wed, 14 Feb 2024 14:46:10 +0100 Subject: [PATCH 45/54] add extra {} to SubscribeItem list[1] --- lib/espMqttClient/src/Packets/Packet.cpp | 686 +++++++++++------------ 1 file changed, 342 insertions(+), 344 deletions(-) diff --git a/lib/espMqttClient/src/Packets/Packet.cpp b/lib/espMqttClient/src/Packets/Packet.cpp index 2f84b503a..5f9ceb486 100644 --- a/lib/espMqttClient/src/Packets/Packet.cpp +++ b/lib/espMqttClient/src/Packets/Packet.cpp @@ -11,428 +11,426 @@ the LICENSE file. namespace espMqttClientInternals { Packet::~Packet() { - free(_data); + free(_data); } size_t Packet::available(size_t index) { - if (index >= _size) return 0; - if (!_getPayload) return _size - index; - return _chunkedAvailable(index); + if (index >= _size) + return 0; + if (!_getPayload) + return _size - index; + return _chunkedAvailable(index); } -const uint8_t* Packet::data(size_t index) const { - if (!_getPayload) { - if (!_data) return nullptr; - if (index >= _size) return nullptr; - return &_data[index]; - } - return _chunkedData(index); +const uint8_t * Packet::data(size_t index) const { + if (!_getPayload) { + if (!_data) + return nullptr; + if (index >= _size) + return nullptr; + return &_data[index]; + } + return _chunkedData(index); } size_t Packet::size() const { - return _size; + return _size; } void Packet::setDup() { - if (!_data) return; - if (packetType() != PacketType.PUBLISH) return; - if (_packetId == 0) return; - _data[0] |= 0x08; + if (!_data) + return; + if (packetType() != PacketType.PUBLISH) + return; + if (_packetId == 0) + return; + _data[0] |= 0x08; } uint16_t Packet::packetId() const { - return _packetId; + return _packetId; } MQTTPacketType Packet::packetType() const { - if (_data) return static_cast(_data[0] & 0xF0); - return static_cast(0); + if (_data) + return static_cast(_data[0] & 0xF0); + return static_cast(0); } bool Packet::removable() const { - if (_packetId == 0) return true; - if ((packetType() == PacketType.PUBACK) || (packetType() == PacketType.PUBCOMP)) return true; - return false; + if (_packetId == 0) + return true; + if ((packetType() == PacketType.PUBACK) || (packetType() == PacketType.PUBCOMP)) + return true; + return false; } -Packet::Packet(espMqttClientTypes::Error& error, - bool cleanSession, - const char* username, - const char* password, - const char* willTopic, - bool willRetain, - uint8_t willQos, - const uint8_t* willPayload, - uint16_t willPayloadLength, - uint16_t keepAlive, - const char* clientId) -: _packetId(0) -, _data(nullptr) -, _size(0) -, _payloadIndex(0) -, _payloadStartIndex(0) -, _payloadEndIndex(0) -, _getPayload(nullptr) { - if (willPayload && willPayloadLength == 0) { - size_t length = strlen(reinterpret_cast(willPayload)); - if (length > UINT16_MAX) { - emc_log_w("Payload length truncated (l:%zu)", length); - willPayloadLength = UINT16_MAX; - } else { - willPayloadLength = length; +Packet::Packet(espMqttClientTypes::Error & error, + bool cleanSession, + const char * username, + const char * password, + const char * willTopic, + bool willRetain, + uint8_t willQos, + const uint8_t * willPayload, + uint16_t willPayloadLength, + uint16_t keepAlive, + const char * clientId) + : _packetId(0) + , _data(nullptr) + , _size(0) + , _payloadIndex(0) + , _payloadStartIndex(0) + , _payloadEndIndex(0) + , _getPayload(nullptr) { + if (willPayload && willPayloadLength == 0) { + size_t length = strlen(reinterpret_cast(willPayload)); + if (length > UINT16_MAX) { + emc_log_w("Payload length truncated (l:%zu)", length); + willPayloadLength = UINT16_MAX; + } else { + willPayloadLength = length; + } } - } - if (!clientId || strlen(clientId) == 0) { - emc_log_w("clientId not set error"); - error = espMqttClientTypes::Error::MALFORMED_PARAMETER; - return; - } - - // Calculate size - size_t remainingLength = - 6 + // protocol - 1 + // protocol level - 1 + // connect flags - 2 + // keepalive - 2 + strlen(clientId) + - (willTopic ? 2 + strlen(willTopic) + 2 + willPayloadLength : 0) + - (username ? 2 + strlen(username) : 0) + - (password ? 2 + strlen(password) : 0); - - // allocate memory - if (!_allocate(remainingLength, false)) { - error = espMqttClientTypes::Error::OUT_OF_MEMORY; - return; - } - - // serialize - size_t pos = 0; - - // FIXED HEADER - _data[pos++] = PacketType.CONNECT | HeaderFlag.CONNECT_RESERVED; - pos += encodeRemainingLength(remainingLength, &_data[pos]); - pos += encodeString(PROTOCOL, &_data[pos]); - _data[pos++] = PROTOCOL_LEVEL; - uint8_t connectFlags = 0; - if (cleanSession) connectFlags |= espMqttClientInternals::ConnectFlag.CLEAN_SESSION; - if (username != nullptr) connectFlags |= espMqttClientInternals::ConnectFlag.USERNAME; - if (password != nullptr) connectFlags |= espMqttClientInternals::ConnectFlag.PASSWORD; - if (willTopic != nullptr) { - connectFlags |= espMqttClientInternals::ConnectFlag.WILL; - if (willRetain) connectFlags |= espMqttClientInternals::ConnectFlag.WILL_RETAIN; - switch (willQos) { - case 0: - connectFlags |= espMqttClientInternals::ConnectFlag.WILL_QOS0; - break; - case 1: - connectFlags |= espMqttClientInternals::ConnectFlag.WILL_QOS1; - break; - case 2: - connectFlags |= espMqttClientInternals::ConnectFlag.WILL_QOS2; - break; + if (!clientId || strlen(clientId) == 0) { + emc_log_w("clientId not set error"); + error = espMqttClientTypes::Error::MALFORMED_PARAMETER; + return; } - } - _data[pos++] = connectFlags; - _data[pos++] = keepAlive >> 8; - _data[pos++] = keepAlive & 0xFF; - // PAYLOAD - // client ID - pos += encodeString(clientId, &_data[pos]); - // will - if (willTopic != nullptr && willPayload != nullptr) { - pos += encodeString(willTopic, &_data[pos]); - _data[pos++] = willPayloadLength >> 8; - _data[pos++] = willPayloadLength & 0xFF; - memcpy(&_data[pos], willPayload, willPayloadLength); - pos += willPayloadLength; - } - // credentials - if (username != nullptr) pos += encodeString(username, &_data[pos]); - if (password != nullptr) encodeString(password, &_data[pos]); + // Calculate size + size_t remainingLength = 6 + // protocol + 1 + // protocol level + 1 + // connect flags + 2 + // keepalive + 2 + strlen(clientId) + (willTopic ? 2 + strlen(willTopic) + 2 + willPayloadLength : 0) + (username ? 2 + strlen(username) : 0) + + (password ? 2 + strlen(password) : 0); - error = espMqttClientTypes::Error::SUCCESS; + // allocate memory + if (!_allocate(remainingLength, false)) { + error = espMqttClientTypes::Error::OUT_OF_MEMORY; + return; + } + + // serialize + size_t pos = 0; + + // FIXED HEADER + _data[pos++] = PacketType.CONNECT | HeaderFlag.CONNECT_RESERVED; + pos += encodeRemainingLength(remainingLength, &_data[pos]); + pos += encodeString(PROTOCOL, &_data[pos]); + _data[pos++] = PROTOCOL_LEVEL; + uint8_t connectFlags = 0; + if (cleanSession) + connectFlags |= espMqttClientInternals::ConnectFlag.CLEAN_SESSION; + if (username != nullptr) + connectFlags |= espMqttClientInternals::ConnectFlag.USERNAME; + if (password != nullptr) + connectFlags |= espMqttClientInternals::ConnectFlag.PASSWORD; + if (willTopic != nullptr) { + connectFlags |= espMqttClientInternals::ConnectFlag.WILL; + if (willRetain) + connectFlags |= espMqttClientInternals::ConnectFlag.WILL_RETAIN; + switch (willQos) { + case 0: + connectFlags |= espMqttClientInternals::ConnectFlag.WILL_QOS0; + break; + case 1: + connectFlags |= espMqttClientInternals::ConnectFlag.WILL_QOS1; + break; + case 2: + connectFlags |= espMqttClientInternals::ConnectFlag.WILL_QOS2; + break; + } + } + _data[pos++] = connectFlags; + _data[pos++] = keepAlive >> 8; + _data[pos++] = keepAlive & 0xFF; + + // PAYLOAD + // client ID + pos += encodeString(clientId, &_data[pos]); + // will + if (willTopic != nullptr && willPayload != nullptr) { + pos += encodeString(willTopic, &_data[pos]); + _data[pos++] = willPayloadLength >> 8; + _data[pos++] = willPayloadLength & 0xFF; + memcpy(&_data[pos], willPayload, willPayloadLength); + pos += willPayloadLength; + } + // credentials + if (username != nullptr) + pos += encodeString(username, &_data[pos]); + if (password != nullptr) + encodeString(password, &_data[pos]); + + error = espMqttClientTypes::Error::SUCCESS; } -Packet::Packet(espMqttClientTypes::Error& error, - uint16_t packetId, - const char* topic, - const uint8_t* payload, - size_t payloadLength, - uint8_t qos, - bool retain) -: _packetId(packetId) -, _data(nullptr) -, _size(0) -, _payloadIndex(0) -, _payloadStartIndex(0) -, _payloadEndIndex(0) -, _getPayload(nullptr) { - size_t remainingLength = - 2 + strlen(topic) + // topic length + topic - 2 + // packet ID - payloadLength; +Packet::Packet(espMqttClientTypes::Error & error, uint16_t packetId, const char * topic, const uint8_t * payload, size_t payloadLength, uint8_t qos, bool retain) + : _packetId(packetId) + , _data(nullptr) + , _size(0) + , _payloadIndex(0) + , _payloadStartIndex(0) + , _payloadEndIndex(0) + , _getPayload(nullptr) { + size_t remainingLength = 2 + strlen(topic) + // topic length + topic + 2 + // packet ID + payloadLength; - if (qos == 0) { - remainingLength -= 2; - _packetId = 0; - } + if (qos == 0) { + remainingLength -= 2; + _packetId = 0; + } - if (!_allocate(remainingLength)) { - error = espMqttClientTypes::Error::OUT_OF_MEMORY; - return; - } + if (!_allocate(remainingLength)) { + error = espMqttClientTypes::Error::OUT_OF_MEMORY; + return; + } - size_t pos = _fillPublishHeader(packetId, topic, remainingLength, qos, retain); + size_t pos = _fillPublishHeader(packetId, topic, remainingLength, qos, retain); - // PAYLOAD - memcpy(&_data[pos], payload, payloadLength); + // PAYLOAD + memcpy(&_data[pos], payload, payloadLength); - error = espMqttClientTypes::Error::SUCCESS; + error = espMqttClientTypes::Error::SUCCESS; } -Packet::Packet(espMqttClientTypes::Error& error, - uint16_t packetId, - const char* topic, +Packet::Packet(espMqttClientTypes::Error & error, + uint16_t packetId, + const char * topic, espMqttClientTypes::PayloadCallback payloadCallback, - size_t payloadLength, - uint8_t qos, - bool retain) -: _packetId(packetId) -, _data(nullptr) -, _size(0) -, _payloadIndex(0) -, _payloadStartIndex(0) -, _payloadEndIndex(0) -, _getPayload(payloadCallback) { - size_t remainingLength = - 2 + strlen(topic) + // topic length + topic - 2 + // packet ID - payloadLength; + size_t payloadLength, + uint8_t qos, + bool retain) + : _packetId(packetId) + , _data(nullptr) + , _size(0) + , _payloadIndex(0) + , _payloadStartIndex(0) + , _payloadEndIndex(0) + , _getPayload(payloadCallback) { + size_t remainingLength = 2 + strlen(topic) + // topic length + topic + 2 + // packet ID + payloadLength; - if (qos == 0) { - remainingLength -= 2; - _packetId = 0; - } + if (qos == 0) { + remainingLength -= 2; + _packetId = 0; + } - if (!_allocate(remainingLength - payloadLength + std::min(payloadLength, static_cast(EMC_RX_BUFFER_SIZE)))) { - error = espMqttClientTypes::Error::OUT_OF_MEMORY; - return; - } + if (!_allocate(remainingLength - payloadLength + std::min(payloadLength, static_cast(EMC_RX_BUFFER_SIZE)))) { + error = espMqttClientTypes::Error::OUT_OF_MEMORY; + return; + } - size_t pos = _fillPublishHeader(packetId, topic, remainingLength, qos, retain); + size_t pos = _fillPublishHeader(packetId, topic, remainingLength, qos, retain); - // payload will be added by 'Packet::available' - _size = pos + payloadLength; - _payloadIndex = pos; - _payloadStartIndex = _payloadIndex; - _payloadEndIndex = _payloadIndex; + // payload will be added by 'Packet::available' + _size = pos + payloadLength; + _payloadIndex = pos; + _payloadStartIndex = _payloadIndex; + _payloadEndIndex = _payloadIndex; - error = espMqttClientTypes::Error::SUCCESS; + error = espMqttClientTypes::Error::SUCCESS; } -Packet::Packet(espMqttClientTypes::Error& error, uint16_t packetId, const char* topic, uint8_t qos) -: _packetId(packetId) -, _data(nullptr) -, _size(0) -, _payloadIndex(0) -, _payloadStartIndex(0) -, _payloadEndIndex(0) -, _getPayload(nullptr) { - SubscribeItem list[1] = {topic, qos}; - _createSubscribe(error, list, 1); +Packet::Packet(espMqttClientTypes::Error & error, uint16_t packetId, const char * topic, uint8_t qos) + : _packetId(packetId) + , _data(nullptr) + , _size(0) + , _payloadIndex(0) + , _payloadStartIndex(0) + , _payloadEndIndex(0) + , _getPayload(nullptr) { + SubscribeItem list[1] = {{topic, qos}}; + _createSubscribe(error, list, 1); } -Packet::Packet(espMqttClientTypes::Error& error, MQTTPacketType type, uint16_t packetId) -: _packetId(packetId) -, _data(nullptr) -, _size(0) -, _payloadIndex(0) -, _payloadStartIndex(0) -, _payloadEndIndex(0) -, _getPayload(nullptr) { - if (!_allocate(2)) { - error = espMqttClientTypes::Error::OUT_OF_MEMORY; - return; - } +Packet::Packet(espMqttClientTypes::Error & error, MQTTPacketType type, uint16_t packetId) + : _packetId(packetId) + , _data(nullptr) + , _size(0) + , _payloadIndex(0) + , _payloadStartIndex(0) + , _payloadEndIndex(0) + , _getPayload(nullptr) { + if (!_allocate(2)) { + error = espMqttClientTypes::Error::OUT_OF_MEMORY; + return; + } - size_t pos = 0; - _data[pos] = type; - if (type == PacketType.PUBREL) { - _data[pos++] |= HeaderFlag.PUBREL_RESERVED; - } else { - pos++; - } - pos += encodeRemainingLength(2, &_data[pos]); - _data[pos++] = packetId >> 8; - _data[pos] = packetId & 0xFF; + size_t pos = 0; + _data[pos] = type; + if (type == PacketType.PUBREL) { + _data[pos++] |= HeaderFlag.PUBREL_RESERVED; + } else { + pos++; + } + pos += encodeRemainingLength(2, &_data[pos]); + _data[pos++] = packetId >> 8; + _data[pos] = packetId & 0xFF; - error = espMqttClientTypes::Error::SUCCESS; + error = espMqttClientTypes::Error::SUCCESS; } -Packet::Packet(espMqttClientTypes::Error& error, uint16_t packetId, const char* topic) -: _packetId(packetId) -, _data(nullptr) -, _size(0) -, _payloadIndex(0) -, _payloadStartIndex(0) -, _payloadEndIndex(0) -, _getPayload(nullptr) { - const char* list[1] = {topic}; - _createUnsubscribe(error, list, 1); +Packet::Packet(espMqttClientTypes::Error & error, uint16_t packetId, const char * topic) + : _packetId(packetId) + , _data(nullptr) + , _size(0) + , _payloadIndex(0) + , _payloadStartIndex(0) + , _payloadEndIndex(0) + , _getPayload(nullptr) { + const char * list[1] = {topic}; + _createUnsubscribe(error, list, 1); } -Packet::Packet(espMqttClientTypes::Error& error, MQTTPacketType type) -: _packetId(0) -, _data(nullptr) -, _size(0) -, _payloadIndex(0) -, _payloadStartIndex(0) -, _payloadEndIndex(0) -, _getPayload(nullptr) { - if (!_allocate(0)) { - error = espMqttClientTypes::Error::OUT_OF_MEMORY; - return; - } - _data[0] |= type; +Packet::Packet(espMqttClientTypes::Error & error, MQTTPacketType type) + : _packetId(0) + , _data(nullptr) + , _size(0) + , _payloadIndex(0) + , _payloadStartIndex(0) + , _payloadEndIndex(0) + , _getPayload(nullptr) { + if (!_allocate(0)) { + error = espMqttClientTypes::Error::OUT_OF_MEMORY; + return; + } + _data[0] |= type; - error = espMqttClientTypes::Error::SUCCESS; + error = espMqttClientTypes::Error::SUCCESS; } bool Packet::_allocate(size_t remainingLength, bool check) { - if (check && EMC_GET_FREE_MEMORY() < EMC_MIN_FREE_MEMORY) { - emc_log_w("Packet buffer not allocated: low memory"); - return false; - } - _size = 1 + remainingLengthLength(remainingLength) + remainingLength; - _data = reinterpret_cast(malloc(_size)); - if (!_data) { - _size = 0; - emc_log_w("Alloc failed (l:%zu)", _size); - return false; - } - emc_log_i("Alloc (l:%zu)", _size); - memset(_data, 0, _size); - return true; + if (check && EMC_GET_FREE_MEMORY() < EMC_MIN_FREE_MEMORY) { + emc_log_w("Packet buffer not allocated: low memory"); + return false; + } + _size = 1 + remainingLengthLength(remainingLength) + remainingLength; + _data = reinterpret_cast(malloc(_size)); + if (!_data) { + _size = 0; + emc_log_w("Alloc failed (l:%zu)", _size); + return false; + } + emc_log_i("Alloc (l:%zu)", _size); + memset(_data, 0, _size); + return true; } -size_t Packet::_fillPublishHeader(uint16_t packetId, - const char* topic, - size_t remainingLength, - uint8_t qos, - bool retain) { - size_t index = 0; +size_t Packet::_fillPublishHeader(uint16_t packetId, const char * topic, size_t remainingLength, uint8_t qos, bool retain) { + size_t index = 0; - // FIXED HEADER - _data[index] = PacketType.PUBLISH; - if (retain) _data[index] |= HeaderFlag.PUBLISH_RETAIN; - if (qos == 0) { - _data[index++] |= HeaderFlag.PUBLISH_QOS0; - } else if (qos == 1) { - _data[index++] |= HeaderFlag.PUBLISH_QOS1; - } else if (qos == 2) { - _data[index++] |= HeaderFlag.PUBLISH_QOS2; - } - index += encodeRemainingLength(remainingLength, &_data[index]); + // FIXED HEADER + _data[index] = PacketType.PUBLISH; + if (retain) + _data[index] |= HeaderFlag.PUBLISH_RETAIN; + if (qos == 0) { + _data[index++] |= HeaderFlag.PUBLISH_QOS0; + } else if (qos == 1) { + _data[index++] |= HeaderFlag.PUBLISH_QOS1; + } else if (qos == 2) { + _data[index++] |= HeaderFlag.PUBLISH_QOS2; + } + index += encodeRemainingLength(remainingLength, &_data[index]); - // VARIABLE HEADER - index += encodeString(topic, &_data[index]); - if (qos > 0) { - _data[index++] = packetId >> 8; - _data[index++] = packetId & 0xFF; - } + // VARIABLE HEADER + index += encodeString(topic, &_data[index]); + if (qos > 0) { + _data[index++] = packetId >> 8; + _data[index++] = packetId & 0xFF; + } - return index; + return index; } -void Packet::_createSubscribe(espMqttClientTypes::Error& error, - SubscribeItem* list, - size_t numberTopics) { - // Calculate size - size_t payload = 0; - for (size_t i = 0; i < numberTopics; ++i) { - payload += 2 + strlen(list[i].topic) + 1; // length bytes, string, qos - } - size_t remainingLength = 2 + payload; // packetId + payload +void Packet::_createSubscribe(espMqttClientTypes::Error & error, SubscribeItem * list, size_t numberTopics) { + // Calculate size + size_t payload = 0; + for (size_t i = 0; i < numberTopics; ++i) { + payload += 2 + strlen(list[i].topic) + 1; // length bytes, string, qos + } + size_t remainingLength = 2 + payload; // packetId + payload - // allocate memory - if (!_allocate(remainingLength)) { - error = espMqttClientTypes::Error::OUT_OF_MEMORY; - return; - } + // allocate memory + if (!_allocate(remainingLength)) { + error = espMqttClientTypes::Error::OUT_OF_MEMORY; + return; + } - // serialize - size_t pos = 0; - _data[pos++] = PacketType.SUBSCRIBE | HeaderFlag.SUBSCRIBE_RESERVED; - pos += encodeRemainingLength(remainingLength, &_data[pos]); - _data[pos++] = _packetId >> 8; - _data[pos++] = _packetId & 0xFF; - for (size_t i = 0; i < numberTopics; ++i) { - pos += encodeString(list[i].topic, &_data[pos]); - _data[pos++] = list[i].qos; - } + // serialize + size_t pos = 0; + _data[pos++] = PacketType.SUBSCRIBE | HeaderFlag.SUBSCRIBE_RESERVED; + pos += encodeRemainingLength(remainingLength, &_data[pos]); + _data[pos++] = _packetId >> 8; + _data[pos++] = _packetId & 0xFF; + for (size_t i = 0; i < numberTopics; ++i) { + pos += encodeString(list[i].topic, &_data[pos]); + _data[pos++] = list[i].qos; + } - error = espMqttClientTypes::Error::SUCCESS; + error = espMqttClientTypes::Error::SUCCESS; } -void Packet::_createUnsubscribe(espMqttClientTypes::Error& error, - const char** list, - size_t numberTopics) { - // Calculate size - size_t payload = 0; - for (size_t i = 0; i < numberTopics; ++i) { - payload += 2 + strlen(list[i]); // length bytes, string - } - size_t remainingLength = 2 + payload; // packetId + payload +void Packet::_createUnsubscribe(espMqttClientTypes::Error & error, const char ** list, size_t numberTopics) { + // Calculate size + size_t payload = 0; + for (size_t i = 0; i < numberTopics; ++i) { + payload += 2 + strlen(list[i]); // length bytes, string + } + size_t remainingLength = 2 + payload; // packetId + payload - // allocate memory - if (!_allocate(remainingLength)) { - error = espMqttClientTypes::Error::OUT_OF_MEMORY; - return; - } + // allocate memory + if (!_allocate(remainingLength)) { + error = espMqttClientTypes::Error::OUT_OF_MEMORY; + return; + } - // serialize - size_t pos = 0; - _data[pos++] = PacketType.UNSUBSCRIBE | HeaderFlag.UNSUBSCRIBE_RESERVED; - pos += encodeRemainingLength(remainingLength, &_data[pos]); - _data[pos++] = _packetId >> 8; - _data[pos++] = _packetId & 0xFF; - for (size_t i = 0; i < numberTopics; ++i) { - pos += encodeString(list[i], &_data[pos]); - } + // serialize + size_t pos = 0; + _data[pos++] = PacketType.UNSUBSCRIBE | HeaderFlag.UNSUBSCRIBE_RESERVED; + pos += encodeRemainingLength(remainingLength, &_data[pos]); + _data[pos++] = _packetId >> 8; + _data[pos++] = _packetId & 0xFF; + for (size_t i = 0; i < numberTopics; ++i) { + pos += encodeString(list[i], &_data[pos]); + } - error = espMqttClientTypes::Error::SUCCESS; + error = espMqttClientTypes::Error::SUCCESS; } size_t Packet::_chunkedAvailable(size_t index) { - // index vs size check done in 'available(index)' + // index vs size check done in 'available(index)' - // index points to header or first payload byte - if (index < _payloadIndex) { - if (_size > _payloadIndex && _payloadEndIndex != 0) { - size_t copied = _getPayload(&_data[_payloadIndex], std::min(static_cast(EMC_TX_BUFFER_SIZE), _size - _payloadStartIndex), index); - _payloadStartIndex = _payloadIndex; - _payloadEndIndex = _payloadStartIndex + copied - 1; + // index points to header or first payload byte + if (index < _payloadIndex) { + if (_size > _payloadIndex && _payloadEndIndex != 0) { + size_t copied = _getPayload(&_data[_payloadIndex], std::min(static_cast(EMC_TX_BUFFER_SIZE), _size - _payloadStartIndex), index); + _payloadStartIndex = _payloadIndex; + _payloadEndIndex = _payloadStartIndex + copied - 1; + } + + // index points to payload unavailable + } else if (index > _payloadEndIndex || _payloadStartIndex > index) { + _payloadStartIndex = index; + size_t copied = _getPayload(&_data[_payloadIndex], std::min(static_cast(EMC_TX_BUFFER_SIZE), _size - _payloadStartIndex), index); + _payloadEndIndex = _payloadStartIndex + copied - 1; } - // index points to payload unavailable - } else if (index > _payloadEndIndex || _payloadStartIndex > index) { - _payloadStartIndex = index; - size_t copied = _getPayload(&_data[_payloadIndex], std::min(static_cast(EMC_TX_BUFFER_SIZE), _size - _payloadStartIndex), index); - _payloadEndIndex = _payloadStartIndex + copied - 1; - } - - // now index points to header or payload available - return _payloadEndIndex - index + 1; + // now index points to header or payload available + return _payloadEndIndex - index + 1; } -const uint8_t* Packet::_chunkedData(size_t index) const { - // CAUTION!! available(index) has to be called first to check available data and possibly fill payloadbuffer - if (index < _payloadIndex) { - return &_data[index]; - } - return &_data[index - _payloadStartIndex + _payloadIndex]; +const uint8_t * Packet::_chunkedData(size_t index) const { + // CAUTION!! available(index) has to be called first to check available data and possibly fill payloadbuffer + if (index < _payloadIndex) { + return &_data[index]; + } + return &_data[index - _payloadStartIndex + _payloadIndex]; } -} // end namespace espMqttClientInternals +} // end namespace espMqttClientInternals From f5ec9e9602990dd34be31c3c2ebc12b2d1ae4931 Mon Sep 17 00:00:00 2001 From: proddy Date: Wed, 14 Feb 2024 14:46:20 +0100 Subject: [PATCH 46/54] remove unneeded file --- lib/framework/ESPUtils.h | 17 ----------------- 1 file changed, 17 deletions(-) delete mode 100644 lib/framework/ESPUtils.h diff --git a/lib/framework/ESPUtils.h b/lib/framework/ESPUtils.h deleted file mode 100644 index f2879dd83..000000000 --- a/lib/framework/ESPUtils.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef ESPUtils_h -#define ESPUtils_h - -#include - -class ESPUtils { - public: - static String defaultDeviceValue(const String & prefix = "") { -#ifndef EMSESP_STANDALONE - return prefix + String(static_cast(ESP.getEfuseMac()), HEX); -#else - return "ems-esp"; -#endif - } -}; - -#endif From b24a63b992c0c2afac136cdac517cb206ae75736 Mon Sep 17 00:00:00 2001 From: proddy Date: Wed, 14 Feb 2024 14:46:59 +0100 Subject: [PATCH 47/54] add missing overrides --- lib_standalone/FS.h | 2 +- lib_standalone/SecuritySettingsService.cpp | 2 +- src/console_stream.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib_standalone/FS.h b/lib_standalone/FS.h index f3e3ef2e8..a29f3ebba 100644 --- a/lib_standalone/FS.h +++ b/lib_standalone/FS.h @@ -54,7 +54,7 @@ class File : public Stream { int peek() override; void flush() override; size_t read(uint8_t * buf, size_t size); - size_t readBytes(char * buffer, size_t length) { + size_t readBytes(char * buffer, size_t length) override { return read((uint8_t *)buffer, length); } diff --git a/lib_standalone/SecuritySettingsService.cpp b/lib_standalone/SecuritySettingsService.cpp index 862adc5e3..f94b7046c 100644 --- a/lib_standalone/SecuritySettingsService.cpp +++ b/lib_standalone/SecuritySettingsService.cpp @@ -11,7 +11,7 @@ SecuritySettingsService::~SecuritySettingsService() { } ArRequestFilterFunction SecuritySettingsService::filterRequest(AuthenticationPredicate predicate) { - return [this, predicate](AsyncWebServerRequest * request) { return true; }; + return [predicate](AsyncWebServerRequest * request) { return true; }; } // Return the admin user on all request - disabling security features diff --git a/src/console_stream.h b/src/console_stream.h index ca862754e..ba1a4458e 100644 --- a/src/console_stream.h +++ b/src/console_stream.h @@ -32,7 +32,7 @@ class EMSESPConsole : public EMSESPShell { #endif ~EMSESPConsole() override; - std::string console_name(); + std::string console_name() override; private: #ifndef EMSESP_STANDALONE From 31ff0f5aba0ddc14f441a642637fe9094baddeae Mon Sep 17 00:00:00 2001 From: proddy Date: Wed, 14 Feb 2024 14:47:09 +0100 Subject: [PATCH 48/54] add override --- lib/uuid-console/src/uuid/console.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/uuid-console/src/uuid/console.h b/lib/uuid-console/src/uuid/console.h index 99fb1ed00..d3c565bd2 100644 --- a/lib/uuid-console/src/uuid/console.h +++ b/lib/uuid-console/src/uuid/console.h @@ -936,7 +936,7 @@ class Shell : public std::enable_shared_from_this, public uuid::log::Hand * @param[in] message New log message, shared by all handlers. * @since 0.1.0 */ - virtual void operator<<(std::shared_ptr message); + virtual void operator<<(std::shared_ptr message) override; /** * Get the current log level. * From d3fadd70819c4493f616793b3876f2cd66a0dcee Mon Sep 17 00:00:00 2001 From: proddy Date: Wed, 14 Feb 2024 14:47:17 +0100 Subject: [PATCH 49/54] remove comment --- src/emsdevice.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/emsdevice.cpp b/src/emsdevice.cpp index 9426f44f6..1ad7a1832 100644 --- a/src/emsdevice.cpp +++ b/src/emsdevice.cpp @@ -1748,7 +1748,6 @@ void EMSdevice::mqtt_ha_entity_config_create() { } } - // TODO remove CMD - see https://github.com/emsesp/EMS-ESP32/issues/1605 if (!dv.has_state(DeviceValueState::DV_HA_CONFIG_CREATED) && (dv.type != DeviceValueType::CMD) && dv.has_state(DeviceValueState::DV_ACTIVE) && !dv.has_state(DeviceValueState::DV_API_MQTT_EXCLUDE)) { // create_device_config is only done once for the EMS device. It can added to any entity, so we take the first From 49d749e89f480b47f6a9dde92906e4c68570cc7f Mon Sep 17 00:00:00 2001 From: proddy Date: Wed, 14 Feb 2024 14:47:29 +0100 Subject: [PATCH 50/54] move generateClientId() --- lib/framework/MqttSettingsService.cpp | 10 +++++++++- lib/framework/MqttSettingsService.h | 8 -------- lib/framework/SecurityManager.h | 5 ----- 3 files changed, 9 insertions(+), 14 deletions(-) diff --git a/lib/framework/MqttSettingsService.cpp b/lib/framework/MqttSettingsService.cpp index 2ac8958d1..9f7b88c8e 100644 --- a/lib/framework/MqttSettingsService.cpp +++ b/lib/framework/MqttSettingsService.cpp @@ -16,6 +16,14 @@ MqttSettingsService::MqttSettingsService(AsyncWebServer * server, FS * fs, Secur addUpdateHandler([this] { onConfigUpdated(); }, false); } +static String generateClientId() { +#ifdef EMSESP_STANDALONE + return "ems-esp"; +#else + return "esp32-" + String(static_cast(ESP.getEfuseMac()), HEX); +#endif +} + MqttSettingsService::~MqttSettingsService() { delete _mqttClient; } @@ -255,7 +263,7 @@ StateUpdateResult MqttSettings::update(JsonObject root, MqttSettings & settings) newSettings.base = root["base"] | FACTORY_MQTT_BASE; newSettings.username = root["username"] | FACTORY_MQTT_USERNAME; newSettings.password = root["password"] | FACTORY_MQTT_PASSWORD; - newSettings.clientId = root["client_id"] | FACTORY_MQTT_CLIENT_ID; + newSettings.clientId = root["client_id"] | generateClientId(); newSettings.keepAlive = static_cast(root["keep_alive"] | FACTORY_MQTT_KEEP_ALIVE); newSettings.cleanSession = root["clean_session"] | FACTORY_MQTT_CLEAN_SESSION; newSettings.mqtt_qos = static_cast(root["mqtt_qos"] | EMSESP_DEFAULT_MQTT_QOS); diff --git a/lib/framework/MqttSettingsService.h b/lib/framework/MqttSettingsService.h index 7fd7ab69c..d4ddf9f86 100644 --- a/lib/framework/MqttSettingsService.h +++ b/lib/framework/MqttSettingsService.h @@ -4,7 +4,6 @@ #include "StatefulService.h" #include "HttpEndpoint.h" #include "FSPersistence.h" -#include "ESPUtils.h" #include @@ -39,13 +38,6 @@ #define FACTORY_MQTT_PASSWORD "" #endif -#ifndef FACTORY_MQTT_CLIENT_ID -#define FACTORY_MQTT_CLIENT_ID generateClientId() -static String generateClientId() { - return ESPUtils::defaultDeviceValue("esp32-"); -} -#endif - #ifndef FACTORY_MQTT_KEEP_ALIVE #define FACTORY_MQTT_KEEP_ALIVE 16 #endif diff --git a/lib/framework/SecurityManager.h b/lib/framework/SecurityManager.h index 1e9bec21b..11bbed956 100644 --- a/lib/framework/SecurityManager.h +++ b/lib/framework/SecurityManager.h @@ -3,16 +3,11 @@ #include "Features.h" #include "ArduinoJsonJWT.h" -#include "ESPUtils.h" #include #include #include -#ifndef FACTORY_JWT_SECRET -#define FACTORY_JWT_SECRET ESPUtils::defaultDeviceValue() -#endif - #define ACCESS_TOKEN_PARAMATER "access_token" #define AUTHORIZATION_HEADER "Authorization" From e31330e931a194256042b04581ab95f5346cd36e Mon Sep 17 00:00:00 2001 From: proddy Date: Wed, 14 Feb 2024 15:06:51 +0100 Subject: [PATCH 51/54] 200 char limit for hostnames --- interface/src/validators/shared.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/interface/src/validators/shared.ts b/interface/src/validators/shared.ts index a028b5893..235b7bcb9 100644 --- a/interface/src/validators/shared.ts +++ b/interface/src/validators/shared.ts @@ -33,7 +33,7 @@ export const IP_ADDRESS_VALIDATOR = { } }; -const HOSTNAME_LENGTH_REGEXP = /^.{0,63}$/; +const HOSTNAME_LENGTH_REGEXP = /^.{0,200}$/; const HOSTNAME_PATTERN_REGEXP = /^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9-]*[A-Za-z0-9])$/; @@ -42,7 +42,7 @@ const isValidHostname = (value: string) => HOSTNAME_LENGTH_REGEXP.test(value) && export const HOSTNAME_VALIDATOR = { validator(rule: InternalRuleItem, value: string, callback: (error?: string) => void) { if (value && !isValidHostname(value)) { - callback('Must be a valid hostname of up to 63 characters'); + callback('Must be a valid hostname'); } else { callback(); } @@ -52,7 +52,7 @@ export const HOSTNAME_VALIDATOR = { export const IP_OR_HOSTNAME_VALIDATOR = { validator(rule: InternalRuleItem, value: string, callback: (error?: string) => void) { if (value && !(isValidIpAddress(value) || isValidHostname(value))) { - callback('Must be a valid IP address or hostname of up to 63 characters'); + callback('Must be a valid IP address or hostname'); } else { callback(); } From ed9cad6e39b564a8c566bd669bf6e864be11a5ac Mon Sep 17 00:00:00 2001 From: proddy Date: Wed, 14 Feb 2024 15:07:02 +0100 Subject: [PATCH 52/54] hostname is multiline --- interface/src/framework/mqtt/MqttSettingsForm.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/interface/src/framework/mqtt/MqttSettingsForm.tsx b/interface/src/framework/mqtt/MqttSettingsForm.tsx index 6a8688dbf..2034d383a 100644 --- a/interface/src/framework/mqtt/MqttSettingsForm.tsx +++ b/interface/src/framework/mqtt/MqttSettingsForm.tsx @@ -72,6 +72,7 @@ const MqttSettingsForm: FC = () => { name="host" label={LL.ADDRESS_OF(LL.BROKER())} fullWidth + multiline variant="outlined" value={data.host} onChange={updateFormValue} From 8bd2a39d4e61523bbdd081870b5fe547e5befa84 Mon Sep 17 00:00:00 2001 From: proddy Date: Wed, 14 Feb 2024 15:07:17 +0100 Subject: [PATCH 53/54] update for 3.6.5-dev14 --- CHANGELOG_LATEST.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG_LATEST.md b/CHANGELOG_LATEST.md index 6590348ee..9ba8bb590 100644 --- a/CHANGELOG_LATEST.md +++ b/CHANGELOG_LATEST.md @@ -32,9 +32,12 @@ - added writeable icon to Web's Custom Entity page for each entity shown in the table - Wifi Tx Power not adjusted [#1614](https://github.com/emsesp/EMS-ESP32/issues/1614) - MQTT discovery of custom entity doesn't consider type of data [#1587](https://github.com/emsesp/EMS-ESP32/issues/1587) +- WiFi TxPower wasn't correctly used. Added an 'Auto' setting, which is the default. ## Changed - HA don't set entity_category to Diagnostic/Configuration for EMS entities [#1459](https://github.com/emsesp/EMS-ESP32/discussions/1459) - upgraded ArduinoJson to 7.0.0 #1538 and then 7.0.2 - small changes to the API for analog and temperature sensors +- Length of mqtt Broker adress [#1619](https://github.com/emsesp/EMS-ESP32/issues/1619) +- C++ optimizations - see From 944d86b64475eaff711e01c65cde6cca2ae3c768 Mon Sep 17 00:00:00 2001 From: proddy Date: Wed, 14 Feb 2024 15:07:35 +0100 Subject: [PATCH 54/54] removed unused _retained's --- lib/framework/MqttSettingsService.cpp | 4 ---- lib/framework/MqttSettingsService.h | 8 -------- 2 files changed, 12 deletions(-) diff --git a/lib/framework/MqttSettingsService.cpp b/lib/framework/MqttSettingsService.cpp index 9f7b88c8e..57d7f5313 100644 --- a/lib/framework/MqttSettingsService.cpp +++ b/lib/framework/MqttSettingsService.cpp @@ -4,10 +4,6 @@ MqttSettingsService::MqttSettingsService(AsyncWebServer * server, FS * fs, SecurityManager * securityManager) : _httpEndpoint(MqttSettings::read, MqttSettings::update, this, server, MQTT_SETTINGS_SERVICE_PATH, securityManager) , _fsPersistence(MqttSettings::read, MqttSettings::update, this, fs, MQTT_SETTINGS_FILE) - , _retainedHost(nullptr) - , _retainedClientId(nullptr) - , _retainedUsername(nullptr) - , _retainedPassword(nullptr) , _reconfigureMqtt(false) , _disconnectedAt(0) , _disconnectReason(espMqttClientTypes::DisconnectReason::TCP_DISCONNECTED) diff --git a/lib/framework/MqttSettingsService.h b/lib/framework/MqttSettingsService.h index d4ddf9f86..9fe5ef71c 100644 --- a/lib/framework/MqttSettingsService.h +++ b/lib/framework/MqttSettingsService.h @@ -109,14 +109,6 @@ class MqttSettingsService : public StatefulService { HttpEndpoint _httpEndpoint; FSPersistence _fsPersistence; - // Pointers to hold retained copies of the mqtt client connection strings. - // This is required as espMqttClient holds references to the supplied connection strings. - char * _retainedHost; - char * _retainedClientId; - char * _retainedUsername; - char * _retainedPassword; - char * _retainedRootCA; - // variable to help manage connection bool _reconfigureMqtt; unsigned long _disconnectedAt;