ski battery charge u sell
Some checks failed
CI and deploy / migration-check (push) Failing after 26s
CI and deploy / deploy (push) Has been skipped

This commit is contained in:
Dusan Vojacek
2026-05-28 23:22:57 +02:00
parent 4e5de5df90
commit 52e4b68789
8 changed files with 23 additions and 16 deletions

View File

@@ -98,10 +98,11 @@ async def write_inverter_setpoints(
export_limit = export_lim
reg178_val = REG178_SELL if deye_mode == "SELL" else REG178_PASSIVE
charge_a_log = charge_a if charge_a is not None else "skip"
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"charge_a={charge_a_log} discharge_a={discharge_a} | "
f"reg142={selling_mode} reg145={solar_sell} reg143={export_limit}W reg178={reg178_val}"
)
@@ -164,10 +165,13 @@ async def write_inverter_setpoints(
"Deye TOU rows 3-6 skipped (already written today, signature unchanged)"
)
amp_regs: list[tuple[int, str, int]] = []
if charge_a is not None:
amp_regs.append((108, "", charge_a))
amp_regs.append((109, "", discharge_a))
registers.extend(
[
(108, "", charge_a),
(109, "", discharge_a),
amp_regs
+ [
(141, "energy_mode (0)", 0),
(142, "limit_control", selling_mode),
(143, "", export_limit),

View File

@@ -331,7 +331,7 @@ def deye_battery_charge_discharge_amps(
max_discharge_a: int,
export_mode: str | None = None,
export_ban: bool = False,
) -> tuple[int, int]:
) -> tuple[int | None, int]:
"""
Proud nabíjení / vybíjení (reg 108 / 109) pro zápis Deye.
@@ -339,14 +339,17 @@ def deye_battery_charge_discharge_amps(
nabíjení neplní, přebytek jde do sítě (142 = zero-export dle instalace, 145 = 1).
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`. **SELL**: 108 = 0, 109 = max.
**CHARGE** ze sítě: 108 z `battery_w`.
**SELL** (selling first, reg 142 = 0): vrací ``(None, max_discharge)`` — reg **108 se nezapisuje**
(export řídí 142/178; nulování 108 a obnova po návratu jsou zbytečné zápisy do paměti).
"""
if lock_battery:
return 0, 0
if deye_mode == "CHARGE":
return battery_watts_to_amps(bat_w, max_charge_a), 0
if deye_mode == "SELL":
return 0, int(max_discharge_a)
return None, int(max_discharge_a)
if self_sustain_local_use:
return int(max_charge_a), int(max_discharge_a)
if _is_passive_pv_surplus_export(

View File

@@ -83,7 +83,7 @@ class PassivePvSurplusChargeAmpsTests(unittest.TestCase):
self.assertGreater(ch, 0)
self.assertEqual(dis, 0)
def test_sell_unchanged(self) -> None:
def test_sell_skips_charge_amp_write(self) -> None:
ch, dis = deye_battery_charge_discharge_amps(
lock_battery=False,
deye_mode="SELL",
@@ -93,7 +93,7 @@ class PassivePvSurplusChargeAmpsTests(unittest.TestCase):
max_charge_a=100,
max_discharge_a=80,
)
self.assertEqual(ch, 0)
self.assertIsNone(ch)
self.assertEqual(dis, 80)