Enpal-Box (lokal) inkl. Wallbox in Homey integrieren

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