From 22bc3d04249c00ca86c7b98bf01994566fe30716 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 24 Apr 2026 06:21:48 +0000 Subject: [PATCH 1/2] Initial plan From 77570b5f5533379704854a0f6f485010d582fbe2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 24 Apr 2026 06:25:20 +0000 Subject: [PATCH 2/2] Add WiFi signal strength (RSSI) to status display Agent-Logs-Url: https://github.com/netmindz/zigbee_wled/sessions/9759ae1e-52e1-429f-af5a-ee96e00ac27d Co-authored-by: netmindz <442066+netmindz@users.noreply.github.com> --- src/web_ui.cpp | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/src/web_ui.cpp b/src/web_ui.cpp index b3c8149..7a429a0 100644 --- a/src/web_ui.cpp +++ b/src/web_ui.cpp @@ -111,6 +111,7 @@ static const char INDEX_HTML[] PROGMEM = R"rawliteral(
WiFi
...
+
Zigbee
@@ -222,16 +223,31 @@ static const char INDEX_HTML[] PROGMEM = R"rawliteral( let config = { lights: [] }; let isApMode = false; +function rssiLabel(rssi) { + if (rssi >= -60) return 'Excellent'; + if (rssi >= -70) return 'Good'; + if (rssi >= -80) return 'Fair'; + return 'Weak'; +} + async function loadStatus() { try { const r = await fetch('/api/status'); const s = await r.json(); document.getElementById('wifiStatus').textContent = s.wifi || 'Unknown'; + const rssiEl = document.getElementById('wifiRssi'); + if (s.rssi && s.wifi && s.wifi !== 'Not connected') { + rssiEl.textContent = s.rssi + ' dBm \u00b7 ' + rssiLabel(s.rssi); + rssiEl.style.display = ''; + } else { + rssiEl.style.display = 'none'; + } document.getElementById('zbStatus').textContent = s.zigbee || 'Unknown'; isApMode = s.apMode || false; document.getElementById('wifiSetup').style.display = isApMode ? 'block' : 'none'; } catch(e) { document.getElementById('wifiStatus').textContent = 'AP Mode'; + document.getElementById('wifiRssi').style.display = 'none'; document.getElementById('wifiSetup').style.display = 'block'; isApMode = true; } @@ -527,6 +543,13 @@ let useSSE = true; function applyStatus(s) { document.getElementById('wifiStatus').textContent = s.wifi || 'Unknown'; + const rssiEl = document.getElementById('wifiRssi'); + if (s.rssi && s.wifi && s.wifi !== 'Not connected') { + rssiEl.textContent = s.rssi + ' dBm \u00b7 ' + rssiLabel(s.rssi); + rssiEl.style.display = ''; + } else { + rssiEl.style.display = 'none'; + } document.getElementById('zbStatus').textContent = s.zigbee || 'Unknown'; isApMode = s.apMode || false; document.getElementById('wifiSetup').style.display = isApMode ? 'block' : 'none'; @@ -669,6 +692,7 @@ static esp_err_t handleRoot(httpd_req_t *req) { static esp_err_t handleStatus(httpd_req_t *req) { JsonDocument doc; doc["wifi"] = WiFi.isConnected() ? WiFi.SSID() : "Not connected"; + doc["rssi"] = WiFi.isConnected() ? static_cast(WiFi.RSSI()) : 0; doc["apMode"] = apMode; doc["zigbee"] = !zigbeeIsEnabled() ? "Disabled - no lights configured" : zigbeeIsPaired() ? "Paired" @@ -1008,6 +1032,7 @@ struct StatusSnapshot { bool zigbeeEnabled; bool zigbeePaired; uint8_t lightCount; + int8_t rssi; }; // Compact light state snapshot for change detection (avoids full JSON compare) @@ -1031,6 +1056,7 @@ static unsigned long sseLastKeepalive = 0; static String buildStatusJson() { JsonDocument doc; doc["wifi"] = WiFi.isConnected() ? WiFi.SSID() : "Not connected"; + doc["rssi"] = WiFi.isConnected() ? static_cast(WiFi.RSSI()) : 0; doc["apMode"] = apMode; doc["zigbee"] = !zigbeeIsEnabled() ? "Disabled - no lights configured" : zigbeeIsPaired() ? "Paired" @@ -1073,6 +1099,7 @@ static StatusSnapshot takeStatusSnapshot() { s.zigbeeEnabled = zigbeeIsEnabled(); s.zigbeePaired = zigbeeIsPaired(); s.lightCount = configStore.getLightCount(); + s.rssi = WiFi.isConnected() ? static_cast(WiFi.RSSI()) : 0; return s; } @@ -1081,7 +1108,8 @@ static bool statusChanged(const StatusSnapshot& a, const StatusSnapshot& b) { || a.apMode != b.apMode || a.zigbeeEnabled != b.zigbeeEnabled || a.zigbeePaired != b.zigbeePaired - || a.lightCount != b.lightCount; + || a.lightCount != b.lightCount + || abs(static_cast(a.rssi) - static_cast(b.rssi)) >= 5; } static void takeLightSnapshot(LightSnapshot* out, uint8_t count) {