Show charging time to full in WebUI
This commit is contained in:
+3
-1
@@ -91,7 +91,9 @@ json { "source": "jbd_bms", "connected": true, "soc": 70, "voltage": 13.
|
|||||||
|
|
||||||
Additional fields may include:
|
Additional fields may include:
|
||||||
|
|
||||||
text cell_count cell_voltages cell_min_voltage cell_max_voltage cell_delta_mv runtime_hours ntc_count cells_valid
|
text cell_count cell_voltages cell_min_voltage cell_max_voltage cell_delta_mv runtime_hours ntc_count cells_valid
|
||||||
|
|
||||||
|
`runtime_hours` is discharge runtime from the ESP32 status payload. The WebUI derives charging time-to-full from `capacity_ah`, `remaining_ah`, and positive incoming `current` without changing the API shape.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ Shows:
|
|||||||
- Battery SOC
|
- Battery SOC
|
||||||
- Voltage
|
- Voltage
|
||||||
- Current
|
- Current
|
||||||
- Estimated runtime
|
- Estimated runtime / charging time-to-full
|
||||||
- Temperature sensors
|
- Temperature sensors
|
||||||
- Relay controls
|
- Relay controls
|
||||||
- Network status
|
- Network status
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ input{width:100%;border:1px solid var(--line);border-radius:12px;padding:12px;ba
|
|||||||
<div class="kpi">
|
<div class="kpi">
|
||||||
<div><div class="muted">Voltage</div><div class="num" id="voltage">--</div></div>
|
<div><div class="muted">Voltage</div><div class="num" id="voltage">--</div></div>
|
||||||
<div><div class="muted">Current</div><div class="num" id="current">--</div></div>
|
<div><div class="muted">Current</div><div class="num" id="current">--</div></div>
|
||||||
<div><div class="muted">Runtime</div><div class="num" id="runtime">--</div></div>
|
<div><div class="muted" id="runtimeLabel">Runtime</div><div class="num" id="runtime">--</div></div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
@@ -233,13 +233,28 @@ input{width:100%;border:1px solid var(--line);border-radius:12px;padding:12px;ba
|
|||||||
const $=id=>document.getElementById(id);
|
const $=id=>document.getElementById(id);
|
||||||
function fmt(n,d=1){return typeof n==="number"?n.toFixed(d):"--"}
|
function fmt(n,d=1){return typeof n==="number"?n.toFixed(d):"--"}
|
||||||
function temp(v){return typeof v==="number"?fmt(v,1)+"°F":"Offline"}
|
function temp(v){return typeof v==="number"?fmt(v,1)+"°F":"Offline"}
|
||||||
function runtimeText(b){
|
function batteryTimeInfo(b){
|
||||||
if(!b.connected) return "--";
|
if(!b.connected) return {label:"Runtime", value:"--"};
|
||||||
if(typeof b.runtime_hours==="number" && b.runtime_hours>0) return fmt(b.runtime_hours,1)+"h";
|
|
||||||
if(typeof b.current==="number" && b.current<-.1 && typeof b.remaining_ah==="number"){
|
const current = b.current;
|
||||||
return fmt(b.remaining_ah/Math.abs(b.current),1)+"h";
|
const remaining = b.remaining_ah;
|
||||||
|
const capacity = b.capacity_ah;
|
||||||
|
|
||||||
|
if(typeof current==="number" && current>.1 &&
|
||||||
|
typeof remaining==="number" && typeof capacity==="number" &&
|
||||||
|
capacity>remaining){
|
||||||
|
return {label:"Time to full", value:fmt((capacity-remaining)/current,1)+"h"};
|
||||||
}
|
}
|
||||||
return "Idle";
|
|
||||||
|
if(typeof b.runtime_hours==="number" && b.runtime_hours>0){
|
||||||
|
return {label:"Runtime", value:fmt(b.runtime_hours,1)+"h"};
|
||||||
|
}
|
||||||
|
|
||||||
|
if(typeof current==="number" && current<-.1 && typeof remaining==="number"){
|
||||||
|
return {label:"Runtime", value:fmt(remaining/Math.abs(current),1)+"h"};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {label:"Battery time", value:"Idle"};
|
||||||
}
|
}
|
||||||
function showTab(name){
|
function showTab(name){
|
||||||
["overview","battery","config"].forEach(t=>{
|
["overview","battery","config"].forEach(t=>{
|
||||||
@@ -269,7 +284,9 @@ function render(data){
|
|||||||
$("socbar").style.width=Math.max(0,Math.min(100,b.soc||0))+"%";
|
$("socbar").style.width=Math.max(0,Math.min(100,b.soc||0))+"%";
|
||||||
$("voltage").textContent=fmt(b.voltage,2)+" V";
|
$("voltage").textContent=fmt(b.voltage,2)+" V";
|
||||||
$("current").textContent=fmt(b.current,2)+" A";
|
$("current").textContent=fmt(b.current,2)+" A";
|
||||||
$("runtime").textContent=runtimeText(b);
|
const timeInfo=batteryTimeInfo(b);
|
||||||
|
$("runtimeLabel").textContent=timeInfo.label;
|
||||||
|
$("runtime").textContent=timeInfo.value;
|
||||||
$("bmsState").textContent=b.connected?"BMS Online":"BMS Offline";
|
$("bmsState").textContent=b.connected?"BMS Online":"BMS Offline";
|
||||||
$("bmsState").className=b.connected?"medium good":"medium bad";
|
$("bmsState").className=b.connected?"medium good":"medium bad";
|
||||||
$("battSource").textContent=b.source||"--";
|
$("battSource").textContent=b.source||"--";
|
||||||
|
|||||||
Reference in New Issue
Block a user