Skip to content

Commit

Permalink
Merge pull request #183 from mathieucarbou/dev
Browse files Browse the repository at this point in the history
Combination of 1+2+3+4+5+6 + websocket reload fix
  • Loading branch information
ayushsharma82 authored Dec 16, 2023
2 parents 4547fd2 + b6579b6 commit 2556e23
Show file tree
Hide file tree
Showing 8 changed files with 3,099 additions and 3,058 deletions.
6 changes: 3 additions & 3 deletions library.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@
"dependencies":
[
{
"name": "ESP Async WebServer",
"version": "1.2.3"
"name": "ESPAsyncWebServer-esphome",
"version": "^3.1.0"
},
{
"name": "ArduinoJson",
"version": "6.17.0"
"version": "^6.17.0"
}
]
}
6 changes: 1 addition & 5 deletions src/Card.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,7 @@
*/
Card::Card(ESPDash *dashboard, const int type, const char* name, const char* symbol, const int min, const int max){
_dashboard = dashboard;
#if defined(ESP8266)
_id = RANDOM_REG32;
#elif defined(ESP32)
_id = esp_random();
#endif
_id = dashboard->nextId();
_type = type;
_name = name;
_symbol = symbol;
Expand Down
6 changes: 1 addition & 5 deletions src/Chart.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,7 @@
*/
Chart::Chart(ESPDash *dashboard, const int type, const char* name){
_dashboard = dashboard;
#if defined(ESP8266)
_id = RANDOM_REG32;
#elif defined(ESP32)
_id = esp_random();
#endif
_id = dashboard->nextId();
_type = type;
_name = name;
_dashboard->add(this);
Expand Down
66 changes: 49 additions & 17 deletions src/ESPDash.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ ESPDash::ESPDash(AsyncWebServer* server, const char* uri, bool enable_default_st
}
// respond with the compressed frontend
AsyncWebServerResponse *response = request->beginResponse_P(200, "text/html", DASH_HTML, sizeof(DASH_HTML));
response->addHeader("Content-Encoding","gzip");
response->addHeader("Cache-Control","public, max-age=900");
response->addHeader("Content-Encoding", "gzip");
response->addHeader("Cache-Control", "public, max-age=900");
request->send(response);
});

Expand Down Expand Up @@ -163,9 +163,22 @@ void ESPDash::remove(Statistic *statistic) {
}

