+
Warte auf erste Messung...
@@ -330,11 +349,110 @@ function showToast(msg, type) {
}
function switchTab(name) {
- ["live","inverters","settings"].forEach((t, i) => {
+ ["energy","live","inverters","settings"].forEach((t, i) => {
document.querySelectorAll(".tab")[i].classList.toggle("active", t === name);
document.querySelectorAll(".panel")[i].classList.toggle("active", t === name);
});
- if (name === "live") startRefresh(); else stopRefresh();
+ if (name === "energy" || name === "live") startRefresh(); else stopRefresh();
+}
+
+// ── Energy Dashboard ──────────────────────────────────────────
+
+function renderEnergy(inverters, aggregates) {
+ const el = document.getElementById("energy-content");
+ if (!aggregates || !Object.keys(aggregates).length) {
+ el.innerHTML = '
Warte auf erste Messung…
';
+ return;
+ }
+
+ const pvW = aggregates.total_pv_power || 0;
+ const gridW = aggregates.grid_power || 0; // + = Bezug, - = Einspeisung
+ const batChW = aggregates.bat_charge_power || 0;
+ const batDchW = aggregates.bat_discharge_power|| 0;
+ const batSoc = aggregates.bat_soc;
+
+ let evW = 0;
+ Object.entries(inverters).forEach(([id, inv]) => {
+ const cfg = invertersList.find(c => c.id === id);
+ if (cfg && cfg.inverter_model === 'KATHREIN_WALLBOX')
+ evW += (inv.values && inv.values.total_power) || 0;
+ });
+
+ const gridImport = Math.max(0, gridW);
+ const gridExport = Math.max(0, -gridW);
+ const houseW = Math.max(0, pvW + gridImport + batDchW - batChW - evW);
+
+ function fW(w) {
+ if (Math.abs(w) < 1) return '0 W';
+ if (Math.abs(w) >= 1000) return (w/1000).toFixed(2) + ' kW';
+ return Math.round(w) + ' W';
+ }
+
+ function node(cx, cy, icon, label, value, col, extra) {
+ return `
+
+ ${icon}
+ ${fW(value)}
+ ${label}
+ ${extra||''}
+ `;
+ }
+
+ const C = { acc:'var(--accent)', red:'var(--red)', grn:'var(--green)', pur:'var(--purple)', blu:'var(--blue)', dim:'var(--text-dim)', brd:'var(--border)' };
+
+ // Flow line helpers
+ function fline(x1,y1,x2,y2, col, cls) {
+ return `
`;
+ }
+
+ const hasBat = batSoc !== undefined && batSoc !== null;
+
+ const svg = `
`;
+
+ function kwhCard(icon, label, val, col) {
+ if (val === undefined || val === null) return '';
+ const d = val >= 100 ? val.toFixed(0) : val >= 10 ? val.toFixed(1) : val.toFixed(2);
+ return `
+
${d}
+
${icon} ${label}
+
`;
+ }
+
+ const cards = [
+ kwhCard('☀️','PV Heute kWh', aggregates.total_energy_today, C.acc),
+ kwhCard('📥','Bezug kWh', aggregates.grid_import_kwh, C.red),
+ kwhCard('📤','Einspeisung kWh', aggregates.grid_export_kwh, C.grn),
+ kwhCard('⚡','Bat. Laden kWh', aggregates.bat_charge_total, C.pur),
+ kwhCard('🔋','Bat. Entl. kWh', aggregates.bat_discharge_total, C.pur),
+ ].filter(Boolean).join('');
+
+ el.innerHTML = `
+
${svg}
+ ${cards ? `
${cards}
` : ''}
+
`;
}
// ── Live Data ─────────────────────────────────────────────────
@@ -348,6 +466,7 @@ async function refreshData() {
document.getElementById("subtitle").textContent =
keys.length ? `${keys.length} Gerät${keys.length !== 1 ? "e" : ""}` : "Keine Geräte";
renderLive(d.inverters || {}, d.aggregates || {});
+ renderEnergy(d.inverters || {}, d.aggregates || {});
} catch(e) {
document.getElementById("pill-mqtt").className = "pill err";
}