Skip to content

Commit

Permalink
add support for X3 EVC Charger (#167)
Browse files Browse the repository at this point in the history
* add support for X3 EVC Charger

* fix code style

* fix code style

* fix code style

* fix isort

* fix flake8

* add test responses

* add test expected values

* add test fixture

* fix code style

* fix isort

* remove copy/paste error

* Update responses.py

* fix type as int

* Update expected_values.py

* fix expected values

---------

Co-authored-by: Daniel Weeber <[email protected]>
  • Loading branch information
DanielWeeber and dweebertwt authored Sep 13, 2024
1 parent fedda9d commit aced347
Show file tree
Hide file tree
Showing 6 changed files with 272 additions and 0 deletions.
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
"x3_mic_pro_g2 = solax.inverters.x3_mic_pro_g2:X3MicProG2",
"x3_v34 = solax.inverters.x3_v34:X3V34",
"x_hybrid = solax.inverters.x_hybrid:XHybrid",
"x3_evc = solax.inverters.x3_evc:X3EVC",
],
},
)
2 changes: 2 additions & 0 deletions solax/inverters/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from .x1_mini_v34 import X1MiniV34
from .x1_smart import X1Smart
from .x3 import X3
from .x3_evc import X3EVC
from .x3_hybrid_g4 import X3HybridG4
from .x3_mic_pro_g2 import X3MicProG2
from .x3_ultra import X3Ultra
Expand All @@ -26,4 +27,5 @@
"X1HybridGen4",
"X3MicProG2",
"X3Ultra",
"X3EVC",
]
109 changes: 109 additions & 0 deletions solax/inverters/x3_evc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
from typing import Any, Dict, Optional

import voluptuous as vol

from solax.inverter import Inverter
from solax.units import Total, Units
from solax.utils import (
div10,
div100,
pack_u16,
to_signed,
to_signed32,
twoway_div10,
twoway_div100,
)


class X3EVC(Inverter):
"""X3 EVC"""

# pylint: disable=duplicate-code
_schema = vol.Schema(
{
vol.Required("type"): vol.All(int, 1),
vol.Required("sn"): str,
vol.Required("ver"): str,
vol.Required("data"): vol.Schema(
vol.All(
[vol.Coerce(float)],
vol.Length(min=96, max=96),
)
),
vol.Required("information"): vol.Schema(
vol.All(vol.Length(min=10, max=10))
),
},
extra=vol.REMOVE_EXTRA,
)

@classmethod
def build_all_variants(cls, host, port, pwd=""):
return [cls._build(host, port, pwd, False)]

@classmethod
def _decode_device_state(cls, device_state):
return {
0: "Preparing",
1: "Preparing",
2: "Charging",
3: "Finishing",
4: "Faulted",
5: "Unavailable",
6: "Reserved",
7: "SuspendedEV",
8: "SuspendedEVSE",
}.get(device_state)

@classmethod
def _decode_device_mode(cls, device_mode):
return {
0: "STOP",
1: "FAST",
2: "ECO",
3: "GREEN",
}.get(device_mode)

@classmethod
def response_decoder(cls):
return {
"Device State": (0, Units.NONE, X3EVC._decode_device_state),
"Device Mode": (1, Units.NONE, X3EVC._decode_device_mode),
"EQ Single": (12, Total(Units.KWH), div10),
"EQ Total": (
pack_u16(14, 15),
Total(Units.KWH),
twoway_div10,
), # not sure if correct
"Total Charger Power": (11, Units.W),
"Voltage A": (2, Units.V, div100),
"Voltage B": (3, Units.V, div100),
"Voltage C": (4, Units.V, div100),
"Current A": (5, Units.A, div100),
"Current B": (6, Units.A, div100),
"Current C": (7, Units.A, div100),
"Charger Power A": (8, Units.W),
"Charger Power B": (9, Units.W),
"Charger Power C": (10, Units.W),
"Extern Current A": (16, Units.W, twoway_div100),
"Extern Current B": (17, Units.W, twoway_div100),
"Extern Current C": (18, Units.W, twoway_div100),
"Extern Power A": (19, Units.W, to_signed),
"Extern Power B": (20, Units.W, to_signed),
"Extern Power C": (21, Units.W, to_signed),
"Extern Total Power": (22, Units.W, to_signed),
"Temperature Plug": (23, Units.C),
"Temperature PCB": (24, Units.C),
"CP State": (26, Units.NONE),
"Charging Duration": (pack_u16(80, 81), Units.NONE, to_signed32),
"OCPP Offline Mode": (85, Units.NONE),
"Type Power": (87, Units.NONE),
"Type Phase": (88, Units.NONE),
"Type Charger": (89, Units.NONE),
}

