Skip to content

Commit badb6a9

Browse files
committed
feat: add support for S5-GR3P(3-20)K
1 parent 3af66c8 commit badb6a9

File tree

9 files changed

+80
-31
lines changed

9 files changed

+80
-31
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ All Solis hybrid inverters should be supported, although the integration has bee
2222
The integration also supports the following Solis string inverters:
2323

2424
* S6-GR1P(2.5-6)K, model "0200"
25+
* S5-GR3P(3-20)K, model "0507"
2526

2627
> [!NOTE]
2728
> If your inverter is not listed here, please open an issue on GitHub using "New Solis Inverter Support Request" template.

custom_components/solis_cloud_control/inverters/inverter.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,24 @@
11
from dataclasses import dataclass, field
22

3+
from custom_components.solis_cloud_control.utils.safe_converters import safe_convert_power_to_watts
4+
35

46
@dataclass
57
class InverterInfo:
68
serial_number: str
79
model: str
810
version: str
911
machine: str
10-
power: float | None
12+
type: str
13+
smart_support: str
14+
generator_support: str
15+
battery_num: str
16+
power: str
17+
power_unit: str
18+
19+
@property
20+
def power_watts(self) -> float | None:
21+
return safe_convert_power_to_watts(self.power, self.power_unit)
1122

1223

1324
@dataclass

custom_components/solis_cloud_control/inverters/inverter_factory.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33

44
from custom_components.solis_cloud_control.api.solis_api import SolisCloudControlApiClient
55
from custom_components.solis_cloud_control.inverters.inverter import Inverter, InverterInfo
6-
from custom_components.solis_cloud_control.utils.safe_converters import safe_convert_power_to_watts
76

87
_LOGGER = logging.getLogger(__name__)
98

@@ -14,14 +13,24 @@ async def create_inverter_info(api_client: SolisCloudControlApiClient, inverter_
1413
model = str(inverter_details.get("model", "Unknown"))
1514
version = str(inverter_details.get("version", "Unknown"))
1615
machine = str(inverter_details.get("machine", "Unknown"))
17-
power = safe_convert_power_to_watts(inverter_details.get("power"), inverter_details.get("powerStr"))
16+
type = str(inverter_details.get("inverterType", "Unknown"))
17+
smart_support = str(inverter_details.get("smartSupport", "Unknown"))
18+
generator_support = str(inverter_details.get("generatorSupport", "Unknown"))
19+
battery_num = str(inverter_details.get("batteryNum", "Unknown"))
20+
power = str(inverter_details.get("power", "Unknown"))
21+
power_unit = str(inverter_details.get("powerStr", "Unknown"))
1822

1923
return InverterInfo(
2024
serial_number=inverter_sn,
2125
model=model,
2226
version=version,
2327
machine=machine,
28+
type=type,
29+
smart_support=smart_support,
30+
generator_support=generator_support,
31+
battery_num=battery_num,
2432
power=power,
33+
power_unit=power_unit,
2534
)
2635

2736

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
from custom_components.solis_cloud_control.api.solis_api import SolisCloudControlApiClient
2+
from custom_components.solis_cloud_control.inverters.inverter import Inverter, InverterInfo
3+
4+
5+
# S5-GR3P(3-20)K
6+
async def create_inverter(
7+
inverter_info: InverterInfo,
8+
api_client: SolisCloudControlApiClient, # noqa: ARG001
9+
) -> Inverter:
10+
return Inverter.create_string_inverter(inverter_info)

custom_components/solis_cloud_control/inverters/model_3331.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ async def create_inverter(
99
) -> Inverter:
1010
inverter = Inverter.create_hybrid_inverter(inverter_info)
1111

12-
power = inverter_info.power if inverter_info.power is not None else 15_000
12+
power = inverter_info.power_watts if inverter_info.power_watts is not None else 15_000
1313
inverter.max_export_power = InverterMaxExportPower(max_value=power, step=100, scale=0.01)
1414

1515
return inverter

custom_components/solis_cloud_control/inverters/model_ca.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ async def create_inverter(
99
) -> Inverter:
1010
inverter = Inverter.create_hybrid_inverter(inverter_info)
1111

12-
power = inverter_info.power if inverter_info.power is not None else 10_000
12+
power = inverter_info.power_watts if inverter_info.power_watts is not None else 10_000
1313
inverter.max_export_power = InverterMaxExportPower(max_value=power)
1414

1515
return inverter

tests/conftest.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,12 @@ def any_inverter_info():
7777
model="any_model",
7878
machine="any_machine",
7979
version="any_version",
80-
power=None,
80+
type="any_type",
81+
smart_support="any_smart_support",
82+
generator_support="any_generator_support",
83+
battery_num="any_battery_num",
84+
power="any_power",
85+
power_unit="any_power_unit",
8186
)
8287

8388

tests/inverters/test_inverter.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import pytest
2+
3+
4+
@pytest.mark.asyncio
5+
@pytest.mark.parametrize(
6+
"power, power_unit, expected_power",
7+
[
8+
("5", "kW", 5000.0),
9+
("5000", "W", 5000.0),
10+
("5.5", "kW", 5500.0),
11+
("5500.5", "W", 5500.5),
12+
("invalid", "kW", None),
13+
("5", "invalid", None),
14+
("5", None, None),
15+
(None, "kW", None),
16+
],
17+
)
18+
async def test_inverter_info_power_watts(mock_api_client, any_inverter_info, power, power_unit, expected_power):
19+
any_inverter_info.power = power
20+
any_inverter_info.power_unit = power_unit
21+
22+
assert any_inverter_info.power_watts == expected_power

tests/inverters/test_inverter_factory.py

Lines changed: 16 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ async def test_create_inverter_info(mock_api_client):
1515
"model": "any model",
1616
"version": "any version",
1717
"machine": "any machine",
18+
"inverterType": "any type",
19+
"smartSupport": "any smart support",
20+
"generatorSupport": "any generator support",
21+
"batteryNum": "any battery num",
1822
"power": 10,
1923
"powerStr": "kW",
2024
}
@@ -26,30 +30,12 @@ async def test_create_inverter_info(mock_api_client):
2630
assert result.model == "any model"
2731
assert result.version == "any version"
2832
assert result.machine == "any machine"
29-
assert result.power == 10_000
30-
31-
32-
@pytest.mark.asyncio
33-
@pytest.mark.parametrize(
34-
"power_details, expected_power",
35-
[
36-
({"power": "5", "powerStr": "kW"}, 5000.0),
37-
({"power": "5000", "powerStr": "W"}, 5000.0),
38-
({"power": "5.5", "powerStr": "kW"}, 5500.0),
39-
({"power": "5500.5", "powerStr": "W"}, 5500.5),
40-
({"power": "invalid", "powerStr": "kW"}, None),
41-
({"power": "5", "powerStr": "invalid"}, None),
42-
({"power": "5"}, None),
43-
({"powerStr": "kW"}, None),
44-
],
45-
)
46-
async def test_create_inverter_info_power(mock_api_client, power_details, expected_power):
47-
mock_api_client.inverter_details.return_value = power_details
48-
49-
inverter_sn = "any serial number"
50-
result = await create_inverter_info(mock_api_client, inverter_sn)
51-
52-
assert result.power == expected_power
33+
assert result.type == "any type"
34+
assert result.smart_support == "any smart support"
35+
assert result.generator_support == "any generator support"
36+
assert result.battery_num == "any battery num"
37+
assert result.power == "10"
38+
assert result.power_unit == "kW"
5339

5440

5541
@pytest.mark.asyncio
@@ -63,7 +49,12 @@ async def test_create_inverter_info_missing_fields(mock_api_client):
6349
assert result.model == "Unknown"
6450
assert result.version == "Unknown"
6551
assert result.machine == "Unknown"
66-
assert result.power is None
52+
assert result.type == "Unknown"
53+
assert result.smart_support == "Unknown"
54+
assert result.generator_support == "Unknown"
55+
assert result.battery_num == "Unknown"
56+
assert result.power == "Unknown"
57+
assert result.power_unit == "Unknown"
6758

6859

6960
@pytest.mark.asyncio

0 commit comments

Comments
 (0)