Optimize Web UI memory handling and polling logic

Made-with: Cursor
This commit is contained in:
drjones
2026-03-11 19:49:18 -07:00
parent f8b588bb73
commit 13be73f7af

View File

@@ -1349,6 +1349,7 @@ async function poll(){
document.getElementById('connDot').style.background='#f28a86';
document.getElementById('bt').textContent='OFFLINE';
}
setTimeout(poll, 1000);
}
document.getElementById('jp').addEventListener('input',e=>document.getElementById('pv').textContent=PT[+e.target.value]);
@@ -1358,7 +1359,7 @@ document.getElementById('aamp').addEventListener('click',async()=>{try{await fet
document.getElementById('asw').addEventListener('click',async()=>{try{await fetch('/api/sweep',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({dwell_ms:+document.getElementById('sd').value,steps1:+document.getElementById('ss1').value,steps2:+document.getElementById('ss2').value,span1_mhz:+document.getElementById('sp1').value,span2_mhz:+document.getElementById('sp2').value})});}catch(e){}});
document.getElementById('dl').addEventListener('click',()=>{const a=document.createElement('a');a.href='/api/log';a.download='jammer-log.txt';a.click();});
poll();setInterval(poll,1000);
poll();
// ── Capture / Replay ─────────────────────────────────────────────────────────
let capPolling=false;
@@ -1453,48 +1454,76 @@ static void handleTelemetry() {
int8_t effDbm = jamPower + ampGainDb;
float effWatts = powf(10.0f, effDbm / 10.0f) / 1000.0f; // dBm -> watts
String json = "{";
json += "\"uptime_ms\":" + String(millis() - uptimeStart) + ",";
json += "\"free_heap\":" + String(ESP.getFreeHeap()) + ",";
json += "\"temp_c\":" + String(tempC, 1) + ",";
json += "\"jamming_enabled\":" + String(jammingEnabled ? "true" : "false") + ",";
json += "\"jam_power\":" + String(jamPower) + ",";
json += "\"jam_power_idx\":" + String(jamPowerIdx) + ",";
json += "\"amp_gain_db\":" + String(ampGainDb) + ",";
json += "\"eff_power_dbm\":" + String(effDbm) + ",";
json += "\"eff_power_w\":" + String(effWatts, 3) + ",";
String err1 = jsonEscape(radio1Error);
String err2 = jsonEscape(radio2Error);
// Sweep state
json += "\"sweep_freq1\":" + String(sweepFreq1, 4) + ",";
json += "\"sweep_center1\":" + String(SWEEP_1_CENTER_MHZ, 2) + ",";
json += "\"sweep_span1\":" + String(sweep1SpanMhz, 2) + ",";
json += "\"sweep_steps1\":" + String(sweep1Steps) + ",";
json += "\"sweep_freq2\":" + String(sweepFreq2, 4) + ",";
json += "\"sweep_center2\":" + String(SWEEP_2_CENTER_MHZ, 2) + ",";
json += "\"sweep_span2\":" + String(sweep2SpanMhz, 2) + ",";
json += "\"sweep_steps2\":" + String(sweep2Steps) + ",";
json += "\"sweep_dwell_ms\":" + String(sweepDwellMs) + ",";
static char jsonBuf[1024]; // Generously sized to avoid fragmentation
snprintf(jsonBuf, sizeof(jsonBuf),
"{"
"\"uptime_ms\":%lu,"
"\"free_heap\":%lu,"
"\"temp_c\":%.1f,"
"\"jamming_enabled\":%s,"
"\"jam_power\":%d,"
"\"jam_power_idx\":%d,"
"\"amp_gain_db\":%d,"
"\"eff_power_dbm\":%d,"
"\"eff_power_w\":%.3f,"
"\"sweep_freq1\":%.4f,"
"\"sweep_center1\":%.2f,"
"\"sweep_span1\":%.2f,"
"\"sweep_steps1\":%u,"
"\"sweep_freq2\":%.4f,"
"\"sweep_center2\":%.2f,"
"\"sweep_span2\":%.2f,"
"\"sweep_steps2\":%u,"
"\"sweep_dwell_ms\":%lu,"
"\"radio1_status\":%d,"
"\"radio1_error\":\"%s\","
"\"radio1_freq\":%.4f,"
"\"radio1_active\":%s,"
"\"radio2_status\":%d,"
"\"radio2_error\":\"%s\","
"\"radio2_freq\":%.4f,"
"\"radio2_active\":%s,"
"\"hop_count1\":%lu,"
"\"hop_count2\":%lu,"
"\"min_heap\":%lu,"
"\"ap_clients\":%d"
"}",
(unsigned long)(millis() - uptimeStart),
(unsigned long)ESP.getFreeHeap(),
(double)tempC,
jammingEnabled ? "true" : "false",
(int)jamPower,
(int)jamPowerIdx,
(int)ampGainDb,
(int)effDbm,
(double)effWatts,
(double)sweepFreq1,
(double)SWEEP_1_CENTER_MHZ,
(double)sweep1SpanMhz,
(unsigned)sweep1Steps,
(double)sweepFreq2,
(double)SWEEP_2_CENTER_MHZ,
(double)sweep2SpanMhz,
(unsigned)sweep2Steps,
(unsigned long)sweepDwellMs,
(int)radio1Status,
err1.c_str(),
(double)sweepFreq1,
radio1Status == 2 ? "true" : "false",
(int)radio2Status,
err2.c_str(),
(double)sweepFreq2,
radio2Status == 2 ? "true" : "false",
(unsigned long)hopCount1,
(unsigned long)hopCount2,
(unsigned long)(minFreeHeap == 0xFFFFFFFF ? ESP.getFreeHeap() : minFreeHeap),
(int)WiFi.softAPgetStationNum()
);
// Radio 1
json += "\"radio1_status\":" + String(radio1Status) + ",";
json += "\"radio1_error\":\"" + jsonEscape(radio1Error) + "\",";
json += "\"radio1_freq\":" + String(sweepFreq1, 4) + ",";
json += "\"radio1_active\":" + String(radio1Status == 2 ? "true" : "false") + ",";
// Radio 2
json += "\"radio2_status\":" + String(radio2Status) + ",";
json += "\"radio2_error\":\"" + jsonEscape(radio2Error) + "\",";
json += "\"radio2_freq\":" + String(sweepFreq2, 4) + ",";
json += "\"radio2_active\":" + String(radio2Status == 2 ? "true" : "false") + ",";
// 24-hour health metrics
json += "\"hop_count1\":" + String(hopCount1) + ",";
json += "\"hop_count2\":" + String(hopCount2) + ",";
json += "\"min_heap\":" + String(minFreeHeap == 0xFFFFFFFF ? ESP.getFreeHeap() : minFreeHeap) + ",";
json += "\"ap_clients\":" + String(WiFi.softAPgetStationNum());
json += "}";
server.send(200, "application/json; charset=utf-8", json);
server.send(200, "application/json; charset=utf-8", jsonBuf);
}
static void handleToggle() {