Add relay and temperature configuration to web UI
This commit is contained in:
@@ -50,6 +50,10 @@ input{width:100%;border:1px solid var(--line);border-radius:12px;padding:12px;ba
|
|||||||
.list{display:grid;gap:8px;margin-top:12px}
|
.list{display:grid;gap:8px;margin-top:12px}
|
||||||
.item{display:flex;justify-content:space-between;gap:8px;background:#0f151d;border:1px solid var(--line);border-radius:12px;padding:10px}
|
.item{display:flex;justify-content:space-between;gap:8px;background:#0f151d;border:1px solid var(--line);border-radius:12px;padding:10px}
|
||||||
.btnrow{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-top:12px}
|
.btnrow{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-top:12px}
|
||||||
|
.configrow{display:grid;grid-template-columns:90px 1fr 90px;gap:8px;align-items:center;background:#0f151d;border:1px solid var(--line);border-radius:12px;padding:10px}
|
||||||
|
.configrow label{color:var(--muted);font-size:12px}
|
||||||
|
.configrow input[type="checkbox"]{width:auto}
|
||||||
|
.configrow input{margin:0}
|
||||||
.kpi{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin-top:12px}
|
.kpi{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin-top:12px}
|
||||||
.kpi div{background:#0f151d;border:1px solid var(--line);border-radius:12px;padding:10px}
|
.kpi div{background:#0f151d;border:1px solid var(--line);border-radius:12px;padding:10px}
|
||||||
.kpi .num{font-size:20px;font-weight:800;margin-top:4px}
|
.kpi .num{font-size:20px;font-weight:800;margin-top:4px}
|
||||||
@@ -148,6 +152,23 @@ input{width:100%;border:1px solid var(--line);border-radius:12px;padding:12px;ba
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<section class="card span12">
|
||||||
|
<div class="label">Relay Config</div>
|
||||||
|
<div class="sub">Rename relay outputs. IDs stay fixed for API/UART compatibility.</div>
|
||||||
|
<div class="list" id="relayConfigList"></div>
|
||||||
|
<button onclick="saveRelayConfig()">Save Relay Names</button>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="card span12">
|
||||||
|
<div class="label">Temperature Sensor Config</div>
|
||||||
|
<div class="sub">Set how many temp sensors are enabled and rename each slot.</div>
|
||||||
|
<div class="list">
|
||||||
|
<input id="tempEnabledCount" placeholder="Enabled sensor count, 0-8" inputmode="numeric">
|
||||||
|
<div id="tempConfigList" class="list"></div>
|
||||||
|
<button onclick="saveTempConfig()">Save Temperature Config</button>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
<section class="card span12">
|
<section class="card span12">
|
||||||
<div class="label">System</div>
|
<div class="label">System</div>
|
||||||
<div class="row"><span class="muted">Firmware</span><span class="v" id="fw">--</span></div>
|
<div class="row"><span class="muted">Firmware</span><span class="v" id="fw">--</span></div>
|
||||||
@@ -252,7 +273,100 @@ function render(data){
|
|||||||
$("apIp").textContent=n.ap_ip||"--";
|
$("apIp").textContent=n.ap_ip||"--";
|
||||||
$("fw").textContent=(s.firmware_name||"--")+" "+(s.firmware_version||"");
|
$("fw").textContent=(s.firmware_name||"--")+" "+(s.firmware_version||"");
|
||||||
$("uptime").textContent=(s.uptime_seconds||0)+" sec";
|
$("uptime").textContent=(s.uptime_seconds||0)+" sec";
|
||||||
|
renderConfigControls(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function renderConfigControls(data){
|
||||||
|
const cfg=data.config||{};
|
||||||
|
const relays=cfg.relays||[];
|
||||||
|
const temps=cfg.temperature_sensors||[];
|
||||||
|
|
||||||
|
const relayBox=$("relayConfigList");
|
||||||
|
if(relayBox){
|
||||||
|
relayBox.innerHTML=relays.map((r,i)=>`
|
||||||
|
<div class="configrow">
|
||||||
|
<label>${r.id}</label>
|
||||||
|
<input id="relayName${i}" value="${r.name||""}" placeholder="Relay name">
|
||||||
|
<label>${r.enabled?"Enabled":"Disabled"}</label>
|
||||||
|
</div>`).join("");
|
||||||
|
}
|
||||||
|
|
||||||
|
const tempCount=$("tempEnabledCount");
|
||||||
|
if(tempCount){
|
||||||
|
tempCount.value=temps.filter(t=>t.enabled).length;
|
||||||
|
}
|
||||||
|
|
||||||
|
const tempBox=$("tempConfigList");
|
||||||
|
if(tempBox){
|
||||||
|
tempBox.innerHTML=temps.map((t,i)=>`
|
||||||
|
<div class="configrow">
|
||||||
|
<label>${t.id}</label>
|
||||||
|
<input id="tempName${i}" value="${t.name||""}" placeholder="Temp name">
|
||||||
|
<label>
|
||||||
|
<input id="tempEnabled${i}" type="checkbox" ${t.enabled?"checked":""}>
|
||||||
|
On
|
||||||
|
</label>
|
||||||
|
</div>`).join("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function saveRelayConfig(){
|
||||||
|
const r=await fetch("/status",{cache:"no-store"});
|
||||||
|
const data=await r.json();
|
||||||
|
const relays=data.config?.relays||[];
|
||||||
|
|
||||||
|
for(let i=0;i<relays.length;i++){
|
||||||
|
const name=$("relayName"+i)?.value.trim();
|
||||||
|
if(!name) continue;
|
||||||
|
|
||||||
|
await fetch("/config/relay",{
|
||||||
|
method:"POST",
|
||||||
|
headers:{"Content-Type":"application/json"},
|
||||||
|
body:JSON.stringify({
|
||||||
|
id:relays[i].id,
|
||||||
|
name:name,
|
||||||
|
enabled:relays[i].enabled
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
await fetch("/config/save",{method:"POST"});
|
||||||
|
await load();
|
||||||
|
alert("Relay names saved");
|
||||||
|
}
|
||||||
|
|
||||||
|
async function saveTempConfig(){
|
||||||
|
const r=await fetch("/status",{cache:"no-store"});
|
||||||
|
const data=await r.json();
|
||||||
|
const temps=data.config?.temperature_sensors||[];
|
||||||
|
|
||||||
|
let count=parseInt($("tempEnabledCount")?.value||"0",10);
|
||||||
|
if(isNaN(count)) count=0;
|
||||||
|
if(count<0) count=0;
|
||||||
|
if(count>temps.length) count=temps.length;
|
||||||
|
|
||||||
|
for(let i=0;i<temps.length;i++){
|
||||||
|
const name=$("tempName"+i)?.value.trim() || temps[i].name || temps[i].id;
|
||||||
|
const manual=$("tempEnabled"+i)?.checked;
|
||||||
|
const enabled=(i<count) || manual;
|
||||||
|
|
||||||
|
await fetch("/config/temp",{
|
||||||
|
method:"POST",
|
||||||
|
headers:{"Content-Type":"application/json"},
|
||||||
|
body:JSON.stringify({
|
||||||
|
id:temps[i].id,
|
||||||
|
name:name,
|
||||||
|
address:temps[i].address||"",
|
||||||
|
enabled:enabled
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
await fetch("/config/save",{method:"POST"});
|
||||||
|
await load();
|
||||||
|
alert("Temperature config saved");
|
||||||
|
}
|
||||||
|
|
||||||
async function loadWifiConfig(){
|
async function loadWifiConfig(){
|
||||||
try{
|
try{
|
||||||
const r=await fetch("/config/wifi",{cache:"no-store"});
|
const r=await fetch("/config/wifi",{cache:"no-store"});
|
||||||
|
|||||||
Reference in New Issue
Block a user