Enpal-Box (lokal) inkl. Wallbox in Homey integrieren
Ziel
Dieses Tutorial zeigt, wie man Daten direkt aus der lokalen Enpal-Box im Heimnetzwerk mit HomeyScript ausliest und in Homey darstellt:
-
PV-Leistung
-
Netzbezug
-
Hausverbrauch
-
Batterie (Laden/Entladen + SoC)
-
Wallbox-Leistung
Die Werte werden über Logik-Variablen verarbeitet und anschließend virtuellen Geräten zugewiesen.
Voraussetzungen
-
Homey (Pro empfohlen)
-
App HomeyScript
-
Enpal-Box im gleichen lokalen Netzwerk wie Homey
-
Zugriff auf die lokale Enpal-Weboberfläche (z. B.
http://192.168.x.x)
Schritt 1: Benötigte Logik-Variablen anlegen
In Homey: Mehr → Logik → Variablen → Neue Variable
Lege folgende Variablen exakt mit diesen Namen an (Typ: Zahl, Startwert: 0):
-
PV_Power -
Grid_Power -
House_Power -
Battery_Charge_Power -
Battery_Discharge_Power -
Battery_SOC -
Wallbox_Power
Schritt 2: IDs der Variablen auslesen
const variables = await Homey.logic.getVariables();
for (const v of Object.values(variables)) {
console.log(v.name, '→', v.id);
}
Notiere alle IDs, diese werden im Hauptscript benötigt.
Schritt 3: Lokale Enpal-Box prüfen
Öffne im Browser die lokale Enpal-Box:
http://192.168.x.x
oder
http://192.168.x.x/deviceMessages
Homey muss im gleichen Netzwerk sein.
Schritt 4: Haupt-HomeyScript einfügen
Lege in HomeyScript ein neues Script an und füge folgendes Script ein. Passe nur die IP und Variablen-IDs an.
function parseValue(val) {
if (!val) return null;
return parseFloat(val.replace(/[^\d.-]/g, ''));
}
function getSensorValue(html, sensorName) {
const regex = new RegExp(`<tr>\\s*<td>\\s*${sensorName}\\s*</td>\\s*<td>(.*?)</td>`, 'i');
const match = html.match(regex);
if (!match) {
console.warn(`⚠️ Sensor "${sensorName}" nicht gefunden`);
return null;
}
return parseValue(match[1]);
}
async function smoothVariablePeak(varId, newValue, historySize = 5, peakThreshold = 0.3) {
const variable = await Homey.logic.getVariable({ id: varId });
if (!variable.history) variable.history = [];
const lastValue = variable.history.length ? variable.history[variable.history.length - 1] : newValue;
if (variable.history.length && Math.abs(newValue - lastValue)/Math.max(lastValue,1) > peakThreshold) {
newValue = lastValue + Math.sign(newValue - lastValue) * lastValue * peakThreshold;
}
variable.history.push(newValue);
if (variable.history.length > historySize) variable.history.shift();
const avg = variable.history.reduce((a,b)=>a+b,0)/variable.history.length;
variable.value = avg;
await Homey.logic.updateVariable({ id: varId, variable });
return avg;
}
const ENPAL_URL = "http://192.168.x.x/deviceMessages"; // ← ANPASSEN!
const VAR_GRID_POWER = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX";
const VAR_PV_POWER = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX";
const VAR_BATTERY_CHARGE_POWER = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX";
const VAR_BATTERY_DISCHARGE_POWER = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX";
const VAR_BATTERY_SOC = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX";
const VAR_WALLBOX_POWER = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX";
const VAR_HOUSE_POWER = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX";
try {
const response = await fetch(ENPAL_URL);
const html = await response.text();
let gridPower = getSensorValue(html, "Power.Grid.Export");
if(gridPower !== null) gridPower = -gridPower;
const gridAvg = await smoothVariablePeak(VAR_GRID_POWER, gridPower || 0);
const pvPower = getSensorValue(html, "Power.DC.Total") || 0;
const pvAvg = await smoothVariablePeak(VAR_PV_POWER, pvPower);
const batteryPower = getSensorValue(html, "Power.Battery.Charge.Discharge") || 0;
const batteryChargeAvg = await smoothVariablePeak(VAR_BATTERY_CHARGE_POWER, batteryPower);
const batteryDischargeAvg = await smoothVariablePeak(VAR_BATTERY_DISCHARGE_POWER, batteryPower);
const batterySoc = getSensorValue(html, "Energy.Battery.Charge.Level.Absolute") || 0;
const batterySocAvg = await smoothVariablePeak(VAR_BATTERY_SOC, batterySoc);
const wallboxPower = getSensorValue(html, "Power.Wallbox.Connector.1.Charging") || 0;
const wallboxAvg = await smoothVariablePeak(VAR_WALLBOX_POWER, wallboxPower);
const housePower = pvPower + (gridPower||0) - batteryDischargeAvg + batteryChargeAvg + wallboxPower;
const houseAvg = await smoothVariablePeak(VAR_HOUSE_POWER, housePower);
return {
grid: Math.round(gridAvg),
pv: Math.round(pvAvg),
batteryCharge: Math.round(batteryChargeAvg),
batteryDischarge: Math.round(batteryDischargeAvg),
batterySoc: Math.round(batterySocAvg),
wallbox: Math.round(wallboxAvg),
house: Math.round(houseAvg)
};
} catch(err) {
console.error("❌ Fehler beim Auslesen der Enpal-Box:", err);
return null;
}
Schritt 5: Script testen
-
Script manuell ausführen
-
Log prüfen auf Fehler und sinnvolle Werte
Schritt 6: Virtuelle Geräte anlegen
-
PV-Anlage, Batterie, Wallbox, Netz, Hausverbrauch
-
Mit den entsprechenden Variablen verknüpfen (
measure_power)
Schritt 7: Homey Energy (optional)
-
PV → Erzeuger
-
Batterie → Speicher
-
Wallbox → Großverbraucher
-
Netz → Netzanschluss
Ergebnis
-
Direkte Nutzung der lokalen Enpal-Box
-
PV, Batterie & Wallbox live in Homey
-
Stabil, schnell und erweiterbar
Hinweise & Troubleshooting
-
Zeigt alles 0 → IP prüfen, Netzwerk prüfen
-
Fehler im Log → Variablen-IDs prüfen
-
Sensor nicht gefunden → Enpal-Firmware kann abweichen