uprava PV omeznovani
Some checks failed
CI and deploy / migration-check (push) Failing after 13s
CI and deploy / deploy (push) Has been skipped

This commit is contained in:
Dusan Vojacek
2026-05-25 11:08:01 +02:00
parent f1a4dbd7e7
commit e06f76b9ff
8 changed files with 439 additions and 91 deletions

View File

@@ -66,6 +66,32 @@ class _DictRecord:
return k in self._d
def plan_skips_deye_reg340_write(
*,
battery_setpoint_w: int,
grid_setpoint_w: int,
export_mode: str | None,
export_limit_w: int,
pv_a_curtailed_w: int,
) -> bool:
"""
Nezapisovat reg 340: plán neexportuje, nenabíjí baterii a neškrtí pole A.
Deye sám řídí PV A přes 108/109/142 (zero export + 0 A nabíjení).
"""
em = (export_mode or "").strip().upper()
if em == "NONE":
no_export = True
elif int(grid_setpoint_w) < 0 or int(export_limit_w) > 0:
no_export = False
else:
no_export = True
return (
no_export
and int(battery_setpoint_w) <= 0
and int(pv_a_curtailed_w) <= 0
)
def _build_setpoints(
mode: OperatingModeInfo,
pi: Any | None,
@@ -102,11 +128,11 @@ def _build_setpoints(
export_ban = sell_f is not None and float(sell_f) < 0 and grid_sp >= 0
gen_cutoff_raw = pi.get("deye_gen_cutoff_enabled")
gen_cutoff = bool(gen_cutoff_raw) if gen_cutoff_raw is not None else False
bat_w = int(pi["battery_setpoint_w"] or 0)
pv_a_allowed: int | None = None
if bool(reg340_pv_a_control_enabled) and int(pv_a_cap_w) > 0:
forecast = int(pi.get("pv_a_forecast_solver_w") or 0)
curtail = int(pi.get("pv_a_curtailed_w") or 0)
pv_a_allowed = compute_pv_a_reg340_max_solar_w(int(pv_a_cap_w), forecast, curtail)
buy_raw = pi.get("effective_buy_price")
buy_f: float | None = float(buy_raw) if buy_raw is not None else None
pv_b = int(pi.get("pv_b_forecast_solver_w") or 0)
@@ -118,8 +144,20 @@ def _build_setpoints(
and pv_b > 0
):
pv_a_allowed = 0
elif plan_skips_deye_reg340_write(
battery_setpoint_w=bat_w,
grid_setpoint_w=grid_sp,
export_mode=export_mode,
export_limit_w=max(0, export_limit),
pv_a_curtailed_w=curtail,
):
pv_a_allowed = None
else:
pv_a_allowed = compute_pv_a_reg340_max_solar_w(
int(pv_a_cap_w), forecast, curtail
)
return ControlSetpoints(
battery_w=int(pi["battery_setpoint_w"] or 0),
battery_w=bat_w,
grid_export_limit=max(0, export_limit),
ev1_current_a=watts_to_amps(ev1_w, phases=3),
ev2_current_a=watts_to_amps(ev2_w, phases=1),