Files
car-key-killer/fix_html.py
drjones 0e4865a7c3 Add 24hr UI overhaul: heat trail canvases, sparklines, hop counters, health monitoring
Firmware:
- logLine now prepends [HH:MM:SS] timestamp to every log entry
- hopCount1/hopCount2 track total frequency hops since boot (exposed in telemetry)
- minFreeHeap tracks lowest free heap ever seen (exposed in telemetry)
- Heartbeat block: updates minFreeHeap, reboots if heap < 15 KB, warns if temp > 75C (once/min)
- Telemetry JSON: added hop_count1, hop_count2, min_heap, ap_clients fields
- Removed noisy [HTTP] GET / log line that filled the 100-line ring buffer in ~2 minutes
- Log poll reduced to every 5 seconds (telemetry still every 1s) to ease HTTP load

UI:
- Canvas height 90px with fading heat trail (last 50 hop positions as glowing blur)
- Known fob frequencies drawn as labeled dashed vertical lines on each canvas
  (Honda 303.825, Chmb 310, Toyota 314.98, Ford/GM 315, Linear 318, LiftMaster 390,
   Holtek 418, Somfy 433.42, EU 433.92, Nero 434.42)
- Frequency axis labels embedded inside canvas bottom bar
- 2-minute temperature sparkline + heap sparkline (120-sample ring buffer)
- 24h mission progress bar under header with elapsed/total display
- 12 metrics: added Hops R1, Hops R2, Hops/sec, Min Heap, AP Clients
- Color-coded temp (yellow >65C, red >80C) and heap (yellow <60kB, red <30kB)
- Pulsing green glow animation on JAMMING ACTIVE banner
- Updated input defaults to match config (dwell=5, steps=25/47, span=20/46)

Made-with: Cursor
2026-03-10 17:45:45 -07:00

29 lines
1.7 KiB
Python

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)