pylxpweb 0.1.0__py3-none-any.whl → 0.5.2__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.
- pylxpweb/__init__.py +47 -2
- pylxpweb/api_namespace.py +241 -0
- pylxpweb/cli/__init__.py +3 -0
- pylxpweb/cli/collect_device_data.py +874 -0
- pylxpweb/client.py +387 -26
- pylxpweb/constants/__init__.py +481 -0
- pylxpweb/constants/api.py +48 -0
- pylxpweb/constants/devices.py +98 -0
- pylxpweb/constants/locations.py +227 -0
- pylxpweb/{constants.py → constants/registers.py} +72 -238
- pylxpweb/constants/scaling.py +479 -0
- pylxpweb/devices/__init__.py +32 -0
- pylxpweb/devices/_firmware_update_mixin.py +504 -0
- pylxpweb/devices/_mid_runtime_properties.py +1427 -0
- pylxpweb/devices/base.py +122 -0
- pylxpweb/devices/battery.py +589 -0
- pylxpweb/devices/battery_bank.py +331 -0
- pylxpweb/devices/inverters/__init__.py +32 -0
- pylxpweb/devices/inverters/_features.py +378 -0
- pylxpweb/devices/inverters/_runtime_properties.py +596 -0
- pylxpweb/devices/inverters/base.py +2124 -0
- pylxpweb/devices/inverters/generic.py +192 -0
- pylxpweb/devices/inverters/hybrid.py +274 -0
- pylxpweb/devices/mid_device.py +183 -0
- pylxpweb/devices/models.py +126 -0
- pylxpweb/devices/parallel_group.py +364 -0
- pylxpweb/devices/station.py +908 -0
- pylxpweb/endpoints/control.py +980 -2
- pylxpweb/endpoints/devices.py +249 -16
- pylxpweb/endpoints/firmware.py +43 -10
- pylxpweb/endpoints/plants.py +15 -19
- pylxpweb/exceptions.py +4 -0
- pylxpweb/models.py +708 -41
- pylxpweb/transports/__init__.py +78 -0
- pylxpweb/transports/capabilities.py +101 -0
- pylxpweb/transports/data.py +501 -0
- pylxpweb/transports/exceptions.py +59 -0
- pylxpweb/transports/factory.py +119 -0
- pylxpweb/transports/http.py +329 -0
- pylxpweb/transports/modbus.py +617 -0
- pylxpweb/transports/protocol.py +217 -0
- {pylxpweb-0.1.0.dist-info → pylxpweb-0.5.2.dist-info}/METADATA +130 -85
- pylxpweb-0.5.2.dist-info/RECORD +52 -0
- {pylxpweb-0.1.0.dist-info → pylxpweb-0.5.2.dist-info}/WHEEL +1 -1
- pylxpweb-0.5.2.dist-info/entry_points.txt +3 -0
- pylxpweb-0.1.0.dist-info/RECORD +0 -19
|
@@ -0,0 +1,481 @@
|
|
|
1
|
+
"""Constants and mappings for Luxpower/EG4 API.
|
|
2
|
+
|
|
3
|
+
This package contains constants, mappings, and helper functions for working
|
|
4
|
+
with the Luxpower/EG4 inverter API. The constants are organized into modules
|
|
5
|
+
for maintainability:
|
|
6
|
+
|
|
7
|
+
- locations: Timezone, country, continent, region mappings
|
|
8
|
+
- registers: Hold/input register definitions and bit manipulation
|
|
9
|
+
- scaling: Data scaling factors and conversion functions
|
|
10
|
+
- api: HTTP constants, backoff/retry configuration
|
|
11
|
+
- devices: Device types, limits, and parsing helpers
|
|
12
|
+
|
|
13
|
+
All symbols are re-exported from this package for backward compatibility,
|
|
14
|
+
so you can import from pylxpweb.constants directly:
|
|
15
|
+
|
|
16
|
+
from pylxpweb.constants import HOLD_AC_CHARGE_POWER_CMD, ScaleFactor
|
|
17
|
+
|
|
18
|
+
Note: This package was refactored from a single large file (v0.3.x) into
|
|
19
|
+
a modular structure (v0.4.0+) for better maintainability.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
from __future__ import annotations
|
|
23
|
+
|
|
24
|
+
# ============================================================================
|
|
25
|
+
# API MODULE
|
|
26
|
+
# ============================================================================
|
|
27
|
+
from .api import (
|
|
28
|
+
# Backoff and retry
|
|
29
|
+
BACKOFF_BASE_DELAY_SECONDS,
|
|
30
|
+
BACKOFF_MAX_DELAY_SECONDS,
|
|
31
|
+
DEVICE_TYPE_GRIDBOSS,
|
|
32
|
+
# Device type constants
|
|
33
|
+
DEVICE_TYPE_INVERTER,
|
|
34
|
+
HTTP_FORBIDDEN,
|
|
35
|
+
# HTTP status codes
|
|
36
|
+
HTTP_OK,
|
|
37
|
+
HTTP_UNAUTHORIZED,
|
|
38
|
+
MAX_LOGIN_RETRIES,
|
|
39
|
+
MAX_TRANSIENT_ERROR_RETRIES,
|
|
40
|
+
TRANSIENT_ERROR_MESSAGES,
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
# ============================================================================
|
|
44
|
+
# DEVICES MODULE
|
|
45
|
+
# ============================================================================
|
|
46
|
+
from .devices import (
|
|
47
|
+
# Register limits
|
|
48
|
+
MAX_REGISTERS_PER_READ,
|
|
49
|
+
SCALE_MID_FREQUENCY,
|
|
50
|
+
# MID device scaling
|
|
51
|
+
SCALE_MID_VOLTAGE,
|
|
52
|
+
SOC_MAX_PERCENT,
|
|
53
|
+
# SOC limits
|
|
54
|
+
SOC_MIN_PERCENT,
|
|
55
|
+
# Timezone parsing
|
|
56
|
+
TIMEZONE_HHMM_HOURS_FACTOR,
|
|
57
|
+
TIMEZONE_HHMM_MINUTES_FACTOR,
|
|
58
|
+
parse_hhmm_timezone,
|
|
59
|
+
scale_mid_frequency,
|
|
60
|
+
scale_mid_voltage,
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
# Re-export all symbols from submodules for backward compatibility
|
|
64
|
+
# This ensures that existing code using `from pylxpweb.constants import X` continues to work
|
|
65
|
+
# ============================================================================
|
|
66
|
+
# LOCATIONS MODULE
|
|
67
|
+
# ============================================================================
|
|
68
|
+
from .locations import (
|
|
69
|
+
# Continent mappings
|
|
70
|
+
CONTINENT_MAP,
|
|
71
|
+
CONTINENT_REVERSE_MAP,
|
|
72
|
+
# Country mappings
|
|
73
|
+
COUNTRY_MAP,
|
|
74
|
+
COUNTRY_REVERSE_MAP,
|
|
75
|
+
# Static country-to-location mapping
|
|
76
|
+
COUNTRY_TO_LOCATION_STATIC,
|
|
77
|
+
# Region mappings
|
|
78
|
+
REGION_MAP,
|
|
79
|
+
REGION_REVERSE_MAP,
|
|
80
|
+
# Timezone mappings
|
|
81
|
+
TIMEZONE_MAP,
|
|
82
|
+
TIMEZONE_REVERSE_MAP,
|
|
83
|
+
get_continent_enum,
|
|
84
|
+
get_continent_region_from_country,
|
|
85
|
+
get_country_enum,
|
|
86
|
+
get_region_enum,
|
|
87
|
+
# Helper functions
|
|
88
|
+
get_timezone_enum,
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
# ============================================================================
|
|
92
|
+
# REGISTERS MODULE
|
|
93
|
+
# ============================================================================
|
|
94
|
+
from .registers import (
|
|
95
|
+
DEVICE_TYPE_CODE_LXP_EU,
|
|
96
|
+
DEVICE_TYPE_CODE_PV_SERIES,
|
|
97
|
+
DEVICE_TYPE_CODE_SNA,
|
|
98
|
+
FUNC_EN_BIT_AC_CHARGE_EN,
|
|
99
|
+
FUNC_EN_BIT_EPS_EN,
|
|
100
|
+
FUNC_EN_BIT_FORCED_CHG_EN,
|
|
101
|
+
FUNC_EN_BIT_FORCED_DISCHG_EN,
|
|
102
|
+
FUNC_EN_BIT_SET_TO_STANDBY,
|
|
103
|
+
# Critical control register
|
|
104
|
+
FUNC_EN_REGISTER,
|
|
105
|
+
# GridBOSS parameters
|
|
106
|
+
GRIDBOSS_PARAMETERS,
|
|
107
|
+
GRIDBOSS_STATS,
|
|
108
|
+
HOLD_AC_CHARGE_ENABLE_1,
|
|
109
|
+
HOLD_AC_CHARGE_ENABLE_2,
|
|
110
|
+
HOLD_AC_CHARGE_END_HOUR_1,
|
|
111
|
+
HOLD_AC_CHARGE_END_MIN_1,
|
|
112
|
+
# AC charge parameters
|
|
113
|
+
HOLD_AC_CHARGE_POWER_CMD,
|
|
114
|
+
HOLD_AC_CHARGE_SOC_LIMIT,
|
|
115
|
+
HOLD_AC_CHARGE_START_HOUR_1,
|
|
116
|
+
HOLD_AC_CHARGE_START_MIN_1,
|
|
117
|
+
# Battery protection parameters
|
|
118
|
+
HOLD_BAT_VOLT_MAX_CHG,
|
|
119
|
+
HOLD_BAT_VOLT_MAX_DISCHG,
|
|
120
|
+
HOLD_BAT_VOLT_MIN_CHG,
|
|
121
|
+
HOLD_BAT_VOLT_MIN_DISCHG,
|
|
122
|
+
HOLD_BAUD_RATE,
|
|
123
|
+
HOLD_DAY,
|
|
124
|
+
HOLD_DISCHG_CUT_OFF_SOC_EOD,
|
|
125
|
+
HOLD_DISCHG_ENABLE_1,
|
|
126
|
+
HOLD_DISCHG_END_HOUR_1,
|
|
127
|
+
HOLD_DISCHG_END_MIN_1,
|
|
128
|
+
# Discharge parameters
|
|
129
|
+
HOLD_DISCHG_POWER_CMD,
|
|
130
|
+
HOLD_DISCHG_START_HOUR_1,
|
|
131
|
+
HOLD_DISCHG_START_MIN_1,
|
|
132
|
+
HOLD_GRID_FREQ_HIGH_1,
|
|
133
|
+
HOLD_GRID_FREQ_LOW_1,
|
|
134
|
+
# Grid protection parameters
|
|
135
|
+
HOLD_GRID_VOLT_HIGH_1,
|
|
136
|
+
HOLD_GRID_VOLT_LOW_1,
|
|
137
|
+
HOLD_HOUR,
|
|
138
|
+
HOLD_LANGUAGE,
|
|
139
|
+
HOLD_MAX_CHG_CURR,
|
|
140
|
+
HOLD_MAX_DISCHG_CURR,
|
|
141
|
+
HOLD_MINUTE,
|
|
142
|
+
HOLD_MODBUS_ADDRESS,
|
|
143
|
+
HOLD_MONTH,
|
|
144
|
+
# Reactive power control
|
|
145
|
+
HOLD_Q_MODE,
|
|
146
|
+
HOLD_Q_POWER,
|
|
147
|
+
HOLD_Q_PV_MODE,
|
|
148
|
+
HOLD_Q_PV_POWER,
|
|
149
|
+
# Register groups
|
|
150
|
+
HOLD_REGISTER_GROUPS,
|
|
151
|
+
HOLD_SECOND,
|
|
152
|
+
# System configuration
|
|
153
|
+
HOLD_SERIAL_NUMBER_H,
|
|
154
|
+
HOLD_SERIAL_NUMBER_L,
|
|
155
|
+
HOLD_SOC_LOW_LIMIT_EPS_DISCHG,
|
|
156
|
+
HOLD_YEAR,
|
|
157
|
+
INPUT_BMS_FAULT,
|
|
158
|
+
INPUT_BMS_WARNING,
|
|
159
|
+
INPUT_CHARGE_VOLT_REF,
|
|
160
|
+
INPUT_DISCHARGE_VOLT_REF,
|
|
161
|
+
INPUT_E_CHG_ALL,
|
|
162
|
+
INPUT_E_CHG_DAY,
|
|
163
|
+
INPUT_E_DISCHG_ALL,
|
|
164
|
+
INPUT_E_DISCHG_DAY,
|
|
165
|
+
INPUT_E_EPS_ALL,
|
|
166
|
+
INPUT_E_EPS_DAY,
|
|
167
|
+
INPUT_E_INV_ALL,
|
|
168
|
+
INPUT_E_INV_DAY,
|
|
169
|
+
INPUT_E_PV1_ALL,
|
|
170
|
+
INPUT_E_PV1_DAY,
|
|
171
|
+
INPUT_E_PV2_ALL,
|
|
172
|
+
INPUT_E_PV2_DAY,
|
|
173
|
+
INPUT_E_PV3_ALL,
|
|
174
|
+
INPUT_E_PV3_DAY,
|
|
175
|
+
INPUT_E_REC_ALL,
|
|
176
|
+
INPUT_E_REC_DAY,
|
|
177
|
+
INPUT_E_TO_GRID_ALL,
|
|
178
|
+
INPUT_E_TO_GRID_DAY,
|
|
179
|
+
INPUT_E_TO_USER_ALL,
|
|
180
|
+
INPUT_E_TO_USER_DAY,
|
|
181
|
+
INPUT_F_AC,
|
|
182
|
+
INPUT_F_EPS,
|
|
183
|
+
INPUT_FAULT_HISTORY_1,
|
|
184
|
+
INPUT_FAULT_HISTORY_2,
|
|
185
|
+
INPUT_FAULT_HISTORY_3,
|
|
186
|
+
INPUT_FAULT_HISTORY_4,
|
|
187
|
+
INPUT_FAULT_HISTORY_5,
|
|
188
|
+
INPUT_I_BAT,
|
|
189
|
+
INPUT_I_BAT_LIMIT,
|
|
190
|
+
INPUT_I_INV_R,
|
|
191
|
+
INPUT_I_INV_S,
|
|
192
|
+
INPUT_I_INV_T,
|
|
193
|
+
INPUT_I_PV1,
|
|
194
|
+
INPUT_I_PV2,
|
|
195
|
+
INPUT_I_PV3,
|
|
196
|
+
INPUT_I_REC_R,
|
|
197
|
+
INPUT_I_REC_S,
|
|
198
|
+
INPUT_I_REC_T,
|
|
199
|
+
INPUT_INTERNAL_FAULT,
|
|
200
|
+
INPUT_MAX_CHG_CURR,
|
|
201
|
+
INPUT_MAX_DISCHG_CURR,
|
|
202
|
+
INPUT_P_CHARGE,
|
|
203
|
+
INPUT_P_DISCHARGE,
|
|
204
|
+
INPUT_P_EPS,
|
|
205
|
+
INPUT_P_INV,
|
|
206
|
+
INPUT_P_PV1,
|
|
207
|
+
INPUT_P_PV2,
|
|
208
|
+
INPUT_P_PV3,
|
|
209
|
+
INPUT_P_REC,
|
|
210
|
+
INPUT_P_TO_GRID,
|
|
211
|
+
INPUT_P_TO_USER,
|
|
212
|
+
INPUT_PF,
|
|
213
|
+
INPUT_REGISTER_GROUPS,
|
|
214
|
+
INPUT_S_EPS,
|
|
215
|
+
INPUT_SOC,
|
|
216
|
+
INPUT_SOH,
|
|
217
|
+
# Input registers (runtime data)
|
|
218
|
+
INPUT_STATUS,
|
|
219
|
+
INPUT_T_BAT,
|
|
220
|
+
INPUT_T_BAT_CONTROL,
|
|
221
|
+
INPUT_T_INNER,
|
|
222
|
+
INPUT_T_RADIATOR_1,
|
|
223
|
+
INPUT_T_RADIATOR_2,
|
|
224
|
+
INPUT_V_AC_R,
|
|
225
|
+
INPUT_V_AC_S,
|
|
226
|
+
INPUT_V_AC_T,
|
|
227
|
+
INPUT_V_BAT,
|
|
228
|
+
INPUT_V_BAT_LIMIT,
|
|
229
|
+
INPUT_V_BUS1,
|
|
230
|
+
INPUT_V_BUS2,
|
|
231
|
+
INPUT_V_EPS_R,
|
|
232
|
+
INPUT_V_EPS_S,
|
|
233
|
+
INPUT_V_EPS_T,
|
|
234
|
+
INPUT_V_PV1,
|
|
235
|
+
INPUT_V_PV2,
|
|
236
|
+
INPUT_V_PV3,
|
|
237
|
+
LXP_EU_PARAMETERS,
|
|
238
|
+
PARAM_KEY_TO_REGISTER_18KPV,
|
|
239
|
+
PV_SERIES_PARAMETERS,
|
|
240
|
+
REGISTER_STATS_18KPV,
|
|
241
|
+
# Verified register mappings
|
|
242
|
+
REGISTER_TO_PARAM_KEYS_18KPV,
|
|
243
|
+
# Model-specific parameters
|
|
244
|
+
SNA_PARAMETERS,
|
|
245
|
+
# Web parameter mappings
|
|
246
|
+
WEB_PARAM_TO_HOLD_REGISTER,
|
|
247
|
+
get_func_en_bit,
|
|
248
|
+
# Bit manipulation functions
|
|
249
|
+
get_func_en_bit_mask,
|
|
250
|
+
set_func_en_bit,
|
|
251
|
+
)
|
|
252
|
+
|
|
253
|
+
# ============================================================================
|
|
254
|
+
# SCALING MODULE
|
|
255
|
+
# ============================================================================
|
|
256
|
+
from .scaling import (
|
|
257
|
+
BATTERY_BANK_SCALING,
|
|
258
|
+
BATTERY_MODULE_SCALING,
|
|
259
|
+
ENERGY_INFO_SCALING,
|
|
260
|
+
GRIDBOSS_RUNTIME_SCALING,
|
|
261
|
+
INVERTER_OVERVIEW_SCALING,
|
|
262
|
+
# Scaling dictionaries
|
|
263
|
+
INVERTER_RUNTIME_SCALING,
|
|
264
|
+
PARAMETER_SCALING,
|
|
265
|
+
# Scaling factor enum
|
|
266
|
+
ScaleFactor,
|
|
267
|
+
# Private but tested function (exported for backward compatibility)
|
|
268
|
+
_get_scaling_for_field,
|
|
269
|
+
# Scaling functions
|
|
270
|
+
apply_scale,
|
|
271
|
+
get_battery_field_precision,
|
|
272
|
+
get_precision,
|
|
273
|
+
scale_battery_value,
|
|
274
|
+
scale_energy_value,
|
|
275
|
+
scale_runtime_value,
|
|
276
|
+
)
|
|
277
|
+
|
|
278
|
+
# ============================================================================
|
|
279
|
+
# __all__ DEFINITION
|
|
280
|
+
# ============================================================================
|
|
281
|
+
# Explicitly list all exported symbols for better IDE support and documentation
|
|
282
|
+
|
|
283
|
+
__all__ = [
|
|
284
|
+
# Locations
|
|
285
|
+
"TIMEZONE_MAP",
|
|
286
|
+
"TIMEZONE_REVERSE_MAP",
|
|
287
|
+
"COUNTRY_MAP",
|
|
288
|
+
"COUNTRY_REVERSE_MAP",
|
|
289
|
+
"CONTINENT_MAP",
|
|
290
|
+
"CONTINENT_REVERSE_MAP",
|
|
291
|
+
"REGION_MAP",
|
|
292
|
+
"REGION_REVERSE_MAP",
|
|
293
|
+
"COUNTRY_TO_LOCATION_STATIC",
|
|
294
|
+
"get_timezone_enum",
|
|
295
|
+
"get_country_enum",
|
|
296
|
+
"get_region_enum",
|
|
297
|
+
"get_continent_enum",
|
|
298
|
+
"get_continent_region_from_country",
|
|
299
|
+
# Registers
|
|
300
|
+
"FUNC_EN_REGISTER",
|
|
301
|
+
"FUNC_EN_BIT_EPS_EN",
|
|
302
|
+
"FUNC_EN_BIT_AC_CHARGE_EN",
|
|
303
|
+
"FUNC_EN_BIT_SET_TO_STANDBY",
|
|
304
|
+
"FUNC_EN_BIT_FORCED_DISCHG_EN",
|
|
305
|
+
"FUNC_EN_BIT_FORCED_CHG_EN",
|
|
306
|
+
"HOLD_AC_CHARGE_POWER_CMD",
|
|
307
|
+
"HOLD_AC_CHARGE_SOC_LIMIT",
|
|
308
|
+
"HOLD_AC_CHARGE_START_HOUR_1",
|
|
309
|
+
"HOLD_AC_CHARGE_START_MIN_1",
|
|
310
|
+
"HOLD_AC_CHARGE_END_HOUR_1",
|
|
311
|
+
"HOLD_AC_CHARGE_END_MIN_1",
|
|
312
|
+
"HOLD_AC_CHARGE_ENABLE_1",
|
|
313
|
+
"HOLD_AC_CHARGE_ENABLE_2",
|
|
314
|
+
"HOLD_DISCHG_POWER_CMD",
|
|
315
|
+
"HOLD_DISCHG_START_HOUR_1",
|
|
316
|
+
"HOLD_DISCHG_START_MIN_1",
|
|
317
|
+
"HOLD_DISCHG_END_HOUR_1",
|
|
318
|
+
"HOLD_DISCHG_END_MIN_1",
|
|
319
|
+
"HOLD_DISCHG_ENABLE_1",
|
|
320
|
+
"HOLD_BAT_VOLT_MAX_CHG",
|
|
321
|
+
"HOLD_BAT_VOLT_MIN_CHG",
|
|
322
|
+
"HOLD_BAT_VOLT_MAX_DISCHG",
|
|
323
|
+
"HOLD_BAT_VOLT_MIN_DISCHG",
|
|
324
|
+
"HOLD_MAX_CHG_CURR",
|
|
325
|
+
"HOLD_MAX_DISCHG_CURR",
|
|
326
|
+
"HOLD_DISCHG_CUT_OFF_SOC_EOD",
|
|
327
|
+
"HOLD_SOC_LOW_LIMIT_EPS_DISCHG",
|
|
328
|
+
"HOLD_GRID_VOLT_HIGH_1",
|
|
329
|
+
"HOLD_GRID_VOLT_LOW_1",
|
|
330
|
+
"HOLD_GRID_FREQ_HIGH_1",
|
|
331
|
+
"HOLD_GRID_FREQ_LOW_1",
|
|
332
|
+
"HOLD_Q_MODE",
|
|
333
|
+
"HOLD_Q_PV_MODE",
|
|
334
|
+
"HOLD_Q_POWER",
|
|
335
|
+
"HOLD_Q_PV_POWER",
|
|
336
|
+
"HOLD_SERIAL_NUMBER_H",
|
|
337
|
+
"HOLD_SERIAL_NUMBER_L",
|
|
338
|
+
"HOLD_YEAR",
|
|
339
|
+
"HOLD_MONTH",
|
|
340
|
+
"HOLD_DAY",
|
|
341
|
+
"HOLD_HOUR",
|
|
342
|
+
"HOLD_MINUTE",
|
|
343
|
+
"HOLD_SECOND",
|
|
344
|
+
"HOLD_LANGUAGE",
|
|
345
|
+
"HOLD_MODBUS_ADDRESS",
|
|
346
|
+
"HOLD_BAUD_RATE",
|
|
347
|
+
"INPUT_STATUS",
|
|
348
|
+
"INPUT_V_PV1",
|
|
349
|
+
"INPUT_V_PV2",
|
|
350
|
+
"INPUT_V_PV3",
|
|
351
|
+
"INPUT_V_BAT",
|
|
352
|
+
"INPUT_SOC",
|
|
353
|
+
"INPUT_P_PV1",
|
|
354
|
+
"INPUT_P_PV2",
|
|
355
|
+
"INPUT_P_PV3",
|
|
356
|
+
"INPUT_P_CHARGE",
|
|
357
|
+
"INPUT_P_DISCHARGE",
|
|
358
|
+
"INPUT_V_AC_R",
|
|
359
|
+
"INPUT_V_AC_S",
|
|
360
|
+
"INPUT_V_AC_T",
|
|
361
|
+
"INPUT_F_AC",
|
|
362
|
+
"INPUT_P_INV",
|
|
363
|
+
"INPUT_P_REC",
|
|
364
|
+
"INPUT_PF",
|
|
365
|
+
"INPUT_V_EPS_R",
|
|
366
|
+
"INPUT_V_EPS_S",
|
|
367
|
+
"INPUT_V_EPS_T",
|
|
368
|
+
"INPUT_F_EPS",
|
|
369
|
+
"INPUT_P_EPS",
|
|
370
|
+
"INPUT_S_EPS",
|
|
371
|
+
"INPUT_P_TO_GRID",
|
|
372
|
+
"INPUT_P_TO_USER",
|
|
373
|
+
"INPUT_E_INV_ALL",
|
|
374
|
+
"INPUT_E_REC_ALL",
|
|
375
|
+
"INPUT_E_CHG_ALL",
|
|
376
|
+
"INPUT_E_DISCHG_ALL",
|
|
377
|
+
"INPUT_E_EPS_ALL",
|
|
378
|
+
"INPUT_E_TO_GRID_ALL",
|
|
379
|
+
"INPUT_E_TO_USER_ALL",
|
|
380
|
+
"INPUT_V_BUS1",
|
|
381
|
+
"INPUT_V_BUS2",
|
|
382
|
+
"INPUT_E_INV_DAY",
|
|
383
|
+
"INPUT_E_REC_DAY",
|
|
384
|
+
"INPUT_E_CHG_DAY",
|
|
385
|
+
"INPUT_E_DISCHG_DAY",
|
|
386
|
+
"INPUT_E_EPS_DAY",
|
|
387
|
+
"INPUT_E_TO_GRID_DAY",
|
|
388
|
+
"INPUT_E_TO_USER_DAY",
|
|
389
|
+
"INPUT_V_BAT_LIMIT",
|
|
390
|
+
"INPUT_I_BAT_LIMIT",
|
|
391
|
+
"INPUT_T_INNER",
|
|
392
|
+
"INPUT_T_RADIATOR_1",
|
|
393
|
+
"INPUT_T_RADIATOR_2",
|
|
394
|
+
"INPUT_T_BAT",
|
|
395
|
+
"INPUT_T_BAT_CONTROL",
|
|
396
|
+
"INPUT_I_REC_R",
|
|
397
|
+
"INPUT_I_REC_S",
|
|
398
|
+
"INPUT_I_REC_T",
|
|
399
|
+
"INPUT_I_INV_R",
|
|
400
|
+
"INPUT_I_INV_S",
|
|
401
|
+
"INPUT_I_INV_T",
|
|
402
|
+
"INPUT_I_PV1",
|
|
403
|
+
"INPUT_I_PV2",
|
|
404
|
+
"INPUT_I_PV3",
|
|
405
|
+
"INPUT_I_BAT",
|
|
406
|
+
"INPUT_INTERNAL_FAULT",
|
|
407
|
+
"INPUT_FAULT_HISTORY_1",
|
|
408
|
+
"INPUT_FAULT_HISTORY_2",
|
|
409
|
+
"INPUT_FAULT_HISTORY_3",
|
|
410
|
+
"INPUT_FAULT_HISTORY_4",
|
|
411
|
+
"INPUT_FAULT_HISTORY_5",
|
|
412
|
+
"INPUT_SOH",
|
|
413
|
+
"INPUT_BMS_FAULT",
|
|
414
|
+
"INPUT_BMS_WARNING",
|
|
415
|
+
"INPUT_E_PV1_ALL",
|
|
416
|
+
"INPUT_E_PV2_ALL",
|
|
417
|
+
"INPUT_E_PV3_ALL",
|
|
418
|
+
"INPUT_E_PV1_DAY",
|
|
419
|
+
"INPUT_E_PV2_DAY",
|
|
420
|
+
"INPUT_E_PV3_DAY",
|
|
421
|
+
"INPUT_MAX_CHG_CURR",
|
|
422
|
+
"INPUT_MAX_DISCHG_CURR",
|
|
423
|
+
"INPUT_CHARGE_VOLT_REF",
|
|
424
|
+
"INPUT_DISCHARGE_VOLT_REF",
|
|
425
|
+
"HOLD_REGISTER_GROUPS",
|
|
426
|
+
"INPUT_REGISTER_GROUPS",
|
|
427
|
+
"WEB_PARAM_TO_HOLD_REGISTER",
|
|
428
|
+
"REGISTER_TO_PARAM_KEYS_18KPV",
|
|
429
|
+
"PARAM_KEY_TO_REGISTER_18KPV",
|
|
430
|
+
"REGISTER_STATS_18KPV",
|
|
431
|
+
"GRIDBOSS_PARAMETERS",
|
|
432
|
+
"GRIDBOSS_STATS",
|
|
433
|
+
# Model-specific parameters
|
|
434
|
+
"SNA_PARAMETERS",
|
|
435
|
+
"PV_SERIES_PARAMETERS",
|
|
436
|
+
"LXP_EU_PARAMETERS",
|
|
437
|
+
"DEVICE_TYPE_CODE_SNA",
|
|
438
|
+
"DEVICE_TYPE_CODE_PV_SERIES",
|
|
439
|
+
"DEVICE_TYPE_CODE_LXP_EU",
|
|
440
|
+
"get_func_en_bit_mask",
|
|
441
|
+
"set_func_en_bit",
|
|
442
|
+
"get_func_en_bit",
|
|
443
|
+
# Scaling
|
|
444
|
+
"ScaleFactor",
|
|
445
|
+
"INVERTER_RUNTIME_SCALING",
|
|
446
|
+
"ENERGY_INFO_SCALING",
|
|
447
|
+
"BATTERY_BANK_SCALING",
|
|
448
|
+
"BATTERY_MODULE_SCALING",
|
|
449
|
+
"GRIDBOSS_RUNTIME_SCALING",
|
|
450
|
+
"INVERTER_OVERVIEW_SCALING",
|
|
451
|
+
"PARAMETER_SCALING",
|
|
452
|
+
"apply_scale",
|
|
453
|
+
"get_precision",
|
|
454
|
+
"get_battery_field_precision",
|
|
455
|
+
"scale_runtime_value",
|
|
456
|
+
"scale_battery_value",
|
|
457
|
+
"scale_energy_value",
|
|
458
|
+
"_get_scaling_for_field",
|
|
459
|
+
# API
|
|
460
|
+
"HTTP_OK",
|
|
461
|
+
"HTTP_UNAUTHORIZED",
|
|
462
|
+
"HTTP_FORBIDDEN",
|
|
463
|
+
"BACKOFF_BASE_DELAY_SECONDS",
|
|
464
|
+
"BACKOFF_MAX_DELAY_SECONDS",
|
|
465
|
+
"MAX_LOGIN_RETRIES",
|
|
466
|
+
"MAX_TRANSIENT_ERROR_RETRIES",
|
|
467
|
+
"TRANSIENT_ERROR_MESSAGES",
|
|
468
|
+
# Devices
|
|
469
|
+
"DEVICE_TYPE_INVERTER",
|
|
470
|
+
"DEVICE_TYPE_GRIDBOSS",
|
|
471
|
+
"TIMEZONE_HHMM_HOURS_FACTOR",
|
|
472
|
+
"TIMEZONE_HHMM_MINUTES_FACTOR",
|
|
473
|
+
"parse_hhmm_timezone",
|
|
474
|
+
"SCALE_MID_VOLTAGE",
|
|
475
|
+
"SCALE_MID_FREQUENCY",
|
|
476
|
+
"scale_mid_voltage",
|
|
477
|
+
"scale_mid_frequency",
|
|
478
|
+
"SOC_MIN_PERCENT",
|
|
479
|
+
"SOC_MAX_PERCENT",
|
|
480
|
+
"MAX_REGISTERS_PER_READ",
|
|
481
|
+
]
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"""API-related constants for HTTP communication and error handling.
|
|
2
|
+
|
|
3
|
+
This module contains HTTP status codes, backoff/retry configuration,
|
|
4
|
+
and transient error detection for API communication.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
# HTTP Status Codes
|
|
10
|
+
# ==============================================================================
|
|
11
|
+
# Standard HTTP status codes used throughout the library
|
|
12
|
+
HTTP_OK = 200
|
|
13
|
+
HTTP_UNAUTHORIZED = 401
|
|
14
|
+
HTTP_FORBIDDEN = 403
|
|
15
|
+
|
|
16
|
+
# ==============================================================================
|
|
17
|
+
# Device Type Constants
|
|
18
|
+
# ==============================================================================
|
|
19
|
+
# Device type identifiers from the Luxpower API
|
|
20
|
+
DEVICE_TYPE_INVERTER = 6 # Standard inverter
|
|
21
|
+
DEVICE_TYPE_GRIDBOSS = 9 # GridBOSS/MID device (parallel group controller)
|
|
22
|
+
|
|
23
|
+
# ==============================================================================
|
|
24
|
+
# Backoff and Retry Constants
|
|
25
|
+
# ==============================================================================
|
|
26
|
+
# Base delay (in seconds) for exponential backoff on API errors
|
|
27
|
+
BACKOFF_BASE_DELAY_SECONDS = 1.0
|
|
28
|
+
|
|
29
|
+
# Maximum delay (in seconds) for exponential backoff
|
|
30
|
+
BACKOFF_MAX_DELAY_SECONDS = 60.0
|
|
31
|
+
|
|
32
|
+
# Maximum number of retry attempts for transient errors
|
|
33
|
+
MAX_TRANSIENT_ERROR_RETRIES = 3
|
|
34
|
+
|
|
35
|
+
# Maximum number of retry attempts for login (re-authentication)
|
|
36
|
+
# This allows recovery from transient network issues during re-auth
|
|
37
|
+
# without requiring manual user intervention (fixes issue #70)
|
|
38
|
+
MAX_LOGIN_RETRIES = 3
|
|
39
|
+
|
|
40
|
+
# Known transient error messages that should trigger automatic retry
|
|
41
|
+
# These are hardware/network communication errors that may succeed on retry
|
|
42
|
+
TRANSIENT_ERROR_MESSAGES = {
|
|
43
|
+
"DATAFRAME_TIMEOUT", # Inverter dataframe communication timeout
|
|
44
|
+
"TIMEOUT", # Generic timeout error
|
|
45
|
+
"BUSY", # Device busy, try again
|
|
46
|
+
"COMMUNICATION_ERROR", # Communication failure with device
|
|
47
|
+
"DEVICE_BUSY", # Device is busy processing another request
|
|
48
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"""Device-related constants and helper functions.
|
|
2
|
+
|
|
3
|
+
This module contains device type identifiers, limits, timezone parsing,
|
|
4
|
+
and other device-specific utility functions.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
# ==============================================================================
|
|
10
|
+
# Timezone Parsing Constants
|
|
11
|
+
# ==============================================================================
|
|
12
|
+
# Factor to convert HHMM format timezone offset to hours/minutes
|
|
13
|
+
# Example: timezone offset 800 → 8 hours, 0 minutes (800 // 100 = 8, 800 % 100 = 0)
|
|
14
|
+
TIMEZONE_HHMM_HOURS_FACTOR = 100
|
|
15
|
+
TIMEZONE_HHMM_MINUTES_FACTOR = 100
|
|
16
|
+
|
|
17
|
+
# ==============================================================================
|
|
18
|
+
# MID Device Scaling Constants
|
|
19
|
+
# ==============================================================================
|
|
20
|
+
# Scaling factors for MID device (GridBOSS) values
|
|
21
|
+
# Note: These differ from standard inverter scaling factors
|
|
22
|
+
SCALE_MID_VOLTAGE = 10 # MID device voltages are scaled by 10
|
|
23
|
+
SCALE_MID_FREQUENCY = 100 # Frequency values are scaled by 100
|
|
24
|
+
|
|
25
|
+
# ==============================================================================
|
|
26
|
+
# SOC (State of Charge) Limits
|
|
27
|
+
# ==============================================================================
|
|
28
|
+
# Minimum and maximum allowed SOC percentage values
|
|
29
|
+
SOC_MIN_PERCENT = 0
|
|
30
|
+
SOC_MAX_PERCENT = 100
|
|
31
|
+
|
|
32
|
+
# ==============================================================================
|
|
33
|
+
# Register Reading Limits
|
|
34
|
+
# ==============================================================================
|
|
35
|
+
# Maximum number of registers that can be read in a single API call
|
|
36
|
+
# API limitation: Cannot read more than 127 registers at once
|
|
37
|
+
MAX_REGISTERS_PER_READ = 127
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
# ==============================================================================
|
|
41
|
+
# Helper Functions
|
|
42
|
+
# ==============================================================================
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def parse_hhmm_timezone(value: int) -> tuple[int, int]:
|
|
46
|
+
"""Parse HHMM format timezone offset into hours and minutes.
|
|
47
|
+
|
|
48
|
+
Args:
|
|
49
|
+
value: Timezone offset in HHMM format (e.g., 800 for +8:00, -530 for -5:30)
|
|
50
|
+
|
|
51
|
+
Returns:
|
|
52
|
+
Tuple of (hours, minutes) with appropriate sign
|
|
53
|
+
|
|
54
|
+
Examples:
|
|
55
|
+
>>> parse_hhmm_timezone(800)
|
|
56
|
+
(8, 0)
|
|
57
|
+
>>> parse_hhmm_timezone(-530)
|
|
58
|
+
(-5, 30)
|
|
59
|
+
>>> parse_hhmm_timezone(-800)
|
|
60
|
+
(-8, 0)
|
|
61
|
+
"""
|
|
62
|
+
hours = abs(value) // TIMEZONE_HHMM_HOURS_FACTOR
|
|
63
|
+
minutes = abs(value) % TIMEZONE_HHMM_MINUTES_FACTOR
|
|
64
|
+
if value < 0:
|
|
65
|
+
hours = -hours
|
|
66
|
+
return hours, minutes
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def scale_mid_voltage(raw_value: int | float) -> float:
|
|
70
|
+
"""Scale MID device voltage value from API format to volts.
|
|
71
|
+
|
|
72
|
+
Args:
|
|
73
|
+
raw_value: Raw voltage value from MID device API (scaled by 10)
|
|
74
|
+
|
|
75
|
+
Returns:
|
|
76
|
+
Voltage in volts (V)
|
|
77
|
+
|
|
78
|
+
Example:
|
|
79
|
+
>>> scale_mid_voltage(2400)
|
|
80
|
+
240.0
|
|
81
|
+
"""
|
|
82
|
+
return float(raw_value) / SCALE_MID_VOLTAGE
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def scale_mid_frequency(raw_value: int | float) -> float:
|
|
86
|
+
"""Scale MID device frequency value from API format to Hz.
|
|
87
|
+
|
|
88
|
+
Args:
|
|
89
|
+
raw_value: Raw frequency value from MID device API (scaled by 100)
|
|
90
|
+
|
|
91
|
+
Returns:
|
|
92
|
+
Frequency in Hz
|
|
93
|
+
|
|
94
|
+
Example:
|
|
95
|
+
>>> scale_mid_frequency(5998)
|
|
96
|
+
59.98
|
|
97
|
+
"""
|
|
98
|
+
return float(raw_value) / SCALE_MID_FREQUENCY
|