Fix: grid_power Aggregat korrekt für Multi-Wechselrichter-Anlagen

- AGG_FIRST: grid_power wird nicht summiert sondern erste Messung genommen
  (Goodwe CT-Klemme misst bereits Gesamt-Netzleistung inkl. Growatt)
- Growatt-Proxy: grid_power = -power_to_grid wenn kein Grid-Meter vorhanden
  (Growatt-only: Einspeisung korrekt, Netzbezug nicht messbar)
- Goodwe + Growatt: Goodwe-Wert hat Vorrang durch Gerätereihenfolge

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
retr0
2026-04-28 13:28:24 +02:00
parent 5765f54ebd
commit cc4777b22f
+16 -5
View File
@@ -46,7 +46,10 @@ AGG_SENSOR_IDS: Dict[str, List[str]] = {
"bat_discharge_total": ["bat_discharge_total", "e_bat_discharge_total"], "bat_discharge_total": ["bat_discharge_total", "e_bat_discharge_total"],
"bat_soc": ["bat_soc", "battery_soc"], "bat_soc": ["bat_soc", "battery_soc"],
} }
AGG_AVG = {"bat_soc"} AGG_AVG = {"bat_soc"}
# Einzelmessungen am Netzanschlusspunkt — nicht über Geräte summieren,
# sondern den besten Wert nehmen (Goodwe CT-Klemme hat Vorrang vor Proxy)
AGG_FIRST = {"grid_power"}
AGGREGATE_META: Dict[str, Dict[str, str]] = { AGGREGATE_META: Dict[str, Dict[str, str]] = {
"total_pv_power": {"name": "PV Gesamtleistung", "unit": "W", "device_class": "power", "state_class": "measurement", "icon": "mdi:solar-power"}, "total_pv_power": {"name": "PV Gesamtleistung", "unit": "W", "device_class": "power", "state_class": "measurement", "icon": "mdi:solar-power"},
@@ -136,10 +139,13 @@ def _compute_aggregates() -> Dict[str, float]:
result: Dict[str, float] = {} result: Dict[str, float] = {}
for agg_id, vals in buckets.items(): for agg_id, vals in buckets.items():
if vals: if vals:
result[agg_id] = round( if agg_id in AGG_AVG:
sum(vals) / len(vals) if agg_id in AGG_AVG else sum(vals), v = sum(vals) / len(vals)
3, elif agg_id in AGG_FIRST:
) v = vals[0] # ersten (besten) Wert nehmen, nicht summieren
else:
v = sum(vals)
result[agg_id] = round(v, 3)
return result return result
# ── EMS Hilfsfunktionen ─────────────────────────────────────── # ── EMS Hilfsfunktionen ───────────────────────────────────────
@@ -223,6 +229,11 @@ def _poll_loop(inv_cfg: Dict[str, Any], stop: threading.Event):
t0 = time.time() t0 = time.time()
values = reader.read(inverter) values = reader.read(inverter)
# Growatt-Proxy: grid_power (positiv=Netzbezug) aus power_to_grid ableiten
# wenn kein dedizierter Grid-Meter vorhanden (Goodwe setzt grid_power direkt)
if values and "grid_power" not in values and "power_to_grid" in values:
values["grid_power"] = -values["power_to_grid"]
# EMS: PV-Überschuss aus anderen Geräten holen und Ladestrom regeln # EMS: PV-Überschuss aus anderen Geräten holen und Ladestrom regeln
if ems is not None and values is not None: if ems is not None and values is not None:
pv_surplus = _get_pv_surplus() pv_surplus = _get_pv_surplus()