diff --git a/Energy_Pie/module.html b/Energy_Pie/module.html index 4cf68e9..57233b6 100644 --- a/Energy_Pie/module.html +++ b/Energy_Pie/module.html @@ -6,7 +6,7 @@ Zeitraum @@ -18,14 +18,14 @@ - +
- +
@@ -42,10 +42,9 @@ const elHint = document.getElementById('hint'); const elGrid = document.getElementById('grid'); - // sofort bei Range-Änderung + // Trigger sofort bei Änderung elRange.addEventListener('change', () => requestAction('SetRange', elRange.value)); - // Datum sofort (mit kleinem debounce) let dateTimer = null; function pushDateNow() { if (dateTimer) clearTimeout(dateTimer); @@ -54,7 +53,6 @@ elDate.addEventListener('input', pushDateNow); elDate.addEventListener('change', pushDateNow); - // Navigation elPrev.addEventListener('click', () => requestAction('Prev', 1)); elToday.addEventListener('click', () => requestAction('Today', 1)); elNext.addEventListener('click', () => requestAction('Next', 1)); @@ -82,46 +80,48 @@ return Number.isFinite(n) ? n : 0; } - function formatKwh(v) { - return `${v.toFixed(2)} kWh`; + function clamp01(x) { + if (!Number.isFinite(x)) return 0; + if (x < 0) return 0; + if (x > 1) return 1; + return x; } - // Donut card (SVG) - function donutCard({ label, value, share, color }) { - // share: 0..1 + function donutCard({ title, percent, subtitle, color }) { + // percent: 0..100 + const share = clamp01(percent / 100); + const r = 56; const c = 2 * Math.PI * r; - const dash = Math.max(0, Math.min(1, share)) * c; + const dash = share * c; const gap = c - dash; return `
-
- + display:flex;align-items:center;justify-content:center;min-height:210px;"> +
+ - - - - + transform="rotate(-90 85 85)" />
-
- ${escapeHtml(value.toFixed(2))} kWh +
+ ${escapeHtml(percent.toFixed(1))}%
-
- ${escapeHtml(label)} +
+ ${escapeHtml(title)}
-
- ${(share*100).toFixed(1)}% +
+ ${escapeHtml(subtitle)}
@@ -130,33 +130,38 @@ } function render(values, meta) { - const prod = toNum(values?.Produktion); - const feed = toNum(values?.Einspeisung); - const grid = toNum(values?.Netz); - const house = toNum(values?.Hausverbrauch); + const prod = toNum(values?.Produktion); + const cons = toNum(values?.Hausverbrauch); // Verbrauch + const grid = toNum(values?.Netz); // Netzbezug - const order = [ - { key: 'Produktion', val: prod, color: '#63B3FF' }, // blau - { key: 'Konsum', val: house, color: '#A855F7' }, // lila (wie Screenshot) - { key: 'Einspeisung', val: feed, color: '#F59E0B' }, // orange - { key: 'Netz', val: grid, color: '#34D399' } // grün - ]; + const eigen = cons - grid; // Eigenverbrauch + const eigenClamped = eigen < 0 ? 0 : eigen; - const sum = order.reduce((a, x) => a + x.val, 0); + const evq = (prod > 0) ? (eigenClamped / prod * 100) : 0; + const autark = (cons > 0) ? (eigenClamped / cons * 100) : 0; - // Hinweis + // Hinweise if (meta?.hasData === false) { elHint.textContent = 'Keine Logdaten für den gewählten Zeitraum.'; } else { - elHint.textContent = sum > 0 ? `Summe (zur Prozent-Berechnung): ${formatKwh(sum)}` : 'Summe: 0.00 kWh'; + elHint.textContent = + `Produktion: ${prod.toFixed(2)} kWh · Verbrauch: ${cons.toFixed(2)} kWh · Netzbezug: ${grid.toFixed(2)} kWh · Eigenverbrauch: ${eigenClamped.toFixed(2)} kWh`; } - elGrid.innerHTML = order.map(x => donutCard({ - label: x.key, - value: x.val, - share: sum > 0 ? (x.val / sum) : 0, - color: x.color - })).join(''); + elGrid.innerHTML = [ + donutCard({ + title: 'EVQ', + percent: clamp01(evq / 100) * 100, + subtitle: 'Eigenverbrauch / Produktion', + color: '#63B3FF' // blau + }), + donutCard({ + title: 'Autarkiegrad', + percent: clamp01(autark / 100) * 100, + subtitle: 'Eigenverbrauch / Verbrauch', + color: '#A855F7' // lila + }) + ].join(''); } // Symcon -> Tile @@ -186,7 +191,6 @@ elPeriod.textContent = ''; } - // Charts render(data.values || {}, { hasData: data.hasData }); };