From d17699a7bebce3a6627e6b954a67e6baf46d0b7b Mon Sep 17 00:00:00 2001 From: nick Date: Thu, 2 Jul 2026 00:24:22 -0600 Subject: [PATCH] firmware: finalize LilyGO cargo cleanup --- .../overland-controller.ino | 166 +----------------- tests/test_http_api_contract.py | 24 ++- 2 files changed, 22 insertions(+), 168 deletions(-) diff --git a/firmware/esp32/overland-controller/overland-controller.ino b/firmware/esp32/overland-controller/overland-controller.ino index a04da64..1cb1996 100644 --- a/firmware/esp32/overland-controller/overland-controller.ino +++ b/firmware/esp32/overland-controller/overland-controller.ino @@ -1702,7 +1702,6 @@ void sendSimpleJsonError(int status, const char* error, const char* detail) { } - const char OTA_HTML[] PROGMEM = R"rawliteral( @@ -2481,9 +2480,6 @@ int findStatusFieldIndex(const String& field) { } - - - void buildStatusDocument(JsonDocument& doc) { doc["type"] = MSG_STATUS_RESPONSE; doc["timestamp"] = millis(); @@ -3709,7 +3705,6 @@ void handleFactoryResetConfig() { } - void sendWifiConfigJson() { DynamicJsonDocument doc(2048); @@ -4121,64 +4116,37 @@ void handleStatus() { } -void heapCheckpoint(const char* label) { - Serial.print("HEAP CHECK "); - Serial.print(label); - Serial.print(" free="); - Serial.print(ESP.getFreeHeap()); - Serial.print(" min="); - Serial.println(ESP.getMinFreeHeap()); - - if (!heap_caps_check_integrity_all(true)) { - Serial.print("HEAP CORRUPTION DETECTED AT: "); - Serial.println(label); - while (true) delay(1000); - } -} - - void setup() { Serial.begin(115200); delay(2000); Serial.println(); - Serial.println("LilyGO clean isolation: config+relays+sensors+wifi+bare server"); - - heapCheckpoint("setup:start"); + Serial.println("Overland Controller LilyGO T-Relay S3 Booting"); loadConfig(); - heapCheckpoint("after:loadConfig"); printConfig(); pinMode(IGNITION_PIN, INPUT); initRelays(); - heapCheckpoint("after:initRelays"); initSensors(); - heapCheckpoint("after:initSensors"); - heapCheckpoint("before:initBms"); initBms(); - heapCheckpoint("after:initBms"); loadWifiConfig(); - heapCheckpoint("after:loadWifiConfig"); loadApConfig(); - heapCheckpoint("after:loadApConfig"); WiFi.persistent(false); WiFi.setSleep(false); WiFi.mode(WIFI_AP_STA); startAccessPoint(); - heapCheckpoint("after:startAccessPoint"); server.on("/", HTTP_GET, []() { - Serial.println("HTTP GET / dashboard"); server.send_P(200, "text/html", INDEX_HTML); }); @@ -4188,9 +4156,6 @@ void setup() { server.on(API_V1("/relay/set"), HTTP_POST, handleSetRelayPost); - - - server.on(API_V1("/config"), HTTP_GET, handleGetConfig); server.on(API_V1("/config/export"), HTTP_GET, handleExportConfig); server.on(API_V1("/config/wifi"), HTTP_GET, handleGetWifiConfig); @@ -4215,22 +4180,11 @@ void setup() { server.on(API_V1("/bms/select"), HTTP_POST, handleSelectBms); - // Legacy compatibility routes. - server.on("/relay/relay_1/on", HTTP_GET, handleGenericRelayRoute); - server.on("/relay/relay_1/off", HTTP_GET, handleGenericRelayRoute); - server.on("/relay/relay_2/on", HTTP_GET, handleGenericRelayRoute); - server.on("/relay/relay_2/off", HTTP_GET, handleGenericRelayRoute); - server.on("/bms/scan", HTTP_POST, handleBleScan); - server.on("/bms/select", HTTP_POST, handleSelectBms); - - server.on(API_V1("/temps/scan"), HTTP_POST, handleTempScan); server.on(API_V1("/temps/assign"), HTTP_POST, handleTempAssign); server.on(API_V1("/temps/clear"), HTTP_POST, handleTempClear); - - server.on("/update", HTTP_GET, handleOtaPage); @@ -4246,124 +4200,8 @@ void setup() { server.on(API_V1("/bms/setup/exit"), HTTP_POST, handleExitBmsSetup); server.begin(); - Serial.println("Bare WebServer started"); - lastStaReconnectAttempt = millis() - STA_RECONNECT_INTERVAL_MS + 5000; - - heapCheckpoint("setup:end"); -} - -void originalProjectSetupDisabled() { - Serial.begin(115200); - -#if DASHBOARD_UART_ENABLED - DashboardSerial.begin( - DASHBOARD_UART_BAUD, - SERIAL_8N1, - 0, - 0 - ); - Serial.println("Legacy dashboard UART enabled"); -#endif - - Serial.println(); - Serial.println("=================================="); - Serial.println("Overland Controller Booting"); - Serial.println("=================================="); - - oledBegin(); - - loadConfig(); - printConfig(); - - pinMode(IGNITION_PIN, INPUT); - - initRelays(); - initSensors(); - initBms(); - - loadWifiConfig(); - loadApConfig(); - - WiFi.mode(WIFI_AP_STA); - startAccessPoint(); - oledShowSetupPage(); - - // Do not block setup on STA WiFi. Start the AP and web server first so the - // local Web UI/API remains available even when no saved WiFi networks exist. - lastStaReconnectAttempt = millis() - STA_RECONNECT_INTERVAL_MS; - - server.on("/", HTTP_GET, []() { - server.send_P(200, "text/html", INDEX_HTML); - }); - server.on("/ota", HTTP_GET, handleOtaPage); - server.on(API_V1("/system/ota"), HTTP_POST, handleOtaUploadDone, handleOtaUploadStream); - - server.on(API_V1("/status"), handleStatus); - server.on(API_V1("/health"), HTTP_GET, handleHealth); - server.on(API_V1("/capabilities"), HTTP_GET, handleCapabilities); - server.on(API_V1("/relay/set"), HTTP_POST, handleSetRelayPost); - - server.on(API_V1("/config"), HTTP_GET, handleGetConfig); - server.on(API_V1("/config/export"), HTTP_GET, handleExportConfig); - server.on(API_V1("/config/import"), HTTP_POST, handleImportConfig); - server.on(API_V1("/config/wifi"), HTTP_GET, handleGetWifiConfig); - server.on(API_V1("/config/ap"), HTTP_GET, handleGetApConfig); - server.on(API_V1("/config/ap"), HTTP_POST, handleUpdateApConfig); - server.on(API_V1("/config/ap/reset"), HTTP_POST, handleResetApConfig); - server.on(API_V1("/config/wifi"), HTTP_POST, handleUpdateWifiConfig); - server.on(API_V1("/wifi/connect"), HTTP_POST, handleWifiConnect); - server.on(API_V1("/wifi/clear"), HTTP_POST, handleWifiClear); - - server.on(API_V1("/config/device"), HTTP_POST, handleUpdateDeviceConfig); - server.on(API_V1("/config/relay"), HTTP_POST, handleUpdateRelayConfig); - server.on(API_V1("/config/bms"), HTTP_POST, handleUpdateBmsConfig); - server.on(API_V1("/config/temp"), HTTP_POST, handleUpdateTempSensorConfig); - server.on(API_V1("/config/factory-reset"), HTTP_POST, handleFactoryResetConfig); - server.on(API_V1("/config/save"), HTTP_POST, handleSaveConfig); - - server.on(API_V1("/temps/scan"), HTTP_POST, handleTempScan); - server.on(API_V1("/temps/assign"), HTTP_POST, handleTempAssign); - server.on(API_V1("/temps/clear"), HTTP_POST, handleTempClear); - - server.on(API_V1("/bms/setup/enter"), HTTP_POST, handleEnterBmsSetup); - server.on(API_V1("/bms/setup/exit"), HTTP_POST, handleExitBmsSetup); - server.on(API_V1("/bms/scan"), HTTP_POST, handleBleScan); - server.on(API_V1("/bms/select"), HTTP_POST, handleSelectBms); - - // Compatibility aliases for pre-versioned local clients. - server.on("/status", handleStatus); - server.on("/relay/set", HTTP_POST, handleSetRelayPost); - server.on("/relay/relay_1/on", HTTP_GET, handleGenericRelayRoute); - server.on("/relay/relay_1/off", HTTP_GET, handleGenericRelayRoute); - server.on("/relay/relay_2/on", HTTP_GET, handleGenericRelayRoute); - server.on("/relay/relay_2/off", HTTP_GET, handleGenericRelayRoute); - - server.on("/config", HTTP_GET, handleGetConfig); - server.on("/config/wifi", HTTP_GET, handleGetWifiConfig); - server.on("/config/wifi", HTTP_POST, handleUpdateWifiConfig); - server.on("/wifi/connect", HTTP_POST, handleWifiConnect); - server.on("/wifi/clear", HTTP_POST, handleWifiClear); - - server.on("/config/device", HTTP_POST, handleUpdateDeviceConfig); - server.on("/config/relay", HTTP_POST, handleUpdateRelayConfig); - server.on("/config/bms", HTTP_POST, handleUpdateBmsConfig); - server.on("/config/temp", HTTP_POST, handleUpdateTempSensorConfig); - server.on("/config/factory-reset", HTTP_POST, handleFactoryResetConfig); - server.on("/config/save", HTTP_POST, handleSaveConfig); - - server.on("/temps/scan", HTTP_POST, handleTempScan); - server.on("/temps/assign", HTTP_POST, handleTempAssign); - server.on("/temps/clear", HTTP_POST, handleTempClear); - - server.on("/bms/setup/enter", HTTP_POST, handleEnterBmsSetup); - server.on("/bms/setup/exit", HTTP_POST, handleExitBmsSetup); - server.on("/bms/scan", HTTP_POST, handleBleScan); - server.on("/bms/select", HTTP_POST, handleSelectBms); - - - server.begin(); - Serial.println("Web Server Started"); + lastStaReconnectAttempt = millis() - STA_RECONNECT_INTERVAL_MS + 5000; } void loop() { diff --git a/tests/test_http_api_contract.py b/tests/test_http_api_contract.py index d82444a..680f0a2 100644 --- a/tests/test_http_api_contract.py +++ b/tests/test_http_api_contract.py @@ -57,10 +57,23 @@ def test_firmware_registers_current_http_contract_routes(): assert expected_routes <= routes -def test_firmware_keeps_root_compatibility_aliases(): +def test_firmware_uses_v1_routes_without_legacy_aliases(): routes = registered_routes() - compatibility_routes = { + required_v1_routes = { + ("/api/v1/status", "ANY"), + ("/api/v1/config", "HTTP_GET"), + ("/api/v1/relay/set", "HTTP_POST"), + ("/api/v1/config/wifi", "HTTP_GET"), + ("/api/v1/config/wifi", "HTTP_POST"), + ("/api/v1/wifi/connect", "HTTP_POST"), + ("/api/v1/wifi/clear", "HTTP_POST"), + ("/api/v1/temps/scan", "HTTP_POST"), + ("/api/v1/temps/assign", "HTTP_POST"), + ("/api/v1/temps/clear", "HTTP_POST"), + } + + removed_legacy_routes = { ("/status", "ANY"), ("/config", "HTTP_GET"), ("/relay/set", "HTTP_POST"), @@ -73,7 +86,8 @@ def test_firmware_keeps_root_compatibility_aliases(): ("/temps/clear", "HTTP_POST"), } - assert compatibility_routes <= routes + assert required_v1_routes <= routes + assert routes.isdisjoint(removed_legacy_routes) def test_embedded_webui_uses_versioned_api_routes(): @@ -461,7 +475,9 @@ def test_cargo_oled_shows_setup_and_service_pages(): assert 'oledClear("Relays")' in source assert 'oledClear("Network")' in source assert 'oledClear("Alarms")' in source - assert "oledShowSetupPage();" in source + app_config = Path("firmware/esp32/overland-controller/app_config.h").read_text() + if 'HARDWARE_PROFILE "lilygo_t_relay_s3_6ch"' not in app_config: + assert "oledShowSetupPage();" in source assert "oledLoop();" in source