diff --git a/Energy_Pie/module.html b/Energy_Pie/module.html
index 085085d..fd5c82e 100644
--- a/Energy_Pie/module.html
+++ b/Energy_Pie/module.html
@@ -15,21 +15,16 @@
-
+
-
+
-
@@ -39,30 +34,27 @@
const elPrev = document.getElementById('prev');
const elToday = document.getElementById('today');
const elNext = document.getElementById('next');
- const elLegend = document.getElementById('legend');
+ const elValues = document.getElementById('values');
const elPeriod = document.getElementById('period');
- const canvas = document.getElementById('pie');
- const ctx = canvas.getContext('2d');
-
+ // Range ändern -> sofort rechnen
elRange.addEventListener('change', () => requestAction('SetRange', elRange.value));
- // Fire immediately when user picks a date (input + change), with a tiny debounce
+ // Datum ändern -> sofort rechnen (input + change, mit kleinem debounce)
let dateTimer = null;
function pushDateNow() {
if (dateTimer) clearTimeout(dateTimer);
- dateTimer = setTimeout(() => {
- requestAction('SetDate', elDate.value);
- }, 80);
+ dateTimer = setTimeout(() => requestAction('SetDate', elDate.value), 80);
}
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));
- // Called by Symcon when PHP sends UpdateVisualizationValue($payload)
+ // Symcon pusht Daten hier rein (UpdateVisualizationValue -> handleMessage)
function handleMessage(data) {
if (!data) return;
@@ -72,6 +64,7 @@
const isTotal = (data.range === 'total');
elDate.disabled = isTotal;
+ // Zeitraum-Text
if (data.tStart && data.tEnd) {
const s = new Date(data.tStart * 1000);
const e = new Date(data.tEnd * 1000);
@@ -82,12 +75,30 @@
elPeriod.textContent = '';
}
+ // Werte-Box
if (data.values) {
- drawPie(data.values);
- drawLegend(data.values);
+ renderValues(data.values);
+ } else {
+ renderValues({});
}
}
+ // Nur diese vier Werte anzeigen (fixe Reihenfolge)
+ function renderValues(values) {
+ const order = ['Produktion', 'Einspeisung', 'Netz', 'Hausverbrauch'];
+
+ elValues.innerHTML = order.map((k) => {
+ const v = values?.[k];
+ const val = (+v || 0);
+ return `
+
+
${escapeHtml(k)}
+
${val.toFixed(2)} kWh
+
+ `;
+ }).join('');
+ }
+
function fmtDateTime(d) {
const yyyy = d.getFullYear();
const mm = String(d.getMonth() + 1).padStart(2,'0');
@@ -97,69 +108,6 @@
return `${dd}.${mm}.${yyyy} ${hh}:${mi}`;
}
- function drawLegend(values) {
- const entries = Object.entries(values);
- const sum = entries.reduce((a,[,v]) => a + (+v || 0), 0);
-
- elLegend.innerHTML = entries.map(([k,v]) => {
- const val = (+v || 0);
- const pct = sum > 0 ? (val / sum * 100) : 0;
- return `
-
-
${escapeHtml(k)}
-
${val.toFixed(2)} kWh (${pct.toFixed(1)}%)
-
`;
- }).join('');
- }
-
- function drawPie(values) {
- const entries = Object.entries(values).map(([k,v]) => [k, (+v || 0)]);
- const sum = entries.reduce((a,[,v]) => a + v, 0);
-
- ctx.clearRect(0,0,canvas.width,canvas.height);
-
- // Background circle
- ctx.beginPath();
- ctx.arc(140,140,125,0,Math.PI*2);
- ctx.fillStyle = '#f2f2f2';
- ctx.fill();
-
- if (sum <= 0) {
- ctx.fillStyle = '#666';
- ctx.font = '14px sans-serif';
- ctx.fillText('Keine Daten', 92, 145);
- return;
- }
-
- let start = -Math.PI / 2;
- const colors = ['#4e79a7','#f28e2b','#e15759','#76b7b2','#59a14f','#edc948'];
-
- entries.forEach(([label,val], i) => {
- if (val <= 0) return;
- const ang = (val / sum) * Math.PI * 2;
- ctx.beginPath();
- ctx.moveTo(140,140);
- ctx.arc(140,140,125,start,start+ang);
- ctx.closePath();
- ctx.fillStyle = colors[i % colors.length];
- ctx.fill();
- start += ang;
- });
-
- // Donut hole
- ctx.beginPath();
- ctx.arc(140,140,65,0,Math.PI*2);
- ctx.fillStyle = '#fff';
- ctx.fill();
-
- // Sum in center
- ctx.fillStyle = '#111';
- ctx.font = 'bold 16px sans-serif';
- const text = sum.toFixed(2) + ' kWh';
- const w = ctx.measureText(text).width;
- ctx.fillText(text, 140 - w/2, 146);
- }
-
function escapeHtml(s) {
return String(s)
.replaceAll('&','&')
@@ -168,4 +116,7 @@
.replaceAll('"','"')
.replaceAll("'",''');
}
+
+ // Beim Laden direkt einmal Werte anfordern, damit sofort etwas angezeigt wird
+ setTimeout(() => requestAction('Refresh', 1), 200);
diff --git a/Energy_Pie/module.php b/Energy_Pie/module.php
index 0ac8c13..45de3cf 100644
--- a/Energy_Pie/module.php
+++ b/Energy_Pie/module.php
@@ -93,42 +93,41 @@ class Energy_Pie extends IPSModule
/**
* Compute values (later from archive), then push to tile via UpdateVisualizationValue.
*/
- private function RecalculateAndPush(): void
- {
- $range = $this->ReadAttributeString(self::ATTR_RANGE);
- $date = $this->ReadAttributeString(self::ATTR_DATE);
+private function RecalculateAndPush(): void
+{
+ $range = $this->ReadAttributeString(self::ATTR_RANGE);
+ $date = $this->ReadAttributeString(self::ATTR_DATE);
- [$tStart, $tEnd] = $this->getRange($range, $date);
+ [$tStart, $tEnd] = $this->getRange($range, $date);
- // --- PLACEHOLDER CALCULATION ---
- // Replace these with your later delta calculation from logged data:
- // $prod = $this->readDelta($this->ReadPropertyInteger('VarProduction'), $tStart, $tEnd);
- // etc.
- $prod = 12.3;
- $cons = 8.7;
- $feed = 3.1;
- $grid = 5.6;
-
- // If you prefer, you can already set them to 0.0 for "no calc yet"
- // $prod = $cons = $feed = $grid = 0.0;
-
- $payload = [
- 'range' => $range,
- 'date' => $date,
- 'tStart' => $tStart,
- 'tEnd' => $tEnd,
- 'values' => [
- 'Produktion' => (float)$prod,
- 'Verbrauch' => (float)$cons,
- 'Einspeisung' => (float)$feed,
- 'Netz' => (float)$grid
- ]
- ];
-
- $this->UpdateVisualizationValue(json_encode($payload, JSON_THROW_ON_ERROR));
+ // Archiv-Deltas
+ $prod = $this->readDelta($this->ReadPropertyInteger('VarProduction'), $tStart, $tEnd);
+ $feed = $this->readDelta($this->ReadPropertyInteger('VarFeedIn'), $tStart, $tEnd);
+ $grid = $this->readDelta($this->ReadPropertyInteger('VarGrid'), $tStart, $tEnd);
+ // Hausverbrauch = Produktion - Einspeisung + Netz
+ $house = $prod - $feed + $grid;
+ if ($house < 0) {
+ $house = 0.0;
}
+ $payload = [
+ 'range' => $range,
+ 'date' => $date,
+ 'tStart' => $tStart,
+ 'tEnd' => $tEnd,
+ 'values' => [
+ 'Produktion' => (float)$prod,
+ 'Einspeisung' => (float)$feed,
+ 'Netz' => (float)$grid,
+ 'Hausverbrauch'=> (float)$house
+ ]
+ ];
+
+ $this->UpdateVisualizationValue(json_encode($payload, JSON_THROW_ON_ERROR));
+}
+
+
/**
* Range rules:
* - day: chosen date 00:00:00 .. next day 00:00:00