// generates the layout JSON string to the frontend
size_t ESPDash::generateLayoutJSON(AsyncWebSocketClient *client, bool changes_only) {
size_t ESPDash::generateLayoutJSON(AsyncWebSocketClient *client, bool changes_only, Card *onlyCard) {
// https://github.com/me-no-dev/ESPAsyncWebServer#limiting-the-number-of-web-socket-clients
// Browsers sometimes do not correctly close the websocket connection, even when the close() function is called in javascript.
// This will eventually exhaust the web server's resources and will cause the server to crash.
// Use DEFAULT_MAX_WS_CLIENTS or DASH_MAX_WS_CLIENTS (specific to ESP-DASH) to set the maximum number of clients
_ws->cleanupClients();

const size_t clients = _ws->count();

if (clients == 0) {
// do not consume cpu and memory if no client is connected
return 0;
}

String buf = "";
buf.reserve(DASH_LAYOUT_JSON_SIZE);
buf.reserve(changes_only ? DASH_PARTIAL_UPDATE_JSON_SIZE : DASH_LAYOUT_JSON_SIZE);

if (changes_only) {
buf += "{\"command\":\"update:components\",";
Expand All @@ -183,7 +196,7 @@ size_t ESPDash::generateLayoutJSON(AsyncWebSocketClient *client, bool changes_on
if (changes_only) {
if (c->_changed) {
c->_changed = false;
} else {
} else if (onlyCard == nullptr || onlyCard->_id != c->_id) {
continue;
}
}
Expand Down Expand Up @@ -302,6 +315,8 @@ size_t ESPDash::generateLayoutJSON(AsyncWebSocketClient *client, bool changes_on
}
obj["i"] = s->_id;
obj["k"] = s->_key;
if(changes_only || strlen(s->_value) > 0)
obj["v"] = s->_value;
obj["v"] = s->_value;
serializeJson(obj, buf);
obj.clear();
Expand All @@ -315,6 +330,9 @@ size_t ESPDash::generateLayoutJSON(AsyncWebSocketClient *client, bool changes_on
// Store the length of the JSON string
size_t total = buf.length();
// Send resp
#ifdef DASH_DEBUG
Serial.printf("client=%d, count=%d, changes_only=%d, total=%d\n%s\n", (client == nullptr ? -1 : client->id()), clients, changes_only, total, buf.c_str());
#endif
if (client != nullptr) {
_ws->text(client->id(), buf.c_str(), total);
} else {
Expand All @@ -333,22 +351,25 @@ size_t ESPDash::generateLayoutJSON(AsyncWebSocketClient *client, bool changes_on
void ESPDash::generateComponentJSON(JsonObject& doc, Card* card, bool change_only){
doc["id"] = card->_id;
if(!change_only){
doc["name"] = card->_name;
doc["type"] = cardTags[card->_type].type;
doc["value_min"] = card->_value_min;
doc["value_max"] = card->_value_max;
doc["n"] = card->_name.c_str();
doc["t"] = cardTags[card->_type].type;
doc["min"] = card->_value_min;
doc["max"] = card->_value_max;
}
doc["symbol"] = card->_symbol;
if(change_only || !card->_symbol.isEmpty())
doc["s"] = card->_symbol;

switch (card->_value_type) {
case Card::INTEGER:
doc["value"] = card->_value_i;
doc["v"] = card->_value_i;
break;
case Card::FLOAT:
doc["value"] = String(card->_value_f, 2);
doc["v"] = String(card->_value_f, 2);
break;
case Card::STRING:
doc["value"] = card->_value_s;
if(change_only || !card->_value_s.isEmpty()) {
doc["v"] = card->_value_s;
}
break;
default:
// blank value
Expand All @@ -363,11 +384,11 @@ void ESPDash::generateComponentJSON(JsonObject& doc, Card* card, bool change_onl
void ESPDash::generateComponentJSON(JsonObject& doc, Chart* chart, bool change_only){
doc["id"] = chart->_id;
if(!change_only){
doc["name"] = chart->_name;
doc["type"] = chartTags[chart->_type].type;
doc["n"] = chart->_name.c_str();
doc["t"] = chartTags[chart->_type].type;
}

JsonArray xAxis = doc["x_axis"].to<JsonArray>();
JsonArray xAxis = doc["x"].to<JsonArray>();
switch (chart->_x_axis_type) {
case GraphAxisType::INTEGER:
#if DASH_USE_LEGACY_CHART_STORAGE == 1
Expand Down Expand Up @@ -418,7 +439,7 @@ void ESPDash::generateComponentJSON(JsonObject& doc, Chart* chart, bool change_o
break;
}

JsonArray yAxis = doc["y_axis"].to<JsonArray>();
JsonArray yAxis = doc["y"].to<JsonArray>();
switch (chart->_y_axis_type) {
case GraphAxisType::INTEGER:
#if DASH_USE_LEGACY_CHART_STORAGE == 1
Expand Down Expand Up @@ -461,6 +482,17 @@ void ESPDash::refreshStatistics() {
generateLayoutJSON(nullptr, true);
}

void ESPDash::refreshCard(Card *card) {
generateLayoutJSON(nullptr, true, card);
}

uint32_t ESPDash::nextId() {
return _idCounter++;
}

bool ESPDash::hasClient() {
return _ws->count() > 0;
}

/*
Destructor
Expand Down
22 changes: 19 additions & 3 deletions src/ESPDash.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ Github URL: https://github.com/ayushsharma82/ESP-DASH
#include "AsyncTCP.h"
#endif

#define DASH_STATUS_IDLE "i"
#define DASH_STATUS_SUCCESS "s"
#define DASH_STATUS_WARNING "w"
#define DASH_STATUS_DANGER "d"

#include "ESPAsyncWebServer.h"
#include "ArduinoJson.h"
#include "Card.h"
Expand All @@ -44,8 +49,8 @@ Github URL: https://github.com/ayushsharma82/ESP-DASH
#define DASH_LAYOUT_JSON_SIZE 1024 * 5
#endif

#ifndef DASH_STATISTICS_JSON_SIZE
#define DASH_STATISTICS_JSON_SIZE 1024 * 1
#ifndef DASH_PARTIAL_UPDATE_JSON_SIZE
#define DASH_PARTIAL_UPDATE_JSON_SIZE DASH_LAYOUT_JSON_SIZE
#endif

#ifndef DASH_CARD_JSON_SIZE
Expand All @@ -60,6 +65,10 @@ Github URL: https://github.com/ayushsharma82/ESP-DASH
#define DASH_USE_LEGACY_CHART_STORAGE 0
#endif

#ifndef DASH_MAX_WS_CLIENTS
#define DASH_MAX_WS_CLIENTS DEFAULT_MAX_WS_CLIENTS
#endif

// Forward Declaration
class Card;
class Chart;
Expand All @@ -78,9 +87,10 @@ class ESPDash{
bool basic_auth = false;
char username[64];
char password[64];
uint32_t _idCounter = 0;

// Generate layout json
size_t generateLayoutJSON(AsyncWebSocketClient *client, bool changes_only = false);
size_t generateLayoutJSON(AsyncWebSocketClient *client, bool changes_only = false, Card *onlyCard = nullptr);

// Generate Component JSON
void generateComponentJSON(JsonObject& obj, Card* card, bool change_only = false);
Expand Down Expand Up @@ -118,6 +128,12 @@ class ESPDash{

void refreshStatistics();

void refreshCard(Card *card);

uint32_t nextId();

bool hasClient();

~ESPDash();
};

Expand Down
20 changes: 10 additions & 10 deletions src/Statistic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,7 @@

Statistic::Statistic(ESPDash *dashboard, const char *key, const char *value) {
_dashboard = dashboard;
#if defined(ESP8266)
_id = RANDOM_REG32;
#elif defined(ESP32)
_id = esp_random();
#endif
_id = dashboard->nextId();
// Safe copy
strncpy(_key, key, sizeof(_key));
strncpy(_value, value, sizeof(_value));
Expand All @@ -15,15 +11,19 @@ Statistic::Statistic(ESPDash *dashboard, const char *key, const char *value) {

void Statistic::set(const char *key, const char *value) {
// Safe copy
strncpy(_key, key, sizeof(_key));
strncpy(_value, value, sizeof(_value));
_changed = true;
_changed = strcmp(_value, value) != 0 || strcmp(_key, key) != 0;
if(_changed) {
strncpy(_key, key, sizeof(_key));
strncpy(_value, value, sizeof(_value));
}
}

void Statistic::set(const char *value) {
// Safe copy
strncpy(_value, value, sizeof(_value));
_changed = true;
_changed = strcmp(_value, value) != 0;
if(_changed)
strncpy(_value, value, sizeof(_value));

}

Statistic::~Statistic() {
Expand Down
Loading

0 comments on commit 2556e23

Please sign in to comment.