# pylint: enable=duplicate-code

@classmethod
def inverter_serial_number_getter(cls, response: Dict[str, Any]) -> Optional[str]:
return response["information"][2]
12 changes: 12 additions & 0 deletions tests/fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
X1_MINI_VALUES_V34_VER3,
X1_SMART_VALUES,
X1_VALUES,
X3_EVC_VALUES,
X3_HYBRID_G4_VALUES,
X3_HYBRID_VALUES,
X3_MICPRO_G2_VALUES,
Expand All @@ -35,6 +36,7 @@
X1_MINI_RESPONSE_V34,
X1_MINI_RESPONSE_V34_VER3,
X1_SMART_RESPONSE,
X3_EVC_RESPONSE,
X3_HYBRID_G3_2X_MPPT_RESPONSE,
X3_HYBRID_G3_2X_MPPT_RESPONSE_V34,
X3_HYBRID_G3_2X_MPPT_RESPONSE_V34_EPS_MODE,
Expand Down Expand Up @@ -235,6 +237,16 @@ def simple_http_fixture(httpserver):
headers=None,
data="optType=ReadRealTimeData",
),
InverterUnderTest(
uri="/",
method="POST",
query_string=None,
response=X3_EVC_RESPONSE,
inverter=inverter.X3EVC,
values=X3_EVC_VALUES,
headers=None,
data="optType=ReadRealTimeData",
),
InverterUnderTest(
uri="/",
method="POST",
Expand Down
32 changes: 32 additions & 0 deletions tests/samples/expected_values.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,38 @@
"EPS Frequency": 0,
}

X3_EVC_VALUES = {
"Device State": "Preparing",
"Device Mode": "FAST",
"EQ Single": 1.2,
"EQ Total": 91751.8,
"Total Charger Power": 11,
"Voltage A": 0.02,
"Voltage B": 0.03,
"Voltage C": 0.04,
"Current A": 0.05,
"Current B": 0.06,
"Current C": 0.07,
"Charger Power A": 8,
"Charger Power B": 9,
"Charger Power C": 10,
"Extern Current A": 0.16,
"Extern Current B": 0.17,
"Extern Current C": 0.18,
"Extern Power A": 19,
"Extern Power B": 20,
"Extern Power C": 21,
"Extern Total Power": 22,
"Temperature Plug": 23,
"Temperature PCB": 24,
"CP State": 26,
"Charging Duration": 5308496.0,
"OCPP Offline Mode": 85,
"Type Power": 87,
"Type Phase": 88,
"Type Charger": 89,
}

X3V34_HYBRID_VALUES = {
"Network Voltage Phase 1": 246.8,
"Network Voltage Phase 2": 249,
Expand Down
116 changes: 116 additions & 0 deletions tests/samples/responses.py
Original file line number Diff line number Diff line change
Expand Up @@ -1753,6 +1753,122 @@
],
}

X3_EVC_RESPONSE = {
"type": 1,
"SN": "SQXXXXXXXX",
"ver": "3.007.05",
"Data": [
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
31,
32,
33,
34,
35,
36,
37,
38,
39,
40,
41,
42,
43,
44,
45,
46,
47,
48,
49,
50,
51,
52,
53,
54,
55,
56,
57,
58,
59,
60,
61,
62,
63,
64,
65,
66,
67,
68,
69,
70,
71,
72,
73,
74,
75,
76,
77,
78,
79,
80,
81,
82,
83,
84,
85,
86,
87,
88,
89,
90,
91,
92,
93,
94,
95,
],
"Information": [
11.000,
1,
"C311XXXXXXXXXX",
1,
1.08,
1.01,
0.00,
0.00,
0.00,
1,
],
}

X3_HYBRID_G3_RESPONSE = {
"type": "X3-Hybiyd-G3",
"SN": "XXXXXXX",
Expand Down

0 comments on commit aced347

Please sign in to comment.