diff --git a/firmware/esp32/overland-controller/overland-controller.ino b/firmware/esp32/overland-controller/overland-controller.ino index d2de811..65e6e6a 100644 --- a/firmware/esp32/overland-controller/overland-controller.ino +++ b/firmware/esp32/overland-controller/overland-controller.ino @@ -33,7 +33,7 @@ body{margin:0;background:var(--bg);color:var(--text);font-family:-apple-system,B .weatherBadge{font-size:20px;font-weight:900;color:var(--text);padding:8px 12px} h1{font-size:21px;margin:0}.sub{color:var(--muted);font-size:13px;margin-top:4px} .pill{border:1px solid var(--line);border-radius:999px;padding:7px 10px;color:var(--muted);font-size:12px;white-space:nowrap} -.tabs{position:fixed;left:0;right:0;bottom:0;background:#080c11;border-top:1px solid var(--line);display:grid;grid-template-columns:repeat(3,1fr);z-index:10} +.tabs{position:fixed;left:0;right:0;bottom:0;background:#080c11;border-top:1px solid var(--line);display:grid;grid-template-columns:repeat(3,1fr);z-index:10}\n.subtabs{display:flex;gap:8px;overflow-x:auto;padding:2px 0 12px;margin-bottom:4px}.subtabbtn{width:auto;white-space:nowrap;border:1px solid var(--line);background:#101722;color:var(--muted);padding:10px 12px;border-radius:999px;font-size:13px}.subtabbtn.active{background:#1f2b3c;color:var(--text);border-color:#3b536f}.configSubpage{display:none}.configSubpage.active{display:block} .tabbtn{border:0;border-radius:0;background:#080c11;color:var(--muted);padding:13px 8px;font-weight:800} .tabbtn.active{color:var(--text);background:#111923} .page{display:none}.page.active{display:block} @@ -173,141 +173,189 @@ input{width:100%;border:1px solid var(--line);border-radius:12px;padding:12px;ba
-
-
-
-
-
Settings
-
Configure the Cargo ESP32 controller. The Cargo ESP remains the source of truth for relays, sensors, WiFi, and AP settings.
-
-
-
+
+ + + + + + +
-
-
-
-
Access Point
-
This is the local camp network hosted by the Cargo ESP32. Phones and the dashboard connect here when no Starlink/home WiFi is available.
+
+
+
+
+
+
Settings
+
Configure the Cargo ESP32 controller. The Cargo ESP remains the source of truth for relays, sensors, WiFi, and AP settings.
+
-
-
-
Current AP--
-
Security--
- -
SSID must be 1-32 characters.
- -
Password must be 8-63 characters. The current password is never displayed.
-
- - +
+ +
+
+
+
General
+
Controller identity shown in the WebUI and dashboard.
+
-
Saving AP settings restarts the access point. Your phone may disconnect and need to reconnect to the new SSID/password. Dashboard auto-migration is planned but not implemented yet.
-
- - -
-
-
-
Home / Starlink WiFi
-
Optional client networks the Cargo ESP can join. Lower priority number is tried first. The AP remains available for local access.
+
+ +
-
-
- - - - - - - - - - - -
-
+ -
-
-
-
Relay Outputs
-
Rename relay outputs. IDs stay fixed for API/UART compatibility.
+
+
+
+
System
+
Read-only firmware and network status.
+
-
-
- -
+
Firmware--
+
Uptime--
+
AP IP--
+ +
+ -
-
-
-
Temperature Assignment
-
Scan probes, then assign a discovered sensor to a configured temp slot.
+
+
+
+
+
+
Access Point
+
This is the local camp network hosted by the Cargo ESP32. Phones and the dashboard connect here when no Starlink/home WiFi is available.
+
-
-
- -
-
-
- -
-
Temperature Sensor Config
-
Set how many temp sensors are enabled and rename each slot.
-
- -
- -
-
- -
-
-
-
Device
-
Controller identity and BMS connection settings.
+
+
Current AP--
+
Security--
+ +
SSID must be 1-32 characters.
+ +
Password must be 8-63 characters. The current password is never displayed.
+
+ + +
+
Saving AP settings restarts the access point. Your phone may disconnect and need to reconnect to the new SSID/password. Dashboard auto-migration is planned but not implemented yet.
-
-
- - -
-
+ -
-
BMS Config
-
Use this for initial setup, bench mode, or replacing the battery/BMS.
-
- - - -
- - +
+
+
+
Home / Starlink WiFi
+
Optional client networks the Cargo ESP can join. Lower priority number is tried first. The AP remains available for local access.
+
+
+
+ + + + + + + + + + + +
+
+
+
+ +
+
+
+
+
+
Relay Outputs
+
Rename relay outputs. IDs stay fixed for API/UART compatibility.
+
+
+
+ +
+
+
+ +
+
+
+
+
+
Temperature Assignment
+
Scan probes, then assign discovered sensors to configured temp slots.
+
+
+
+ +
+
+
+ +
+
+
+
Temperature Sensor Config
+
Set how many temp sensors are enabled, rename each slot, and pick the weather badge sensor.
+
+
+
+ +
+ +
+
+
+
+ +
+
+
+
+
+
BMS Config
+
JBD/Xiaoxiang BLE settings. Use this for initial setup, bench mode, or replacing the battery/BMS.
+
+
+
+ + + +
+ + +
+
+ +
+
BMS Polling--
+
+
+
+
+ +
+
+
+
+
+
Maintenance
+
Reset and recovery actions. These can disrupt the controller.
+
- +
-
-
- -
-
System Actions
-
Use carefully. Factory reset clears install-specific configuration.
-
- -
-
- -
-
System
-
Firmware--
-
Uptime--
-
AP IP--
-
+ + -
@@ -474,6 +522,15 @@ function batteryTimeInfo(b){ return {label:"Battery time", value:"Idle"}; } +function showConfigSubtab(name){ + ["general","wifi","relays","temps","bms","maintenance"].forEach(t=>{ + const page=$("config-"+t); + const btn=$("configTab-"+t); + if(page) page.classList.toggle("active",t===name); + if(btn) btn.classList.toggle("active",t===name); + }); +} + function showTab(name){ ["overview","battery","config"].forEach(t=>{ $(t+"Page").classList.toggle("active",t===name); diff --git a/tests/test_http_api_contract.py b/tests/test_http_api_contract.py index 062196f..39016ca 100644 --- a/tests/test_http_api_contract.py +++ b/tests/test_http_api_contract.py @@ -375,3 +375,29 @@ def test_embedded_webui_api_badge_labels_are_clear(): assert "API Live" in source assert "API Error" in source assert 'textContent="Offline"' not in source + + +def test_embedded_webui_config_page_is_grouped(): + source = firmware_source() + + assert "configGroupTitle" in source + assert "General" in source + assert "Home / Starlink WiFi" in source + assert "Relay Outputs" in source + assert "Temperature Assignment" in source + assert "BMS Config" in source + assert "Maintenance" in source + + +def test_embedded_webui_config_subtabs(): + source = firmware_source() + + assert "function showConfigSubtab(name)" in source + assert "config-general" in source + assert "config-wifi" in source + assert "config-relays" in source + assert "config-temps" in source + assert "config-bms" in source + assert "config-maintenance" in source + assert "WiFi / AP" in source + assert "subtabbtn active" in source