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)