From 961ab3758bbda56992f303998e7bfc618d47b3b3 Mon Sep 17 00:00:00 2001 From: nick Date: Thu, 4 Jun 2026 20:54:48 -0600 Subject: [PATCH] Add setup workflow controls to web UI --- .../overland-controller.ino | 162 ++++++++++++++++++ 1 file changed, 162 insertions(+) diff --git a/firmware/esp32/overland-controller/overland-controller.ino b/firmware/esp32/overland-controller/overland-controller.ino index 8ff5245..328e638 100644 --- a/firmware/esp32/overland-controller/overland-controller.ino +++ b/firmware/esp32/overland-controller/overland-controller.ino @@ -169,6 +169,50 @@ input{width:100%;border:1px solid var(--line);border-radius:12px;padding:12px;ba +
+
Device Config
+
+ + +
+
+ +
+
BMS Config
+
Use this for initial setup, bench mode, or replacing the battery/BMS.
+
+ + + +
+ + +
+
+ + +
+
+
+ +
+
Temperature Assignment
+
Scan probes, then assign a discovered sensor to a configured temp slot.
+
+ +
+
+
+ +
+
System Actions
+
Use carefully. Factory reset clears install-specific configuration.
+
+ + +
+
+
System
Firmware--
@@ -215,6 +259,7 @@ async function relay(id,on){ await load(); } function render(data){ + window.lastStatus=data; $("conn").textContent="Live"; $("conn").className="pill good"; $("device").textContent=data.config?.device_name||"Overland Controller"; @@ -274,6 +319,123 @@ function render(data){ $("fw").textContent=(s.firmware_name||"--")+" "+(s.firmware_version||""); $("uptime").textContent=(s.uptime_seconds||0)+" sec"; renderConfigControls(data); + populateSetupFields(data); +} + + +function populateSetupFields(data){ + const cfg=data.config||{}; + if($("deviceNameInput")) $("deviceNameInput").value=cfg.device_name||""; + + const bms=cfg.bms||{}; + if($("bmsNameInput")) $("bmsNameInput").value=bms.name||""; + if($("bmsAddressInput")) $("bmsAddressInput").value=bms.address||""; + if($("bmsAddressTypeInput")) $("bmsAddressTypeInput").value=bms.address_type||"public"; +} + +async function saveDeviceConfig(){ + const name=$("deviceNameInput")?.value.trim(); + if(!name){ alert("Device name is required"); return; } + + await fetch("/config/device",{ + method:"POST", + headers:{"Content-Type":"application/json"}, + body:JSON.stringify({device_name:name}) + }); + + await fetch("/config/save",{method:"POST"}); + await load(); + alert("Device name saved"); +} + +async function saveBmsFullConfig(){ + const name=$("bmsNameInput")?.value.trim()||"BMS"; + const address=$("bmsAddressInput")?.value.trim()||""; + let address_type=($("bmsAddressTypeInput")?.value.trim()||"public").toLowerCase(); + + if(address_type!=="public" && address_type!=="random"){ + alert("Address type must be public or random"); + return; + } + + await fetch("/config/bms",{ + method:"POST", + headers:{"Content-Type":"application/json"}, + body:JSON.stringify({ + enabled:true, + name:name, + address:address, + address_type:address_type + }) + }); + + await fetch("/config/save",{method:"POST"}); + await reconnectBms(false); + await load(); + alert("BMS config saved"); +} + +async function reconnectBms(showAlert=true){ + await fetch("/bms/reconnect",{method:"POST"}); + if(showAlert) alert("BMS reconnect requested"); +} + +async function scanTemps(){ + const box=$("tempScanResults"); + if(box) box.innerHTML=`
Scanning...wait
`; + + const r=await fetch("/temps/scan",{method:"POST"}); + const d=await r.json(); + const devices=d.devices||[]; + + if(!box) return; + + if(!devices.length){ + box.innerHTML=`
No probes found0
`; + return; + } + + const cfg=window.lastStatus?.config||{}; + const temps=cfg.temperature_sensors||[]; + + box.innerHTML=devices.map(dev=>` +
+
+ ${dev.address} + #${dev.index} +
+
+ ${temps.slice(0,4).map((t,i)=>` + + `).join("")} +
+
`).join(""); +} + +async function assignTemp(id,index){ + await fetch("/temps/assign",{ + method:"POST", + headers:{"Content-Type":"application/json"}, + body:JSON.stringify({id:id,index:index}) + }); + + await fetch("/config/save",{method:"POST"}); + await load(); + alert("Temp probe assigned to "+id); +} + +async function restartController(){ + if(!confirm("Restart the controller now?")) return; + await fetch("/system/restart",{method:"POST"}); + alert("Restart requested"); +} + +async function factoryReset(){ + if(!confirm("Factory reset all controller configuration?")) return; + if(!confirm("This clears WiFi/BMS/relay/temp config. Continue?")) return; + + await fetch("/config/factory-reset",{method:"POST"}); + alert("Factory reset requested. Reconnect to the controller AP if needed."); } function renderConfigControls(data){