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: