Skip to content

Commit 9f5c7cf

Browse files
rnaubermartijnvdmolenRichard Nauber
authored
Add support for X1 Boost (FW Version 3) (continued) (#160)
* Add support for X1 Boost (FW Version 3) * Update x1_boost.py: relax the requirements on the type field to support v3 * fix order of imports * support x1_boost_g4 * linting * add entrypoint * linting * Remove inverter temperature as it is not exposed in the x1_boost_g4_v3 --------- Co-authored-by: martijnvdmolen <mkvdmolen@gmail.com> Co-authored-by: Richard Nauber <richard@nauber.dev>
1 parent aced347 commit 9f5c7cf

File tree

7 files changed

+354
-3
lines changed

7 files changed

+354
-3
lines changed

setup.py

+1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
"qvolt_hyb_g3_3p = solax.inverters.qvolt_hyb_g3_3p:QVOLTHYBG33P",
3535
"x1 = solax.inverters.x1:X1",
3636
"x1_boost = solax.inverters.x1_boost:X1Boost",
37+
"x1_boost_g4 = solax.inverters.x1_boost_g4:X1BoostG4",
3738
"x1_hybrid_gen4 = solax.inverters.x1_hybrid_gen4:X1HybridGen4",
3839
"x1_mini = solax.inverters.x1_mini:X1Mini",
3940
"x1_mini_v34 = solax.inverters.x1_mini_v34:X1MiniV34",

solax/inverters/__init__.py

+2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from .qvolt_hyb_g3_3p import QVOLTHYBG33P
22
from .x1 import X1
33
from .x1_boost import X1Boost
4+
from .x1_boost_g4 import X1BoostG4
45
from .x1_hybrid_gen4 import X1HybridGen4
56
from .x1_mini import X1Mini
67
from .x1_mini_v34 import X1MiniV34
@@ -24,6 +25,7 @@
2425
"X3HybridG4",
2526
"X3",
2627
"X1Boost",
28+
"X1BoostG4",
2729
"X1HybridGen4",
2830
"X3MicProG2",
2931
"X3Ultra",

solax/inverters/x1_boost.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,10 @@ class X1Boost(Inverter):
2424
vol.Required("data"): vol.Schema(
2525
vol.All(
2626
[vol.Coerce(float)],
27-
vol.Length(min=200, max=200),
27+
vol.Any(
28+
vol.Length(min=100, max=100),
29+
vol.Length(min=200, max=200),
30+
),
2831
)
2932
),
3033
vol.Required("information"): vol.Schema(

solax/inverters/x1_boost_g4.py

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
from typing import Any, Dict, Optional
2+
3+
import voluptuous as vol
4+
5+
from solax.inverter import Inverter
6+
from solax.units import DailyTotal, Total, Units
7+
from solax.utils import div10, div100, pack_u16, to_signed
8+
9+
10+
class X1BoostG4(Inverter):
11+
"""
12+
X1-Boost gen 4 with Pocket WiFi 3.009.03
13+
Includes X-Forwarded-For for direct LAN API access
14+
"""
15+
16+
# pylint: disable=duplicate-code
17+
_schema = vol.Schema(
18+
{
19+
vol.Required("type", "type"): vol.All(int, 18),
20+
vol.Required(
21+
"sn",
22+
): str,
23+
vol.Required("ver"): str,
24+
vol.Required("data"): vol.Schema(
25+
vol.All([vol.Coerce(float)], vol.Length(min=100, max=100))
26+
),
27+
vol.Required("information"): vol.Schema(
28+
vol.All(vol.Length(min=10, max=10))
29+
),
30+
},
31+
extra=vol.REMOVE_EXTRA,
32+
)
33+
34+
@classmethod
35+
def response_decoder(cls):
36+
return {
37+
"AC Voltage": (0, Units.V, div10),
38+
"AC Output Current": (1, Units.A, div10),
39+
"AC Output Power": (3, Units.W),
40+
"PV1 Voltage": (4, Units.V, div10),
41+
"PV2 Voltage": (5, Units.V, div10),
42+
"PV1 Current": (8, Units.A, div10),
43+
"PV2 Current": (9, Units.A, div10),
44+
"PV1 Power": (13, Units.W),
45+
"PV2 Power": (14, Units.W),
46+
"AC Frequency": (2, Units.HZ, div100),
47+
"Total Generated Energy": (pack_u16(19, 20), Total(Units.KWH), div10),
48+
"Today's Generated Energy": (21, DailyTotal(Units.KWH), div10),
49+
"Exported Power": (pack_u16(72, 73), Units.W, to_signed),
50+
"Total Export Energy": (pack_u16(74, 75), Total(Units.KWH), div100),
51+
"Total Import Energy": (pack_u16(76, 77), Total(Units.KWH), div100),
52+
}
53+
54+
@classmethod
55+
def inverter_serial_number_getter(cls, response: Dict[str, Any]) -> Optional[str]:
56+
return response["information"][2]
57+
58+
@classmethod
59+
def build_all_variants(cls, host, port, pwd=""):
60+
versions = [
61+
cls._build(host, port, pwd, True),
62+
cls._build(host, port, pwd, False),
63+
]
64+
for inverter in versions:
65+
inverter.http_client = inverter.http_client.with_headers(
66+
{"X-Forwarded-For": "5.8.8.8"}
67+
)
68+
return versions

tests/fixtures.py

+24
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77
from tests.samples.expected_values import (
88
QVOLTHYBG33P_VALUES,
99
X1_BOOST_VALUES,
10+
X1_BOOST_VALUES_G4_V3,
1011
X1_BOOST_VALUES_OVERFLOWN,
12+
X1_BOOST_VALUES_V3,
1113
X1_HYBRID_G4_VALUES,
1214
X1_MINI_VALUES,
1315
X1_MINI_VALUES_V34,
@@ -29,7 +31,9 @@
2931
QVOLTHYBG33P_RESPONSE_V34,
3032
X1_BOOST_AIR_MINI_RESPONSE,
3133
X1_BOOST_RESPONSE,
34+
X1_BOOST_RESPONSE_G4_V3,
3235
X1_BOOST_RESPONSE_OVERFLOWN,
36+
X1_BOOST_RESPONSE_V3,
3337
X1_HYBRID_G3_2X_MPPT_RESPONSE,
3438
X1_HYBRID_G3_RESPONSE,
3539
X1_HYBRID_G4_RESPONSE,
@@ -137,6 +141,26 @@ def simple_http_fixture(httpserver):
137141
headers=X_FORWARDED_HEADER,
138142
data=None,
139143
),
144+
InverterUnderTest(
145+
uri="/",
146+
method="POST",
147+
query_string="optType=ReadRealTimeData",
148+
response=X1_BOOST_RESPONSE_V3,
149+
inverter=inverter.X1Boost,
150+
values=X1_BOOST_VALUES_V3,
151+
headers=X_FORWARDED_HEADER,
152+
data=None,
153+
),
154+
InverterUnderTest(
155+
uri="/",
156+
method="POST",
157+
query_string="optType=ReadRealTimeData",
158+
response=X1_BOOST_RESPONSE_G4_V3,
159+
inverter=inverter.X1BoostG4,
160+
values=X1_BOOST_VALUES_G4_V3,
161+
headers=X_FORWARDED_HEADER,
162+
data=None,
163+
),
140164
InverterUnderTest(
141165
uri="/",
142166
method="POST",

tests/samples/expected_values.py

+37-2
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
"Grid Imported Energy": 42,
2828
}
2929

30-
3130
X3_VALUES = {
3231
"PV1 Current": 0,
3332
"PV2 Current": 1,
@@ -410,7 +409,6 @@
410409
"Inverter Temperature": 41,
411410
}
412411

413-
414412
X1_MINI_VALUES_V34_VER3 = {
415413
"Network Voltage": 234.8,
416414
"Output Current": 0.7,
@@ -468,6 +466,25 @@
468466
"Total Import Energy": 81.84,
469467
}
470468

469+
X1_BOOST_VALUES_V3 = {
470+
"AC Voltage": 228.1,
471+
"AC Output Current": 3.1,
472+
"AC Output Power": 703.0,
473+
"PV1 Voltage": 120.7,
474+
"PV2 Voltage": 125.4,
475+
"PV1 Current": 2.9,
476+
"PV2 Current": 2.9,
477+
"PV1 Power": 356.0,
478+
"PV2 Power": 365.0,
479+
"AC Frequency": 50.02,
480+
"Total Generated Energy": 2029.3,
481+
"Today's Generated Energy": 5.0,
482+
"Inverter Temperature": 30.0,
483+
"Exported Power": 0.0,
484+
"Total Export Energy": 0.0,
485+
"Total Import Energy": 0.0,
486+
}
487+
471488
X1_BOOST_VALUES_OVERFLOWN = {
472489
"AC Voltage": 237.4,
473490
"AC Output Current": 6.7,
@@ -487,6 +504,24 @@
487504
"Total Import Energy": 1850.05,
488505
}
489506

507+
X1_BOOST_VALUES_G4_V3 = {
508+
"AC Voltage": 239.7,
509+
"AC Output Current": 0.9,
510+
"AC Output Power": 128.0,
511+
"PV1 Voltage": 164.5,
512+
"PV2 Voltage": 0.0,
513+
"PV1 Current": 0.8,
514+
"PV2 Current": 0.0,
515+
"PV1 Power": 138.0,
516+
"PV2 Power": 0.0,
517+
"AC Frequency": 50.02,
518+
"Total Generated Energy": 7.8,
519+
"Today's Generated Energy": 6.8,
520+
"Exported Power": 0.0,
521+
"Total Export Energy": 0.0,
522+
"Total Import Energy": 0.0,
523+
}
524+
490525
QVOLTHYBG33P_VALUES = {
491526
"Network Voltage Phase 1": 221.4,
492527
"Network Voltage Phase 2": 223.8,

0 commit comments

Comments
 (0)