fix: restore /stats Wi-Fi signal quality and refresh web panel screenshots

This commit is contained in:
Jared Dohrman
2026-04-15 17:35:29 +10:00
parent f67aaebe7e
commit 785f5c2fd3
6 changed files with 116 additions and 45 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 325 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 394 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 372 KiB

+42 -42
View File
@@ -86,48 +86,48 @@ If you are deciding between otherwise similar boards, these target-level setting
This table includes all repeater MQTT targets currently defined in `variants/eastmesh_mqtt/platformio.ini`.
| Target | MCU | RAM | PSRAM | Flash | LoRa | Display | GPS | SD |
| ------------------------ | ------- | ------ | ----- | ----- | ------ | --------------- | --- | -- |
| Ebyte_EoRa-S3 | ESP32S3 | 512 KB | 2 MB | 4 MB | SX1262 | OLED (SSD1306) | | |
| Generic_E22_sx1262 | ESP32 | 520 KB | No | 4 MB | SX1262 | None | | |
| Generic_E22_sx1268 | ESP32 | 520 KB | No | 4 MB | SX1268 | None | | |
| Heltec_ct62 | ESP32C3 | 400 KB | No | 4 MB | SX1262 | None | | |
| Heltec_E213 | ESP32S3 | 512 KB | 8 MB | 16 MB | SX1262 | E-paper (2.13") | | |
| Heltec_E290 | ESP32S3 | 512 KB | 8 MB | 16 MB | SX1262 | E-paper (2.9") | | |
| Heltec_T190 | ESP32S3 | 512 KB | 8 MB | 16 MB | SX1262 | TFT (ST7789) | | |
| heltec_tracker_v2 | ESP32S3 | 512 KB | No | 8 MB | SX1262 | TFT (ST7735) | ✅ | |
| Heltec_v2 | ESP32 | 520 KB | No | 8 MB | SX1276 | OLED (SSD1306) | | |
| Heltec_v3 | ESP32S3 | 512 KB | No | 8 MB | SX1262 | OLED (SSD1306) | ✅ | |
| heltec_v4 | ESP32S3 | 512 KB | 2 MB | 16 MB | SX1262 | OLED (SSD1306) | ✅ | |
| heltec_v4_tft | ESP32S3 | 512 KB | 2 MB | 16 MB | SX1262 | TFT (ST7789) | ✅ | |
| Heltec_Wireless_Paper | ESP32S3 | 512 KB | No | 8 MB | SX1262 | E-paper (2.13") | | |
| Heltec_Wireless_Tracker | ESP32S3 | 512 KB | No | 8 MB | SX1262 | TFT (ST7735) | ✅ | |
| Heltec_WSL3 | ESP32S3 | 512 KB | No | 8 MB | SX1262 | None | ✅ | |
| LilyGo_T3S3_sx1262 | ESP32S3 | 512 KB | 2 MB | 4 MB | SX1262 | OLED (SSD1306) | | 🧪 |
| LilyGo_T3S3_sx1276 | ESP32S3 | 512 KB | 2 MB | 4 MB | SX1276 | OLED (SSD1306) | | 🧪 |
| LilyGo_TBeam_1W | ESP32S3 | 512 KB | 8 MB | 16 MB | SX1262 | OLED (SH1106) | ✅ | ✅ |
| LilyGo_TDeck | ESP32S3 | 512 KB | No | 16 MB | SX1262 | TFT (ST7789) | ✅ | 🧪 |
| LilyGo_Tlora_C6 | ESP32C6 | 512 KB | No | 4 MB | SX1262 | None | | |
| LilyGo_TLora_V2_1_1_6 | ESP32 | 520 KB | No | 4 MB | SX1276 | OLED (SSD1306) | ✅ | |
| M5Stack_Unit_C6L | ESP32C6 | 512 KB | No | 4 MB | SX1262 | None | ✅ | |
| Meshadventurer_sx1262 | ESP32 | 520 KB | No | 4 MB | SX1262 | OLED (SSD1306) | ✅ | |
| Meshadventurer_sx1268 | ESP32 | 520 KB | No | 4 MB | SX1268 | OLED (SSD1306) | ✅ | |
| Meshimi | ESP32C6 | 512 KB | No | 4 MB | SX1262 | None | | |
| nibble_screen_connect | ESP32S3 | 512 KB | No | 4 MB | SX1262 | OLED (SSD1306) | | |
| RAK_3112 | ESP32S3 | 512 KB | No | 8 MB | SX1262 | None | ✅ | |
| Station_G2 | ESP32S3 | 512 KB | 8 MB | 16 MB | SX1262 | OLED (SH1106) | ✅ | |
| Station_G2_logging | ESP32S3 | 512 KB | 8 MB | 16 MB | SX1262 | OLED (SH1106) | ✅ | |
| T_Beam_S3_Supreme_SX1262 | ESP32S3 | 512 KB | 8 MB | 8 MB | SX1262 | OLED (SH1106) | ✅ | ✅ |
| Tbeam_SX1262 | ESP32 | 520 KB | No | 4 MB | SX1262 | OLED (SSD1306) | ✅ | |
| Tbeam_SX1276 | ESP32 | 520 KB | No | 4 MB | SX1276 | OLED (SSD1306) | ✅ | |
| Tenstar_C3_sx1262 | ESP32C3 | 400 KB | No | 4 MB | SX1262 | None | | |
| Tenstar_C3_sx1268 | ESP32C3 | 400 KB | No | 4 MB | SX1268 | None | | |
| ThinkNode_M2 | ESP32S3 | 512 KB | No | 4 MB | SX1262 | OLED (SH1106) | | |
| ThinkNode_M5 | ESP32S3 | 512 KB | No | 4 MB | SX1262 | E-paper (GxEPD) | ✅ | |
| WHY2025_badge | ESP32C6 | 512 KB | No | 4 MB | SX1262 | None | | |
| Xiao_C3 | ESP32C3 | 400 KB | No | 4 MB | SX1262 | None | ✅ | |
| Xiao_C6 | ESP32C6 | 512 KB | No | 4 MB | SX1262 | None | | |
| Xiao_S3_WIO | ESP32S3 | 512 KB | No | 8 MB | SX1262 | None | ✅ | |
| Target | MCU | RAM | PSRAM | Flash | LoRa | Display | GPS | SD |
| ------------------------ | ------- | ------ | ----- | ----- | ------ | --------------- | --- | --- |
| Ebyte_EoRa-S3 | ESP32S3 | 512 KB | 2 MB | 4 MB | SX1262 | OLED (SSD1306) | | |
| Generic_E22_sx1262 | ESP32 | 520 KB | No | 4 MB | SX1262 | None | | |
| Generic_E22_sx1268 | ESP32 | 520 KB | No | 4 MB | SX1268 | None | | |
| Heltec_ct62 | ESP32C3 | 400 KB | No | 4 MB | SX1262 | None | | |
| Heltec_E213 | ESP32S3 | 512 KB | 8 MB | 16 MB | SX1262 | E-paper (2.13") | | |
| Heltec_E290 | ESP32S3 | 512 KB | 8 MB | 16 MB | SX1262 | E-paper (2.9") | | |
| Heltec_T190 | ESP32S3 | 512 KB | 8 MB | 16 MB | SX1262 | TFT (ST7789) | | |
| heltec_tracker_v2 | ESP32S3 | 512 KB | No | 8 MB | SX1262 | TFT (ST7735) | ✅ | |
| Heltec_v2 | ESP32 | 520 KB | No | 8 MB | SX1276 | OLED (SSD1306) | | |
| Heltec_v3 | ESP32S3 | 512 KB | No | 8 MB | SX1262 | OLED (SSD1306) | ✅ | |
| heltec_v4 | ESP32S3 | 512 KB | 2 MB | 16 MB | SX1262 | OLED (SSD1306) | ✅ | |
| heltec_v4_tft | ESP32S3 | 512 KB | 2 MB | 16 MB | SX1262 | TFT (ST7789) | ✅ | |
| Heltec_Wireless_Paper | ESP32S3 | 512 KB | No | 8 MB | SX1262 | E-paper (2.13") | | |
| Heltec_Wireless_Tracker | ESP32S3 | 512 KB | No | 8 MB | SX1262 | TFT (ST7735) | ✅ | |
| Heltec_WSL3 | ESP32S3 | 512 KB | No | 8 MB | SX1262 | None | ✅ | |
| LilyGo_T3S3_sx1262 | ESP32S3 | 512 KB | 2 MB | 4 MB | SX1262 | OLED (SSD1306) | | 🧪 |
| LilyGo_T3S3_sx1276 | ESP32S3 | 512 KB | 2 MB | 4 MB | SX1276 | OLED (SSD1306) | | 🧪 |
| LilyGo_TBeam_1W | ESP32S3 | 512 KB | 8 MB | 16 MB | SX1262 | OLED (SH1106) | ✅ | ✅ |
| LilyGo_TDeck | ESP32S3 | 512 KB | No | 16 MB | SX1262 | TFT (ST7789) | ✅ | 🧪 |
| LilyGo_Tlora_C6 | ESP32C6 | 512 KB | No | 4 MB | SX1262 | None | | |
| LilyGo_TLora_V2_1_1_6 | ESP32 | 520 KB | No | 4 MB | SX1276 | OLED (SSD1306) | ✅ | |
| M5Stack_Unit_C6L | ESP32C6 | 512 KB | No | 4 MB | SX1262 | None | ✅ | |
| Meshadventurer_sx1262 | ESP32 | 520 KB | No | 4 MB | SX1262 | OLED (SSD1306) | ✅ | |
| Meshadventurer_sx1268 | ESP32 | 520 KB | No | 4 MB | SX1268 | OLED (SSD1306) | ✅ | |
| Meshimi | ESP32C6 | 512 KB | No | 4 MB | SX1262 | None | | |
| nibble_screen_connect | ESP32S3 | 512 KB | No | 4 MB | SX1262 | OLED (SSD1306) | | |
| RAK_3112 | ESP32S3 | 512 KB | No | 8 MB | SX1262 | None | ✅ | |
| Station_G2 | ESP32S3 | 512 KB | 8 MB | 16 MB | SX1262 | OLED (SH1106) | ✅ | |
| Station_G2_logging | ESP32S3 | 512 KB | 8 MB | 16 MB | SX1262 | OLED (SH1106) | ✅ | |
| T_Beam_S3_Supreme_SX1262 | ESP32S3 | 512 KB | 8 MB | 8 MB | SX1262 | OLED (SH1106) | ✅ | ✅ |
| Tbeam_SX1262 | ESP32 | 520 KB | No | 4 MB | SX1262 | OLED (SSD1306) | ✅ | |
| Tbeam_SX1276 | ESP32 | 520 KB | No | 4 MB | SX1276 | OLED (SSD1306) | ✅ | |
| Tenstar_C3_sx1262 | ESP32C3 | 400 KB | No | 4 MB | SX1262 | None | | |
| Tenstar_C3_sx1268 | ESP32C3 | 400 KB | No | 4 MB | SX1268 | None | | |
| ThinkNode_M2 | ESP32S3 | 512 KB | No | 4 MB | SX1262 | OLED (SH1106) | | |
| ThinkNode_M5 | ESP32S3 | 512 KB | No | 4 MB | SX1262 | E-paper (GxEPD) | ✅ | |
| WHY2025_badge | ESP32C6 | 512 KB | No | 4 MB | SX1262 | None | | |
| Xiao_C3 | ESP32C3 | 400 KB | No | 4 MB | SX1262 | None | ✅ | |
| Xiao_C6 | ESP32C6 | 512 KB | No | 4 MB | SX1262 | None | | |
| Xiao_S3_WIO | ESP32S3 | 512 KB | No | 8 MB | SX1262 | None | ✅ | |
Note: all current `repeater_mqtt` boards support the local web panel except `Xiao_C3`, where it is disabled to preserve limited board resources.
+8 -2
View File
@@ -26,9 +26,15 @@ Operational guidance:
## Screenshot Overview
The layout below reflects the current panel structure for the repeater web UI.
The screenshots below show the current split between the lighter `/app` admin page and the dedicated `/stats` status page.
![Repeater web panel overview](./_assets/repeater_web_panel_overview.png)
### `/app`
![Repeater web panel `/app` overview](./_assets/repeater_web_panel_app.png)
### `/stats`
![Repeater web panel `/stats` overview](./_assets/repeater_web_panel_stats.png)
## Requirements
+66 -1
View File
@@ -2132,35 +2132,96 @@ bool MyMesh::formatWebStatsSummaryJson(char* reply, size_t reply_size) {
#else
char wifi_ssid[48];
char wifi_status[20];
char wifi_state[24];
char wifi_ip[20];
char wifi_signal[16];
char wifi_powersave[12];
escapeJsonString(network.getWifiSSID()[0] ? network.getWifiSSID() : "-", wifi_ssid, sizeof(wifi_ssid));
escapeJsonString(network.getWifiPowerSave(), wifi_powersave, sizeof(wifi_powersave));
int wifi_rssi = 0;
int wifi_quality = 0;
int wifi_code = 0;
#if defined(ESP32)
if (network.getWifiSSID()[0] == 0) {
strncpy(wifi_status, "unconfigured", sizeof(wifi_status) - 1);
wifi_status[sizeof(wifi_status) - 1] = 0;
strncpy(wifi_state, "unconfigured", sizeof(wifi_state) - 1);
wifi_state[sizeof(wifi_state) - 1] = 0;
strncpy(wifi_ip, "--", sizeof(wifi_ip) - 1);
wifi_ip[sizeof(wifi_ip) - 1] = 0;
strncpy(wifi_signal, "--", sizeof(wifi_signal) - 1);
wifi_signal[sizeof(wifi_signal) - 1] = 0;
} else if (network.isWifiConnected()) {
strncpy(wifi_status, "connected", sizeof(wifi_status) - 1);
wifi_status[sizeof(wifi_status) - 1] = 0;
strncpy(wifi_state, "connected", sizeof(wifi_state) - 1);
wifi_state[sizeof(wifi_state) - 1] = 0;
String ip = WiFi.localIP().toString();
escapeJsonString(ip.c_str(), wifi_ip, sizeof(wifi_ip));
wifi_rssi = WiFi.RSSI();
wifi_code = static_cast<int>(WiFi.status());
if (wifi_rssi <= -100) {
wifi_quality = 0;
strncpy(wifi_signal, "poor", sizeof(wifi_signal) - 1);
} else if (wifi_rssi >= -50) {
wifi_quality = 100;
strncpy(wifi_signal, "excellent", sizeof(wifi_signal) - 1);
} else {
wifi_quality = 2 * (wifi_rssi + 100);
if (wifi_rssi >= -60) {
strncpy(wifi_signal, "excellent", sizeof(wifi_signal) - 1);
} else if (wifi_rssi >= -67) {
strncpy(wifi_signal, "good", sizeof(wifi_signal) - 1);
} else if (wifi_rssi >= -75) {
strncpy(wifi_signal, "fair", sizeof(wifi_signal) - 1);
} else {
strncpy(wifi_signal, "poor", sizeof(wifi_signal) - 1);
}
}
wifi_signal[sizeof(wifi_signal) - 1] = 0;
} else {
strncpy(wifi_status, "connecting", sizeof(wifi_status) - 1);
wifi_status[sizeof(wifi_status) - 1] = 0;
wifi_code = static_cast<int>(WiFi.status());
switch (WiFi.status()) {
case WL_IDLE_STATUS:
strncpy(wifi_state, "idle", sizeof(wifi_state) - 1);
break;
case WL_NO_SSID_AVAIL:
strncpy(wifi_state, "no_ssid", sizeof(wifi_state) - 1);
break;
case WL_SCAN_COMPLETED:
strncpy(wifi_state, "scan_completed", sizeof(wifi_state) - 1);
break;
case WL_CONNECT_FAILED:
strncpy(wifi_state, "connect_failed", sizeof(wifi_state) - 1);
break;
case WL_CONNECTION_LOST:
strncpy(wifi_state, "connection_lost", sizeof(wifi_state) - 1);
break;
case WL_DISCONNECTED:
strncpy(wifi_state, "disconnected", sizeof(wifi_state) - 1);
break;
default:
strncpy(wifi_state, "unknown", sizeof(wifi_state) - 1);
break;
}
wifi_state[sizeof(wifi_state) - 1] = 0;
strncpy(wifi_ip, "--", sizeof(wifi_ip) - 1);
wifi_ip[sizeof(wifi_ip) - 1] = 0;
strncpy(wifi_signal, "--", sizeof(wifi_signal) - 1);
wifi_signal[sizeof(wifi_signal) - 1] = 0;
}
#else
strncpy(wifi_status, "unsupported", sizeof(wifi_status) - 1);
wifi_status[sizeof(wifi_status) - 1] = 0;
strncpy(wifi_state, "unsupported", sizeof(wifi_state) - 1);
wifi_state[sizeof(wifi_state) - 1] = 0;
strncpy(wifi_ip, "--", sizeof(wifi_ip) - 1);
wifi_ip[sizeof(wifi_ip) - 1] = 0;
strncpy(wifi_signal, "--", sizeof(wifi_signal) - 1);
wifi_signal[sizeof(wifi_signal) - 1] = 0;
#endif
const int battery_pct = board.getBatteryPercent();
@@ -2189,7 +2250,7 @@ bool MyMesh::formatWebStatsSummaryJson(char* reply, size_t reply_size) {
"\"packets\":{\"recv\":%u,\"sent\":%u,\"flood_tx\":%u,\"direct_tx\":%u,\"flood_rx\":%u,\"direct_rx\":%u,"
"\"recv_errors\":%u,\"direct_dups\":%u,\"flood_dups\":%u,\"neighbors\":%u},"
"\"memory\":{\"heap_free\":%u,\"heap_min\":%u,\"heap_max\":%u,\"psram_free\":%u,\"psram_min\":%u,\"psram_max\":%u},"
"\"wifi\":{\"ssid\":\"%s\",\"status\":\"%s\",\"connected\":%s,\"ip\":\"%s\",\"rssi\":%d,\"powersave\":\"%s\"},"
"\"wifi\":{\"ssid\":\"%s\",\"status\":\"%s\",\"connected\":%s,\"state\":\"%s\",\"code\":%d,\"ip\":\"%s\",\"rssi\":%d,\"quality\":%d,\"signal\":\"%s\",\"powersave\":\"%s\"},"
"\"services\":{\"mqtt_connected\":%s,\"web_enabled\":%s,\"web_panel_up\":%s,\"web_auth\":\"%s\","
"\"archive_available\":%s}",
(_stats_history.isEnabled() && _stats_history.isRecentHistoryAvailable()) ? "true" : "false",
@@ -2241,8 +2302,12 @@ bool MyMesh::formatWebStatsSummaryJson(char* reply, size_t reply_size) {
wifi_ssid,
wifi_status,
network.isWifiConnected() ? "true" : "false",
wifi_state,
wifi_code,
wifi_ip,
wifi_rssi,
wifi_quality,
wifi_signal,
wifi_powersave,
mqtt_connected ? "true" : "false",
web.isWebEnabled() ? "true" : "false",