From 0ad8696dfc43aa00c91cd02fa96b53c017bdbc42 Mon Sep 17 00:00:00 2001 From: s-hadinger <49731213+s-hadinger@users.noreply.github.com> Date: Mon, 21 Apr 2025 11:32:32 +0200 Subject: [PATCH] WebUI status line for MQTT and TLS, added 'FUNC_WEB_STATUS' event (#23326) * WebUI status line for MQTT and TLS, added 'FUNC_WEB_STATUS' event * add Berry support --- CHANGELOG.md | 1 + tasmota/include/tasmota.h | 1 + tasmota/my_user_config.h | 1 + tasmota/tasmota_support/support_command.ino | 10 ++++ .../xdrv_01_9_webserver.ino | 51 ++++++++++++++++++- .../tasmota_xdrv_driver/xdrv_02_9_mqtt.ino | 11 ++++ .../tasmota_xdrv_driver/xdrv_52_9_berry.ino | 5 ++ 7 files changed, 79 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 49a4bb5be..54a66f6c9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ All notable changes to this project will be documented in this file. ### Added - Command `JsonPP 0..7` to enable (>0) JSON Pretty Print on user interfaces and set number of indents - Command `JsonPP |backlog ;...` to enable JSON PP only once +- WebUI status line for MQTT and TLS, added `FUNC_WEB_STATUS` event ### Breaking Changed diff --git a/tasmota/include/tasmota.h b/tasmota/include/tasmota.h index 5a73e1628..a0bf27851 100644 --- a/tasmota/include/tasmota.h +++ b/tasmota/include/tasmota.h @@ -442,6 +442,7 @@ enum XsnsFunctions { FUNC_SETTINGS_OVERRIDE, FUNC_SETUP_RING1, FUNC_SETUP_RING2, FUNC_WEB_GET_ARG, FUNC_WEB_ADD_HANDLER, FUNC_SET_SCHEME, FUNC_HOTPLUG_SCAN, FUNC_TIME_SYNCED, FUNC_DEVICE_GROUP_ITEM, FUNC_NETWORK_UP, FUNC_NETWORK_DOWN, + FUNC_WEB_STATUS, FUNC_return_result = 200, // Insert function WITHOUT return results before here. Following functions return results FUNC_PIN_STATE, FUNC_MODULE_INIT, FUNC_ADD_BUTTON, FUNC_ADD_SWITCH, FUNC_BUTTON_PRESSED, FUNC_BUTTON_MULTI_PRESSED, FUNC_SET_DEVICE_POWER, diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index c822571be..e32b882af 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -503,6 +503,7 @@ #define WEB_USERNAME "admin" // Web server Admin mode user name // #define DISABLE_REFERER_CHK // [SetOption128] Disable HTTP API #define USE_ENHANCED_GUI_WIFI_SCAN // Enable Wi-Fi scan output with BSSID (+0k5 code) + #define USE_WEB_STATUS_LINE // Enable upper status line in web UI (+0k5 code) // #define USE_ALPINEJS // Enable AlpineJS v2.8.2 (+8k8 code) // #define USE_WEBSEND_RESPONSE // Enable command WebSend response message (+1k code) // #define USE_WEBGETCONFIG // Enable restoring config from external webserver (+0k6) diff --git a/tasmota/tasmota_support/support_command.ino b/tasmota/tasmota_support/support_command.ino index a1f02b4d7..5c5c37d55 100644 --- a/tasmota/tasmota_support/support_command.ino +++ b/tasmota/tasmota_support/support_command.ino @@ -952,6 +952,7 @@ void CmndStatus(void) CmndStatusResponse(0); } + // Status 1 - StatusPRM if ((0 == payload) || (1 == payload)) { Response_P(PSTR("{\"" D_CMND_STATUS D_STATUS1_PARAMETER "\":{\"" D_JSON_BAUDRATE "\":%d,\"" D_CMND_SERIALCONFIG "\":\"%s\",\"" D_CMND_GROUPTOPIC "\":\"%s\",\"" D_CMND_OTAURL "\":\"%s\",\"" D_JSON_RESTARTREASON "\":\"%s\",\"" D_JSON_UPTIME "\":\"%s\",\"" D_JSON_STARTUPUTC "\":\"%s\",\"" D_CMND_SLEEP "\":%d,\"" @@ -970,6 +971,7 @@ void CmndStatus(void) CmndStatusResponse(1); } + // Status 2 - StatusFWR if ((0 == payload) || (2 == payload)) { Response_P(PSTR("{\"" D_CMND_STATUS D_STATUS2_FIRMWARE "\":{\"" D_JSON_VERSION "\":\"%s%s%s\",\"" D_JSON_BUILDDATETIME "\":\"%s\"" #ifdef ESP8266 @@ -988,6 +990,7 @@ void CmndStatus(void) CmndStatusResponse(2); } + // Status 3 - StatusLOG if ((0 == payload) || (3 == payload)) { Response_P(PSTR("{\"" D_CMND_STATUS D_STATUS3_LOGGING "\":{\"" D_CMND_SERIALLOG "\":%d,\"" D_CMND_WEBLOG "\":%d,\"" D_CMND_MQTTLOG "\":%d,\"" #ifdef USE_UFILESYS @@ -1007,6 +1010,7 @@ void CmndStatus(void) CmndStatusResponse(3); } + // Status 4 - StatusMEM if ((0 == payload) || (4 == payload)) { Response_P(PSTR("{\"" D_CMND_STATUS D_STATUS4_MEMORY "\":{\"" D_JSON_PROGRAMSIZE "\":%d,\"" D_JSON_FREEMEMORY "\":%d,\"" D_JSON_HEAPSIZE "\":%d,\"" #ifdef ESP32 @@ -1037,6 +1041,7 @@ void CmndStatus(void) CmndStatusResponse(4); } + // Status 5 - StatusNET if ((0 == payload) || (5 == payload)) { #ifdef USE_IPV6 if (5 == payload) { WifiDumpAddressesIPv6(); } @@ -1093,6 +1098,7 @@ void CmndStatus(void) CmndStatusResponse(5); } + // Status 6 - StatusMQT if (((0 == payload) || (6 == payload)) && Settings->flag.mqtt_enabled) { // SetOption3 - Enable MQTT uint32_t mqtt_tls = 0; #ifdef USE_MQTT_TLS @@ -1134,6 +1140,7 @@ void CmndStatus(void) } #endif // USE_ENERGY_MARGIN_DETECTION + // Status 8 / 10 - StatusSNS if ((0 == payload) || (8 == payload) || (10 == payload)) { Response_P(PSTR("{\"" D_CMND_STATUS D_STATUS10_SENSOR "\":")); MqttShowSensor(true); @@ -1141,6 +1148,7 @@ void CmndStatus(void) CmndStatusResponse((8 == payload) ? 8 : 10); } + // Status 11 - StatusSTS if ((0 == payload) || (11 == payload)) { Response_P(PSTR("{\"" D_CMND_STATUS D_STATUS11_STATUS "\":")); MqttShowState(); @@ -1150,6 +1158,7 @@ void CmndStatus(void) #ifndef FIRMWARE_MINIMAL if (CrashFlag()) { + // Status 12 - StatusSTK if ((0 == payload) || (12 == payload)) { Response_P(PSTR("{\"" D_CMND_STATUS D_STATUS12_STATUS "\":")); CrashDump(); @@ -1160,6 +1169,7 @@ void CmndStatus(void) #endif // FIRMWARE_MINIMAL #ifdef USE_SHUTTER + // Status 13 if ((0 == payload) || (13 == payload)) { if (ShutterStatus()) { CmndStatusResponse(13); } } diff --git a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino index 5962494d7..f12d35355 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino @@ -251,7 +251,7 @@ const char HTTP_HEAD_STYLE3[] PROGMEM = "" "" - "
" // COLOR_BACKGROUND, COLOR_TEXT + "
" // COLOR_BACKGROUND, COLOR_TEXT #ifdef FIRMWARE_MINIMAL #ifdef FIRMWARE_SAFEBOOT "

" D_SAFEBOOT "

" // COLOR_TEXT_WARNING @@ -445,6 +445,18 @@ const char HTTP_END[] PROGMEM = const char HTTP_DEVICE_CONTROL[] PROGMEM = ""; // ?o is related to WebGetArg(PSTR("o"), tmp, sizeof(tmp)) const char HTTP_DEVICE_STATE[] PROGMEM = "%s"; +const char HTTP_STATUS_STICKER[] PROGMEM = + "" + "%s" + ""; + enum ButtonTitle { BUTTON_RESTART, BUTTON_RESET_CONFIGURATION, BUTTON_MAIN, BUTTON_CONFIGURATION, BUTTON_INFORMATION, BUTTON_FIRMWARE_UPGRADE, BUTTON_MANAGEMENT, @@ -1151,6 +1163,36 @@ void WSContentStop(void) { WSContentEnd(); } +#ifdef USE_WEB_STATUS_LINE +/*-------------------------------------------------------------------------------------------*/ +// Display a Sticker in the Status bar (upper right) with a name (MQTT, TlS, VPN) +// and an optional tooltip text to indicate the duration of the connection (or -1 if none) +// +// Convert seconds to a string representing days, hours or minutes. +// The string will contain the most coarse time only, rounded down (61m == 01h, 01h37m == 01h). +void WSContentStatusSticker(const char *msg, int32_t seconds) +{ + char title_attr[64] = ""; + + if (seconds > 0) { + static const uint32_t conversions[4] = {24 * 3600, 3600, 60, 1}; + static const char units[4] = { 'd', 'h', 'm', 's'}; // day, hour, minute + + char unit; + int32_t time_unit = seconds; + for(uint32_t i = 0; i < 4; ++i) { + unit = units[i]; + if (time_unit >= conversions[i]) { // always pass even if 00m + time_unit = seconds / conversions[i]; + break; + } + } + ext_snprintf_P(title_attr, sizeof(title_attr), PSTR(" title='Connected for %i%c'"), time_unit, unit); + } + WSContentSend_P(HTTP_STATUS_STICKER, 0xAAAAAA, title_attr, msg); +} +#endif // USE_WEB_STATUS_LINE + /*********************************************************************************************/ void WebRestart(uint32_t type) { @@ -1884,6 +1926,13 @@ bool HandleRootStatusRefresh(void) { WSContentSend_P(PSTR("\">")); } +#ifdef USE_WEB_STATUS_LINE + // create a DIV for the upper status bar, positioned right-justified + WSContentSend_P(PSTR("
")); + XsnsXdrvCall(FUNC_WEB_STATUS); + WSContentSend_P(PSTR("
")); +#endif // USE_WEB_STATUS_LINE + WSContentSend_P(PSTR("{t}")); // WSContentSeparator(3); // Reset seperator to ignore previous outputs if (Settings->web_time_end) { diff --git a/tasmota/tasmota_xdrv_driver/xdrv_02_9_mqtt.ino b/tasmota/tasmota_xdrv_driver/xdrv_02_9_mqtt.ino index 8bf74e581..dc9185ea9 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_02_9_mqtt.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_02_9_mqtt.ino @@ -2116,6 +2116,17 @@ bool Xdrv02(uint32_t function) case FUNC_WEB_ADD_HANDLER: WebServer_on(PSTR("/" WEB_HANDLE_MQTT), HandleMqttConfiguration); break; +#ifdef USE_WEB_STATUS_LINE + case FUNC_WEB_STATUS: + // MqttConnectCount(), mqtt_tls + if (MqttIsConnected()) { + WSContentStatusSticker(PSTR("MQTT"), -1); + if (MqttTLSEnabled()) { + WSContentStatusSticker(PSTR("TLS"), -1); + } + } + break; +#endif // USE_WEB_STATUS_LINE #endif // not FIRMWARE_MINIMAL #endif // USE_WEBSERVER case FUNC_COMMAND: diff --git a/tasmota/tasmota_xdrv_driver/xdrv_52_9_berry.ino b/tasmota/tasmota_xdrv_driver/xdrv_52_9_berry.ino index b79acfe4c..247d96c81 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_52_9_berry.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_52_9_berry.ino @@ -1061,6 +1061,11 @@ bool Xdrv52(uint32_t function) WebServer_on("/bc", HandleBerryConsole); WebServer_on("/tapp", HandleBerryBECLoader, HTTP_GET); break; +#ifdef USE_WEB_STATUS_LINE + case FUNC_WEB_STATUS: + callBerryEventDispatcher(PSTR("web_status_line"), nullptr, 0, nullptr); + break; +#endif // USE_WEB_STATUS_LINE #endif // USE_WEBSERVER case FUNC_SAVE_BEFORE_RESTART: callBerryEventDispatcher(PSTR("save_before_restart"), nullptr, 0, nullptr);