fix(control): reg 108 v PV_SURPLUS sleduje charge intent (BA81 nenabíjelo levné ráno)
deye_battery_charge_discharge_amps: v PASSIVE+PV_SURPLUS reg 108 = max když plán chce nabíjet (bat_w>0) místo tvrdé 0; baterka nabere co zvládne, přebytek nad nabíjecí rychlost do sítě. + kalibrace: SoC u maxima → dojet na 100% (BMS). Sell beze změny. Vědomě přepsán test starého chování. 365 passed. Všechny Deye lokality. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -17,6 +17,10 @@ from services.control.models import ControlSetpoints, InverterConfig, OperatingM
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
#: Tolerance pod max SoC, v rámci níž se v PV přebytku nechá baterka dojet na max
|
||||
#: (reg 108 = max) kvůli BMS rekalibraci SoC (LiFePO4 potřebuje občas na 100 %).
|
||||
BATTERY_CALIB_TOPOFF_MARGIN_PCT = 3.0
|
||||
|
||||
|
||||
def _deye_system_time_register_rows() -> tuple[datetime, list[tuple[int, str, int]]]:
|
||||
"""Hodnoty pro reg 62-64 (Europe/Prague); sekundy v reg 64 = 0 (stabilnější zápis)."""
|
||||
@@ -437,12 +441,20 @@ def deye_battery_charge_discharge_amps(
|
||||
max_discharge_a: int,
|
||||
export_mode: str | None = None,
|
||||
export_ban: bool = False,
|
||||
current_soc_pct: float | None = None,
|
||||
max_soc_pct: int | None = None,
|
||||
) -> tuple[int | None, int]:
|
||||
"""
|
||||
Proud nabíjení / vybíjení (reg 108 / 109) pro zápis Deye.
|
||||
|
||||
**PV_SURPLUS** (PASSIVE, export FVE): **108 = 0**, **109 = max** — baterie se přes limit
|
||||
nabíjení neplní, přebytek jde do sítě (142 = zero-export dle instalace, 145 = 1).
|
||||
**PV_SURPLUS** (PASSIVE, export FVE) — reg 108 SLEDUJE charge intent plánu (fix 2026-06-16):
|
||||
- `bat_w > 0` (plán chce nabíjet z přebytku) → **108 = max**: baterie nabere kolik fyzicky
|
||||
zvládne (nabíjecí rychlost), přebytek NAD ni jde do sítě (BA81: výroba 12 kW > rychlost
|
||||
6 kW → 6 do baterky, 6 ven). Dřív tvrdě 108=0 i při bat_w>0 → baterka nenabíjela ani
|
||||
levné ranní PV (control bug).
|
||||
- kalibrace: SoC u maxima (`>= max_soc − margin`) + přebytek → **108 = max**, ať dojede na
|
||||
100 % (BMS rekalibrace SoC). Strop drží Deye max_soc.
|
||||
- jen „prodej PV a drž baterku" daleko od maxima (`bat_w <= 0`) → **108 = 0**, přebytek ven.
|
||||
|
||||
PASSIVE + nabíjení bez exportního záměru (`battery_w > 0`, export_mode NONE): **108 = max**.
|
||||
**CHARGE** ze sítě: 108 z `battery_w`.
|
||||
@@ -464,6 +476,16 @@ def deye_battery_charge_discharge_amps(
|
||||
export_ban=export_ban,
|
||||
grid_w=grid_w,
|
||||
):
|
||||
# reg 108 sleduje charge intent: nabíjet z přebytku (bat_w>0) nebo dojet na max
|
||||
# kvůli BMS kalibraci (SoC u maxima + přebytek) → 108 = max; jinak 108 = 0 (přebytek
|
||||
# ven). Strop SoC drží Deye max_soc, takže 108=max nepřebije nad povolené.
|
||||
near_full_calib = (
|
||||
current_soc_pct is not None
|
||||
and max_soc_pct is not None
|
||||
and float(current_soc_pct) >= float(max_soc_pct) - BATTERY_CALIB_TOPOFF_MARGIN_PCT
|
||||
)
|
||||
if bat_w > 0 or near_full_calib:
|
||||
return int(max_charge_a), int(max_discharge_a)
|
||||
return 0, int(max_discharge_a)
|
||||
if bat_w > 0:
|
||||
return int(max_charge_a), int(max_discharge_a)
|
||||
|
||||
Reference in New Issue
Block a user