diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7f4a9b5a..8d57f911 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -64,7 +64,7 @@ jobs: run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-url https://github.com/mathieucarbou/esphome-ESPAsyncTCP#v2.0.0 - name: Install ESPAsyncWebServer - run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-url https://github.com/mathieucarbou/ESPAsyncWebServer#v2.10.1 + run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-url https://github.com/mathieucarbou/ESPAsyncWebServer#v3.0.2 - name: Install ArduinoJson run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-url https://github.com/bblanchon/ArduinoJson#v7.0.4 @@ -97,31 +97,31 @@ jobs: - name: esp32dev|arduino board: esp32dev platform: espressif32 - opts: + opts: "--project-option 'lib_compat_mode = strict'" - name: esp32dev|arduino-2 board: esp32dev platform: espressif32@6.7.0 - opts: + opts: "--project-option 'lib_compat_mode = strict'" - name: esp32dev|arduino-3 board: esp32dev platform: espressif32 - opts: "--project-option 'platform_packages=platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.0, platform_packages=platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/arduino-esp32/releases/download/3.0.0/esp32-arduino-libs-3.0.0.zip'" + opts: "--project-option 'lib_compat_mode = strict' --project-option 'platform_packages=platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.2, platform_packages=platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/arduino-esp32/releases/download/3.0.2/esp32-arduino-libs-3.0.2.zip'" - name: esp32-s3-devkitc-1|arduino board: esp32-s3-devkitc-1 platform: espressif32 - opts: + opts: "--project-option 'lib_compat_mode = strict'" - name: esp32-s3-devkitc-1|arduino-2 board: esp32-s3-devkitc-1 platform: espressif32@6.7.0 - opts: + opts: "--project-option 'lib_compat_mode = strict'" - name: esp32-s3-devkitc-1|arduino-3 board: esp32-s3-devkitc-1 platform: espressif32 - opts: "--project-option 'platform_packages=platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.0, platform_packages=platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/arduino-esp32/releases/download/3.0.0/esp32-arduino-libs-3.0.0.zip'" + opts: "--project-option 'lib_compat_mode = strict' --project-option 'platform_packages=platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.2, platform_packages=platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/arduino-esp32/releases/download/3.0.2/esp32-arduino-libs-3.0.2.zip'" - name: huzzah|espressif8266 board: huzzah platform: espressif8266 - opts: + opts: "--project-option 'lib_compat_mode = strict'" steps: - uses: actions/checkout@v4 - name: Set up cache diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml new file mode 100644 index 00000000..4279cc6b --- /dev/null +++ b/.github/workflows/stale.yml @@ -0,0 +1,17 @@ +name: 'Close stale issues and PR' +on: + schedule: + - cron: '30 6 * * *' + +jobs: + stale: + runs-on: ubuntu-latest + steps: + - uses: actions/stale@v9 + with: + stale-issue-message: 'This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days.' + stale-pr-message: 'This PR is marked as stale because it has been open 45 days with no activity. You can remove stale label or comment if this PR is still valid.' + close-issue-message: 'This issue was closed because it has been stalled for 5 days with no activity.' + days-before-stale: 30 + days-before-close: 5 + days-before-pr-close: -1 diff --git a/README.md b/README.md index 170d062c..d678e6be 100644 --- a/README.md +++ b/README.md @@ -79,7 +79,7 @@ ESP-DASH Pro comes with the following extended functionality:

License

