diff --git a/main/User_config.h b/main/User_config.h index 31a8351004..3571d43a96 100644 --- a/main/User_config.h +++ b/main/User_config.h @@ -707,4 +707,8 @@ void storeSignalValue(uint64_t); # define QueueSize 18 #endif +#ifndef EXPIRE_AFTER +# define EXPIRE_AFTER "0" +#endif + #endif diff --git a/main/config_WebContent.h b/main/config_WebContent.h index 4c6ad58403..b7f3f679d9 100644 --- a/main/config_WebContent.h +++ b/main/config_WebContent.h @@ -130,7 +130,7 @@ const char config_logging_body[] = body_header #endif "


" body_footer_config_menu; -const char config_webui_body[] = body_header "
Configure WebUI

Display Metric

Secure WebUI


" body_footer_config_menu; +const char config_webui_body[] = body_header "
Configure WebUI

Display Metric

Secure WebUI

Expire After


" body_footer_config_menu; const char config_rf_body[] = body_header "
" diff --git a/main/mqttDiscovery.cpp b/main/mqttDiscovery.cpp index 6a249e9db7..0a428d1dea 100644 --- a/main/mqttDiscovery.cpp +++ b/main/mqttDiscovery.cpp @@ -26,6 +26,8 @@ #include "User_config.h" +uint16_t expireAfter = String(EXPIRE_AFTER).toInt(); + #ifdef ZmqttDiscovery # include "TheengsCommon.h" @@ -571,8 +573,11 @@ void createDiscovery(const char* sensor_type, sensor["pl_avail"] = payload_available; // payload_on if (payload_not_available[0]) sensor["pl_not_avail"] = payload_not_available; //payload_off - if (state_class && state_class[0]) + if (state_class && state_class[0]) { sensor["stat_cla"] = state_class; //add the state class on the sensors ( https://developers.home-assistant.io/docs/core/entity/sensor/#available-state-classes ) + if (expireAfter > 0 && strcmp(state_class, "measurement") == 0) + sensor["exp_aft"] = expireAfter; // handle stale sensors + } if (state_on != nullptr) if (strcmp(state_on, "true") == 0) { sensor["stat_on"] = true; diff --git a/main/webUI.cpp b/main/webUI.cpp index c024490555..457318fe05 100644 --- a/main/webUI.cpp +++ b/main/webUI.cpp @@ -86,6 +86,7 @@ const char* www_username = WEBUI_LOGIN; String authFailResponse = "Authentication Failed"; bool webUISecure = WEBUI_AUTH; boolean displayMetric = DISPLAY_METRIC; +extern uint16_t expireAfter; /*********************************************************************************************\ * ESP32 AutoMutex @@ -502,9 +503,10 @@ void handleCN() { /** * @brief /WU - Configuration Page - * T: handleWU: uri: /wu, args: 3, method: 1 + * T: handleWU: uri: /wu, args: 4, method: 1 * T: handleWU Arg: 0, dm=on - displayMetric * T: handleWU Arg: 1, sw=on - webUISecure + * T: handleWU Arg: 2, ea=0 - expireAfter * T: handleWU Arg: 2, save= */ void handleWU() { @@ -526,6 +528,11 @@ void handleWU() { } webUISecure = server.hasArg("sw"); + if (server.hasArg("ea") && expireAfter != server.arg("ea").toInt()) { + expireAfter = server.arg("ea").toInt(); + update = true; + } + if (server.hasArg("save") && update) { WebUIConfig_save(); } @@ -541,7 +548,7 @@ void handleWU() { response += String(script); response += String(style); int logLevel = Log.getLevel(); - snprintf(buffer, WEB_TEMPLATE_BUFFER_MAX_SIZE, config_webui_body, jsonChar, gateway_name, (displayMetric ? "checked" : ""), (webUISecure ? "checked" : "")); + snprintf(buffer, WEB_TEMPLATE_BUFFER_MAX_SIZE, config_webui_body, jsonChar, gateway_name, (displayMetric ? "checked" : ""), (webUISecure ? "checked" : ""), expireAfter); response += String(buffer); snprintf(buffer, WEB_TEMPLATE_BUFFER_MAX_SIZE, footer, OMG_VERSION); response += String(buffer); @@ -1789,6 +1796,7 @@ void WebUISetup() { THEENGS_LOG_TRACE(F("[WebUI] displayMetric %T" CR), displayMetric); THEENGS_LOG_TRACE(F("[WebUI] WebUI Secure %T" CR), webUISecure); + THEENGS_LOG_TRACE(F("[WebUI] Expire After %u" CR), expireAfter); THEENGS_LOG_NOTICE(F("OpenMQTTGateway URL: http://%s/" CR), WiFi.localIP().toString().c_str()); displayPrint("URL: http://", (char*)WiFi.localIP().toString().c_str()); THEENGS_LOG_NOTICE(F("webUI setup done" CR)); @@ -1864,6 +1872,7 @@ String stateWebUIStatus() { JsonObject WebUIdata = WebUIdataBuffer.to(); WebUIdata["displayMetric"] = (bool)displayMetric; WebUIdata["webUISecure"] = (bool)webUISecure; + WebUIdata["expireAfter"] = expireAfter; WebUIdata["displayQueue"] = uxQueueMessagesWaiting(webUIQueue); String output; @@ -1880,6 +1889,7 @@ bool WebUIConfig_save() { JsonObject jo = jsonBuffer.to(); jo["displayMetric"] = (bool)displayMetric; jo["webUISecure"] = (bool)webUISecure; + jo["expireAfter"] = expireAfter; // Save config into NVS (non-volatile storage) String conf = ""; serializeJson(jsonBuffer, conf); @@ -1893,6 +1903,7 @@ bool WebUIConfig_save() { void WebUIConfig_init() { displayMetric = DISPLAY_METRIC; webUISecure = WEBUI_AUTH; + expireAfter = String(EXPIRE_AFTER).toInt(); THEENGS_LOG_NOTICE(F("WebUI config initialised" CR)); } @@ -1913,6 +1924,7 @@ bool WebUIConfig_load() { JsonObject jo = jsonBuffer.as(); displayMetric = jo["displayMetric"].as(); webUISecure = jo["webUISecure"].as(); + expireAfter = jo["expireAfter"].as(); return true; } else { preferences.end();