Fix: EMS Ladestrom = PV-Überschuss + aktuelle Wallbox-Leistung

Goodwe misst Überschuss NACH Wallbox-Verbrauch. EMS muss deshalb
bestehende Ladeleistung (total_power) addieren um Gesamtbudget zu kennen:
  new_current = (surplus + wallbox_power) / (230V × phases)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
retr0
2026-04-28 13:22:57 +02:00
parent 20d935bd73
commit ff428145f4
2 changed files with 16 additions and 8 deletions
+14 -7
View File
@@ -58,16 +58,22 @@ class EmsController:
t += timedelta(days=1)
return t
def _surplus_to_ma(self, surplus_w: float) -> int:
"""PV-Überschuss in Watt → Ladestrom in mA (pro Phase)."""
current_a = surplus_w / (VOLTAGE_V * self.phases)
def _surplus_to_ma(self, surplus_w: float, wallbox_w: float = 0.0) -> int:
"""Gesamte verfügbare PV-Leistung → Ladestrom in mA (pro Phase).
surplus_w: noch ins Netz eingespeister Überschuss
wallbox_w: aktuell von der Wallbox gezogene Leistung
Summe = gesamt verfügbar für Laden."""
total_w = surplus_w + wallbox_w
current_a = total_w / (VOLTAGE_V * self.phases)
ma = int(current_a * 1000)
return max(6000, min(32000, ma))
def update(self, wallbox_reader, pv_surplus_w: float, charging_state: int) -> str:
def update(self, wallbox_reader, pv_surplus_w: float, charging_state: int,
wallbox_power_w: float = 0.0) -> str:
"""
Wird vom Poll-Loop aufgerufen.
pv_surplus_w: positiv = PV exportiert ins Netz (verfügbar für Laden)
pv_surplus_w: positiv = PV exportiert ins Netz (verbleibender Überschuss)
wallbox_power_w: aktuell von der Wallbox gezogene Leistung (aus Meter-Daten)
Gibt eine kurze Status-Beschreibung zurück.
"""
now = time.time()
@@ -98,9 +104,10 @@ class EmsController:
if has_pv:
self._no_pv_since = None
self._forced_charging = False
ma = self._surplus_to_ma(pv_surplus_w)
ma = self._surplus_to_ma(pv_surplus_w, wallbox_power_w)
total_w = pv_surplus_w + wallbox_power_w
wallbox_reader.set_current(ma, self.phases)
return f"PV-Laden {ma // 1000:.1f}A ({pv_surplus_w:.0f}W)"
return f"PV-Laden {ma / 1000:.1f}A ({total_w:.0f}W, Überschuss {pv_surplus_w:.0f}W)"
# Kein PV
if self._no_pv_since is None:
+2 -1
View File
@@ -228,7 +228,8 @@ def _poll_loop(inv_cfg: Dict[str, Any], stop: threading.Event):
# 0x0060 manchmal nicht lesbar → 1 (EV Connected) annehmen,
# damit EMS aktiviert; Wallbox ignoriert Befehle wenn kein Auto da
charging_state = int(values.get("charging_state", 1))
ems_status = ems.update(reader, pv_surplus, charging_state)
wallbox_power = values.get("total_power", 0.0)
ems_status = ems.update(reader, pv_surplus, charging_state, wallbox_power)
values["ems_status_code"] = float(charging_state)
log.info("[%s] EMS: %s | PV-Überschuss: %.0fW", inv_id, ems_status, pv_surplus)