System Metrics
-System Metrics
+Live Frequency Sweep
+2-Minute History
+Live Frequency Sweep
-Radio Status
+Radio Status
-Controls
+Controls
--
-
Sweep Settings
-+
System Log
- ++
diff --git a/fix_html.py b/fix_html.py new file mode 100644 index 0000000..0caacab --- /dev/null +++ b/fix_html.py @@ -0,0 +1,28 @@ +import re +with open('src/main.cpp', 'r') as f: + content = f.read() + +# Make logLine print to serial +content = content.replace('static void logLine(const String& s) {\n logRing[logHead] = s;\n logHead = (logHead + 1) % LOG_LINES;\n if (logCount < LOG_LINES) logCount++;\n}', 'static void logLine(const String& s) {\n logRing[logHead] = s;\n logHead = (logHead + 1) % LOG_LINES;\n if (logCount < LOG_LINES) logCount++;\n Serial.println(s);\n}') + +# Fix jammingEnabled check +content = content.replace(' if (jammingEnabled) {\n logLine("[JAM] Already jamming, ignoring start request");\n return;\n }', ' if (jammingEnabled) {\n logLine("[JAM] Already jamming, ignoring start request");\n // return; // Allow re-initialization if needed\n }') + +# Move kHtml to global scope +html_pattern = r'(static const char kHtml\[\] PROGMEM = R"HTML\([\s\S]*?\)HTML";)' +match = re.search(html_pattern, content) +if match: + html_block = match.group(1).replace('static const char kHtml[] PROGMEM', 'const char kHtml[]') + content = content.replace(match.group(1), '') + + # insert before handleRoot + content = content.replace('static void handleRoot() {', html_block + '\n\nstatic void handleRoot() {') + +# Fix send_P to send +content = content.replace('server.send_P(200, "text/html; charset=utf-8", kHtml);', 'server.send(200, "text/html; charset=utf-8", kHtml);') + +# Fix initial jam start +content = content.replace(' // Start jamming immediately if enabled\n if (jammingEnabled) {\n startJamming();\n } else {', ' // Start jamming immediately if enabled\n if (jammingEnabled) {\n jammingEnabled = false;\n startJamming();\n } else {') + +with open('src/main.cpp', 'w') as f: + f.write(content) diff --git a/src/main.cpp b/src/main.cpp index 25c64ce..e917639 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -70,6 +70,12 @@ static int8_t ampGainDb = DEFAULT_AMP_GAIN_DB; // Auto-reinit watchdog static uint32_t lastReInitCheck = 0; +// 24-hour operation health tracking +static uint32_t hopCount1 = 0; // total frequency hops since boot +static uint32_t hopCount2 = 0; +static uint32_t minFreeHeap = 0xFFFFFFFF; // lowest heap ever observed +static uint32_t lastTempWarnMs = 0; // rate-limit temperature warnings + // Log ring buffer static constexpr size_t LOG_LINES = 100; static String logRing[LOG_LINES]; @@ -77,10 +83,17 @@ static size_t logHead = 0; static size_t logCount = 0; static void logLine(const String& s) { - logRing[logHead] = s; + uint32_t ms = millis(); + uint32_t ss = ms / 1000; + uint32_t mm = ss / 60; ss %= 60; + uint32_t hh = mm / 60; mm %= 60; + char ts[12]; + snprintf(ts, sizeof(ts), "[%02u:%02u:%02u] ", hh, mm, ss); + const String line = String(ts) + s; + logRing[logHead] = line; logHead = (logHead + 1) % LOG_LINES; if (logCount < LOG_LINES) logCount++; - Serial.println(s); + Serial.println(line); } static String getLogsText() { @@ -322,378 +335,372 @@ static void updateJamPower(uint8_t idx) { // Web server handlers const char kHtml[] = R"HTML( - - -
- - -