-ESP-DASH is licensed under General Public License v3 ( GPLv3 ). If you are intending to use ESP-DASH in a commercial project, please consider buying the [ESP-DASH Pro](https://espdash.pro) which comes with a less restrictive SCL-1.0 license ( SOFTT Commercial License 1.0 ). +ESP-DASH is licensed under General Public License v3 ( GPLv3 ). If you are intending to use ESP-DASH in a commercial project, please consider buying the [ESP-DASH Pro](https://espdash.pro) which comes with a less restrictive SCL-1.1 license ( SOFTT Commercial License 1.1 ).

diff --git a/library.json b/library.json index c94c45c8..c7f4d770 100644 --- a/library.json +++ b/library.json @@ -15,7 +15,7 @@ "maintainer": true } ], - "version": "4.0.4", + "version": "4.0.5", "frameworks": "arduino", "platforms": ["espressif32", "espressif8266"], "dependencies": [ @@ -28,7 +28,7 @@ { "owner": "mathieucarbou", "name": "ESP Async WebServer", - "version": "^2.10.1", + "version": "^3.0.2", "platforms": ["espressif8266", "espressif32"] } ] diff --git a/library.properties b/library.properties index f571f9ab..aace960f 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESP-DASH -version=4.0.4 +version=4.0.5 author=Ayush Sharma category=Communication maintainer=Ayush Sharma diff --git a/platformio.ini b/platformio.ini index 0c1b21e0..44003c8d 100644 --- a/platformio.ini +++ b/platformio.ini @@ -7,7 +7,7 @@ build_flags = lib_deps = bblanchon/ArduinoJson @ 7.0.4 mathieucarbou/Async TCP @ ^3.1.4 - mathieucarbou/ESP Async WebServer @ 2.10.1 + mathieucarbou/ESP Async WebServer @ 3.0.2 upload_protocol = esptool monitor_speed = 115200 monitor_filters = esp32_exception_decoder, log2file @@ -32,8 +32,8 @@ board = esp32-s3-devkitc-1 [env:arduino-3] platform = espressif32 platform_packages= - platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.0 - platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/arduino-esp32/releases/download/3.0.0/esp32-arduino-libs-3.0.0.zip + platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.2 + platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/arduino-esp32/releases/download/3.0.2/esp32-arduino-libs-3.0.2.zip board = esp32-s3-devkitc-1 [env:esp8266] @@ -41,5 +41,5 @@ platform = espressif8266 board = huzzah lib_deps = bblanchon/ArduinoJson @ 7.0.4 - mathieucarbou/ESP Async WebServer @ 2.10.1 + mathieucarbou/ESP Async WebServer @ 3.0.2 esphome/ESPAsyncTCP-esphome @ 2.0.0 diff --git a/src/ESPDash.cpp b/src/ESPDash.cpp index f7b52b41..3a469990 100644 --- a/src/ESPDash.cpp +++ b/src/ESPDash.cpp @@ -36,18 +36,18 @@ ESPDash::ESPDash(AsyncWebServer* server, const char* uri, bool enable_default_st // Attach AsyncWebServer Routes _server->on(uri, HTTP_GET, [this](AsyncWebServerRequest *request){ if(basic_auth){ - if(!request->authenticate(username, password)) + if(!request->authenticate(username.c_str(), password.c_str())) return request->requestAuthentication(); } // respond with the compressed frontend - AsyncWebServerResponse *response = request->beginResponse_P(200, "text/html", DASH_HTML, sizeof(DASH_HTML)); + AsyncWebServerResponse *response = request->beginResponse(200, "text/html", DASH_HTML, sizeof(DASH_HTML)); response->addHeader("Content-Encoding", "gzip"); response->addHeader("Cache-Control", "public, max-age=900"); request->send(response); }); // Websocket Callback Handler - _ws->onEvent([&](AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len){ + _ws->onEvent([&](__unused AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len){ // Request Buffer #if ARDUINOJSON_VERSION_MAJOR == 7 JsonDocument json; @@ -64,6 +64,8 @@ ESPDash::ESPDash(AsyncWebServer* server, const char* uri, bool enable_default_st // client side commands parsing if (json["command"] == "get:layout") { _asyncAccessInProgress = true; + if (_beforeUpdateCallback) + _beforeUpdateCallback(false); generateLayoutJSON(client, false); _asyncAccessInProgress = false; } else if (json["command"] == "ping") { @@ -105,11 +107,11 @@ ESPDash::ESPDash(AsyncWebServer* server, const char* uri, bool enable_default_st } void ESPDash::setAuthentication(const char *user, const char *pass) { - basic_auth = strlen(user) > 0 && strlen(pass) > 0; + username = user; + password = pass; + basic_auth = username.length() && password.length(); if(basic_auth) { - strncpy(username, user, sizeof(username)); - strncpy(password, pass, sizeof(password)); - _ws->setAuthentication(user, pass); + _ws->setAuthentication(username.c_str(), password.c_str()); } } @@ -314,7 +316,7 @@ void ESPDash::generateLayoutJSON(AsyncWebSocketClient* client, bool changes_only doc["stats"][idx]["i"] = s->_id; doc["stats"][idx]["k"] = s->_key; - if (changes_only || strlen(s->_value) > 0) + if (changes_only || s->_value.length() > 0) doc["stats"][idx]["v"] = s->_value; doc["stats"][idx]["v"] = s->_value; idx++; @@ -487,6 +489,8 @@ void ESPDash::sendUpdates(bool force) { if (!hasClient()) { return; } + if (_beforeUpdateCallback) + _beforeUpdateCallback(!force); generateLayoutJSON(nullptr, !force); } @@ -495,6 +499,8 @@ void ESPDash::refreshCard(Card *card) { if (!hasClient()) { return; } + if (_beforeUpdateCallback) + _beforeUpdateCallback(true); generateLayoutJSON(nullptr, true, card); } diff --git a/src/ESPDash.h b/src/ESPDash.h index ab54d14f..9ed17f29 100644 --- a/src/ESPDash.h +++ b/src/ESPDash.h @@ -68,6 +68,11 @@ class Statistic; // ESPDASH Class class ESPDash{ + public: + // changes_only: true (equivalent to sendUpdates(false)) - when sending updates to the client + // changes_only: false (equivalent to sendUpdates(true)) - when sending the entire layout to the client or when forcing a full update + typedef std::function BeforeUpdateCallback; + private: AsyncWebServer* _server = nullptr; AsyncWebSocket* _ws = nullptr; @@ -77,9 +82,10 @@ class ESPDash{ Vector statistics; bool default_stats_enabled = false; bool basic_auth = false; - char username[64]; - char password[64]; + String username; + String password; uint32_t _idCounter = 0; + BeforeUpdateCallback _beforeUpdateCallback = nullptr; volatile bool _asyncAccessInProgress = false; @@ -129,6 +135,12 @@ class ESPDash{ // in which case you should not modify them bool isAsyncAccessInProgress() { return _asyncAccessInProgress; } + // Register a callback that will be called before some updates will be sent to the client. + // This callback can be used for example to refresh some card values that never change after only when a full layout is request (i.e. on page reload). + // This allows to avoid spending time refreshing cards that never change, but still allows them to be refreshed hen the user refresh the dashboard. + // If called from the async_http task, isAsyncAccessInProgress() will return true while in this callback. + void onBeforeUpdate(BeforeUpdateCallback callback) { _beforeUpdateCallback = callback; } + ~ESPDash(); }; diff --git a/src/Statistic.cpp b/src/Statistic.cpp index b32bddc2..46995903 100644 --- a/src/Statistic.cpp +++ b/src/Statistic.cpp @@ -5,16 +5,15 @@ Statistic::Statistic(ESPDash *dashboard, const char *key, const char *value) { _id = dashboard->nextId(); // Safe copy _key = key; - strncpy(_value, value, sizeof(_value)); + _value = value; _dashboard->add(this); } void Statistic::set(const char *value) { // Safe copy - _changed = strcmp(_value, value) != 0; + _changed = _value != value; if(_changed) - strncpy(_value, value, sizeof(_value)); - + _value = value; } Statistic::~Statistic() { diff --git a/src/Statistic.h b/src/Statistic.h index bf796dc4..819343a5 100644 --- a/src/Statistic.h +++ b/src/Statistic.h @@ -16,7 +16,7 @@ class Statistic { ESPDash *_dashboard; uint32_t _id; const char *_key; - char _value[64]; + String _value; bool _changed = false; public: