Skip to content

Commit d61c8cc

Browse files
authored
Merge pull request #2202 from rosenrot00/fix/sofar-parallel-feedin-limit
Adjust Sofar feed-in power limit for parallel systems
2 parents c87a3fa + 72f5def commit d61c8cc

2 files changed

Lines changed: 68 additions & 1 deletion

File tree

custom_components/solax_modbus/plugin_sofar.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import asyncio
22
import logging
3-
from dataclasses import dataclass, field
3+
from dataclasses import dataclass, field, replace
44
from datetime import datetime
55
from typing import Any
66

@@ -4367,6 +4367,22 @@ def getSoftwareVersion(self, new_data: dict[str, Any]) -> str | None:
43674367
def getHardwareVersion(self, new_data: dict[str, Any]) -> str | None:
43684368
return new_data.get("hardware_version", None)
43694369

4370+
def localDataCallback(self, hub: Any) -> bool:
4371+
parallel_setting = hub.data.get("parallel_masterslave", "Slave")
4372+
if parallel_setting == "Master":
4373+
system_limit_w = hub.inverterPowerKw * 1000
4374+
number_entity = hub.numberEntities.get("feedin_max_power")
4375+
if number_entity:
4376+
number_entity._attr_native_min_value = 0
4377+
number_entity._attr_native_max_value = system_limit_w
4378+
number_entity.entity_description = replace(
4379+
number_entity.entity_description,
4380+
native_min_value=0,
4381+
native_max_value=system_limit_w,
4382+
)
4383+
_LOGGER.info(f"Parallel Master: Set feedin_max_power limit to 0-{system_limit_w}W (inverter_power_kw={hub.inverterPowerKw}kW)")
4384+
return True
4385+
43704386

43714387
plugin_instance = sofar_plugin(
43724388
plugin_name="Sofar",
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
from dataclasses import dataclass
2+
from types import SimpleNamespace
3+
from typing import Any
4+
5+
from custom_components.solax_modbus.plugin_sofar import plugin_instance
6+
7+
8+
@dataclass
9+
class MockEntityDescription:
10+
native_min_value: int
11+
native_max_value: int
12+
13+
14+
class MockNumberEntity:
15+
def __init__(self) -> None:
16+
self._attr_native_min_value = 0
17+
self._attr_native_max_value = 20000
18+
self.entity_description = MockEntityDescription(
19+
native_min_value=0,
20+
native_max_value=20000,
21+
)
22+
23+
24+
def make_hub(parallel_setting: str, inverter_power_kw: int) -> Any:
25+
return SimpleNamespace(
26+
data={"parallel_masterslave": parallel_setting},
27+
inverterPowerKw=inverter_power_kw,
28+
numberEntities={"feedin_max_power": MockNumberEntity()},
29+
)
30+
31+
32+
def test_parallel_master_uses_total_system_power_for_feedin_limit() -> None:
33+
hub = make_hub("Master", 40)
34+
35+
assert plugin_instance.localDataCallback(hub) is True
36+
37+
entity = hub.numberEntities["feedin_max_power"]
38+
assert entity._attr_native_min_value == 0
39+
assert entity._attr_native_max_value == 40000
40+
assert entity.entity_description.native_min_value == 0
41+
assert entity.entity_description.native_max_value == 40000
42+
43+
44+
def test_single_or_slave_inverter_keeps_existing_feedin_limit() -> None:
45+
hub = make_hub("Slave", 100)
46+
47+
assert plugin_instance.localDataCallback(hub) is True
48+
49+
entity = hub.numberEntities["feedin_max_power"]
50+
assert entity._attr_native_max_value == 20000
51+
assert entity.entity_description.native_max_value == 20000

0 commit comments

Comments
 (0)