From 615c6763f68a889fd22c67e913a29f0b8934d307 Mon Sep 17 00:00:00 2001 From: s-hadinger <49731213+s-hadinger@users.noreply.github.com> Date: Sat, 14 Dec 2024 22:39:45 +0100 Subject: [PATCH 1/5] Tls ecdsa (#22649) * TLS add support for ECDSA on ESP32 * Reduce size for ESP8266 --- CHANGELOG.md | 1 + .../src/WiFiClientSecureLightBearSSL.cpp | 49 +++++++++++++++---- 2 files changed, 41 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dc5e3931b..e14afd0d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ All notable changes to this project will be documented in this file. ## [14.4.0.1] ### Added - MCP23XXX_DRV control register IOCON in template (#22622) +- TLS add support for ECDSA on ESP32 ### Breaking Changed diff --git a/lib/lib_ssl/tls_mini/src/WiFiClientSecureLightBearSSL.cpp b/lib/lib_ssl/tls_mini/src/WiFiClientSecureLightBearSSL.cpp index a11b04f03..4259023e5 100755 --- a/lib/lib_ssl/tls_mini/src/WiFiClientSecureLightBearSSL.cpp +++ b/lib/lib_ssl/tls_mini/src/WiFiClientSecureLightBearSSL.cpp @@ -788,19 +788,39 @@ extern "C" { // created with more than two primes, and most numbers, even large ones, can // be easily factored. static void pubkeyfingerprint_pubkey_fingerprint(br_x509_pubkeyfingerprint_context *xc) { - br_rsa_public_key rsakey = xc->ctx.pkey.key.rsa; + if (xc->ctx.pkey.key_type == BR_KEYTYPE_RSA) { + br_rsa_public_key rsakey = xc->ctx.pkey.key.rsa; - br_sha1_context shactx; + br_sha1_context shactx; - br_sha1_init(&shactx); + br_sha1_init(&shactx); - // The tag string doesn't really matter, but it should differ depending on - // key type. Since we only support RSA for now, it's a fixed string. - sha1_update_len(&shactx, "ssh-rsa", 7); // tag - sha1_update_len(&shactx, rsakey.e, rsakey.elen); // exponent - sha1_update_len(&shactx, rsakey.n, rsakey.nlen); // modulus + // The tag string doesn't really matter, but it should differ depending on + // key type. For RSA it's a fixed string. + sha1_update_len(&shactx, "ssh-rsa", 7); // tag + sha1_update_len(&shactx, rsakey.e, rsakey.elen); // exponent + sha1_update_len(&shactx, rsakey.n, rsakey.nlen); // modulus - br_sha1_out(&shactx, xc->pubkey_recv_fingerprint); // copy to fingerprint + br_sha1_out(&shactx, xc->pubkey_recv_fingerprint); // copy to fingerprint + } + #ifndef ESP8266 + else if (xc->ctx.pkey.key_type == BR_KEYTYPE_EC) { + br_ec_public_key eckey = xc->ctx.pkey.key.ec; + + br_sha1_context shactx; + + br_sha1_init(&shactx); + + // The tag string doesn't really matter, but it should differ depending on + // key type. For ECDSA it's a fixed string. + sha1_update_len(&shactx, "ecdsa-sha2-nistp256", 19); // tag + sha1_update_len(&shactx, eckey.q, eckey.qlen); // exponent + } + #endif + else { + // We don't support anything else, so just set the fingerprint to all zeros. + memset(xc->pubkey_recv_fingerprint, 0, 20); + } } // Callback when complete chain has been parsed. @@ -856,11 +876,19 @@ extern "C" { ctx->fingerprint_all = fingerprint_all; } +#ifdef ESP8266 // We limit to a single cipher to reduce footprint // we reference it, don't put in PROGMEM static const uint16_t suites[] = { BR_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 }; +#else + // add more flexibility on ESP32 + static const uint16_t suites[] = { + BR_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + BR_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + }; +#endif // Default initializion for our SSL clients static void br_ssl_client_base_init(br_ssl_client_context *cc) { @@ -884,6 +912,9 @@ extern "C" { // we support only P256 EC curve for AWS IoT, no EC curve for Letsencrypt unless forced br_ssl_engine_set_ec(&cc->eng, &br_ec_p256_m15); // TODO +#ifndef ESP8266 + br_ssl_engine_set_ecdsa(&cc->eng, &br_ecdsa_i15_vrfy_asn1); +#endif } } From b3b969978283df8da352e9d7580642caaeddbb28 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sun, 15 Dec 2024 00:32:51 +0100 Subject: [PATCH 2/5] Display related fixes - CHange Display removed PWM control of backlight GPIO for universal display regression from v14.1.0 - Fix Display DisplayMode adds a display device while not configured - Fix GUI intermittent exception on screen updates due to flash access --- CHANGELOG.md | 5 +- RELEASENOTES.md | 5 +- tasmota/tasmota_support/support.ino | 3 + .../xdrv_01_9_webserver.ino | 20 ++++--- .../tasmota_xdrv_driver/xdrv_13_display.ino | 56 ++++++++++--------- 5 files changed, 52 insertions(+), 37 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e14afd0d6..e705f0533 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,18 +6,21 @@ All notable changes to this project will be documented in this file. ## [14.4.0.1] ### Added - MCP23XXX_DRV control register IOCON in template (#22622) -- TLS add support for ECDSA on ESP32 +- ESP32 support for TLS ECDSA (#22649) ### Breaking Changed ### Changed - Berry make Leds animate calls reentrant (#22643) - SSL clean up remnants of old fingerprint algorithm (#22645) +- Display removed PWM control of backlight GPIO for universal display regression from v14.1.0 ### Fixed - ESP32 rules operation priority regression from v13.3.0.4 (#22636) - GUI display power button regression from v14.3.0.5 (#15788) - MCP23xxx, PCF8574 and Shift595 power control when a display is configured regression from v14.3.0.7 +- Display DisplayMode adds a display device while not configured +- GUI intermittent exception on screen updates due to flash access ### Removed diff --git a/RELEASENOTES.md b/RELEASENOTES.md index d2433f585..89ec06e2f 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -117,14 +117,17 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm ## Changelog v14.4.0.1 ### Added - MCP23XXX_DRV control register IOCON in template [#22622](https://github.com/arendst/Tasmota/issues/22622) +- ESP32 support for TLS ECDSA [#22649](https://github.com/arendst/Tasmota/issues/22649) ### Breaking Changed ### Changed +- Display removed PWM control of backlight GPIO for universal display regression from v14.1.0 +- SSL clean up remnants of old fingerprint algorithm [#22645](https://github.com/arendst/Tasmota/issues/22645) - Berry make Leds animate calls reentrant [#22643](https://github.com/arendst/Tasmota/issues/22643) -- SSL clean up remnants of old fingerprint algorithm (#22645)[#22645](https://github.com/arendst/Tasmota/issues/22645) ### Fixed +- Display DisplayMode adds a display device while not configured - GUI display power button regression from v14.3.0.5 [#15788](https://github.com/arendst/Tasmota/issues/15788) - MCP23xxx, PCF8574 and Shift595 power control when a display is configured regression from v14.3.0.7 - ESP32 rules operation priority regression from v13.3.0.4 [#22636](https://github.com/arendst/Tasmota/issues/22636) diff --git a/tasmota/tasmota_support/support.ino b/tasmota/tasmota_support/support.ino index 7d34b6c51..4caa4bdf4 100755 --- a/tasmota/tasmota_support/support.ino +++ b/tasmota/tasmota_support/support.ino @@ -835,6 +835,9 @@ int32_t UpdateDevicesPresent(int32_t change) { // AddLog(LOG_LEVEL_DEBUG, PSTR("APP: Max 32 devices supported")); } TasmotaGlobal.devices_present = devices_present; + +// AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("DVC: DevicesPresent %d, Change %d"), TasmotaGlobal.devices_present, change); + return difference; } diff --git a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino index db4e9540c..5c9f55e5a 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino @@ -1289,7 +1289,7 @@ void WebGetDeviceCounts(void) { } #endif // USE_SHUTTER -// AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("HTP: DP %d, BNLNS %d, SB %08X"), TasmotaGlobal.devices_present, Web.buttons_non_light_non_shutter, Web.light_shutter_button_mask); +// AddLog(LOG_LEVEL_DEBUG, PSTR("HTP: DP %d, BNLNS %d, SB %08X"), TasmotaGlobal.devices_present, Web.buttons_non_light_non_shutter, Web.light_shutter_button_mask); } #ifdef USE_LIGHT @@ -1374,7 +1374,6 @@ void HandleRoot(void) { if (TasmotaGlobal.devices_present) { WebGetDeviceCounts(); - uint32_t button_idx = 1; if (Web.buttons_non_light_non_shutter) { // Any non light AND non shutter button - Show toggle buttons WSContentSend_P(HTTP_TABLE100); // "<table style='width:100%%'>" WSContentSend_P(PSTR("<tr>")); @@ -1400,7 +1399,7 @@ void HandleRoot(void) { if (Web.buttons_non_light_non_shutter % rows) { cols++; } uint32_t button_ptr = 0; - for (button_idx = 1; button_idx <= TasmotaGlobal.devices_present; button_idx++) { + for (uint32_t button_idx = 1; button_idx <= TasmotaGlobal.devices_present; button_idx++) { if (bitRead(Web.light_shutter_button_mask, button_idx -1)) { continue; } // Skip non-sequential light and/or shutter button bool set_button = ((button_idx <= MAX_BUTTON_TEXT) && strlen(GetWebButton(button_idx -1))); snprintf_P(stemp, sizeof(stemp), PSTR(" %d"), button_idx); @@ -1457,7 +1456,7 @@ void HandleRoot(void) { if (TasmotaGlobal.light_type) { // Any light - Show light button and slider(s) uint32_t light_device = LightDevice(); uint32_t light_devices = LightDevices(); - button_idx = light_device; + uint32_t button_idx = light_device; WSContentSend_P(HTTP_TABLE100); // "<table style='width:100%%'>" @@ -1904,11 +1903,14 @@ bool HandleRootStatusRefresh(void) { WSContentSend_P(PSTR("{t}<tr>")); uint32_t cols = Web.buttons_non_light_non_shutter; uint32_t fontsize = (cols < 5) ? 70 - (cols * 8) : 32; - for (uint32_t idx = 1; idx <= Web.buttons_non_light_non_shutter; idx++) { - if (bitRead(Web.light_shutter_button_mask, idx -1)) { continue; } // Skip non-sequential shutter button - snprintf_P(svalue, sizeof(svalue), PSTR("%d"), bitRead(TasmotaGlobal.power, idx -1)); - WSContentSend_P(HTTP_DEVICE_STATE, 100 / cols, (bitRead(TasmotaGlobal.power, idx -1)) ? PSTR("bold") : PSTR("normal"), fontsize, - (cols < 5) ? GetStateText(bitRead(TasmotaGlobal.power, idx -1)) : svalue); + uint32_t button_ptr = 0; + for (uint32_t button_idx = 1; button_idx <= TasmotaGlobal.devices_present; button_idx++) { + if (bitRead(Web.light_shutter_button_mask, button_idx -1)) { continue; } // Skip non-sequential shutter button + bool power_state = bitRead(TasmotaGlobal.power, button_idx -1); + snprintf_P(svalue, sizeof(svalue), PSTR("%d"), power_state); + WSContentSend_P(HTTP_DEVICE_STATE, 100 / cols, (power_state) ? "bold" : "normal", fontsize, (cols < 5) ? GetStateText(power_state) : svalue); + button_ptr++; + if (button_ptr == Web.buttons_non_light_non_shutter) { break; } } WSContentSend_P(PSTR("</tr></table>")); } diff --git a/tasmota/tasmota_xdrv_driver/xdrv_13_display.ino b/tasmota/tasmota_xdrv_driver/xdrv_13_display.ino index 9d2381a61..a6ebf1e6f 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_13_display.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_13_display.ino @@ -1852,57 +1852,61 @@ void DisplayLocalSensor(void) \*********************************************************************************************/ void DisplayInitDriver(void) { + Settings->display_model = 0; XdspCall(FUNC_DISPLAY_INIT_DRIVER); // AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "Display model %d"), Settings->display_model); - if (Settings->display_model) { -// ApplyDisplayDimmer(); // Not allowed here. Way too early in init sequence. Global power state has not been set at this point in time + if (!Settings->display_model) { return; } + +// AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("DSP: Model %d"), Settings->display_model); + +// ApplyDisplayDimmer(); // Not allowed here. Way too early in init sequence. Global power state has not been set at this point in time #ifdef USE_MULTI_DISPLAY - Set_display(0); + Set_display(0); #endif // USE_MULTI_DISPLAY - if (renderer) { - renderer->setTextFont(Settings->display_font); - renderer->setTextSize(Settings->display_size); - // force opaque mode - renderer->setDrawMode(0); + if (renderer) { + renderer->setTextFont(Settings->display_font); + renderer->setTextSize(Settings->display_size); + // force opaque mode + renderer->setDrawMode(0); - for (uint32_t cnt = 0; cnt < (MAX_INDEXCOLORS - PREDEF_INDEXCOLORS); cnt++) { - index_colors[cnt] = 0; - } + for (uint32_t cnt = 0; cnt < (MAX_INDEXCOLORS - PREDEF_INDEXCOLORS); cnt++) { + index_colors[cnt] = 0; } + } #ifdef USE_DT_VARS - free_dt_vars(); + free_dt_vars(); #endif #ifdef USE_UFILESYS - Display_Text_From_File(DISP_BATCH_FILE); + Display_Text_From_File(DISP_BATCH_FILE); #endif #ifdef USE_GRAPH - for (uint8_t count = 0; count < NUM_GRAPHS; count++) { graph[count] = 0; } + for (uint8_t count = 0; count < NUM_GRAPHS; count++) { graph[count] = 0; } #endif - UpdateDevicesPresent(1); - if (!PinUsed(GPIO_BACKLIGHT)) { - if ((LT_PWM1 == TasmotaGlobal.light_type) && // Single PWM light channel - ((4 == Settings->display_model) || // ILI9341 legacy - (17 == Settings->display_model)) // Universal - ) { - UpdateDevicesPresent(-1); // Assume PWM channel is used for backlight - } + UpdateDevicesPresent(1); + if (!PinUsed(GPIO_BACKLIGHT)) { + if ((LT_PWM1 == TasmotaGlobal.light_type) && // Single PWM light channel + (4 == Settings->display_model) // ILI9341 legacy +// ((4 == Settings->display_model) || // ILI9341 legacy +// (17 == Settings->display_model)) // Universal - Too invasive in case displays have no backlight pin + ) { + UpdateDevicesPresent(-1); // Assume PWM channel is used for backlight } - disp_device = TasmotaGlobal.devices_present; + } + disp_device = TasmotaGlobal.devices_present; #ifndef USE_DISPLAY_MODES1TO5 - Settings->display_mode = 0; + Settings->display_mode = 0; #else - DisplayLogBufferInit(); + DisplayLogBufferInit(); #endif // USE_DISPLAY_MODES1TO5 - } } void DisplaySetPower(void) { From 6fbf8c58f72ed22bfe46d42505f2eb7da4cb0866 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sun, 15 Dec 2024 12:33:43 +0100 Subject: [PATCH 3/5] Fix GUI timing related divide by zero exception --- CHANGELOG.md | 1 + .../xdrv_01_9_webserver.ino | 36 +++++++++---------- .../tasmota_xdrv_driver/xdrv_13_display.ino | 18 +++------- 3 files changed, 24 insertions(+), 31 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e705f0533..f2885de68 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ All notable changes to this project will be documented in this file. - MCP23xxx, PCF8574 and Shift595 power control when a display is configured regression from v14.3.0.7 - Display DisplayMode adds a display device while not configured - GUI intermittent exception on screen updates due to flash access +- GUI timing related divide by zero exception ### Removed diff --git a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino index 5c9f55e5a..cf32f4e76 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino @@ -1885,21 +1885,23 @@ bool HandleRootStatusRefresh(void) { XsnsXdrvCall(FUNC_WEB_SENSOR); WSContentSend_P(PSTR("</table>")); - if (!Settings->flag6.gui_no_state_text && // SetOption161 - (GUI) Disable display of state text (1) - TasmotaGlobal.devices_present) { + if (!Settings->flag6.gui_no_state_text) { // SetOption161 - (GUI) Disable display of state text (1) + if (!Web.buttons_non_light_non_shutter) { // Might still be zero on restart so chk if we have at least one + WebGetDeviceCounts(); + } + if ((Web.buttons_non_light_non_shutter > 0) && + ( Web.buttons_non_light_non_shutter <= 8)) { // We need at least one non light AND non shutter button #ifdef USE_SONOFF_IFAN - if (IsModuleIfan()) { - WSContentSend_P(PSTR("{t}<tr>")); - WSContentSend_P(HTTP_DEVICE_STATE, 36, (bitRead(TasmotaGlobal.power, 0)) ? PSTR("bold") : PSTR("normal"), 54, GetStateText(bitRead(TasmotaGlobal.power, 0))); - uint32_t fanspeed = GetFanspeed(); - snprintf_P(svalue, sizeof(svalue), PSTR("%d"), fanspeed); - WSContentSend_P(HTTP_DEVICE_STATE, 64, (fanspeed) ? PSTR("bold") : PSTR("normal"), 54, (fanspeed) ? svalue : GetStateText(0)); - WSContentSend_P(PSTR("</tr></table>")); - } else { + if (IsModuleIfan()) { + WSContentSend_P(PSTR("{t}<tr>")); + WSContentSend_P(HTTP_DEVICE_STATE, 36, (bitRead(TasmotaGlobal.power, 0)) ? PSTR("bold") : PSTR("normal"), 54, GetStateText(bitRead(TasmotaGlobal.power, 0))); + uint32_t fanspeed = GetFanspeed(); + snprintf_P(svalue, sizeof(svalue), PSTR("%d"), fanspeed); + WSContentSend_P(HTTP_DEVICE_STATE, 64, (fanspeed) ? PSTR("bold") : PSTR("normal"), 54, (fanspeed) ? svalue : GetStateText(0)); + WSContentSend_P(PSTR("</tr></table>")); + } else { #endif // USE_SONOFF_IFAN - - if (Web.buttons_non_light_non_shutter <= 8) { // Any non light AND non shutter button WSContentSend_P(PSTR("{t}<tr>")); uint32_t cols = Web.buttons_non_light_non_shutter; uint32_t fontsize = (cols < 5) ? 70 - (cols * 8) : 32; @@ -1908,17 +1910,15 @@ bool HandleRootStatusRefresh(void) { if (bitRead(Web.light_shutter_button_mask, button_idx -1)) { continue; } // Skip non-sequential shutter button bool power_state = bitRead(TasmotaGlobal.power, button_idx -1); snprintf_P(svalue, sizeof(svalue), PSTR("%d"), power_state); - WSContentSend_P(HTTP_DEVICE_STATE, 100 / cols, (power_state) ? "bold" : "normal", fontsize, (cols < 5) ? GetStateText(power_state) : svalue); + WSContentSend_P(HTTP_DEVICE_STATE, 100 / cols, (power_state) ? PSTR("bold") : PSTR("normal"), fontsize, (cols < 5) ? GetStateText(power_state) : svalue); button_ptr++; - if (button_ptr == Web.buttons_non_light_non_shutter) { break; } + if (button_ptr >= Web.buttons_non_light_non_shutter) { break; } } WSContentSend_P(PSTR("</tr></table>")); - } - #ifdef USE_SONOFF_IFAN - } + } #endif // USE_SONOFF_IFAN - + } } if (1 == Web.slider_update_time) { diff --git a/tasmota/tasmota_xdrv_driver/xdrv_13_display.ino b/tasmota/tasmota_xdrv_driver/xdrv_13_display.ino index a6ebf1e6f..732586d65 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_13_display.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_13_display.ino @@ -1852,11 +1852,12 @@ void DisplayLocalSensor(void) \*********************************************************************************************/ void DisplayInitDriver(void) { - Settings->display_model = 0; + uint32_t display_model = Settings->display_model; + Settings->display_model = 0; // Test if any display_model is available XdspCall(FUNC_DISPLAY_INIT_DRIVER); - -// AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "Display model %d"), Settings->display_model); - + if (Settings->display_model) { // If model found keep using user configured one for backward compatibility + Settings->display_model = display_model; + } if (!Settings->display_model) { return; } // AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("DSP: Model %d"), Settings->display_model); @@ -1891,15 +1892,6 @@ void DisplayInitDriver(void) { #endif UpdateDevicesPresent(1); - if (!PinUsed(GPIO_BACKLIGHT)) { - if ((LT_PWM1 == TasmotaGlobal.light_type) && // Single PWM light channel - (4 == Settings->display_model) // ILI9341 legacy -// ((4 == Settings->display_model) || // ILI9341 legacy -// (17 == Settings->display_model)) // Universal - Too invasive in case displays have no backlight pin - ) { - UpdateDevicesPresent(-1); // Assume PWM channel is used for backlight - } - } disp_device = TasmotaGlobal.devices_present; #ifndef USE_DISPLAY_MODES1TO5 From b0c505d17175974ea06567ccd2dae8866dbdfd7d Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sun, 15 Dec 2024 12:38:26 +0100 Subject: [PATCH 4/5] Fix display model --- tasmota/tasmota_xdrv_driver/xdrv_13_display.ino | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_13_display.ino b/tasmota/tasmota_xdrv_driver/xdrv_13_display.ino index 732586d65..5ba88cefa 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_13_display.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_13_display.ino @@ -1853,9 +1853,9 @@ void DisplayLocalSensor(void) void DisplayInitDriver(void) { uint32_t display_model = Settings->display_model; - Settings->display_model = 0; // Test if any display_model is available + Settings->display_model = 0; // Test if any display_model is available XdspCall(FUNC_DISPLAY_INIT_DRIVER); - if (Settings->display_model) { // If model found keep using user configured one for backward compatibility + if (Settings->display_model && display_model) { // If any model found keep using user configured one for backward compatibility Settings->display_model = display_model; } if (!Settings->display_model) { return; } From da7473e07c39056421382f1cc29fe56d5ea0c671 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sun, 15 Dec 2024 14:10:06 +0100 Subject: [PATCH 5/5] save a few bytes --- tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino index cf32f4e76..1e4dfbf52 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino @@ -1891,18 +1891,15 @@ bool HandleRootStatusRefresh(void) { } if ((Web.buttons_non_light_non_shutter > 0) && ( Web.buttons_non_light_non_shutter <= 8)) { // We need at least one non light AND non shutter button - + WSContentSend_P(PSTR("{t}<tr>")); #ifdef USE_SONOFF_IFAN if (IsModuleIfan()) { - WSContentSend_P(PSTR("{t}<tr>")); WSContentSend_P(HTTP_DEVICE_STATE, 36, (bitRead(TasmotaGlobal.power, 0)) ? PSTR("bold") : PSTR("normal"), 54, GetStateText(bitRead(TasmotaGlobal.power, 0))); uint32_t fanspeed = GetFanspeed(); snprintf_P(svalue, sizeof(svalue), PSTR("%d"), fanspeed); WSContentSend_P(HTTP_DEVICE_STATE, 64, (fanspeed) ? PSTR("bold") : PSTR("normal"), 54, (fanspeed) ? svalue : GetStateText(0)); - WSContentSend_P(PSTR("</tr></table>")); } else { #endif // USE_SONOFF_IFAN - WSContentSend_P(PSTR("{t}<tr>")); uint32_t cols = Web.buttons_non_light_non_shutter; uint32_t fontsize = (cols < 5) ? 70 - (cols * 8) : 32; uint32_t button_ptr = 0; @@ -1914,10 +1911,10 @@ bool HandleRootStatusRefresh(void) { button_ptr++; if (button_ptr >= Web.buttons_non_light_non_shutter) { break; } } - WSContentSend_P(PSTR("</tr></table>")); #ifdef USE_SONOFF_IFAN } #endif // USE_SONOFF_IFAN + WSContentSend_P(PSTR("</tr></table>")); } }