goodwe 0.2.32__py3-none-any.whl → 0.3.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- goodwe/__init__.py +3 -3
- goodwe/const.py +135 -66
- goodwe/dt.py +78 -82
- goodwe/es.py +20 -21
- goodwe/et.py +380 -210
- goodwe/exceptions.py +0 -4
- goodwe/inverter.py +20 -26
- goodwe/model.py +14 -5
- goodwe/protocol.py +51 -2
- goodwe/sensor.py +142 -94
- {goodwe-0.2.32.dist-info → goodwe-0.3.0.dist-info}/METADATA +8 -22
- goodwe-0.3.0.dist-info/RECORD +16 -0
- {goodwe-0.2.32.dist-info → goodwe-0.3.0.dist-info}/WHEEL +1 -1
- goodwe/goodwe.py +0 -22
- goodwe/processor.py +0 -37
- goodwe/xs.py +0 -43
- goodwe-0.2.32.dist-info/RECORD +0 -19
- {goodwe-0.2.32.dist-info → goodwe-0.3.0.dist-info}/LICENSE +0 -0
- {goodwe-0.2.32.dist-info → goodwe-0.3.0.dist-info}/top_level.txt +0 -0
goodwe/__init__.py
CHANGED
|
@@ -8,7 +8,6 @@ from .dt import DT
|
|
|
8
8
|
from .es import ES
|
|
9
9
|
from .et import ET
|
|
10
10
|
from .exceptions import InverterError, RequestFailedException
|
|
11
|
-
from .goodwe import GoodWeXSProcessor, AbstractDataProcessor, GoodWeInverter
|
|
12
11
|
from .inverter import Inverter, OperationMode, Sensor, SensorKind
|
|
13
12
|
from .model import DT_MODEL_TAGS, ES_MODEL_TAGS, ET_MODEL_TAGS
|
|
14
13
|
from .protocol import ProtocolCommand, UdpInverterProtocol, Aa55ProtocolCommand
|
|
@@ -70,8 +69,9 @@ async def discover(host: str, timeout: int = 1, retries: int = 3) -> Inverter:
|
|
|
70
69
|
try:
|
|
71
70
|
logger.debug("Probing inverter at %s.", host)
|
|
72
71
|
response = await DISCOVERY_COMMAND.execute(host, timeout, retries)
|
|
73
|
-
|
|
74
|
-
|
|
72
|
+
response = response.response_data()
|
|
73
|
+
model_name = response[5:15].decode("ascii").rstrip()
|
|
74
|
+
serial_number = response[31:47].decode("ascii")
|
|
75
75
|
|
|
76
76
|
inverter_class: Type[Inverter] | None = None
|
|
77
77
|
for model_tag in ET_MODEL_TAGS:
|
goodwe/const.py
CHANGED
|
@@ -70,97 +70,131 @@ WORK_MODES_ES: Dict[int, str] = {
|
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
SAFETY_COUNTRIES: Dict[int, str] = {
|
|
73
|
-
0: "
|
|
74
|
-
1: "
|
|
75
|
-
2: "
|
|
76
|
-
3: "
|
|
77
|
-
4: "
|
|
78
|
-
5: "
|
|
79
|
-
6: "
|
|
80
|
-
7: "
|
|
81
|
-
8: "G98",
|
|
82
|
-
9: "Australia",
|
|
83
|
-
10: "
|
|
73
|
+
0: "IT CEI 0-21",
|
|
74
|
+
1: "CZ-A1",
|
|
75
|
+
2: "DE LV with PV",
|
|
76
|
+
3: "ES-A",
|
|
77
|
+
4: "GR",
|
|
78
|
+
5: "DK2",
|
|
79
|
+
6: "BE",
|
|
80
|
+
7: "RO-A",
|
|
81
|
+
8: "GB G98",
|
|
82
|
+
9: "Australia A",
|
|
83
|
+
10: "FR mainland",
|
|
84
84
|
11: "China",
|
|
85
|
-
12: "60Hz
|
|
86
|
-
13: "
|
|
85
|
+
12: "60Hz 230Vac Default",
|
|
86
|
+
13: "PL LV",
|
|
87
87
|
14: "South Africa",
|
|
88
|
-
|
|
89
|
-
16: "Brazil",
|
|
88
|
+
16: "Brazil 220Vac",
|
|
90
89
|
17: "Thailand MEA",
|
|
91
90
|
18: "Thailand PEA",
|
|
92
91
|
19: "Mauritius",
|
|
93
|
-
20: "
|
|
94
|
-
21: "
|
|
95
|
-
22: "China
|
|
96
|
-
23: "
|
|
97
|
-
24: "
|
|
92
|
+
20: "NL-A",
|
|
93
|
+
21: "G98/NI",
|
|
94
|
+
22: "China Higher",
|
|
95
|
+
23: "FR island 50Hz",
|
|
96
|
+
24: "FR island 60Hz",
|
|
98
97
|
25: "Australia Ergon",
|
|
99
98
|
26: "Australia Energex",
|
|
100
|
-
27: "
|
|
99
|
+
27: "NL 16/20A",
|
|
101
100
|
28: "Korea",
|
|
102
|
-
29: "China
|
|
103
|
-
30: "
|
|
101
|
+
29: "China Utility",
|
|
102
|
+
30: "AT-A",
|
|
104
103
|
31: "India",
|
|
105
|
-
32: "50Hz
|
|
104
|
+
32: "50Hz 230Vac Default",
|
|
106
105
|
33: "Warehouse",
|
|
107
106
|
34: "Philippines",
|
|
108
|
-
35: "
|
|
107
|
+
35: "IE-16/25A",
|
|
109
108
|
36: "Taiwan",
|
|
110
|
-
37: "
|
|
109
|
+
37: "BG",
|
|
111
110
|
38: "Barbados",
|
|
112
|
-
39: "China
|
|
113
|
-
40: "G99",
|
|
114
|
-
41: "
|
|
115
|
-
42: "Chile",
|
|
116
|
-
43: "Brazil
|
|
117
|
-
44: "
|
|
118
|
-
45: "IEEE1547
|
|
119
|
-
46: "IEEE1547
|
|
120
|
-
47: "IEEE1547
|
|
121
|
-
48: "60Hz
|
|
122
|
-
49: "50Hz
|
|
123
|
-
50: "
|
|
124
|
-
51: "
|
|
125
|
-
52: "
|
|
126
|
-
53: "
|
|
111
|
+
39: "China Highest",
|
|
112
|
+
40: "GB G99-A",
|
|
113
|
+
41: "SE LV",
|
|
114
|
+
42: "Chile BT",
|
|
115
|
+
43: "Brazil 127Vac",
|
|
116
|
+
44: "Newzealand",
|
|
117
|
+
45: "IEEE1547 208Vac",
|
|
118
|
+
46: "IEEE1547 220Vac",
|
|
119
|
+
47: "IEEE1547 240Vac",
|
|
120
|
+
48: "60Hz 127Vac Default",
|
|
121
|
+
49: "50Hz 127Vac Default",
|
|
122
|
+
50: "Australia WAPN",
|
|
123
|
+
51: "Australia MicroGrid",
|
|
124
|
+
52: "JP 50Hz",
|
|
125
|
+
53: "JP 60Hz",
|
|
127
126
|
54: "India Higher",
|
|
128
127
|
55: "DEWA LV",
|
|
129
128
|
56: "DEWA MV",
|
|
130
|
-
57: "
|
|
131
|
-
58: "GreenGrid",
|
|
132
|
-
59: "
|
|
129
|
+
57: "SK",
|
|
130
|
+
58: "NZ GreenGrid",
|
|
131
|
+
59: "HU",
|
|
133
132
|
60: "Sri Lanka",
|
|
134
|
-
61: "
|
|
133
|
+
61: "ES island",
|
|
135
134
|
62: "Ergon30K",
|
|
136
135
|
63: "Energex30K",
|
|
137
|
-
64: "IEEE1547 230/
|
|
136
|
+
64: "IEEE1547 230/400Vac",
|
|
138
137
|
65: "IEC61727 60Hz",
|
|
139
|
-
66: "
|
|
140
|
-
67: "CEI-
|
|
141
|
-
68: "
|
|
142
|
-
69: "
|
|
143
|
-
70: "
|
|
144
|
-
71: "
|
|
145
|
-
72: "
|
|
146
|
-
73: "
|
|
138
|
+
66: "CH",
|
|
139
|
+
67: "IT CEI 0-16",
|
|
140
|
+
68: "Australia Horizon",
|
|
141
|
+
69: "CY",
|
|
142
|
+
70: "Australia SAPN",
|
|
143
|
+
71: "Australia Ausgrid",
|
|
144
|
+
72: "Australia Essential",
|
|
145
|
+
73: "Australia Victoria",
|
|
147
146
|
74: "Hong Kong",
|
|
148
|
-
75: "
|
|
149
|
-
76: "
|
|
150
|
-
77: "
|
|
151
|
-
78: "
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
147
|
+
75: "PL MV",
|
|
148
|
+
76: "NL-B",
|
|
149
|
+
77: "SE MV",
|
|
150
|
+
78: "DE MV",
|
|
151
|
+
79: "DE LV without PV",
|
|
152
|
+
80: "ES-D",
|
|
153
|
+
81: "Australia Endeavour",
|
|
154
|
+
82: "Argentina",
|
|
155
|
+
83: "Israel LV",
|
|
156
|
+
84: "IEC61727 50Hz",
|
|
157
|
+
85: "Australia B",
|
|
158
|
+
86: "Australia C",
|
|
159
|
+
87: "Chile MT-A",
|
|
160
|
+
88: "Chile MT-B",
|
|
161
|
+
89: "Vietnam",
|
|
162
|
+
90: "reserve14",
|
|
163
|
+
91: "Israel-HV",
|
|
164
|
+
93: "NewZealand:2015",
|
|
165
|
+
94: "RO-D",
|
|
166
|
+
96: "US 208Vac Default",
|
|
167
|
+
97: "US 240Vac Default",
|
|
168
|
+
98: "US CA 208Vac",
|
|
169
|
+
99: "US CA 240Vac",
|
|
156
170
|
100: "cUSA_208VacCA_SDGE",
|
|
157
171
|
101: "cUSA_240VacCA_SDGE",
|
|
158
172
|
102: "cUSA_208VacCA_PGE",
|
|
159
173
|
103: "cUSA_240VacCA_PGE",
|
|
160
|
-
104: "
|
|
161
|
-
105: "
|
|
162
|
-
106: "
|
|
163
|
-
107: "
|
|
174
|
+
104: "US HI 208Vac",
|
|
175
|
+
105: "US HI 240Vac",
|
|
176
|
+
106: "USA_208VacHECO_14HM",
|
|
177
|
+
107: "USA_240VacHECO_14HM",
|
|
178
|
+
108: "US 480Vac",
|
|
179
|
+
109: "US CA 480Vac",
|
|
180
|
+
110: "US HI 480Vac",
|
|
181
|
+
111: "US Kauai 208Vac",
|
|
182
|
+
112: "US Kauai 240Vac",
|
|
183
|
+
113: "US Kauai 480Vac",
|
|
184
|
+
114: "US ISO-NE 208Vac",
|
|
185
|
+
115: "US ISO-NE 240Vac",
|
|
186
|
+
116: "US ISO-NE 480Vac",
|
|
187
|
+
118: "PR 208Vac",
|
|
188
|
+
119: "PR 240Vac",
|
|
189
|
+
120: "PR 480Vac",
|
|
190
|
+
128: "Poland_B",
|
|
191
|
+
129: "EE",
|
|
192
|
+
135: "CZ-A2",
|
|
193
|
+
136: "CZ-B1",
|
|
194
|
+
146: "Brazil 208Vac",
|
|
195
|
+
147: "Brazil 230Vac",
|
|
196
|
+
148: "Brazil 240Vac",
|
|
197
|
+
149: "Brazil 254Vac",
|
|
164
198
|
}
|
|
165
199
|
|
|
166
200
|
ERROR_CODES: Dict[int, str] = {
|
|
@@ -263,3 +297,38 @@ BMS_WARNING_CODES: Dict[int, str] = {
|
|
|
263
297
|
1: 'Discharging under-voltage 1',
|
|
264
298
|
0: 'Charging over-voltage 1',
|
|
265
299
|
}
|
|
300
|
+
|
|
301
|
+
DERATING_MODE_CODES: Dict[int, str] = {
|
|
302
|
+
31: '',
|
|
303
|
+
30: '',
|
|
304
|
+
29: '',
|
|
305
|
+
28: '',
|
|
306
|
+
27: '',
|
|
307
|
+
26: '',
|
|
308
|
+
25: '',
|
|
309
|
+
24: '',
|
|
310
|
+
23: '',
|
|
311
|
+
22: '',
|
|
312
|
+
21: '',
|
|
313
|
+
20: '',
|
|
314
|
+
19: '',
|
|
315
|
+
18: '',
|
|
316
|
+
17: '',
|
|
317
|
+
16: '',
|
|
318
|
+
15: '',
|
|
319
|
+
14: '',
|
|
320
|
+
13: '',
|
|
321
|
+
12: '',
|
|
322
|
+
11: '',
|
|
323
|
+
10: 'Power calibration limit power (For ATS)',
|
|
324
|
+
9: 'Overvoltage derating (For GW)',
|
|
325
|
+
8: 'Maximum current derating',
|
|
326
|
+
7: 'Limited power start derating',
|
|
327
|
+
6: 'DRED derating',
|
|
328
|
+
5: 'Export power derating',
|
|
329
|
+
4: 'PU Curve',
|
|
330
|
+
3: 'Power VS Frequency',
|
|
331
|
+
2: 'Reactive power derating(PF/QU/FixQ)',
|
|
332
|
+
1: 'Active power derating',
|
|
333
|
+
0: 'Overtemperature derating',
|
|
334
|
+
}
|
goodwe/dt.py
CHANGED
|
@@ -6,7 +6,7 @@ from .exceptions import InverterError
|
|
|
6
6
|
from .inverter import Inverter
|
|
7
7
|
from .inverter import OperationMode
|
|
8
8
|
from .inverter import SensorKind as Kind
|
|
9
|
-
from .model import
|
|
9
|
+
from .model import is_3_mppt, is_single_phase
|
|
10
10
|
from .protocol import ProtocolCommand, ModbusReadCommand, ModbusWriteCommand, ModbusWriteMultiCommand
|
|
11
11
|
from .sensor import *
|
|
12
12
|
|
|
@@ -15,21 +15,21 @@ class DT(Inverter):
|
|
|
15
15
|
"""Class representing inverter of DT/MS/D-NS/XS or GE's GEP(PSB/PSC) families"""
|
|
16
16
|
|
|
17
17
|
__all_sensors: Tuple[Sensor, ...] = (
|
|
18
|
-
Timestamp("timestamp",
|
|
19
|
-
Voltage("vpv1",
|
|
20
|
-
Current("ipv1",
|
|
18
|
+
Timestamp("timestamp", 30100, "Timestamp"),
|
|
19
|
+
Voltage("vpv1", 30103, "PV1 Voltage", Kind.PV),
|
|
20
|
+
Current("ipv1", 30104, "PV1 Current", Kind.PV),
|
|
21
21
|
Calculated("ppv1",
|
|
22
|
-
lambda data: round(read_voltage(data,
|
|
22
|
+
lambda data: round(read_voltage(data, 30103) * read_current(data, 30104)),
|
|
23
23
|
"PV1 Power", "W", Kind.PV),
|
|
24
|
-
Voltage("vpv2",
|
|
25
|
-
Current("ipv2",
|
|
24
|
+
Voltage("vpv2", 30105, "PV2 Voltage", Kind.PV),
|
|
25
|
+
Current("ipv2", 30106, "PV2 Current", Kind.PV),
|
|
26
26
|
Calculated("ppv2",
|
|
27
|
-
lambda data: round(read_voltage(data,
|
|
27
|
+
lambda data: round(read_voltage(data, 30105) * read_current(data, 30106)),
|
|
28
28
|
"PV2 Power", "W", Kind.PV),
|
|
29
|
-
Voltage("vpv3",
|
|
30
|
-
Current("ipv3",
|
|
29
|
+
Voltage("vpv3", 30107, "PV3 Voltage", Kind.PV),
|
|
30
|
+
Current("ipv3", 30108, "PV3 Current", Kind.PV),
|
|
31
31
|
Calculated("ppv3",
|
|
32
|
-
lambda data: round(read_voltage(data,
|
|
32
|
+
lambda data: round(read_voltage(data, 30107) * read_current(data, 30108)),
|
|
33
33
|
"PV3 Power", "W", Kind.PV),
|
|
34
34
|
# Voltage("vpv4", 14, "PV4 Voltage", Kind.PV),
|
|
35
35
|
# Current("ipv4", 16, "PV4 Current", Kind.PV),
|
|
@@ -37,72 +37,70 @@ class DT(Inverter):
|
|
|
37
37
|
# Current("ipv5", 16, "PV5 Current", Kind.PV),
|
|
38
38
|
# Voltage("vpv6", 14, "PV6 Voltage", Kind.PV),
|
|
39
39
|
# Current("ipv6", 16, "PV7 Current", Kind.PV),
|
|
40
|
-
Voltage("vline1",
|
|
41
|
-
Voltage("vline2",
|
|
42
|
-
Voltage("vline3",
|
|
43
|
-
Voltage("vgrid1",
|
|
44
|
-
Voltage("vgrid2",
|
|
45
|
-
Voltage("vgrid3",
|
|
46
|
-
Current("igrid1",
|
|
47
|
-
Current("igrid2",
|
|
48
|
-
Current("igrid3",
|
|
49
|
-
Frequency("fgrid1",
|
|
50
|
-
Frequency("fgrid2",
|
|
51
|
-
Frequency("fgrid3",
|
|
40
|
+
Voltage("vline1", 30115, "On-grid L1-L2 Voltage", Kind.AC),
|
|
41
|
+
Voltage("vline2", 30116, "On-grid L2-L3 Voltage", Kind.AC),
|
|
42
|
+
Voltage("vline3", 30117, "On-grid L3-L1 Voltage", Kind.AC),
|
|
43
|
+
Voltage("vgrid1", 30118, "On-grid L1 Voltage", Kind.AC),
|
|
44
|
+
Voltage("vgrid2", 30119, "On-grid L2 Voltage", Kind.AC),
|
|
45
|
+
Voltage("vgrid3", 30120, "On-grid L3 Voltage", Kind.AC),
|
|
46
|
+
Current("igrid1", 30121, "On-grid L1 Current", Kind.AC),
|
|
47
|
+
Current("igrid2", 30122, "On-grid L2 Current", Kind.AC),
|
|
48
|
+
Current("igrid3", 30123, "On-grid L3 Current", Kind.AC),
|
|
49
|
+
Frequency("fgrid1", 30124, "On-grid L1 Frequency", Kind.AC),
|
|
50
|
+
Frequency("fgrid2", 30125, "On-grid L2 Frequency", Kind.AC),
|
|
51
|
+
Frequency("fgrid3", 30126, "On-grid L3 Frequency", Kind.AC),
|
|
52
52
|
Calculated("pgrid1",
|
|
53
|
-
lambda data: round(read_voltage(data,
|
|
53
|
+
lambda data: round(read_voltage(data, 30118) * read_current(data, 30121)),
|
|
54
54
|
"On-grid L1 Power", "W", Kind.AC),
|
|
55
55
|
Calculated("pgrid2",
|
|
56
|
-
lambda data: round(read_voltage(data,
|
|
56
|
+
lambda data: round(read_voltage(data, 30119) * read_current(data, 30122)),
|
|
57
57
|
"On-grid L2 Power", "W", Kind.AC),
|
|
58
58
|
Calculated("pgrid3",
|
|
59
|
-
lambda data: round(read_voltage(data,
|
|
59
|
+
lambda data: round(read_voltage(data, 30120) * read_current(data, 30123)),
|
|
60
60
|
"On-grid L3 Power", "W", Kind.AC),
|
|
61
|
-
|
|
62
|
-
Power("ppv",
|
|
63
|
-
Integer("work_mode",
|
|
64
|
-
Enum2("work_mode_label",
|
|
65
|
-
Long("error_codes",
|
|
66
|
-
Integer("warning_code",
|
|
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
|
-
Integer("
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
Integer("xx142", 142, "Unknown sensor@142"),
|
|
105
|
-
Integer("xx144", 144, "Unknown sensor@144"),
|
|
61
|
+
# 30127 reserved
|
|
62
|
+
Power("ppv", 30128, "PV Power", Kind.PV),
|
|
63
|
+
Integer("work_mode", 30129, "Work Mode code"),
|
|
64
|
+
Enum2("work_mode_label", 30129, WORK_MODES, "Work Mode"),
|
|
65
|
+
Long("error_codes", 30130, "Error Codes"),
|
|
66
|
+
Integer("warning_code", 30132, "Warning code"),
|
|
67
|
+
Apparent4("apparent_power", 30133, "Apparent Power", Kind.AC),
|
|
68
|
+
Reactive4("reactive_power", 30135, "Reactive Power", Kind.AC),
|
|
69
|
+
# 30137 reserved
|
|
70
|
+
# 30138 reserved
|
|
71
|
+
# 30139 reserved
|
|
72
|
+
# 30140 reserved
|
|
73
|
+
Temp("temperature", 30141, "Inverter Temperature", Kind.AC),
|
|
74
|
+
# 30142 reserved
|
|
75
|
+
# 30143 reserved
|
|
76
|
+
Energy("e_day", 30144, "Today's PV Generation", Kind.PV),
|
|
77
|
+
Energy4("e_total", 30145, "Total PV Generation", Kind.PV),
|
|
78
|
+
Long("h_total", 30147, "Hours Total", "h", Kind.PV),
|
|
79
|
+
Integer("safety_country", 30149, "Safety Country code", "", Kind.AC),
|
|
80
|
+
Enum2("safety_country_label", 30149, SAFETY_COUNTRIES, "Safety Country", Kind.AC),
|
|
81
|
+
# 30150 reserved
|
|
82
|
+
# 30151 reserved
|
|
83
|
+
# 30152 reserved
|
|
84
|
+
# 30153 reserved
|
|
85
|
+
# 30154 reserved
|
|
86
|
+
# 30155 reserved
|
|
87
|
+
# 30156 reserved
|
|
88
|
+
# 30157 reserved
|
|
89
|
+
# 30158 reserved
|
|
90
|
+
# 30159 reserved
|
|
91
|
+
# 30160 reserved
|
|
92
|
+
# 30161 reserved
|
|
93
|
+
Integer("funbit", 30162, "FunBit", "", Kind.PV),
|
|
94
|
+
Voltage("vbus", 30163, "Bus Voltage", Kind.PV),
|
|
95
|
+
Voltage("vnbus", 30164, "NBus Voltage", Kind.PV),
|
|
96
|
+
Long("derating_mode", 30165, "Derating Mode code"),
|
|
97
|
+
EnumBitmap4("derating_mode_label", 30165, DERATING_MODE_CODES, "Derating Mode"),
|
|
98
|
+
# 30167 reserved
|
|
99
|
+
# 30168 reserved
|
|
100
|
+
# 30169 reserved
|
|
101
|
+
# 30170 reserved
|
|
102
|
+
# 30171 reserved
|
|
103
|
+
# 30172 reserved
|
|
106
104
|
)
|
|
107
105
|
|
|
108
106
|
# Modbus registers of inverter settings, offsets are modbus register addresses
|
|
@@ -137,7 +135,7 @@ class DT(Inverter):
|
|
|
137
135
|
@staticmethod
|
|
138
136
|
def _single_phase_only(s: Sensor) -> bool:
|
|
139
137
|
"""Filter to exclude phase2/3 sensors on single phase inverters"""
|
|
140
|
-
return not ((s.id_.endswith('2') or s.id_.endswith('3')) and 'pv' not in s.id_
|
|
138
|
+
return not ((s.id_.endswith('2') or s.id_.endswith('3')) and 'pv' not in s.id_)
|
|
141
139
|
|
|
142
140
|
@staticmethod
|
|
143
141
|
def _pv1_pv2_only(s: Sensor) -> bool:
|
|
@@ -146,12 +144,12 @@ class DT(Inverter):
|
|
|
146
144
|
|
|
147
145
|
async def read_device_info(self):
|
|
148
146
|
response = await self._read_from_socket(self._READ_DEVICE_VERSION_INFO)
|
|
149
|
-
response = response
|
|
147
|
+
response = response.response_data()
|
|
150
148
|
try:
|
|
151
149
|
self.model_name = response[22:32].decode("ascii").rstrip()
|
|
152
150
|
except:
|
|
153
151
|
print("No model name sent from the inverter.")
|
|
154
|
-
self.serial_number = response[6:22]
|
|
152
|
+
self.serial_number = self._decode(response[6:22])
|
|
155
153
|
self.dsp1_version = read_unsigned_int(response, 66)
|
|
156
154
|
self.dsp2_version = read_unsigned_int(response, 68)
|
|
157
155
|
self.arm_version = read_unsigned_int(response, 70)
|
|
@@ -164,7 +162,7 @@ class DT(Inverter):
|
|
|
164
162
|
else:
|
|
165
163
|
self._settings.update({s.id_: s for s in self.__settings_three_phase})
|
|
166
164
|
|
|
167
|
-
if
|
|
165
|
+
if is_3_mppt(self):
|
|
168
166
|
# this is 3 PV strings inverter, keep all sensors
|
|
169
167
|
pass
|
|
170
168
|
else:
|
|
@@ -172,9 +170,9 @@ class DT(Inverter):
|
|
|
172
170
|
self._sensors = tuple(filter(self._pv1_pv2_only, self._sensors))
|
|
173
171
|
pass
|
|
174
172
|
|
|
175
|
-
async def read_runtime_data(self
|
|
176
|
-
|
|
177
|
-
data = self._map_response(
|
|
173
|
+
async def read_runtime_data(self) -> Dict[str, Any]:
|
|
174
|
+
response = await self._read_from_socket(self._READ_DEVICE_RUNNING_DATA)
|
|
175
|
+
data = self._map_response(response, self._sensors)
|
|
178
176
|
return data
|
|
179
177
|
|
|
180
178
|
async def read_setting(self, setting_id: str) -> Any:
|
|
@@ -182,9 +180,8 @@ class DT(Inverter):
|
|
|
182
180
|
if not setting:
|
|
183
181
|
raise ValueError(f'Unknown setting "{setting_id}"')
|
|
184
182
|
count = (setting.size_ + (setting.size_ % 2)) // 2
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
return setting.read_value(buffer)
|
|
183
|
+
response = await self._read_from_socket(ModbusReadCommand(self.comm_addr, setting.offset, count))
|
|
184
|
+
return setting.read_value(response)
|
|
188
185
|
|
|
189
186
|
async def write_setting(self, setting_id: str, value: Any):
|
|
190
187
|
setting = self._settings.get(setting_id)
|
|
@@ -208,7 +205,6 @@ class DT(Inverter):
|
|
|
208
205
|
return await self.read_setting('grid_export_limit')
|
|
209
206
|
|
|
210
207
|
async def set_grid_export_limit(self, export_limit: int) -> None:
|
|
211
|
-
setting = self._settings.get('grid_export_limit')
|
|
212
208
|
if export_limit >= 0:
|
|
213
209
|
return await self.write_setting('grid_export_limit', export_limit)
|
|
214
210
|
|
goodwe/es.py
CHANGED
|
@@ -98,8 +98,8 @@ class ES(Inverter):
|
|
|
98
98
|
lambda data: round(read_bytes2(data, 47) + read_bytes2(data, 81)),
|
|
99
99
|
"Plant Power", "W", Kind.AC),
|
|
100
100
|
Decimal("meter_power_factor", 83, 1000, "Meter Power Factor", "", Kind.GRID), # modbus 0x531
|
|
101
|
-
Integer("xx85", 85, "Unknown sensor@85"),
|
|
102
|
-
Integer("xx87", 87, "Unknown sensor@87"),
|
|
101
|
+
# Integer("xx85", 85, "Unknown sensor@85"),
|
|
102
|
+
# Integer("xx87", 87, "Unknown sensor@87"),
|
|
103
103
|
Long("diagnose_result", 89, "Diag Status Code"),
|
|
104
104
|
EnumBitmap4("diagnose_result_label", 89, DIAG_STATUS_CODES, "Diag Status"),
|
|
105
105
|
# Energy4("e_total_exp", 93, "Total Energy (export)", Kind.GRID),
|
|
@@ -188,10 +188,11 @@ class ES(Inverter):
|
|
|
188
188
|
|
|
189
189
|
async def read_device_info(self):
|
|
190
190
|
response = await self._read_from_socket(self._READ_DEVICE_VERSION_INFO)
|
|
191
|
-
|
|
192
|
-
self.
|
|
193
|
-
self.
|
|
194
|
-
self.
|
|
191
|
+
response = response.response_data()
|
|
192
|
+
self.firmware = self._decode(response[0:5]).rstrip()
|
|
193
|
+
self.model_name = self._decode(response[5:15]).rstrip()
|
|
194
|
+
self.serial_number = self._decode(response[31:47])
|
|
195
|
+
self.software_version = self._decode(response[51:63])
|
|
195
196
|
try:
|
|
196
197
|
if len(self.firmware) >= 2:
|
|
197
198
|
self.dsp1_version = int(self.firmware[0:2])
|
|
@@ -205,9 +206,9 @@ class ES(Inverter):
|
|
|
205
206
|
if self._supports_eco_mode_v2():
|
|
206
207
|
self._settings.update({s.id_: s for s in self.__settings_arm_fw_14})
|
|
207
208
|
|
|
208
|
-
async def read_runtime_data(self
|
|
209
|
-
|
|
210
|
-
data = self._map_response(
|
|
209
|
+
async def read_runtime_data(self) -> Dict[str, Any]:
|
|
210
|
+
response = await self._read_from_socket(self._READ_DEVICE_RUNNING_DATA)
|
|
211
|
+
data = self._map_response(response, self.__sensors)
|
|
211
212
|
return data
|
|
212
213
|
|
|
213
214
|
async def read_setting(self, setting_id: str) -> Any:
|
|
@@ -221,13 +222,11 @@ class ES(Inverter):
|
|
|
221
222
|
raise ValueError(f'Unknown setting "{setting_id}"')
|
|
222
223
|
count = (setting.size_ + (setting.size_ % 2)) // 2
|
|
223
224
|
if self._is_modbus_setting(setting):
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
return setting.read_value(buffer)
|
|
225
|
+
response = await self._read_from_socket(ModbusReadCommand(self.comm_addr, setting.offset, count))
|
|
226
|
+
return setting.read_value(response)
|
|
227
227
|
else:
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
return setting.read_value(buffer)
|
|
228
|
+
response = await self._read_from_socket(Aa55ReadCommand(setting.offset, count))
|
|
229
|
+
return setting.read_value(response)
|
|
231
230
|
else:
|
|
232
231
|
all_settings = await self.read_settings_data()
|
|
233
232
|
return all_settings.get(setting_id)
|
|
@@ -244,11 +243,11 @@ class ES(Inverter):
|
|
|
244
243
|
if setting.size_ == 1:
|
|
245
244
|
# modbus can address/store only 16 bit values, read the other 8 bytes
|
|
246
245
|
if self._is_modbus_setting(setting):
|
|
247
|
-
|
|
248
|
-
raw_value = setting.encode_value(value,
|
|
246
|
+
response = await self._read_from_socket(ModbusReadCommand(self.comm_addr, setting.offset, 1))
|
|
247
|
+
raw_value = setting.encode_value(value, response.response_data()[0:2])
|
|
249
248
|
else:
|
|
250
|
-
|
|
251
|
-
raw_value = setting.encode_value(value,
|
|
249
|
+
response = await self._read_from_socket(Aa55ReadCommand(setting.offset, 1))
|
|
250
|
+
raw_value = setting.encode_value(value, response.response_data()[2:4])
|
|
252
251
|
else:
|
|
253
252
|
raw_value = setting.encode_value(value)
|
|
254
253
|
if len(raw_value) <= 2:
|
|
@@ -264,8 +263,8 @@ class ES(Inverter):
|
|
|
264
263
|
await self._read_from_socket(Aa55WriteMultiCommand(setting.offset, raw_value))
|
|
265
264
|
|
|
266
265
|
async def read_settings_data(self) -> Dict[str, Any]:
|
|
267
|
-
|
|
268
|
-
data = self._map_response(
|
|
266
|
+
response = await self._read_from_socket(self._READ_DEVICE_SETTINGS_DATA)
|
|
267
|
+
data = self._map_response(response, self.settings())
|
|
269
268
|
return data
|
|
270
269
|
|
|
271
270
|
async def get_grid_export_limit(self) -> int:
|