From ff428145f4585e3b43a88040acf5976fd10418e1 Mon Sep 17 00:00:00 2001 From: retr0 <42kdesigners@gmail.com> Date: Tue, 28 Apr 2026 13:22:57 +0200 Subject: [PATCH] =?UTF-8?q?Fix:=20EMS=20Ladestrom=20=3D=20PV-=C3=9Cberschu?= =?UTF-8?q?ss=20+=20aktuelle=20Wallbox-Leistung?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- haos-addon/src/ems_controller.py | 21 ++++++++++++++------- haos-addon/src/main.py | 3 ++- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/haos-addon/src/ems_controller.py b/haos-addon/src/ems_controller.py index d692d53..a578081 100644 --- a/haos-addon/src/ems_controller.py +++ b/haos-addon/src/ems_controller.py @@ -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: diff --git a/haos-addon/src/main.py b/haos-addon/src/main.py index c3225e1..3319049 100644 --- a/haos-addon/src/main.py +++ b/haos-addon/src/main.py @@ -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)