Skip to content

Commit

Permalink
Merge pull request #226 from mathieucarbou/dev
Browse files Browse the repository at this point in the history
Several improvements regarding transfer size and speed
  • Loading branch information
ayushsharma82 authored Jul 6, 2024
2 parents e64eb8b + f47b9df commit d38bb48
Show file tree
Hide file tree
Showing 4 changed files with 132 additions and 85 deletions.
12 changes: 6 additions & 6 deletions src/Chart.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ void Chart::updateX(int arr_x[], size_t x_size){
_x_axis_i_ptr = arr_x;
_x_axis_ptr_size = x_size;
#endif
_changed = true;
_x_changed = true;
}

void Chart::updateX(float arr_x[], size_t x_size){
Expand All @@ -73,7 +73,7 @@ void Chart::updateX(float arr_x[], size_t x_size){
_x_axis_f_ptr = arr_x;
_x_axis_ptr_size = x_size;
#endif
_changed = true;
_x_changed = true;
}

void Chart::updateX(String arr_x[], size_t x_size){
Expand All @@ -88,7 +88,7 @@ void Chart::updateX(String arr_x[], size_t x_size){
_x_axis_s_ptr = arr_x;
_x_axis_ptr_size = x_size;
#endif
_changed = true;
_x_changed = true;
}

void Chart::updateX(const char* arr_x[], size_t x_size){
Expand All @@ -103,7 +103,7 @@ void Chart::updateX(const char* arr_x[], size_t x_size){
_x_axis_char_ptr = arr_x;
_x_axis_ptr_size = x_size;
#endif
_changed = true;
_x_changed = true;
}

void Chart::updateY(int arr_y[], size_t y_size){
Expand All @@ -118,7 +118,7 @@ void Chart::updateY(int arr_y[], size_t y_size){
_y_axis_i_ptr = arr_y;
_y_axis_ptr_size = y_size;
#endif
_changed = true;
_y_changed = true;
}

void Chart::updateY(float arr_y[], size_t y_size){
Expand All @@ -133,7 +133,7 @@ void Chart::updateY(float arr_y[], size_t y_size){
_y_axis_f_ptr = arr_y;
_y_axis_ptr_size = y_size;
#endif
_changed = true;
_y_changed = true;
}

/*
Expand Down
3 changes: 2 additions & 1 deletion src/Chart.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ class Chart {
uint32_t _id;
const char *_name;
int _type;
bool _changed;
bool _x_changed;
bool _y_changed;
GraphAxisType _x_axis_type;
GraphAxisType _y_axis_type;

Expand Down
168 changes: 90 additions & 78 deletions src/ESPDash.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ void ESPDash::generateLayoutJSON(AsyncWebSocketClient* client, bool changes_only
for (int i = 0; i < charts.Size(); i++) {
Chart* c = charts[i];
if (changes_only) {
if (!c->_changed) {
if (!c->_x_changed && !c->_y_changed) {
continue;
}
}
Expand All @@ -249,7 +249,8 @@ void ESPDash::generateLayoutJSON(AsyncWebSocketClient* client, bool changes_only

// Clear change flags
if (changes_only) {
c->_changed = false;
c->_x_changed = false;
c->_y_changed = false;
}
}

Expand Down Expand Up @@ -342,6 +343,7 @@ void ESPDash::generateLayoutJSON(AsyncWebSocketClient* client, bool changes_only

void ESPDash::send(AsyncWebSocketClient* client, JsonDocument& doc) {
const size_t len = measureJson(doc);
// ESP_LOGW("ESPDash", "Required Heap size to build WebSocket message: %d bytes. Free Heap: %" PRIu32 " bytes", len, ESP.getFreeHeap());
AsyncWebSocketMessageBuffer* buffer = _ws->makeBuffer(len);
assert(buffer);
serializeJson(doc, buffer->get(), len);
Expand All @@ -354,7 +356,13 @@ void ESPDash::send(AsyncWebSocketClient* client, JsonDocument& doc) {
}

bool ESPDash::overflowed(JsonDocument& doc) {
#if DASH_JSON_SIZE > 0 // ArduinoJson 6 (mandatory) or 7
return doc.overflowed() || measureJson(doc.as<JsonObject>()) > DASH_JSON_SIZE;
#elif DASH_MIN_FREE_HEAP > 0 // ArduinoJson 7 only
return ESP.getFreeHeap() >= DASH_MIN_FREE_HEAP;
#else // ArduinoJson 7 only
return doc.overflowed();
#endif
}

/*
Expand Down Expand Up @@ -402,84 +410,88 @@ void ESPDash::generateComponentJSON(JsonObject& doc, Chart* chart, bool change_o
doc["t"] = chartTags[chart->_type].type;
}

JsonArray xAxis = doc["x"].to<JsonArray>();
switch (chart->_x_axis_type) {
case GraphAxisType::INTEGER:
#if DASH_USE_LEGACY_CHART_STORAGE == 1
for(int i=0; i < chart->_x_axis_i.Size(); i++)
xAxis.add(chart->_x_axis_i[i]);
#else
if (chart->_x_axis_i_ptr != nullptr) {
for(unsigned int i=0; i < chart->_x_axis_ptr_size; i++)
xAxis.add(chart->_x_axis_i_ptr[i]);
}
#endif
break;
case GraphAxisType::FLOAT:
#if DASH_USE_LEGACY_CHART_STORAGE == 1
for(int i=0; i < chart->_x_axis_f.Size(); i++)
xAxis.add(chart->_x_axis_f[i]);
#else
if (chart->_x_axis_f_ptr != nullptr) {
for(unsigned int i=0; i < chart->_x_axis_ptr_size; i++)
xAxis.add(chart->_x_axis_f_ptr[i]);
}
#endif
break;
case GraphAxisType::CHAR:
#if DASH_USE_LEGACY_CHART_STORAGE == 1
for(int i=0; i < chart->_x_axis_s.Size(); i++)
xAxis.add(chart->_x_axis_s[i].c_str());
#else
if (chart->_x_axis_char_ptr != nullptr) {
for(unsigned int i=0; i < chart->_x_axis_ptr_size; i++)
xAxis.add(chart->_x_axis_char_ptr[i]);
}
#endif
break;
case GraphAxisType::STRING:
#if DASH_USE_LEGACY_CHART_STORAGE == 1
for(int i=0; i < chart->_x_axis_s.Size(); i++)
xAxis.add(chart->_x_axis_s[i].c_str());
#else
if (chart->_x_axis_s_ptr != nullptr) {
for(unsigned int i=0; i < chart->_x_axis_ptr_size; i++)
xAxis.add(chart->_x_axis_s_ptr[i]);
}
#endif
break;
default:
// blank value
break;
if(!change_only || chart->_x_changed) {
JsonArray xAxis = doc["x"].to<JsonArray>();
switch (chart->_x_axis_type) {
case GraphAxisType::INTEGER:
#if DASH_USE_LEGACY_CHART_STORAGE == 1
for(int i=0; i < chart->_x_axis_i.Size(); i++)
xAxis.add(chart->_x_axis_i[i]);
#else
if (chart->_x_axis_i_ptr != nullptr) {
for(unsigned int i=0; i < chart->_x_axis_ptr_size; i++)
xAxis.add(chart->_x_axis_i_ptr[i]);
}
#endif
break;
case GraphAxisType::FLOAT:
#if DASH_USE_LEGACY_CHART_STORAGE == 1
for(int i=0; i < chart->_x_axis_f.Size(); i++)
xAxis.add(chart->_x_axis_f[i]);
#else
if (chart->_x_axis_f_ptr != nullptr) {
for(unsigned int i=0; i < chart->_x_axis_ptr_size; i++)
xAxis.add(chart->_x_axis_f_ptr[i]);
}
#endif
break;
case GraphAxisType::CHAR:
#if DASH_USE_LEGACY_CHART_STORAGE == 1
for(int i=0; i < chart->_x_axis_s.Size(); i++)
xAxis.add(chart->_x_axis_s[i].c_str());
#else
if (chart->_x_axis_char_ptr != nullptr) {
for(unsigned int i=0; i < chart->_x_axis_ptr_size; i++)
xAxis.add(chart->_x_axis_char_ptr[i]);
}
#endif
break;
case GraphAxisType::STRING:
#if DASH_USE_LEGACY_CHART_STORAGE == 1
for(int i=0; i < chart->_x_axis_s.Size(); i++)
xAxis.add(chart->_x_axis_s[i].c_str());
#else
if (chart->_x_axis_s_ptr != nullptr) {
for(unsigned int i=0; i < chart->_x_axis_ptr_size; i++)
xAxis.add(chart->_x_axis_s_ptr[i]);
}
#endif
break;
default:
// blank value
break;
}
}

JsonArray yAxis = doc["y"].to<JsonArray>();
switch (chart->_y_axis_type) {
case GraphAxisType::INTEGER:
#if DASH_USE_LEGACY_CHART_STORAGE == 1
for(int i=0; i < chart->_y_axis_i.Size(); i++)
yAxis.add(chart->_y_axis_i[i]);
#else
if (chart->_y_axis_i_ptr != nullptr) {
for(unsigned int i=0; i < chart->_y_axis_ptr_size; i++)
yAxis.add(chart->_y_axis_i_ptr[i]);
}
#endif
break;
case GraphAxisType::FLOAT:
#if DASH_USE_LEGACY_CHART_STORAGE == 1
for(int i=0; i < chart->_y_axis_f.Size(); i++)
yAxis.add(chart->_y_axis_f[i]);
#else
if (chart->_y_axis_f_ptr != nullptr) {
for(unsigned int i=0; i < chart->_y_axis_ptr_size; i++)
yAxis.add(chart->_y_axis_f_ptr[i]);
}
#endif
break;
default:
// blank value
break;
if(!change_only || chart->_y_changed) {
JsonArray yAxis = doc["y"].to<JsonArray>();
switch (chart->_y_axis_type) {
case GraphAxisType::INTEGER:
#if DASH_USE_LEGACY_CHART_STORAGE == 1
for(int i=0; i < chart->_y_axis_i.Size(); i++)
yAxis.add(chart->_y_axis_i[i]);
#else
if (chart->_y_axis_i_ptr != nullptr) {
for(unsigned int i=0; i < chart->_y_axis_ptr_size; i++)
yAxis.add(chart->_y_axis_i_ptr[i]);
}
#endif
break;
case GraphAxisType::FLOAT:
#if DASH_USE_LEGACY_CHART_STORAGE == 1
for(int i=0; i < chart->_y_axis_f.Size(); i++)
yAxis.add(chart->_y_axis_f[i]);
#else
if (chart->_y_axis_f_ptr != nullptr) {
for(unsigned int i=0; i < chart->_y_axis_ptr_size; i++)
yAxis.add(chart->_y_axis_f_ptr[i]);
}
#endif
break;
default:
// blank value
break;
}
}
}

Expand Down
34 changes: 34 additions & 0 deletions src/ESPDash.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,45 @@ Github URL: https://github.com/ayushsharma82/ESP-DASH
#include "Chart.h"
#include "Statistic.h"

// If DASH_JSON_SIZE is set to a value, ESP-DASH will frequently measure the Json payload to make sure it remains within this size.
// If the Json payload to send is larger, the payload will be split in several parts and sent in multiple messages.
//
// When this value is set:
// - it should not be too large to avoid sending a big message, which takes longer to send and to build because of the frequent json size measurements. 4096 and 8192 are good values for large dashboards.
// - it should not be too small to avoid sending too many messages, which can slow down the dashboard rendering and fill the websocket message queue. 2048 is a good minimum value.
//
// When using ArduinoJson 7, you can set this value to 0 (by default) to disable the websocket message fragmentation in smaller parts and to disable the measurements, to improve performance.
// This will speed up the rendering, at the expense of risking to exhaust the heap in the case of large dashboard.
// To workaround that, when using DASH_JSON_SIZE == 0 with ArduinoJson 7, you can also set DASH_MIN_FREE_HEAP to a value which is more than the size of the biggest payload for your dashboard.
// For example, if your app is big and has a payload sie of 12kb, then you can set DASH_MIN_FREE_HEAP to 16384 (16kb) to make sure the heap is never exhausted.
// When DASH_MIN_FREE_HEAP is set to a value, you instruct ESP-DASH to check the free heap to make sure there is enough heap to send the payload.
//
// In summary:
//
// - With ArduinoJson 6: DASH_JSON_SIZE should be set to a value greater than 0 and fragmentation is used.
// - With ArduinoJson 7: DASH_JSON_SIZE can be set to 0 to disable the fragmentation and the measurements, at the risk of going out of heap. This option gives the best performance but you need to make sure to have enough heap in case your application is large.
// - With ArduinoJson 7: if DASH_JSON_SIZE is set to 0 and DASH_MIN_FREE_HEAP is set to a value greater than 0, heap will be checked before sending the payload and fragmentation will trigger if not enough heap..
// - DASH_MIN_FREE_HEAP will have no effect is DASH_JSON_SIZE is not set to 0
//
// To help you decide, you can uncomment line 543 in the cpp which will display the free heap size and teh required heap size to build the websocket message.
// ESP_LOGW("ESPDash", "Required Heap size to build WebSocket message: %d bytes. Free Heap: %" PRIu32 " bytes", len, ESP.getFreeHeap());
#ifndef DASH_JSON_SIZE
#if ARDUINOJSON_VERSION_MAJOR == 6 && !defined(DASH_JSON_DOCUMENT_ALLOCATION)
#define DASH_JSON_SIZE 2048
#else
#define DASH_JSON_SIZE 0
#endif // ARDUINOJSON_VERSION_MAJOR == 6 && !defined(DASH_JSON_DOCUMENT_ALLOCATION)
#endif // DASH_JSON_SIZE

// Only for ArduinoJson 7
#ifndef DASH_MIN_FREE_HEAP
#define DASH_MIN_FREE_HEAP 0
#endif

#if ARDUINOJSON_VERSION_MAJOR == 6 && !defined(DASH_JSON_DOCUMENT_ALLOCATION)
#if DASH_JSON_SIZE == 0
#error "DASH_JSON_SIZE must be set to a value greater than 0 when using ArduinoJson 6"
#endif
#define DASH_JSON_DOCUMENT_ALLOCATION DASH_JSON_SIZE * 3
#endif

Expand Down

0 comments on commit d38bb48

Please sign in to comment.