Optimize WiFi strength indicator (#23924)

* Optimize WiFi strength indicator

- Simplify `WifiGetRssiAsQuality`
- Make WiFi strength indicator in web status line color independent
- Correct count of visible bars in strength indicator
- Save flash space (64 bytes; with WiFi status line 80 bytes)
- Highlight connected SSID/AP in settings with compiler option `USE_HIGHLIGHT_CONNECTED_AP` (needs additional 256 bytes)

* Change format of RSSI display
This commit is contained in:
SteWers 2025-09-21 15:26:03 +02:00 committed by GitHub
parent 40bf796ef3
commit ec6e1dd2a6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 57 additions and 51 deletions

View File

@ -1,20 +1,20 @@
/////////////////////////////////////////////////////////////////////
// compressed by tools/unishox/compress-html-uncompressed.py
// input sha256: 9a486b094383e66396481c3f2fc7b8babdd200f81183d673b24be18bb3ead6d8
// input sha256: 6a58e374e830bc7855fee6d3d35791432657297a910013f2d70a79e6861a02af
/////////////////////////////////////////////////////////////////////
const size_t HTTP_HEAD_STYLE_WIFI_SIZE = 373; // compressed size 230 bytes
const size_t HTTP_HEAD_STYLE_WIFI_SIZE = 345; // compressed size 232 bytes
const char HTTP_HEAD_STYLE_WIFI_COMPRESSED[] PROGMEM = "\x3A\x0F\xE9\x8D\x3D\xA3\xFA\x25\x0A\x3C\xCE\x4F\x90\xC3\x61\xE0\x53\xD1\xE1\x54"
"\x08\x32\x06\x67\xB6\xB7\x38\xF3\xFB\x0A\xEB\x4C\xD9\xEE\x3A\x5F\xC3\x3D\xA3\x2C"
"\x41\x37\x87\x8F\x33\x8C\x81\x16\xED\x8E\xF6\x04\x2E\x99\xE0\x76\x7C\x47\xF3\xCC"
"\xE5\x10\xC3\x62\xF6\x05\xA2\x2A\x2B\xFD\xF7\x86\x5F\xDF\x50\x21\x59\x3A\xFF\x62"
"\x68\xBF\x1E\x67\x35\x9F\x44\x08\x73\xAB\x06\x1D\x61\xE0\x59\xF3\xCC\xCE\xFE\x77"
"\x4E\xB3\xAC\x33\xF6\x63\xE3\x4E\xF1\xEE\x3A\x59\xC6\x40\x85\xBB\x9C\xA2\x04\x5D"
"\xD8\xE5\x90\xC3\x61\xE2\xB0\x61\xE6\x72\x32\x18\x6C\x3C\x04\xCC\x51\xE6\x72\x42"
"\x18\x6C\x3D\xC7\x4B\x39\x08\x10\xB0\x83\x9C\x40\x8B\x84\x1C\xE2\x04\x2C\x20\xE7"
"\x88\x10\xF0\x73\x88\x86\x1B\x0F\x71\xD2\xCE\x51\x02\x1F\x09\xA0\x8D\x99\x9C\x94"
"\x40\x85\x84\x1C\xC2\x04\x3C\x20\xE7\x10\xC3\x61\xEE\x3A\x59\xCB\x20\x53\xE1\xE6"
"\xB0\x61\xE6\x72\x10\x21\xE1\x07\x2C\x86\x1B\x0F\x71\xD2\xFE\x19\xD2\xC3\xAD\x33"
"\x67\xB4\x15\x38\x34\xAA\x08\xEF\x1E\xE3";
"\x79\x9C\x94\x43\x0D\x87\x81\x99\xED\xAD\xCE\x3C\xFE\xC2\xBA\xD3\x36\x7B\x8E\x97"
"\xF0\xCF\x68\xCB\x10\x4D\xE1\xE3\xCC\xE3\x20\x45\xBB\x63\xBD\x81\x0B\xA6\x78\x1D"
"\x9F\x11\xFC\xF3\x39\x44\x30\xD8\xBD\x81\x68\x8A\xBF\x7D\xE1\x97\xF7\xD4\x08\x56"
"\x4E\xBF\xD8\x9A\x2F\xC7\x99\xCD\x67\xD1\x02\x1C\xEA\xC1\x87\x58\x78\x16\x7C\xF3"
"\x33\xBF\x9D\xD3\xAC\xEB\x0C\xFD\xD1\xB2\x8E\xF1\xEE\x3A\x59\xC6\x40\x85\xBB\x9C"
"\xA2\x04\x5D\xD8\xE5\x90\xC3\x61\xE2\xB0\x61\xE6\x71\x10\xC3\x61\xE0\x26\x62\x8F"
"\x33\x9F\x21\x86\xC3\xDC\x74\xB3\x90\x81\x0B\x06\x39\xC4\x08\xB8\x31\xCE\x20\x42"
"\xC1\x8E\x71\x02\x1E\x0C\x73\x88\x61\xB0\xF7\x1D\x2C\xE5\x10\x21\xF0\x96\x08\xD9"
"\x89\xC9\x44\x08\x58\x41\xCB\x20\x43\xC2\x0E\x59\x0C\x36\x1E\xE3\xA5\x9C\xB2\x04"
"\xFE\x1D\xCE\x7C\x81\x0B\x08\x38\xC8\x10\xF0\x83\x8C\x86\x1B\x0F\x71\xD3\x0E\x5B"
"\x3D\xA5\x83\x2C\x3D\xA3\x23\xCC\xE8\x72\xCF\x71";
#define HTTP_HEAD_STYLE_WIFI Decompress(HTTP_HEAD_STYLE_WIFI_COMPRESSED,HTTP_HEAD_STYLE_WIFI_SIZE).c_str()

View File

@ -1,9 +1,9 @@
const char HTTP_HEAD_STYLE_WIFI[] PROGMEM =
".wifi{width:18px;height:18px;position:relative}"
".arc{padding:0;position:absolute;border:2px solid transparent;border-radius:50%;border-top-color:var(--c_frm)}"
".a0{width:2px;height:3px;top:10px;left:11px}"
".a1{width:6px;height:6px;top:7px;left:9px}"
".a2{width:12px;height:12px;top:4px;left:6px}"
".a3{width:18px;height:18px;top:1px;left:3px}"
".arc.active{border-top-color:var(--c_ttl)}"
".wifi{width:18px;height:12px;position:relative}"
".arc{padding:0;position:absolute;border:2px solid transparent;border-radius:50%;border-top-color:var(--c_txt)}"
".a0{width:2px;height:3px;top:9px;left:8px}"
".a1{width:6px;height:6px;top:6px;left:6px}"
".a2{width:12px;height:12px;top:3px;left:3px}"
".a3{width:18px;height:18px;top:0px;left:0px}"
".o30{opacity:.3}"
;

View File

@ -58,16 +58,9 @@ const uint8_t WIFI_RETRY_OFFSET_SEC = WIFI_RETRY_SECONDS; // seconds
* - Values in between are linearly mapped (each 2.5 dBm = 5%)
*/
int WifiGetRssiAsQuality(int rssi) {
int quality = 0;
if (rssi <= -100) {
quality = 0;
} else if (rssi >= -50) {
quality = 100;
} else {
quality = 2 * (rssi + 100);
}
return quality;
if (rssi <= -100) { return 0; }
if (rssi >= -50) { return 100; }
return 2 * (rssi + 100);
}
// 0 1 2 3 4

View File

@ -248,9 +248,10 @@ const char HTTP_SCRIPT_INFO_END[] PROGMEM =
const char HTTP_HEAD_STYLE_SSI[] PROGMEM =
// Signal Strength Indicator
".si{display:inline-flex;align-items:flex-end;height:15px;padding:0}"
".si i{width:3px;margin-right:1px;border-radius:3px;background-color:var(--c_txt)}"
".si .b0{height:25%}.si .b1{height:50%}.si .b2{height:75%}.si .b3{height:100%}.o30{opacity:.3}";
".si{display:inline-flex;align-items:flex-end;height:15px;padding:0;"
"i{width:3px;margin-right:1px;border-radius:3px;background-color:var(--c_txt)}"
".b0{height:25%}.b1{height:50%}.b2{height:75%}.b3{height:100%}}"
".o30{opacity:.3}";
// special case if MINIMAL, then we don't use compressed version
#ifdef FIRMWARE_MINIMAL
@ -1973,12 +1974,12 @@ bool HandleRootStatusRefresh(void) {
#ifdef USE_WEB_STATUS_LINE_WIFI
if (Settings->flag4.network_wifi) {
int32_t rssi = WiFi.RSSI();
WSContentSend_P(PSTR("<div class='wifi' title='%s: " D_RSSI " %d%%, %d dBm' style='padding:0 2px 0 2px;'><div class='arc a3 %s'></div><div class='arc a2 %s'></div><div class='arc a1 %s'></div><div class='arc a0 active'></div></div>"),
WSContentSend_P(PSTR("<div class='wifi' title='%s: " D_RSSI " %d%% (%d dBm)'><div class='arc a3%s'></div><div class='arc a2%s'></div><div class='arc a1%s'></div><div class='arc a0'></div></div>"),
SettingsTextEscaped(SET_STASSID1 + Settings->sta_active).c_str(),
WifiGetRssiAsQuality(rssi), rssi,
rssi >= -55 ? "active" : "",
rssi >= -70 ? "active" : "",
rssi >= -85 ? "active" : "");
rssi < -55 ? " o30" : "",
rssi < -70 ? " o30" : "",
rssi < -85 ? " o30" : "");
}
#endif // USE_WEB_STATUS_LINE_WIFI
#ifdef USE_WEB_STATUS_LINE_HEAP
@ -2576,33 +2577,45 @@ void HandleWifiConfiguration(void) {
}
skipduplicated = false;
String nextSSID = "";
#ifdef USE_HIGHLIGHT_CONNECTED_AP
bool HighlightAP;
#endif
// Handle all APs with the same SSID
for (uint32_t j = 0; j < n; j++) {
if ((indices[j] < n) && ((nextSSID = WiFi.SSID(indices[j])) == ssid)) {
if (!skipduplicated) {
// Update RSSI / quality
rssi = WiFi.RSSI(indices[j]);
uint32_t rssi_as_quality = WifiGetRssiAsQuality(rssi);
uint32_t num_bars = changeUIntScale(rssi_as_quality, 0, 100, 0, 4);
uint8_t rssi_as_quality = WifiGetRssiAsQuality(rssi);
uint8_t num_bars = changeUIntScale(rssi_as_quality, 0, 100, 0, 4);
WSContentSend_P(PSTR("<div title='%d dBm (%d%%)'>"), rssi, rssi_as_quality);
WSContentSend_P(PSTR("<div title='%d%% (%d dBm)'>"), rssi_as_quality, rssi);
if (limitScannedNetworks) {
// Print SSID and item
WSContentSend_P(PSTR("<a href='#p' onclick='c(this)'>%s</a><span class='q'><div class='si'>"), HtmlEscape(ssid_copy).c_str());
ssid_showed++;
skipduplicated = true; // For the simplified page, just show 1 SSID if there are many Networks with the same
#ifdef USE_HIGHLIGHT_CONNECTED_AP
HighlightAP = ssid_copy == WiFi.SSID();
#endif
} else {
// Print item
WSContentSend_P(PSTR("%s<span class='q'>(%d) <div class='si'>"), WiFi.BSSIDstr(indices[j]).c_str(), WiFi.channel(indices[j])
);
WSContentSend_P(PSTR("%s<span class='q'>(%d) <div class='si'>"), WiFi.BSSIDstr(indices[j]).c_str(), WiFi.channel(indices[j]));
#ifdef USE_HIGHLIGHT_CONNECTED_AP
HighlightAP = WiFi.BSSIDstr(indices[j]) == WiFi.BSSIDstr();
#endif
}
// Print signal strength indicator
for (uint32_t k = 0; k < 4; ++k) {
WSContentSend_P(PSTR("<i class='b%d%s'></i>"), k, (num_bars < k) ? PSTR(" o30") : PSTR(""));
for (uint8_t k = 0; k < 4; k++) {
#ifdef USE_HIGHLIGHT_CONNECTED_AP
WSContentSend_P(PSTR("<i class='b%d%s'%s></i>"), k, (k >= num_bars) ? PSTR(" o30") : PSTR(""), HighlightAP ? PSTR(" style='background-color:var(--c_btn);'") : PSTR(""));
#else
WSContentSend_P(PSTR("<i class='b%d%s'></i>"), k, (k >= num_bars) ? PSTR(" o30") : PSTR(""));
#endif
}
WSContentSend_P(PSTR("</div></span></div>"));
} else {
if (ssid_showed <= networksToShow ) { networksToShow++; }
if (ssid_showed <= networksToShow) { networksToShow++; }
}
indices[j] = n;
}
@ -3001,7 +3014,7 @@ void HandleInformation(void) {
}
if (Settings->flag4.network_wifi) {
int32_t rssi = WiFi.RSSI();
WSContentSend_P(PSTR("}1" D_AP "%d " D_INFORMATION "}2" D_SSID " %s<br>" D_RSSI " %d%%, %d dBm<br>" D_MODE " %s<br>" D_CHANNEL " %d<br>" D_BSSID " %s"),
WSContentSend_P(PSTR("}1" D_AP "%d " D_INFORMATION "}2" D_SSID " %s<br>" D_RSSI " %d%% (%d dBm)<br>" D_MODE " %s<br>" D_CHANNEL " %d<br>" D_BSSID " %s"),
Settings->sta_active +1,
SettingsTextEscaped(SET_STASSID1 + Settings->sta_active).c_str(),
WifiGetRssiAsQuality(rssi), rssi,

View File

@ -1917,9 +1917,9 @@ const char ZB_WEB_U[] PROGMEM =
// Lighting
".bx{height:14px;width:14px;display:inline-block;border:1px solid currentColor;background-color:var(--cl,#fff)}"
// Signal Strength Indicator
".si{display:inline-flex;align-items:flex-end;height:15px;padding:0}"
".si i{width:3px;margin-right:1px;border-radius:3px;background-color:#%06x}"
".si .b0{height:25%%}.si .b1{height:50%%}.si .b2{height:75%%}.si .b3{height:100%%}.o30{opacity:.3}"
".si{display:inline-flex;align-items:flex-end;height:15px;padding:0;"
"i{width:3px;margin-right:1px;border-radius:3px;background-color:#%06x}"
".b0{height:25%%}.b1{height:50%%}.b2{height:75%%}.b3{height:100%%}}.o30{opacity:.3}"
"</style>"
"\0"
@ -2277,8 +2277,8 @@ void ZigbeeShow(bool json)
EscapeHTMLString(name).c_str(), sbatt, slqi);
if(device.validLqi()) {
for(uint32_t j = 0; j < 4; ++j) {
WSContentSend_PD(PSTR("<i class='b%d%s'></i>"), j, (num_bars < j) ? PSTR(" o30") : PSTR(""));
for(uint32_t j = 0; j < 4; j++) {
WSContentSend_P(PSTR("<i class='b%d%s'></i>"), j, (j >= num_bars) ? PSTR(" o30") : PSTR(""));
}
}
snprintf_P(dhm, sizeof(dhm), PSTR("<td>&nbsp;"));