prekopani SELL
This commit is contained in:
@@ -32,6 +32,9 @@ DEYE_CLOCK_RESYNC_INTERVAL_HOURS = 24
|
||||
# Deye LV baterie: převod výkon → proud pro registry 108/109 (viz docs/04-modules/modbus-registers.md)
|
||||
BATT_VOLTAGE_V = 51.2
|
||||
|
||||
# Reg 143 ve SELL: strop exportu = min(site max, |grid_setpoint|), dolní podlahová konstanta kvůli nule.
|
||||
REG143_SELL_CAP_MIN_W = 200
|
||||
|
||||
# Reg 178 – pevné hodnoty (bit4–5); bez read-modify-write (kolize s Loxone / transaction ID)
|
||||
REG178_SELL = 0b00100000 # 32, grid peak shaving disable
|
||||
REG178_PASSIVE = 0b00110000 # 48, grid peak shaving enable (PASSIVE i CHARGE)
|
||||
@@ -1374,18 +1377,30 @@ def get_deye_mode(setpoints: ControlSetpoints) -> str:
|
||||
"""
|
||||
Fyzický režim Deye: SELL | CHARGE | PASSIVE.
|
||||
|
||||
SELL only when battery actively discharges for grid export (bat_w < -500
|
||||
AND grid_w < -200). Pass-through (PV → grid, battery idle) stays PASSIVE
|
||||
with reg 108 = 0 + reg 145 = 1 (solar sell).
|
||||
battery_w=None (SELF_SUSTAIN) → bat_w considered 0 → PASSIVE; při exportu se ale
|
||||
zapíše plný reg. 108/109 (viz ``self_sustain_local_use`` v ``write_inverter_setpoints``).
|
||||
Pravidlo držet jednoduché (viz ``docs/04-modules/operating-modes.md``):
|
||||
|
||||
- **SELL** — jen když plán explicitně počítá s **vybíjením baterie do sítě** ve smyslu:
|
||||
záporný export z portu sítě a zároveň **|battery_w| ≥ |grid_setpoint_w|** (výdej z
|
||||
baterie není menší než plánovaný čistý export). Pak Deye „selling first“ (reg. 142=0).
|
||||
|
||||
- **PASSIVE** — všude jinde: přetok FVE do sítě / do baterie řeší reg. **108** (nabíjení),
|
||||
**109** (vybíjení, škálované podle plánu), **142** dle ``deye_zero_export_mode`` instalace,
|
||||
**145** solar sell. Žádné odhady PV vs. load v této funkci.
|
||||
|
||||
- **CHARGE** — nabíjení ze sítě (``battery_w`` > 500 a ``grid_setpoint_w`` > 200).
|
||||
|
||||
``battery_w=None`` (SELF_SUSTAIN) → bat_w 0 → PASSIVE zde; plné 108/109 řeší
|
||||
``self_sustain_local_use`` v ``write_inverter_setpoints``.
|
||||
"""
|
||||
grid_w = int(setpoints.grid_setpoint_w or 0)
|
||||
bat_w = 0 if setpoints.battery_w is None else int(setpoints.battery_w)
|
||||
if bat_w < -500 and grid_w < -200:
|
||||
return "SELL"
|
||||
|
||||
if bat_w > 500 and grid_w > 200:
|
||||
return "CHARGE"
|
||||
|
||||
if grid_w < 0 and bat_w < 0 and abs(bat_w) >= abs(grid_w):
|
||||
return "SELL"
|
||||
|
||||
return "PASSIVE"
|
||||
|
||||
|
||||
@@ -1451,26 +1466,40 @@ async def write_inverter_setpoints(
|
||||
elif deye_mode == "CHARGE":
|
||||
charge_a = battery_watts_to_amps(bat_w, inv.max_charge_a)
|
||||
discharge_a = 0
|
||||
elif deye_mode == "SELL":
|
||||
# Záměrný výdej baterie do sítě: plný vybíjecí proud; export strop dle plánu níže.
|
||||
charge_a = 0
|
||||
discharge_a = int(inv.max_discharge_a)
|
||||
elif setpoints_now.self_sustain_local_use:
|
||||
# SELF_SUSTAIN: plný nabíjecí i vybíjecí proud invertoru — přebytek FVE jde do baterie,
|
||||
# reg. 142 = zero export to load/CT (viz selling_mode níže), ne reg. 108 = 0.
|
||||
charge_a = int(inv.max_charge_a)
|
||||
discharge_a = int(inv.max_discharge_a)
|
||||
else:
|
||||
charge_a = int(inv.max_charge_a) if bat_w > 0 else 0
|
||||
discharge_a = int(inv.max_discharge_a)
|
||||
# PASSIVE: škáluj 108/109 podle |battery_w| — ne plný max při malém setpointu z LP.
|
||||
if bat_w > 0:
|
||||
charge_a = battery_watts_to_amps(bat_w, inv.max_charge_a)
|
||||
discharge_a = 0
|
||||
elif bat_w < 0:
|
||||
charge_a = 0
|
||||
discharge_a = battery_watts_to_amps(bat_w, inv.max_discharge_a)
|
||||
else:
|
||||
charge_a = 0
|
||||
discharge_a = 0
|
||||
|
||||
zero_exp_mode = int(inv.deye_zero_export_mode or 1)
|
||||
selling_mode = 0 if deye_mode == "SELL" else zero_exp_mode
|
||||
solar_sell = 1
|
||||
export_limit = export_lim
|
||||
if deye_mode == "SELL" and grid_w < -200:
|
||||
export_limit = min(export_lim, max(REG143_SELL_CAP_MIN_W, abs(grid_w)))
|
||||
reg178_val = REG178_SELL if deye_mode == "SELL" else REG178_PASSIVE
|
||||
|
||||
logger.info(
|
||||
f"[control] site={site_id} fyzický režim Deye: {deye_mode} | "
|
||||
f"battery_w={raw_bat!r} grid_w={grid_w} | "
|
||||
f"charge_a={charge_a} discharge_a={discharge_a} | "
|
||||
f"reg142={selling_mode} reg145={solar_sell} reg178={reg178_val}"
|
||||
f"reg142={selling_mode} reg145={solar_sell} reg143={export_limit}W reg178={reg178_val}"
|
||||
)
|
||||
|
||||
now_cet, time_rows = _deye_system_time_register_rows()
|
||||
|
||||
Reference in New Issue
Block a user