[SYS] Improve central queue stability (#1796)
* [SYS] Improve central queue stability Improve central queue stability and add metrics * Change partition for esp32dev-pilight-somfy-cc1101 to avoid program size too big error message with esp32dev-pilight-somfy-cc1101 * Only check for gateway updates at the start to avoid consuming extra memory during operations Publish the information about the available release with the retain flag
This commit is contained in:
1 parent
811bc1f608
commit
aca0850cd8
3 files changed
+47
-31
No files matched your search
@@ -185,6 +185,7 @@ custom_description = Gateway using Somfy Remote library, need CC1101
|
|||||||
[env:esp32dev-pilight-somfy-cc1101]
|
[env:esp32dev-pilight-somfy-cc1101]
|
||||||
platform = ${com.esp32_platform}
|
platform = ${com.esp32_platform}
|
||||||
board = esp32dev
|
board = esp32dev
|
||||||
|
board_build.partitions = min_spiffs.csv
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${com-esp32.lib_deps}
|
${com-esp32.lib_deps}
|
||||||
${libraries.esppilight}
|
${libraries.esppilight}
|
||||||
|
|||||||
+6
-7
@@ -662,8 +662,8 @@ void procBLETask(void* pvParameters) {
|
|||||||
*/
|
*/
|
||||||
void BLEscan() {
|
void BLEscan() {
|
||||||
// Don't start the next scan until processing of previous results is complete.
|
// Don't start the next scan until processing of previous results is complete.
|
||||||
while (uxQueueMessagesWaiting(BLEQueue) || jsonQueue.size() != 0) {
|
while (uxQueueMessagesWaiting(BLEQueue) || queueLength != 0) { // the criteria on queueLength could be adjusted to parallelize the scan and the queue processing
|
||||||
yield();
|
delay(1); // Wait for queue to empty, a yield here instead of the delay cause the WDT to trigger
|
||||||
}
|
}
|
||||||
Log.notice(F("Scan begin" CR));
|
Log.notice(F("Scan begin" CR));
|
||||||
BLEScan* pBLEScan = BLEDevice::getScan();
|
BLEScan* pBLEScan = BLEDevice::getScan();
|
||||||
@@ -806,9 +806,8 @@ void coreTask(void* pvParameters) {
|
|||||||
delay(waitms = interval > 100 ? 100 : interval); // 100ms
|
delay(waitms = interval > 100 ? 100 : interval); // 100ms
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
Log.trace(F("BLE core task canceled by processLock" CR));
|
|
||||||
}
|
}
|
||||||
|
delay(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -872,7 +871,7 @@ void setupBTTasksAndBLE() {
|
|||||||
xTaskCreatePinnedToCore(
|
xTaskCreatePinnedToCore(
|
||||||
procBLETask, /* Function to implement the task */
|
procBLETask, /* Function to implement the task */
|
||||||
"procBLETask", /* Name of the task */
|
"procBLETask", /* Name of the task */
|
||||||
8000, /* Stack size in bytes */
|
8500, /* Stack size in bytes */
|
||||||
NULL, /* Task input parameter */
|
NULL, /* Task input parameter */
|
||||||
2, /* Priority of the task (set higher than core task) */
|
2, /* Priority of the task (set higher than core task) */
|
||||||
&xProcBLETaskHandle, /* Task handle. */
|
&xProcBLETaskHandle, /* Task handle. */
|
||||||
@@ -1031,7 +1030,7 @@ void launchBTDiscovery(bool overrideDiscovery) {
|
|||||||
0, "", "", false, "",
|
0, "", "", false, "",
|
||||||
model.c_str(), brand.c_str(), model_id.c_str(), macWOdots.c_str(), false,
|
model.c_str(), brand.c_str(), model_id.c_str(), macWOdots.c_str(), false,
|
||||||
stateClassMeasurement, nullptr, nullptr, "[\"lb\",\"kg\",\"jin\"]");
|
stateClassMeasurement, nullptr, nullptr, "[\"lb\",\"kg\",\"jin\"]");
|
||||||
} else if (strcmp(prop.key().c_str(), "device") != 0 || strcmp(prop.key().c_str(), "mac") != 0) { // Exception on device and mac as these ones are not sensors
|
} else if (strcmp(prop.key().c_str(), "device") != 0 && strcmp(prop.key().c_str(), "mac") != 0) { // Exception on device and mac as these ones are not sensors
|
||||||
createDiscovery("sensor",
|
createDiscovery("sensor",
|
||||||
discovery_topic.c_str(), entity_name.c_str(), unique_id.c_str(),
|
discovery_topic.c_str(), entity_name.c_str(), unique_id.c_str(),
|
||||||
will_Topic, prop.value()["name"], value_template.c_str(),
|
will_Topic, prop.value()["name"], value_template.c_str(),
|
||||||
@@ -1138,7 +1137,7 @@ void PublishDeviceData(JsonObject& BLEdata) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void process_bledata(JsonObject& BLEdata) {
|
void process_bledata(JsonObject& BLEdata) {
|
||||||
yield();
|
yield(); // Necessary to let the loop run in case of connectivity issues
|
||||||
if (!BLEdata.containsKey("id")) {
|
if (!BLEdata.containsKey("id")) {
|
||||||
Log.error(F("No mac address in the payload" CR));
|
Log.error(F("No mac address in the payload" CR));
|
||||||
return;
|
return;
|
||||||
|
|||||||
+40
-24
@@ -62,8 +62,12 @@ unsigned long timer_sys_checks = 0;
|
|||||||
# define ARDUINOJSON_ENABLE_STD_STRING 1
|
# define ARDUINOJSON_ENABLE_STD_STRING 1
|
||||||
|
|
||||||
# include <queue>
|
# include <queue>
|
||||||
|
int queueLength = 0;
|
||||||
|
int queueLengthSum = 0;
|
||||||
|
int blockedMessages = 0;
|
||||||
|
int maxQueueLength = 0;
|
||||||
# ifndef QueueSize
|
# ifndef QueueSize
|
||||||
# define QueueSize 32
|
# define QueueSize 18
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -88,7 +92,6 @@ struct JsonBundle {
|
|||||||
};
|
};
|
||||||
|
|
||||||
std::queue<JsonBundle> jsonQueue;
|
std::queue<JsonBundle> jsonQueue;
|
||||||
int queueLengthSum = 0;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
StaticJsonDocument<JSON_MSG_BUFFER> modulesBuffer;
|
StaticJsonDocument<JSON_MSG_BUFFER> modulesBuffer;
|
||||||
@@ -264,7 +267,7 @@ static String ota_server_cert = "";
|
|||||||
# include <nvs.h>
|
# include <nvs.h>
|
||||||
# include <nvs_flash.h>
|
# include <nvs_flash.h>
|
||||||
|
|
||||||
bool ProcessLock = false; // Process lock when we want to use a critical function like OTA for example
|
bool ProcessLock = true; // Process lock when we want to use a critical function like OTA for example, at start to true so as to wait for critical functions to be performed before BLE start
|
||||||
# if !defined(NO_INT_TEMP_READING)
|
# if !defined(NO_INT_TEMP_READING)
|
||||||
// ESP32 internal temperature reading
|
// ESP32 internal temperature reading
|
||||||
# include <stdio.h>
|
# include <stdio.h>
|
||||||
@@ -426,11 +429,16 @@ void pubMainCore(JsonObject& data) {
|
|||||||
// Add a document to the queue
|
// Add a document to the queue
|
||||||
void enqueueJsonObject(const StaticJsonDocument<JSON_MSG_BUFFER>& jsonDoc) {
|
void enqueueJsonObject(const StaticJsonDocument<JSON_MSG_BUFFER>& jsonDoc) {
|
||||||
if (jsonDoc.size() == 0) {
|
if (jsonDoc.size() == 0) {
|
||||||
Log.error(F("Empty JSON, not enqueued" CR));
|
Log.error(F("Empty JSON, skipping" CR));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#if defined(ESP8266) || defined(ESP32) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1280__)
|
||||||
|
if (queueLength >= QueueSize) {
|
||||||
|
Log.warning(F("%d Doc(s) in queue, doc blocked" CR), queueLength);
|
||||||
|
blockedMessages++;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Log.trace(F("Enqueue JSON" CR));
|
Log.trace(F("Enqueue JSON" CR));
|
||||||
#if defined(ESP8266) || defined(ESP32) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1280__)
|
|
||||||
JsonBundle bundle;
|
JsonBundle bundle;
|
||||||
bundle.doc = jsonDoc;
|
bundle.doc = jsonDoc;
|
||||||
jsonQueue.push(bundle);
|
jsonQueue.push(bundle);
|
||||||
@@ -484,21 +492,21 @@ void buildTopicFromId(JsonObject& Jsondata, const char* origin) {
|
|||||||
|
|
||||||
// Empty the documents queue
|
// Empty the documents queue
|
||||||
void emptyQueue() {
|
void emptyQueue() {
|
||||||
while (true) {
|
queueLength = jsonQueue.size();
|
||||||
JsonBundle bundle;
|
if (queueLength > maxQueueLength) {
|
||||||
|
maxQueueLength = queueLength;
|
||||||
if (jsonQueue.empty()) {
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
if (queueLength == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
JsonBundle bundle;
|
||||||
Log.trace(F("Dequeue JSON" CR));
|
Log.trace(F("Dequeue JSON" CR));
|
||||||
bundle = jsonQueue.front();
|
bundle = jsonQueue.front();
|
||||||
jsonQueue.pop();
|
jsonQueue.pop();
|
||||||
|
|
||||||
JsonObject obj = bundle.doc.as<JsonObject>();
|
JsonObject obj = bundle.doc.as<JsonObject>();
|
||||||
pubMainCore(obj);
|
pubMainCore(obj);
|
||||||
queueLengthSum++;
|
queueLengthSum++;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
void emptyQueue() {}
|
void emptyQueue() {}
|
||||||
#endif
|
#endif
|
||||||
@@ -523,6 +531,7 @@ void pub(const char* topicori, const char* payload, bool retainFlag) {
|
|||||||
*/
|
*/
|
||||||
void pub(const char* topicori, JsonObject& data) {
|
void pub(const char* topicori, JsonObject& data) {
|
||||||
String dataAsString = "";
|
String dataAsString = "";
|
||||||
|
bool ret = sensor_Retain;
|
||||||
|
|
||||||
#if defined(ESP8266) || defined(ESP32)
|
#if defined(ESP8266) || defined(ESP32)
|
||||||
# if message_UTCtimestamp == true
|
# if message_UTCtimestamp == true
|
||||||
@@ -532,6 +541,10 @@ void pub(const char* topicori, JsonObject& data) {
|
|||||||
data["unixtime"] = unixtimestamp();
|
data["unixtime"] = unixtimestamp();
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
if (data.containsKey("retain") && data["retain"].is<bool>()) {
|
||||||
|
ret = data["retain"];
|
||||||
|
data.remove("retain");
|
||||||
|
}
|
||||||
if (data.containsKey("origin")) { // temporary, in the future use this instead of topicori
|
if (data.containsKey("origin")) { // temporary, in the future use this instead of topicori
|
||||||
data.remove("origin");
|
data.remove("origin");
|
||||||
}
|
}
|
||||||
@@ -559,7 +572,7 @@ void pub(const char* topicori, JsonObject& data) {
|
|||||||
|
|
||||||
#if jsonPublishing
|
#if jsonPublishing
|
||||||
Log.trace(F("jsonPubl - ON" CR));
|
Log.trace(F("jsonPubl - ON" CR));
|
||||||
pubMQTT(topic, dataAsString.c_str());
|
pubMQTT(topic.c_str(), dataAsString.c_str(), ret);
|
||||||
pubWebUI(topicori, data);
|
pubWebUI(topicori, data);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -2026,14 +2039,20 @@ void loop() {
|
|||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
if (now > (timer_sys_checks + (TimeBetweenCheckingSYS * 1000)) || !timer_sys_checks) {
|
if (now > (timer_sys_checks + (TimeBetweenCheckingSYS * 1000)) || !timer_sys_checks) {
|
||||||
# if defined(ESP32) && defined(MQTT_HTTPS_FW_UPDATE)
|
|
||||||
checkForUpdates();
|
|
||||||
# endif
|
|
||||||
# if defined(ESP8266) || defined(ESP32)
|
# if defined(ESP8266) || defined(ESP32)
|
||||||
# if message_UTCtimestamp || message_unixtimestamp
|
# if message_UTCtimestamp || message_unixtimestamp
|
||||||
syncNTP();
|
syncNTP();
|
||||||
# endif
|
# endif
|
||||||
# endif
|
# endif
|
||||||
|
if (!timer_sys_checks) { // Update check at start up only
|
||||||
|
# if defined(ESP32) && defined(MQTT_HTTPS_FW_UPDATE)
|
||||||
|
checkForUpdates();
|
||||||
|
# endif
|
||||||
|
# ifdef ZgatewayBT
|
||||||
|
ProcessLock = false; // Release BLE processes at start
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
|
||||||
timer_sys_checks = millis();
|
timer_sys_checks = millis();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -2293,7 +2312,7 @@ void eraseAndRestart() {
|
|||||||
|
|
||||||
#if defined(ESP8266) || defined(ESP32) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1280__)
|
#if defined(ESP8266) || defined(ESP32) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1280__)
|
||||||
String stateMeasures() {
|
String stateMeasures() {
|
||||||
StaticJsonDocument<JSON_MSG_BUFFER> SYSdata;
|
StaticJsonDocument<1024> SYSdata;
|
||||||
|
|
||||||
SYSdata["uptime"] = uptime();
|
SYSdata["uptime"] = uptime();
|
||||||
|
|
||||||
@@ -2312,6 +2331,8 @@ String stateMeasures() {
|
|||||||
SYSdata["mqttsecure"] = mqtt_secure;
|
SYSdata["mqttsecure"] = mqtt_secure;
|
||||||
SYSdata["msgproc"] = queueLengthSum;
|
SYSdata["msgproc"] = queueLengthSum;
|
||||||
SYSdata["msgspeed"] = round2((float)queueLengthSum / uptime());
|
SYSdata["msgspeed"] = round2((float)queueLengthSum / uptime());
|
||||||
|
SYSdata["msgblock"] = blockedMessages;
|
||||||
|
SYSdata["maxqueue"] = maxQueueLength;
|
||||||
# ifdef ESP32
|
# ifdef ESP32
|
||||||
minFreeMem = ESP.getMinFreeHeap();
|
minFreeMem = ESP.getMinFreeHeap();
|
||||||
SYSdata["minfreemem"] = minFreeMem;
|
SYSdata["minfreemem"] = minFreeMem;
|
||||||
@@ -2593,9 +2614,6 @@ String latestVersion;
|
|||||||
*/
|
*/
|
||||||
bool checkForUpdates() {
|
bool checkForUpdates() {
|
||||||
Log.notice(F("Update check, free heap: %d"), ESP.getFreeHeap());
|
Log.notice(F("Update check, free heap: %d"), ESP.getFreeHeap());
|
||||||
# ifdef ZGatewayBT
|
|
||||||
ProcessLock = true;
|
|
||||||
# endif
|
|
||||||
HTTPClient http;
|
HTTPClient http;
|
||||||
http.setTimeout((GeneralTimeOut - 1) * 1000); // -1 to avoid WDT
|
http.setTimeout((GeneralTimeOut - 1) * 1000); // -1 to avoid WDT
|
||||||
http.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS);
|
http.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS);
|
||||||
@@ -2616,6 +2634,7 @@ bool checkForUpdates() {
|
|||||||
Log.error(F("Error on HTTP request"));
|
Log.error(F("Error on HTTP request"));
|
||||||
}
|
}
|
||||||
http.end(); //Free the resources
|
http.end(); //Free the resources
|
||||||
|
Log.notice(F("Update check done, free heap: %d"), ESP.getFreeHeap());
|
||||||
if (jsondata.containsKey("latest_version")) {
|
if (jsondata.containsKey("latest_version")) {
|
||||||
jsondata["installed_version"] = OMG_VERSION;
|
jsondata["installed_version"] = OMG_VERSION;
|
||||||
jsondata["entity_picture"] = ENTITY_PICTURE;
|
jsondata["entity_picture"] = ENTITY_PICTURE;
|
||||||
@@ -2623,6 +2642,7 @@ bool checkForUpdates() {
|
|||||||
jsondata["release_summary"] = "";
|
jsondata["release_summary"] = "";
|
||||||
latestVersion = jsondata["latest_version"].as<String>();
|
latestVersion = jsondata["latest_version"].as<String>();
|
||||||
jsondata["origin"] = subjectRLStoMQTT;
|
jsondata["origin"] = subjectRLStoMQTT;
|
||||||
|
jsondata["retain"] = true;
|
||||||
enqueueJsonObject(jsondata);
|
enqueueJsonObject(jsondata);
|
||||||
Log.trace(F("Update file found on server" CR));
|
Log.trace(F("Update file found on server" CR));
|
||||||
return true;
|
return true;
|
||||||
@@ -2630,10 +2650,6 @@ bool checkForUpdates() {
|
|||||||
Log.trace(F("No update file found on server" CR));
|
Log.trace(F("No update file found on server" CR));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
# ifdef ZGatewayBT
|
|
||||||
ProcessLock = false;
|
|
||||||
# endif
|
|
||||||
Log.notice(F("Update check done, free heap: %d"), ESP.getFreeHeap());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# else
|
# else
|
||||||
|
|||||||
Reference in new issue
Block a user