diff --git a/.changeset/remove-home-use-timing-note.md b/.changeset/remove-home-use-timing-note.md new file mode 100644 index 000000000..a78cd39a7 --- /dev/null +++ b/.changeset/remove-home-use-timing-note.md @@ -0,0 +1,5 @@ +--- +"ftw": patch +--- + +Remove the timing note under the Overview energy flow. Home use still shows current power, and the diagram still marks missing or paused data. diff --git a/web/app.js b/web/app.js index 5220659b2..e0be5262e 100644 --- a/web/app.js +++ b/web/app.js @@ -565,15 +565,6 @@ } var opts = energyFlowOpts(data); opts.live = lastFlowLive; lastFlowReadings = window.ftwFlowReadingsFromStatus(data, opts); - var homeNote = document.getElementById("home-use-estimate"); - if (!homeNote) { - homeNote = document.createElement("p"); - homeNote.id = "home-use-estimate"; - homeNote.className = "muted"; - flowEl.insertAdjacentElement("afterend", homeNote); - } - homeNote.textContent = lastFlowReadings.homeEstimateNote || ""; - homeNote.hidden = !homeNote.textContent; (lastFlowReadings.planets || []).forEach(function (p) { if (p.role !== "ev" || p.placeholder || !p.name) return; var lpEv = loadpointsByDriver && loadpointsByDriver[p.name]; diff --git a/web/components/energy-flow-readings.js b/web/components/energy-flow-readings.js index d32ad6092..0ccd48a8c 100644 --- a/web/components/energy-flow-readings.js +++ b/web/components/energy-flow-readings.js @@ -39,39 +39,6 @@ export function fmtKwhShort(kwh) { return kwh.toFixed(2); } -function usableHomeEstimate(estimate) { - const from = num(estimate?.from_ms), to = num(estimate?.to_ms); - const age = num(estimate?.end_age_ms); - return num(estimate?.watts) !== null && estimate.watts >= 0 && - from !== null && to !== null && from > 0 && to > from && to - from <= 300000 && - to < 8640000000000000 && age !== null && age >= 0 && age <= 180000; -} - -export function homeEstimateNote(estimate, live = true, powerBalanceW = null) { - if (!estimate) return ""; - if (!live) return "Home use estimate paused · no live data"; - const current = powerBalanceW === null ? "" : - `Estimated home use ${(powerBalanceW / 1000).toFixed(1)} kW · latest power readings; device delays may differ.`; - if (current && !usableHomeEstimate(estimate)) return current; - if (num(estimate.watts) === null) { - if (estimate.reason === "charger_source_time_unavailable") return "Home use estimate unavailable · charger source time unknown"; - const sourceAge = num(estimate.source_age_ms); - return "Home use estimate unavailable · waiting for source observations" + - (sourceAge > 0 ? ` · last source report ${Math.ceil(sourceAge / 1000)} s old` : ""); - } - if (!usableHomeEstimate(estimate)) { - return "Home use estimate unavailable · readings are too old"; - } - const from = new Date(estimate.from_ms), to = new Date(estimate.to_ms); - const options = {hour:"2-digit", minute:"2-digit", second:"2-digit", hourCycle:"h23", timeZoneName:"short"}; - if (from.toDateString() !== to.toDateString()) Object.assign(options, {year:"numeric", month:"short", day:"numeric"}); - const period = new Intl.DateTimeFormat("en-GB", options).formatRange(from, to); - const age = estimate.end_age_ms === 0 ? "ended now" : `ended ${Math.ceil(estimate.end_age_ms / 1000)} s ago`; - const basis = {counters:"energy counters", power_integral:"sampled power", mixed:"charger energy + sampled power"}[estimate.energy_basis] || "energy estimate"; - const timing = estimate.timing_basis === "source" ? "Device clocks may differ." : "Includes arrival times; device delay is unknown."; - return `${current || "Home use unavailable · no current power balance."} Energy mean ${(estimate.watts / 1000).toFixed(1)} kW · ${Math.round((estimate.to_ms - estimate.from_ms) / 1000)} s window · ${period} · ${age} · ${basis}. ${timing}`; -} - function planetColor(role, watts, thresholdW) { if (watts === undefined || watts === null) { if (role === "grid" || role === "pv") return "var(--fg-muted)"; @@ -259,7 +226,6 @@ export function flowReadingsFromStatus(status, opts) { return { load: loadW === null ? null : loadW / 1000, loadEstimated: hasEstimate, - homeEstimateNote: homeEstimateNote(status?.load_estimate, opts?.live !== false, powerBalanceW), planets: withControlMarks(planets, status?.control_feedback, opts?.live !== false), selfPoweredPctToday, }; diff --git a/web/energy-flow-readings.test.mjs b/web/energy-flow-readings.test.mjs index 1195be768..4af56e4c3 100644 --- a/web/energy-flow-readings.test.mjs +++ b/web/energy-flow-readings.test.mjs @@ -1,9 +1,9 @@ import assert from "node:assert/strict"; import { describe, it } from "node:test"; -import { flowReadingsFromStatus, fmtKwhShort, homeEstimateNote } from "./components/energy-flow-readings.js"; +import { flowReadingsFromStatus, fmtKwhShort } from "./components/energy-flow-readings.js"; -it("shows current household power and keeps the energy mean with its own period and age", () => { +it("shows current household power without a note about the past energy mean", () => { const estimate = {watts: 886, from_ms: Date.UTC(2026,9,18,10), to_ms: Date.UTC(2026,9,18,10,1), age_ms: 90000, end_age_ms:60000, energy_basis:'mixed', timing_basis: 'mixed'}; const status = {load_w: 1800, load_estimate: estimate, energy:{today:{load_wh:2000,import_wh:500,history_quality:'estimated'}}}; const result = flowReadingsFromStatus(status); @@ -11,18 +11,7 @@ it("shows current household power and keeps the energy mean with its own period assert.equal(result.loadEstimated, true); assert.equal(status.load_w, 1800); assert.equal(result.selfPoweredPctToday, null); - assert.match(result.homeEstimateNote, /Estimated home use 1.8 kW/); - assert.match(result.homeEstimateNote, /Energy mean 0.9 kW/); - assert.match(result.homeEstimateNote, /60 s window/); - assert.match(result.homeEstimateNote, /\d{2}:00:00.+\d{2}:01:00/); - assert.match(result.homeEstimateNote, /ended 60 s ago/); - assert.match(result.homeEstimateNote, /charger energy \+ sampled power/); - assert.match(result.homeEstimateNote, /Includes arrival times/); - assert.match(homeEstimateNote(estimate, false), /paused/); - assert.match(homeEstimateNote({...estimate, end_age_ms: 181000}), /too old/); - assert.match(homeEstimateNote({...estimate, from_ms:estimate.to_ms-300000,age_ms:210000}), /300 s window/); - assert.match(homeEstimateNote({watts:null,reason:'charger_source_time_unavailable'}), /source time unknown/); - assert.match(homeEstimateNote({watts: null}), /unavailable/); + assert.equal("homeEstimateNote" in result, false); assert.equal(flowReadingsFromStatus({...status,load_estimate:{watts:null}}).load, 1.8); assert.equal(flowReadingsFromStatus({...status,load_estimate:{...estimate,end_age_ms:181000}}).load, 1.8); assert.equal(flowReadingsFromStatus({...status,load_w:null}).load, null); @@ -32,13 +21,8 @@ it("never lets a past zero mean overwrite a positive current Load", () => { const status={load_w:1234,history_quality:"complete",load_estimate:{watts:0,from_ms:1000,to_ms:11000,end_age_ms:60000}}; const result=flowReadingsFromStatus(status); assert.equal(result.load,1.234); - assert.match(result.homeEstimateNote,/Estimated home use 1.2 kW/); - assert.match(result.homeEstimateNote,/Energy mean 0.0 kW/); - assert.match(result.homeEstimateNote,/ended 60 s ago/); const missing=flowReadingsFromStatus({...status,load_w:null,history_quality:"incomplete"}); assert.equal(missing.load,null); - assert.match(missing.homeEstimateNote,/no current power balance/); - assert.match(missing.homeEstimateNote,/Energy mean 0.0 kW/); }); it("keeps a qualified power balance visible while the energy interval is unavailable", () => { @@ -47,10 +31,6 @@ it("keeps a qualified power balance visible while the energy interval is unavail const result = flowReadingsFromStatus(status); assert.equal(result.load, 1.234); assert.equal(result.loadEstimated, true); - assert.match(result.homeEstimateNote, /latest power readings/); - assert.match(result.homeEstimateNote, /device delays may differ/); - assert.doesNotMatch(result.homeEstimateNote, /\d+ s mean|unavailable|ended now/); - assert.match(flowReadingsFromStatus(status,{live:false}).homeEstimateNote, /paused/); assert.equal(status.load_estimate.watts, null); } }); @@ -61,7 +41,6 @@ it("distinguishes a real zero balance from missing, invalid or stale inputs", () for (const value of [undefined, null, "0", NaN, Infinity, -1]) { const result = flowReadingsFromStatus({...base,load_w:value}); assert.equal(result.load,null); - assert.match(result.homeEstimateNote,/unavailable/); } });