pylxpweb 0.1.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.
pylxpweb/constants.py ADDED
@@ -0,0 +1,1183 @@
1
+ """Constants and mappings for Luxpower/EG4 API.
2
+
3
+ This module contains mapping tables extracted from the EG4 web interface
4
+ to convert between human-readable API values and the enum values required
5
+ for configuration updates.
6
+
7
+ These mappings were discovered by analyzing the HTML form at:
8
+ /WManage/web/config/plant/edit/{plant_id}
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ # Timezone mappings: Human-readable (from API) → Form enum (for POST)
14
+ # Source: Analyzed all 28 timezone options from the HTML form
15
+ TIMEZONE_MAP: dict[str, str] = {
16
+ "GMT -12": "WEST12",
17
+ "GMT -11": "WEST11",
18
+ "GMT -10": "WEST10",
19
+ "GMT -9": "WEST9",
20
+ "GMT -8": "WEST8",
21
+ "GMT -7": "WEST7",
22
+ "GMT -6": "WEST6",
23
+ "GMT -5": "WEST5",
24
+ "GMT -4": "WEST4",
25
+ "GMT -3": "WEST3",
26
+ "GMT -2": "WEST2",
27
+ "GMT -1": "WEST1",
28
+ "GMT 0": "ZERO",
29
+ "GMT +1": "EAST1",
30
+ "GMT +2": "EAST2",
31
+ "GMT +3": "EAST3",
32
+ "GMT +3:30": "EAST3_30",
33
+ "GMT +4": "EAST4",
34
+ "GMT +5": "EAST5",
35
+ "GMT +5:30": "EAST5_30",
36
+ "GMT +6": "EAST6",
37
+ "GMT +6:30": "EAST6_30",
38
+ "GMT +7": "EAST7",
39
+ "GMT +8": "EAST8",
40
+ "GMT +9": "EAST9",
41
+ "GMT +10": "EAST10",
42
+ "GMT +11": "EAST11",
43
+ "GMT +12": "EAST12",
44
+ }
45
+
46
+ # Reverse mapping: Form enum → Human-readable
47
+ TIMEZONE_REVERSE_MAP: dict[str, str] = {v: k for k, v in TIMEZONE_MAP.items()}
48
+
49
+ # Country mappings: Human-readable (from API) → Form enum (for POST)
50
+ # Source: Analyzed country options from HTML form (North America region shown)
51
+ # NOTE: This list is incomplete - only shows North American countries
52
+ # Additional countries would appear based on selected continent/region
53
+ COUNTRY_MAP: dict[str, str] = {
54
+ "Canada": "CANADA",
55
+ "United States of America": "UNITED_STATES_OF_AMERICA",
56
+ "Mexico": "MEXICO",
57
+ "Greenland": "GREENLAND",
58
+ }
59
+
60
+ # Reverse mapping: Form enum → Human-readable
61
+ COUNTRY_REVERSE_MAP: dict[str, str] = {v: k for k, v in COUNTRY_MAP.items()}
62
+
63
+ # Continent mappings: Human-readable → Form enum
64
+ # Source: All 6 continent options from HTML form
65
+ CONTINENT_MAP: dict[str, str] = {
66
+ "Africa": "AFRICA",
67
+ "Asia": "ASIA",
68
+ "Europe": "EUROPE",
69
+ "North America": "NORTH_AMERICA",
70
+ "Oceania": "OCEANIA",
71
+ "South America": "SOUTH_AMERICA",
72
+ }
73
+
74
+ CONTINENT_REVERSE_MAP: dict[str, str] = {v: k for k, v in CONTINENT_MAP.items()}
75
+
76
+ # Region mappings: Human-readable → Form enum
77
+ # Source: Region options from HTML form (context: North America continent)
78
+ # NOTE: Region options are hierarchical and depend on selected continent
79
+ REGION_MAP: dict[str, str] = {
80
+ # North America regions (when continent = NORTH_AMERICA)
81
+ "Caribbean": "CARIBBEAN",
82
+ "Central America": "CENTRAL_AMERICA",
83
+ "North America": "NORTH_AMERICA",
84
+ # Additional regions would be discovered when exploring other continents
85
+ }
86
+
87
+ REGION_REVERSE_MAP: dict[str, str] = {v: k for k, v in REGION_MAP.items()}
88
+
89
+
90
+ def get_timezone_enum(human_readable: str) -> str:
91
+ """Convert human-readable timezone to API enum.
92
+
93
+ Args:
94
+ human_readable: Timezone string like "GMT -8"
95
+
96
+ Returns:
97
+ API enum like "WEST8"
98
+
99
+ Raises:
100
+ ValueError: If timezone is not recognized
101
+ """
102
+ if human_readable in TIMEZONE_MAP:
103
+ return TIMEZONE_MAP[human_readable]
104
+ raise ValueError(f"Unknown timezone: {human_readable}")
105
+
106
+
107
+ def get_country_enum(human_readable: str) -> str:
108
+ """Convert human-readable country to API enum.
109
+
110
+ Args:
111
+ human_readable: Country string like "United States of America"
112
+
113
+ Returns:
114
+ API enum like "UNITED_STATES_OF_AMERICA"
115
+
116
+ Raises:
117
+ ValueError: If country is not recognized
118
+ """
119
+ if human_readable in COUNTRY_MAP:
120
+ return COUNTRY_MAP[human_readable]
121
+ raise ValueError(f"Unknown country: {human_readable}")
122
+
123
+
124
+ def get_region_enum(human_readable: str) -> str:
125
+ """Convert human-readable region to API enum.
126
+
127
+ Args:
128
+ human_readable: Region string like "North America"
129
+
130
+ Returns:
131
+ API enum like "NORTH_AMERICA"
132
+
133
+ Raises:
134
+ ValueError: If region is not recognized
135
+ """
136
+ if human_readable in REGION_MAP:
137
+ return REGION_MAP[human_readable]
138
+ raise ValueError(f"Unknown region: {human_readable}")
139
+
140
+
141
+ def get_continent_enum(human_readable: str) -> str:
142
+ """Convert human-readable continent to API enum.
143
+
144
+ Args:
145
+ human_readable: Continent string like "North America"
146
+
147
+ Returns:
148
+ API enum like "NORTH_AMERICA"
149
+
150
+ Raises:
151
+ ValueError: If continent is not recognized
152
+ """
153
+ if human_readable in CONTINENT_MAP:
154
+ return CONTINENT_MAP[human_readable]
155
+ raise ValueError(f"Unknown continent: {human_readable}")
156
+
157
+
158
+ # Static mapping for common countries (fast path)
159
+ # This covers the most frequently used countries to avoid API calls
160
+ COUNTRY_TO_LOCATION_STATIC: dict[str, tuple[str, str]] = {
161
+ # North America
162
+ "United States of America": ("NORTH_AMERICA", "NORTH_AMERICA"),
163
+ "Canada": ("NORTH_AMERICA", "NORTH_AMERICA"),
164
+ "Mexico": ("NORTH_AMERICA", "CENTRAL_AMERICA"),
165
+ "Greenland": ("NORTH_AMERICA", "NORTH_AMERICA"),
166
+ # Europe (common)
167
+ "United Kingdom": ("EUROPE", "WESTERN_EUROPE"),
168
+ "Germany": ("EUROPE", "CENTRAL_EUROPE"),
169
+ "France": ("EUROPE", "WESTERN_EUROPE"),
170
+ "Spain": ("EUROPE", "SOUTHERN_EUROPE"),
171
+ "Italy": ("EUROPE", "SOUTHERN_EUROPE"),
172
+ "The Netherlands": ("EUROPE", "WESTERN_EUROPE"),
173
+ "Belgium": ("EUROPE", "WESTERN_EUROPE"),
174
+ "Switzerland": ("EUROPE", "CENTRAL_EUROPE"),
175
+ "Austria": ("EUROPE", "CENTRAL_EUROPE"),
176
+ "Poland": ("EUROPE", "CENTRAL_EUROPE"),
177
+ "Sweden": ("EUROPE", "NORDIC_EUROPE"),
178
+ "Norway": ("EUROPE", "NORDIC_EUROPE"),
179
+ "Denmark": ("EUROPE", "NORDIC_EUROPE"),
180
+ # Asia (common)
181
+ "China": ("ASIA", "EAST_ASIA"),
182
+ "Japan": ("ASIA", "EAST_ASIA"),
183
+ "South korea": ("ASIA", "EAST_ASIA"),
184
+ "India": ("ASIA", "SOUTH_ASIA"),
185
+ "Singapore": ("ASIA", "SOUTHEAST_ASIA"),
186
+ "Thailand": ("ASIA", "SOUTHEAST_ASIA"),
187
+ "Malaysia": ("ASIA", "SOUTHEAST_ASIA"),
188
+ "Indonesia": ("ASIA", "SOUTHEAST_ASIA"),
189
+ "Philippines": ("ASIA", "SOUTHEAST_ASIA"),
190
+ "Vietnam": ("ASIA", "SOUTHEAST_ASIA"),
191
+ # Oceania
192
+ "Australia": ("OCEANIA", "OCEANIA"),
193
+ "New Zealand": ("OCEANIA", "OCEANIA"),
194
+ # South America
195
+ "Brazil": ("SOUTH_AMERICA", "SA_EAST"),
196
+ "Argentina": ("SOUTH_AMERICA", "SA_SOUTHERN_PART"), # Note: API has "Aregntine" typo
197
+ "Chile": ("SOUTH_AMERICA", "SA_SOUTHERN_PART"),
198
+ # Africa (common)
199
+ "South Africa": ("AFRICA", "SOUTH_AFRICA"),
200
+ "Egypt": ("AFRICA", "NORTH_AFRICA"),
201
+ }
202
+
203
+
204
+ def get_continent_region_from_country(country_human: str) -> tuple[str, str]:
205
+ """Derive continent and region enums from country name.
206
+
207
+ Uses static mapping for common countries (fast path).
208
+ For unknown countries, requires dynamic fetching from locale API.
209
+
210
+ Args:
211
+ country_human: Human-readable country name from API
212
+
213
+ Returns:
214
+ Tuple of (continent_enum, region_enum)
215
+
216
+ Raises:
217
+ ValueError: If country is not in static mapping (requires dynamic fetch)
218
+ """
219
+ # Fast path: check static mapping
220
+ if country_human in COUNTRY_TO_LOCATION_STATIC:
221
+ return COUNTRY_TO_LOCATION_STATIC[country_human]
222
+
223
+ # Country not in static mapping - requires dynamic fetch
224
+ raise ValueError(
225
+ f"Country '{country_human}' not in static mapping. "
226
+ "Dynamic fetching from locale API required."
227
+ )
228
+
229
+
230
+ # ============================================================================
231
+ # INVERTER PARAMETER MAPPINGS (Hold Registers)
232
+ # ============================================================================
233
+ # Source: EG4-18KPV-12LV Modbus Protocol specification
234
+ # Complete documentation: docs/api/PARAMETER_MAPPING.md
235
+
236
+ # Critical Control Register (Address 21) - Function Enable Bit Field
237
+ FUNC_EN_REGISTER = 21
238
+ FUNC_EN_BIT_EPS_EN = 0 # Off-grid mode enable
239
+ FUNC_EN_BIT_AC_CHARGE_EN = 7 # AC charge enable
240
+ FUNC_EN_BIT_SET_TO_STANDBY = 9 # 0=Standby, 1=Power On
241
+ FUNC_EN_BIT_FORCED_DISCHG_EN = 10 # Forced discharge enable
242
+ FUNC_EN_BIT_FORCED_CHG_EN = 11 # Force charge enable
243
+
244
+ # AC Charge Parameters
245
+ HOLD_AC_CHARGE_POWER_CMD = 66 # AC charge power (0-100%)
246
+ HOLD_AC_CHARGE_SOC_LIMIT = 67 # AC charge SOC limit (0-100%)
247
+ HOLD_AC_CHARGE_START_HOUR_1 = 68 # Time period 1 start hour (0-23)
248
+ HOLD_AC_CHARGE_START_MIN_1 = 69 # Time period 1 start minute (0-59)
249
+ HOLD_AC_CHARGE_END_HOUR_1 = 70 # Time period 1 end hour (0-23)
250
+ HOLD_AC_CHARGE_END_MIN_1 = 71 # Time period 1 end minute (0-59)
251
+ HOLD_AC_CHARGE_ENABLE_1 = 72 # Time period 1 enable (0=Off, 1=On)
252
+ HOLD_AC_CHARGE_ENABLE_2 = 73 # Time period 2 enable (0=Off, 1=On)
253
+
254
+ # Discharge Parameters
255
+ HOLD_DISCHG_POWER_CMD = 74 # Discharge power command (0-100%)
256
+ HOLD_DISCHG_START_HOUR_1 = 75 # Discharge start hour 1 (0-23)
257
+ HOLD_DISCHG_START_MIN_1 = 76 # Discharge start minute 1 (0-59)
258
+ HOLD_DISCHG_END_HOUR_1 = 77 # Discharge end hour 1 (0-23)
259
+ HOLD_DISCHG_END_MIN_1 = 78 # Discharge end minute 1 (0-59)
260
+ HOLD_DISCHG_ENABLE_1 = 79 # Discharge enable 1 (0=Off, 1=On)
261
+
262
+ # Battery Protection Parameters
263
+ HOLD_BAT_VOLT_MAX_CHG = 99 # Battery max charge voltage (V, /100)
264
+ HOLD_BAT_VOLT_MIN_CHG = 100 # Battery min charge voltage (V, /100)
265
+ HOLD_BAT_VOLT_MAX_DISCHG = 101 # Battery max discharge voltage (V, /100)
266
+ HOLD_BAT_VOLT_MIN_DISCHG = 102 # Battery min discharge voltage (V, /100)
267
+ HOLD_MAX_CHG_CURR = 103 # Max charge current (A, /10)
268
+ HOLD_MAX_DISCHG_CURR = 104 # Max discharge current (A, /10)
269
+ HOLD_DISCHG_CUT_OFF_SOC_EOD = 105 # On-grid discharge cutoff SOC (10-90%)
270
+ HOLD_SOC_LOW_LIMIT_EPS_DISCHG = 106 # Off-grid SOC low limit (0-100%)
271
+
272
+ # Grid Protection Parameters
273
+ HOLD_GRID_VOLT_HIGH_1 = 25 # Grid voltage high limit 1 (V, /10)
274
+ HOLD_GRID_VOLT_LOW_1 = 26 # Grid voltage low limit 1 (V, /10)
275
+ HOLD_GRID_FREQ_HIGH_1 = 27 # Grid frequency high 1 (Hz, /100)
276
+ HOLD_GRID_FREQ_LOW_1 = 28 # Grid frequency low 1 (Hz, /100)
277
+
278
+ # Reactive Power Control
279
+ HOLD_Q_MODE = 59 # Reactive power mode (0-4)
280
+ HOLD_Q_PV_MODE = 60 # PV reactive power mode (0-4)
281
+ HOLD_Q_POWER = 61 # Reactive power setting (-100 to 100%)
282
+ HOLD_Q_PV_POWER = 62 # PV reactive power (-100 to 100%)
283
+
284
+ # System Configuration
285
+ HOLD_SERIAL_NUMBER_H = 0 # Serial number (high word)
286
+ HOLD_SERIAL_NUMBER_L = 1 # Serial number (low word)
287
+ HOLD_YEAR = 2 # System year (2000-2099)
288
+ HOLD_MONTH = 3 # System month (1-12)
289
+ HOLD_DAY = 4 # System day (1-31)
290
+ HOLD_HOUR = 5 # System hour (0-23)
291
+ HOLD_MINUTE = 6 # System minute (0-59)
292
+ HOLD_SECOND = 7 # System second (0-59)
293
+ HOLD_LANGUAGE = 8 # Language (0=EN, 1=CN)
294
+ HOLD_MODBUS_ADDRESS = 9 # Modbus RTU address (1-247)
295
+ HOLD_BAUD_RATE = 10 # Baud rate index (0-6)
296
+
297
+ # ============================================================================
298
+ # INPUT REGISTERS (Runtime Data - Read Only)
299
+ # ============================================================================
300
+
301
+ # Power & Energy (Addresses 0-31)
302
+ INPUT_STATUS = 0 # Device status code
303
+ INPUT_V_PV1 = 1 # PV1 voltage (V, /10)
304
+ INPUT_V_PV2 = 2 # PV2 voltage (V, /10)
305
+ INPUT_V_PV3 = 3 # PV3 voltage (V, /10)
306
+ INPUT_V_BAT = 4 # Battery voltage (V, /100)
307
+ INPUT_SOC = 5 # State of Charge (%)
308
+ INPUT_P_PV1 = (6, 7) # PV1 power (W, 2 registers)
309
+ INPUT_P_PV2 = (8, 9) # PV2 power (W, 2 registers)
310
+ INPUT_P_PV3 = (10, 11) # PV3 power (W, 2 registers)
311
+ INPUT_P_CHARGE = (12, 13) # Battery charge power (W, 2 registers)
312
+ INPUT_P_DISCHARGE = (14, 15) # Battery discharge power (W, 2 registers)
313
+ INPUT_V_AC_R = 16 # AC R-phase voltage (V, /10)
314
+ INPUT_V_AC_S = 17 # AC S-phase voltage (V, /10)
315
+ INPUT_V_AC_T = 18 # AC T-phase voltage (V, /10)
316
+ INPUT_F_AC = 19 # AC frequency (Hz, /100)
317
+ INPUT_P_INV = (20, 21) # Inverter output power (W, 2 registers)
318
+ INPUT_P_REC = (22, 23) # Grid import power (W, 2 registers)
319
+ INPUT_PF = (24, 25) # Power factor (/1000, 2 registers)
320
+ INPUT_V_EPS_R = 26 # EPS R-phase voltage (V, /10)
321
+ INPUT_V_EPS_S = 27 # EPS S-phase voltage (V, /10)
322
+ INPUT_V_EPS_T = 28 # EPS T-phase voltage (V, /10)
323
+ INPUT_F_EPS = 29 # EPS frequency (Hz, /100)
324
+ INPUT_P_EPS = (30, 31) # EPS output power (W, 2 registers)
325
+
326
+ # System Status (Addresses 32-60)
327
+ INPUT_S_EPS = 32 # EPS status
328
+ INPUT_P_TO_GRID = 33 # Export to grid power (W)
329
+ INPUT_P_TO_USER = (34, 35) # Load consumption power (W, 2 registers)
330
+ INPUT_E_INV_ALL = 36 # Total inverter energy (kWh, /10)
331
+ INPUT_E_REC_ALL = 37 # Total grid import energy (kWh, /10)
332
+ INPUT_E_CHG_ALL = 38 # Total charge energy (kWh, /10)
333
+ INPUT_E_DISCHG_ALL = 39 # Total discharge energy (kWh, /10)
334
+ INPUT_E_EPS_ALL = 40 # Total EPS energy (kWh, /10)
335
+ INPUT_E_TO_GRID_ALL = 41 # Total export energy (kWh, /10)
336
+ INPUT_E_TO_USER_ALL = 42 # Total load energy (kWh, /10)
337
+ INPUT_V_BUS1 = 43 # Bus 1 voltage (V, /10)
338
+ INPUT_V_BUS2 = 44 # Bus 2 voltage (V, /10)
339
+ INPUT_E_INV_DAY = (45, 46) # Daily inverter energy (kWh, /10, 2 registers)
340
+ INPUT_E_REC_DAY = (47, 48) # Daily grid import (kWh, /10, 2 registers)
341
+ INPUT_E_CHG_DAY = (49, 50) # Daily charge energy (kWh, /10, 2 registers)
342
+ INPUT_E_DISCHG_DAY = (51, 52) # Daily discharge energy (kWh, /10, 2 registers)
343
+ INPUT_E_EPS_DAY = (53, 54) # Daily EPS energy (kWh, /10, 2 registers)
344
+ INPUT_E_TO_GRID_DAY = (55, 56) # Daily export energy (kWh, /10, 2 registers)
345
+ INPUT_E_TO_USER_DAY = (57, 58) # Daily load energy (kWh, /10, 2 registers)
346
+ INPUT_V_BAT_LIMIT = 59 # Max charge voltage (V, /100)
347
+ INPUT_I_BAT_LIMIT = 60 # Max charge current (A, /10)
348
+
349
+ # Temperature Sensors (Addresses 61-75)
350
+ INPUT_T_INNER = 61 # Internal temperature (°C)
351
+ INPUT_T_RADIATOR_1 = 62 # Radiator 1 temperature (°C)
352
+ INPUT_T_RADIATOR_2 = 63 # Radiator 2 temperature (°C)
353
+ INPUT_T_BAT = 64 # Battery temperature (°C)
354
+ INPUT_T_BAT_CONTROL = 65 # Battery control temp (°C)
355
+ INPUT_I_REC_R = 66 # Grid R-phase current (A, /100)
356
+ INPUT_I_REC_S = 67 # Grid S-phase current (A, /100)
357
+ INPUT_I_REC_T = 68 # Grid T-phase current (A, /100)
358
+ INPUT_I_INV_R = 69 # Inverter R-phase current (A, /100)
359
+ INPUT_I_INV_S = 70 # Inverter S-phase current (A, /100)
360
+ INPUT_I_INV_T = 71 # Inverter T-phase current (A, /100)
361
+ INPUT_I_PV1 = 72 # PV1 current (A, /100)
362
+ INPUT_I_PV2 = 73 # PV2 current (A, /100)
363
+ INPUT_I_PV3 = 74 # PV3 current (A, /100)
364
+ INPUT_I_BAT = 75 # Battery current (A, /100)
365
+
366
+ # Advanced Status (Addresses 76-106)
367
+ INPUT_INTERNAL_FAULT = (76, 77) # Internal fault code (2 registers)
368
+ INPUT_FAULT_HISTORY_1 = (78, 79) # Fault history 1 (2 registers)
369
+ INPUT_FAULT_HISTORY_2 = (80, 81) # Fault history 2 (2 registers)
370
+ INPUT_FAULT_HISTORY_3 = (82, 83) # Fault history 3 (2 registers)
371
+ INPUT_FAULT_HISTORY_4 = (84, 85) # Fault history 4 (2 registers)
372
+ INPUT_FAULT_HISTORY_5 = (86, 87) # Fault history 5 (2 registers)
373
+ INPUT_SOH = 88 # State of Health (%)
374
+ INPUT_BMS_FAULT = 89 # BMS fault code
375
+ INPUT_BMS_WARNING = 90 # BMS warning code
376
+ INPUT_E_PV1_ALL = (91, 92) # Total PV1 energy (kWh, /10, 2 registers)
377
+ INPUT_E_PV2_ALL = (93, 94) # Total PV2 energy (kWh, /10, 2 registers)
378
+ INPUT_E_PV3_ALL = (95, 96) # Total PV3 energy (kWh, /10, 2 registers)
379
+ INPUT_E_PV1_DAY = (97, 98) # Daily PV1 energy (kWh, /10, 2 registers)
380
+ INPUT_E_PV2_DAY = (99, 100) # Daily PV2 energy (kWh, /10, 2 registers)
381
+ INPUT_E_PV3_DAY = (101, 102) # Daily PV3 energy (kWh, /10, 2 registers)
382
+ INPUT_MAX_CHG_CURR = 103 # Max charge current (A, /10)
383
+ INPUT_MAX_DISCHG_CURR = 104 # Max discharge current (A, /10)
384
+ INPUT_CHARGE_VOLT_REF = 105 # Charge voltage reference (V, /100)
385
+ INPUT_DISCHARGE_VOLT_REF = 106 # Discharge voltage ref (V, /100)
386
+
387
+ # ============================================================================
388
+ # PARAMETER GROUPS FOR EFFICIENT READING
389
+ # ============================================================================
390
+ # Based on Modbus 40-register limitation and logical grouping
391
+
392
+ # Hold Register Groups (Configuration Parameters)
393
+ HOLD_REGISTER_GROUPS = {
394
+ "system_config": (0, 20), # System time, serial, communication
395
+ "func_enable": (21, 21), # Critical function enable register
396
+ "grid_protection": (25, 58), # Grid voltage/frequency limits
397
+ "reactive_power": (59, 62), # Reactive power control
398
+ "ac_charge": (66, 73), # AC charging configuration
399
+ "discharge": (74, 89), # Discharge configuration
400
+ "battery_protection": (99, 109), # Battery limits and protection
401
+ }
402
+
403
+ # Input Register Groups (Runtime Data)
404
+ INPUT_REGISTER_GROUPS = {
405
+ "power_energy": (0, 31), # Power metrics and voltages
406
+ "energy_counters": (32, 60), # Daily and lifetime energy
407
+ "temperatures": (61, 75), # Temperature and current sensors
408
+ "advanced_status": (76, 106), # Faults, SOH, PV energy breakdown
409
+ }
410
+
411
+ # ============================================================================
412
+ # WEB API PARAMETER NAME MAPPINGS
413
+ # ============================================================================
414
+ # Mapping between web frontend parameter names and Hold register addresses
415
+
416
+ WEB_PARAM_TO_HOLD_REGISTER = {
417
+ "acChargePower": HOLD_AC_CHARGE_POWER_CMD,
418
+ "acChargeSocLimit": HOLD_AC_CHARGE_SOC_LIMIT,
419
+ "dischargeCutoffSoc": HOLD_DISCHG_CUT_OFF_SOC_EOD,
420
+ "epsDischargeLimit": HOLD_SOC_LOW_LIMIT_EPS_DISCHG,
421
+ "funcAcCharge": (FUNC_EN_REGISTER, FUNC_EN_BIT_AC_CHARGE_EN),
422
+ "funcForcedCharge": (FUNC_EN_REGISTER, FUNC_EN_BIT_FORCED_CHG_EN),
423
+ "funcForcedDischarge": (FUNC_EN_REGISTER, FUNC_EN_BIT_FORCED_DISCHG_EN),
424
+ "operatingMode": (FUNC_EN_REGISTER, FUNC_EN_BIT_SET_TO_STANDBY),
425
+ }
426
+
427
+ # ============================================================================
428
+ # VERIFIED API REGISTER MAPPINGS (Live Testing)
429
+ # ============================================================================
430
+ # Source: Live API testing with 18KPV inverter (research/register_number_mapping.json)
431
+ # These mappings confirmed by querying individual registers (startRegister=N, pointNumber=1)
432
+ #
433
+ # NOTE: Parameter keys returned by API are DIFFERENT from register addresses!
434
+ # Example: Register 66 returns "HOLD_AC_CHARGE_POWER_CMD", not "66"
435
+ #
436
+ # Parameter Key Prefixes:
437
+ # HOLD_* - Hold registers (configuration, read/write)
438
+ # INPUT_* - Input registers (runtime data, read-only)
439
+ # FUNC_* - Function enable bits (typically from register 21)
440
+ # BIT_* - Bit field values
441
+ # MIDBOX_* - GridBOSS-specific parameters
442
+
443
+ # Register → API Parameter Key Mappings (18KPV, Verified)
444
+ REGISTER_TO_PARAM_KEYS_18KPV: dict[int, list[str]] = {
445
+ 15: ["HOLD_COM_ADDR"],
446
+ 16: ["HOLD_LANGUAGE"],
447
+ 19: ["HOLD_DEVICE_TYPE_CODE", "BIT_DEVICE_TYPE_ODM", "BIT_MACHINE_TYPE"],
448
+ 20: ["HOLD_PV_INPUT_MODE"],
449
+ # Register 21: Critical function enable register (27 bit fields!)
450
+ 21: [
451
+ "FUNC_EPS_EN", # Bit 0: Off-grid mode
452
+ "FUNC_OVF_LOAD_DERATE_EN",
453
+ "FUNC_DRMS_EN",
454
+ "FUNC_LVRT_EN",
455
+ "FUNC_ANTI_ISLAND_EN",
456
+ "FUNC_NEUTRAL_DETECT_EN",
457
+ "FUNC_GRID_ON_POWER_SS_EN",
458
+ "FUNC_AC_CHARGE", # Bit 7: AC charge enable
459
+ "FUNC_SW_SEAMLESSLY_EN",
460
+ "FUNC_SET_TO_STANDBY", # Bit 9: Standby mode (0=Standby, 1=On)
461
+ "FUNC_FORCED_DISCHG_EN", # Bit 10: Forced discharge
462
+ "FUNC_FORCED_CHG_EN", # Bit 11: Force charge
463
+ "FUNC_ISO_EN",
464
+ "FUNC_GFCI_EN",
465
+ "FUNC_DCI_EN",
466
+ "FUNC_FEED_IN_GRID_EN",
467
+ "FUNC_LSP_SET_TO_STANDBY",
468
+ "FUNC_LSP_ISO_EN",
469
+ "FUNC_LSP_FAN_CHECK_EN",
470
+ "FUNC_LSP_WHOLE_DAY_SCHEDULE_EN",
471
+ "FUNC_LSP_LCD_REMOTE_DIS_CHG_EN",
472
+ "FUNC_LSP_SELF_CONSUMPTION_EN",
473
+ "FUNC_LSP_AC_CHARGE",
474
+ "FUNC_LSP_BAT_ACTIVATION_EN",
475
+ "FUNC_LSP_BYPASS_MODE_EN",
476
+ "FUNC_LSP_BYPASS_EN",
477
+ "FUNC_LSP_CHARGE_PRIORITY_EN",
478
+ ],
479
+ 22: ["HOLD_START_PV_VOLT"],
480
+ 23: ["HOLD_CONNECT_TIME"],
481
+ 24: ["HOLD_RECONNECT_TIME"],
482
+ 25: ["HOLD_GRID_VOLT_CONN_LOW"],
483
+ 26: [
484
+ "HOLD_GRID_VOLT_CONN_HIGH",
485
+ "FUNC_LSP_WHOLE_BYPASS_1_EN",
486
+ "FUNC_LSP_WHOLE_BYPASS_2_EN",
487
+ "FUNC_LSP_WHOLE_BYPASS_3_EN",
488
+ "FUNC_LSP_WHOLE_BAT_FIRST_1_EN",
489
+ "FUNC_LSP_WHOLE_BAT_FIRST_2_EN",
490
+ "FUNC_LSP_WHOLE_BAT_FIRST_3_EN",
491
+ "FUNC_LSP_WHOLE_SELF_CONSUMPTION_1_EN",
492
+ "FUNC_LSP_WHOLE_SELF_CONSUMPTION_2_EN",
493
+ "FUNC_LSP_WHOLE_SELF_CONSUMPTION_3_EN",
494
+ "FUNC_LSP_BATT_VOLT_OR_SOC",
495
+ ],
496
+ 27: ["HOLD_GRID_FREQ_CONN_LOW"],
497
+ 28: ["HOLD_GRID_FREQ_CONN_HIGH"],
498
+ # AC Charge registers
499
+ 66: ["HOLD_AC_CHARGE_POWER_CMD"],
500
+ 67: ["HOLD_AC_CHARGE_SOC_LIMIT"],
501
+ 70: ["HOLD_AC_CHARGE_START_HOUR_1", "HOLD_AC_CHARGE_START_MINUTE_1"],
502
+ # Battery protection
503
+ 100: ["HOLD_LEAD_ACID_DISCHARGE_CUT_OFF_VOLT"],
504
+ # System functions (Register 110: 14 bit fields)
505
+ 110: [
506
+ "FUNC_PV_GRID_OFF_EN",
507
+ "FUNC_RUN_WITHOUT_GRID",
508
+ "FUNC_MICRO_GRID_EN",
509
+ "FUNC_BAT_SHARED",
510
+ "FUNC_CHARGE_LAST",
511
+ "FUNC_BUZZER_EN",
512
+ "FUNC_TAKE_LOAD_TOGETHER",
513
+ "FUNC_GO_TO_OFFGRID",
514
+ "FUNC_GREEN_EN",
515
+ "FUNC_BATTERY_ECO_EN",
516
+ "BIT_WORKING_MODE",
517
+ "BIT_PVCT_SAMPLE_TYPE",
518
+ "BIT_PVCT_SAMPLE_RATIO",
519
+ "BIT_CT_SAMPLE_RATIO",
520
+ ],
521
+ 120: [
522
+ "FUNC_HALF_HOUR_AC_CHG_START_EN",
523
+ "FUNC_SNA_BAT_DISCHARGE_CONTROL",
524
+ "FUNC_PHASE_INDEPEND_COMPENSATE_EN",
525
+ "BIT_AC_CHARGE_TYPE",
526
+ "BIT_DISCHG_CONTROL_TYPE",
527
+ "BIT_ON_GRID_EOD_TYPE",
528
+ "BIT_GENERATOR_CHARGE_TYPE",
529
+ ],
530
+ # Additional verified registers
531
+ 150: ["HOLD_EQUALIZATION_PERIOD"],
532
+ 160: ["HOLD_AC_CHARGE_START_BATTERY_SOC"],
533
+ 190: ["HOLD_P2"],
534
+ }
535
+
536
+ # Reverse mapping: API Parameter Key → Register (for 18KPV)
537
+ # Note: Some parameters appear in multiple registers (bit fields)
538
+ PARAM_KEY_TO_REGISTER_18KPV: dict[str, int] = {
539
+ param: reg for reg, params in REGISTER_TO_PARAM_KEYS_18KPV.items() for param in params
540
+ }
541
+
542
+ # Statistics (18KPV verified via live API testing)
543
+ REGISTER_STATS_18KPV = {
544
+ "total_registers_queried": 200, # Registers 0-199
545
+ "registers_with_parameters": 147, # Registers that returned parameter keys
546
+ "empty_registers": 49, # Registers with no parameters
547
+ "error_registers": 4, # Registers that returned errors
548
+ "total_unique_parameters": 488, # From all 3 ranges combined
549
+ }
550
+
551
+ # ============================================================================
552
+ # GRIDBOSS PARAMETER MAPPINGS (Range-based, Read via Web Interface)
553
+ # ============================================================================
554
+ # Source: Live GridBOSS testing using 3-range approach (research/register_mapping_complete.json)
555
+ # GridBOSS devices do NOT support individual register reads (pointNumber=1)
556
+ # Must use range reads: (0,127), (127,127), (240,127)
557
+ #
558
+ # Total: 557 unique parameters across 3 ranges
559
+ # - Range 1 (0-126): 189 parameters
560
+ # - Range 2 (127-253): 252 parameters
561
+ # - Range 3 (240-366): 144 parameters (134 MIDBOX-specific)
562
+ #
563
+ # MIDBOX Parameters: 159 unique parameters specific to GridBOSS
564
+ # - Smart Load control (SL_*)
565
+ # - AC Coupling (AC_COUPLE_*)
566
+ # - Generator control (GEN_*)
567
+
568
+ # All GridBOSS parameters (alphabetically sorted)
569
+ GRIDBOSS_PARAMETERS = [
570
+ "BIT_AC_CHARGE_TYPE",
571
+ "BIT_CT_SAMPLE_RATIO",
572
+ "BIT_DEVICE_TYPE_ODM",
573
+ "BIT_DISCHG_CONTROL_TYPE",
574
+ "BIT_DRY_CONTRACTOR_MULTIPLEX",
575
+ "BIT_FAN_1_MAX_SPEED",
576
+ "BIT_FAN_2_MAX_SPEED",
577
+ "BIT_FAN_3_MAX_SPEED",
578
+ "BIT_FAN_4_MAX_SPEED",
579
+ "BIT_FAN_5_MAX_SPEED",
580
+ "BIT_GENERATOR_CHARGE_TYPE",
581
+ "BIT_LCD_TYPE",
582
+ "BIT_MACHINE_TYPE",
583
+ "BIT_METER_NUMBER",
584
+ "BIT_METER_PHASE",
585
+ "BIT_MIDBOX_SP_MODE_1",
586
+ "BIT_MIDBOX_SP_MODE_2",
587
+ "BIT_MIDBOX_SP_MODE_3",
588
+ "BIT_MIDBOX_SP_MODE_4",
589
+ "BIT_ON_GRID_EOD_TYPE",
590
+ "BIT_OUT_CT_POSITION",
591
+ "BIT_PVCT_SAMPLE_RATIO",
592
+ "BIT_PVCT_SAMPLE_TYPE",
593
+ "BIT_WATT_NODE_UPDATE_FREQUENCY",
594
+ "BIT_WORKING_MODE",
595
+ "FUNC_ACTIVE_POWER_LIMIT_MODE",
596
+ "FUNC_AC_CHARGE",
597
+ "FUNC_AC_COUPLE_DARK_START_EN",
598
+ "FUNC_AC_COUPLE_EN_1",
599
+ "FUNC_AC_COUPLE_EN_2",
600
+ "FUNC_AC_COUPLE_EN_3",
601
+ "FUNC_AC_COUPLE_EN_4",
602
+ "FUNC_AC_COUPLE_ON_EPS_PORT_EN",
603
+ "FUNC_AC_COUPLING_FUNCTION",
604
+ "FUNC_ANTI_ISLAND_EN",
605
+ "FUNC_BATTERY_BACKUP_CTRL",
606
+ "FUNC_BATTERY_CALIBRATION_EN",
607
+ "FUNC_BATTERY_ECO_EN",
608
+ "FUNC_BAT_CHARGE_CONTROL",
609
+ "FUNC_BAT_DISCHARGE_CONTROL",
610
+ "FUNC_BAT_SHARED",
611
+ "FUNC_BUZZER_EN",
612
+ "FUNC_CHARGE_LAST",
613
+ "FUNC_CT_DIRECTION_REVERSED",
614
+ "FUNC_DCI_EN",
615
+ "FUNC_DRMS_EN",
616
+ "FUNC_ENERTEK_WORKING_MODE",
617
+ "FUNC_EPS_EN",
618
+ "FUNC_FAN_SPEED_SLOPE_CTRL_1",
619
+ "FUNC_FAN_SPEED_SLOPE_CTRL_2",
620
+ "FUNC_FAN_SPEED_SLOPE_CTRL_3",
621
+ "FUNC_FAN_SPEED_SLOPE_CTRL_4",
622
+ "FUNC_FAN_SPEED_SLOPE_CTRL_5",
623
+ "FUNC_FEED_IN_GRID_EN",
624
+ "FUNC_FORCED_CHG_EN",
625
+ "FUNC_FORCED_DISCHG_EN",
626
+ "FUNC_GEN_CTRL",
627
+ "FUNC_GEN_PEAK_SHAVING",
628
+ "FUNC_GFCI_EN",
629
+ "FUNC_GO_TO_OFFGRID",
630
+ "FUNC_GREEN_EN",
631
+ "FUNC_GRID_CT_CONNECTION_EN",
632
+ "FUNC_GRID_ON_POWER_SS_EN",
633
+ "FUNC_GRID_PEAK_SHAVING",
634
+ "FUNC_HALF_HOUR_AC_CHG_START_EN",
635
+ "FUNC_ISO_EN",
636
+ "FUNC_LSP_AC_CHARGE",
637
+ "FUNC_LSP_BATT_VOLT_OR_SOC",
638
+ "FUNC_LSP_BAT_ACTIVATION_EN",
639
+ "FUNC_LSP_BAT_FIRST_10_EN",
640
+ "FUNC_LSP_BAT_FIRST_11_EN",
641
+ "FUNC_LSP_BAT_FIRST_12_EN",
642
+ "FUNC_LSP_BAT_FIRST_13_EN",
643
+ "FUNC_LSP_BAT_FIRST_14_EN",
644
+ "FUNC_LSP_BAT_FIRST_15_EN",
645
+ "FUNC_LSP_BAT_FIRST_16_EN",
646
+ "FUNC_LSP_BAT_FIRST_17_EN",
647
+ "FUNC_LSP_BAT_FIRST_18_EN",
648
+ "FUNC_LSP_BAT_FIRST_19_EN",
649
+ "FUNC_LSP_BAT_FIRST_1_EN",
650
+ "FUNC_LSP_BAT_FIRST_20_EN",
651
+ "FUNC_LSP_BAT_FIRST_21_EN",
652
+ "FUNC_LSP_BAT_FIRST_22_EN",
653
+ "FUNC_LSP_BAT_FIRST_23_EN",
654
+ "FUNC_LSP_BAT_FIRST_24_EN",
655
+ "FUNC_LSP_BAT_FIRST_25_EN",
656
+ "FUNC_LSP_BAT_FIRST_26_EN",
657
+ "FUNC_LSP_BAT_FIRST_27_EN",
658
+ "FUNC_LSP_BAT_FIRST_28_EN",
659
+ "FUNC_LSP_BAT_FIRST_29_EN",
660
+ "FUNC_LSP_BAT_FIRST_2_EN",
661
+ "FUNC_LSP_BAT_FIRST_30_EN",
662
+ "FUNC_LSP_BAT_FIRST_31_EN",
663
+ "FUNC_LSP_BAT_FIRST_32_EN",
664
+ "FUNC_LSP_BAT_FIRST_33_EN",
665
+ "FUNC_LSP_BAT_FIRST_34_EN",
666
+ "FUNC_LSP_BAT_FIRST_35_EN",
667
+ "FUNC_LSP_BAT_FIRST_36_EN",
668
+ "FUNC_LSP_BAT_FIRST_37_EN",
669
+ "FUNC_LSP_BAT_FIRST_38_EN",
670
+ "FUNC_LSP_BAT_FIRST_39_EN",
671
+ "FUNC_LSP_BAT_FIRST_3_EN",
672
+ "FUNC_LSP_BAT_FIRST_40_EN",
673
+ "FUNC_LSP_BAT_FIRST_41_EN",
674
+ "FUNC_LSP_BAT_FIRST_42_EN",
675
+ "FUNC_LSP_BAT_FIRST_43_EN",
676
+ "FUNC_LSP_BAT_FIRST_44_EN",
677
+ "FUNC_LSP_BAT_FIRST_45_EN",
678
+ "FUNC_LSP_BAT_FIRST_46_EN",
679
+ "FUNC_LSP_BAT_FIRST_47_EN",
680
+ "FUNC_LSP_BAT_FIRST_48_EN",
681
+ "FUNC_LSP_BAT_FIRST_4_EN",
682
+ "FUNC_LSP_BAT_FIRST_5_EN",
683
+ "FUNC_LSP_BAT_FIRST_6_EN",
684
+ "FUNC_LSP_BAT_FIRST_7_EN",
685
+ "FUNC_LSP_BAT_FIRST_8_EN",
686
+ "FUNC_LSP_BAT_FIRST_9_EN",
687
+ "FUNC_LSP_BYPASS_10_EN",
688
+ "FUNC_LSP_BYPASS_11_EN",
689
+ "FUNC_LSP_BYPASS_12_EN",
690
+ "FUNC_LSP_BYPASS_13_EN",
691
+ "FUNC_LSP_BYPASS_14_EN",
692
+ "FUNC_LSP_BYPASS_15_EN",
693
+ "FUNC_LSP_BYPASS_16_EN",
694
+ "FUNC_LSP_BYPASS_17_EN",
695
+ "FUNC_LSP_BYPASS_18_EN",
696
+ "FUNC_LSP_BYPASS_19_EN",
697
+ "FUNC_LSP_BYPASS_1_EN",
698
+ "FUNC_LSP_BYPASS_20_EN",
699
+ "FUNC_LSP_BYPASS_21_EN",
700
+ "FUNC_LSP_BYPASS_22_EN",
701
+ "FUNC_LSP_BYPASS_23_EN",
702
+ "FUNC_LSP_BYPASS_24_EN",
703
+ "FUNC_LSP_BYPASS_25_EN",
704
+ "FUNC_LSP_BYPASS_26_EN",
705
+ "FUNC_LSP_BYPASS_27_EN",
706
+ "FUNC_LSP_BYPASS_28_EN",
707
+ "FUNC_LSP_BYPASS_29_EN",
708
+ "FUNC_LSP_BYPASS_2_EN",
709
+ "FUNC_LSP_BYPASS_30_EN",
710
+ "FUNC_LSP_BYPASS_31_EN",
711
+ "FUNC_LSP_BYPASS_32_EN",
712
+ "FUNC_LSP_BYPASS_33_EN",
713
+ "FUNC_LSP_BYPASS_34_EN",
714
+ "FUNC_LSP_BYPASS_35_EN",
715
+ "FUNC_LSP_BYPASS_36_EN",
716
+ "FUNC_LSP_BYPASS_37_EN",
717
+ "FUNC_LSP_BYPASS_38_EN",
718
+ "FUNC_LSP_BYPASS_39_EN",
719
+ "FUNC_LSP_BYPASS_3_EN",
720
+ "FUNC_LSP_BYPASS_40_EN",
721
+ "FUNC_LSP_BYPASS_41_EN",
722
+ "FUNC_LSP_BYPASS_42_EN",
723
+ "FUNC_LSP_BYPASS_43_EN",
724
+ "FUNC_LSP_BYPASS_44_EN",
725
+ "FUNC_LSP_BYPASS_45_EN",
726
+ "FUNC_LSP_BYPASS_46_EN",
727
+ "FUNC_LSP_BYPASS_47_EN",
728
+ "FUNC_LSP_BYPASS_48_EN",
729
+ "FUNC_LSP_BYPASS_4_EN",
730
+ "FUNC_LSP_BYPASS_5_EN",
731
+ "FUNC_LSP_BYPASS_6_EN",
732
+ "FUNC_LSP_BYPASS_7_EN",
733
+ "FUNC_LSP_BYPASS_8_EN",
734
+ "FUNC_LSP_BYPASS_9_EN",
735
+ "FUNC_LSP_BYPASS_EN",
736
+ "FUNC_LSP_BYPASS_MODE_EN",
737
+ "FUNC_LSP_CHARGE_PRIORITY_EN",
738
+ "FUNC_LSP_FAN_CHECK_EN",
739
+ "FUNC_LSP_ISO_EN",
740
+ "FUNC_LSP_LCD_REMOTE_DIS_CHG_EN",
741
+ "FUNC_LSP_OUTPUT_10_EN",
742
+ "FUNC_LSP_OUTPUT_11_EN",
743
+ "FUNC_LSP_OUTPUT_12_EN",
744
+ "FUNC_LSP_OUTPUT_1_EN",
745
+ "FUNC_LSP_OUTPUT_2_EN",
746
+ "FUNC_LSP_OUTPUT_3_EN",
747
+ "FUNC_LSP_OUTPUT_4_EN",
748
+ "FUNC_LSP_OUTPUT_5_EN",
749
+ "FUNC_LSP_OUTPUT_6_EN",
750
+ "FUNC_LSP_OUTPUT_7_EN",
751
+ "FUNC_LSP_OUTPUT_8_EN",
752
+ "FUNC_LSP_OUTPUT_9_EN",
753
+ "FUNC_LSP_SELF_CONSUMPTION_EN",
754
+ "FUNC_LSP_SET_TO_STANDBY",
755
+ "FUNC_LSP_WHOLE_BAT_FIRST_1_EN",
756
+ "FUNC_LSP_WHOLE_BAT_FIRST_2_EN",
757
+ "FUNC_LSP_WHOLE_BAT_FIRST_3_EN",
758
+ "FUNC_LSP_WHOLE_BYPASS_1_EN",
759
+ "FUNC_LSP_WHOLE_BYPASS_2_EN",
760
+ "FUNC_LSP_WHOLE_BYPASS_3_EN",
761
+ "FUNC_LSP_WHOLE_DAY_SCHEDULE_EN",
762
+ "FUNC_LSP_WHOLE_SELF_CONSUMPTION_1_EN",
763
+ "FUNC_LSP_WHOLE_SELF_CONSUMPTION_2_EN",
764
+ "FUNC_LSP_WHOLE_SELF_CONSUMPTION_3_EN",
765
+ "FUNC_LVRT_EN",
766
+ "FUNC_MICRO_GRID_EN",
767
+ "FUNC_MIDBOX_EN",
768
+ "FUNC_NEUTRAL_DETECT_EN",
769
+ "FUNC_N_PE_CONNECT_INNER_EN",
770
+ "FUNC_ON_GRID_ALWAYS_ON",
771
+ "FUNC_OVF_LOAD_DERATE_EN",
772
+ "FUNC_PARALLEL_DATA_SYNC_EN",
773
+ "FUNC_PHASE_INDEPEND_COMPENSATE_EN",
774
+ "FUNC_PV_ARC",
775
+ "FUNC_PV_ARC_FAULT_CLEAR",
776
+ "FUNC_PV_GRID_OFF_EN",
777
+ "FUNC_PV_SELL_TO_GRID_EN",
778
+ "FUNC_QUICK_CHARGE_CTRL",
779
+ "FUNC_RETAIN_SHUTDOWN",
780
+ "FUNC_RETAIN_STANDBY",
781
+ "FUNC_RSD_DISABLE",
782
+ "FUNC_RUN_WITHOUT_GRID",
783
+ "FUNC_RUN_WITHOUT_GRID_12K",
784
+ "FUNC_SET_TO_STANDBY",
785
+ "FUNC_SHEDDING_MODE_EN_1",
786
+ "FUNC_SHEDDING_MODE_EN_2",
787
+ "FUNC_SHEDDING_MODE_EN_3",
788
+ "FUNC_SHEDDING_MODE_EN_4",
789
+ "FUNC_SMART_LOAD_ENABLE",
790
+ "FUNC_SMART_LOAD_EN_1",
791
+ "FUNC_SMART_LOAD_EN_2",
792
+ "FUNC_SMART_LOAD_EN_3",
793
+ "FUNC_SMART_LOAD_EN_4",
794
+ "FUNC_SMART_LOAD_GRID_ON_1",
795
+ "FUNC_SMART_LOAD_GRID_ON_2",
796
+ "FUNC_SMART_LOAD_GRID_ON_3",
797
+ "FUNC_SMART_LOAD_GRID_ON_4",
798
+ "FUNC_SNA_BAT_DISCHARGE_CONTROL",
799
+ "FUNC_SPORADIC_CHARGE",
800
+ "FUNC_SW_SEAMLESSLY_EN",
801
+ "FUNC_TAKE_LOAD_TOGETHER",
802
+ "FUNC_TOTAL_LOAD_COMPENSATION_EN",
803
+ "FUNC_TRIP_TIME_UNIT",
804
+ "FUNC_WATT_NODE_CT_DIRECTION_A",
805
+ "FUNC_WATT_NODE_CT_DIRECTION_B",
806
+ "FUNC_WATT_NODE_CT_DIRECTION_C",
807
+ "FUNC_WATT_VOLT_EN",
808
+ "HOLD_ACTIVE_POWER_PERCENT_CMD",
809
+ "HOLD_AC_CHARGE_BATTERY_CURRENT",
810
+ "HOLD_AC_CHARGE_END_BATTERY_SOC",
811
+ "HOLD_AC_CHARGE_END_BATTERY_VOLTAGE",
812
+ "HOLD_AC_CHARGE_END_HOUR",
813
+ "HOLD_AC_CHARGE_END_HOUR_1",
814
+ "HOLD_AC_CHARGE_END_HOUR_2",
815
+ "HOLD_AC_CHARGE_END_MINUTE",
816
+ "HOLD_AC_CHARGE_END_MINUTE_1",
817
+ "HOLD_AC_CHARGE_END_MINUTE_2",
818
+ "HOLD_AC_CHARGE_POWER_CMD",
819
+ "HOLD_AC_CHARGE_SOC_LIMIT",
820
+ "HOLD_AC_CHARGE_START_BATTERY_SOC",
821
+ "HOLD_AC_CHARGE_START_BATTERY_VOLTAGE",
822
+ "HOLD_AC_CHARGE_START_HOUR",
823
+ "HOLD_AC_CHARGE_START_HOUR_1",
824
+ "HOLD_AC_CHARGE_START_HOUR_2",
825
+ "HOLD_AC_CHARGE_START_MINUTE",
826
+ "HOLD_AC_CHARGE_START_MINUTE_1",
827
+ "HOLD_AC_CHARGE_START_MINUTE_2",
828
+ "HOLD_AC_FIRST_END_HOUR",
829
+ "HOLD_AC_FIRST_END_HOUR_1",
830
+ "HOLD_AC_FIRST_END_HOUR_2",
831
+ "HOLD_AC_FIRST_END_MINUTE",
832
+ "HOLD_AC_FIRST_END_MINUTE_1",
833
+ "HOLD_AC_FIRST_END_MINUTE_2",
834
+ "HOLD_AC_FIRST_START_HOUR",
835
+ "HOLD_AC_FIRST_START_HOUR_1",
836
+ "HOLD_AC_FIRST_START_HOUR_2",
837
+ "HOLD_AC_FIRST_START_MINUTE",
838
+ "HOLD_AC_FIRST_START_MINUTE_1",
839
+ "HOLD_AC_FIRST_START_MINUTE_2",
840
+ "HOLD_BATTERY_LOW_TO_UTILITY_SOC",
841
+ "HOLD_BATTERY_LOW_TO_UTILITY_VOLTAGE",
842
+ "HOLD_BATTERY_WARNING_RECOVERY_SOC",
843
+ "HOLD_BATTERY_WARNING_RECOVERY_VOLTAGE",
844
+ "HOLD_BATTERY_WARNING_SOC",
845
+ "HOLD_BATTERY_WARNING_VOLTAGE",
846
+ "HOLD_CHARGE_POWER_PERCENT_CMD",
847
+ "HOLD_COM_ADDR",
848
+ "HOLD_CONNECT_TIME",
849
+ "HOLD_CT_POWER_OFFSET",
850
+ "HOLD_DEVICE_TYPE_CODE",
851
+ "HOLD_DISCHG_CUT_OFF_SOC_EOD",
852
+ "HOLD_DISCHG_POWER_PERCENT_CMD",
853
+ "HOLD_EPS_FREQ_SET",
854
+ "HOLD_EPS_VOLT_SET",
855
+ "HOLD_EQUALIZATION_PERIOD",
856
+ "HOLD_EQUALIZATION_TIME",
857
+ "HOLD_EQUALIZATION_VOLTAGE",
858
+ "HOLD_FEED_IN_GRID_POWER_PERCENT",
859
+ "HOLD_FLOATING_VOLTAGE",
860
+ "HOLD_FORCED_CHARGE_END_HOUR",
861
+ "HOLD_FORCED_CHARGE_END_HOUR_1",
862
+ "HOLD_FORCED_CHARGE_END_HOUR_2",
863
+ "HOLD_FORCED_CHARGE_END_MINUTE",
864
+ "HOLD_FORCED_CHARGE_END_MINUTE_1",
865
+ "HOLD_FORCED_CHARGE_END_MINUTE_2",
866
+ "HOLD_FORCED_CHARGE_START_HOUR",
867
+ "HOLD_FORCED_CHARGE_START_HOUR_1",
868
+ "HOLD_FORCED_CHARGE_START_HOUR_2",
869
+ "HOLD_FORCED_CHARGE_START_MINUTE",
870
+ "HOLD_FORCED_CHARGE_START_MINUTE_1",
871
+ "HOLD_FORCED_CHARGE_START_MINUTE_2",
872
+ "HOLD_FORCED_CHG_POWER_CMD",
873
+ "HOLD_FORCED_CHG_SOC_LIMIT",
874
+ "HOLD_FORCED_DISCHARGE_END_HOUR",
875
+ "HOLD_FORCED_DISCHARGE_END_HOUR_1",
876
+ "HOLD_FORCED_DISCHARGE_END_HOUR_2",
877
+ "HOLD_FORCED_DISCHARGE_END_MINUTE",
878
+ "HOLD_FORCED_DISCHARGE_END_MINUTE_1",
879
+ "HOLD_FORCED_DISCHARGE_END_MINUTE_2",
880
+ "HOLD_FORCED_DISCHARGE_START_HOUR",
881
+ "HOLD_FORCED_DISCHARGE_START_HOUR_1",
882
+ "HOLD_FORCED_DISCHARGE_START_HOUR_2",
883
+ "HOLD_FORCED_DISCHARGE_START_MINUTE",
884
+ "HOLD_FORCED_DISCHARGE_START_MINUTE_1",
885
+ "HOLD_FORCED_DISCHARGE_START_MINUTE_2",
886
+ "HOLD_FORCED_DISCHG_POWER_CMD",
887
+ "HOLD_FORCED_DISCHG_SOC_LIMIT",
888
+ "HOLD_FW_CODE",
889
+ "HOLD_GRID_FREQ_CONN_HIGH",
890
+ "HOLD_GRID_FREQ_CONN_LOW",
891
+ "HOLD_GRID_FREQ_LIMIT1_HIGH",
892
+ "HOLD_GRID_FREQ_LIMIT1_HIGH_TIME",
893
+ "HOLD_GRID_FREQ_LIMIT1_LOW",
894
+ "HOLD_GRID_FREQ_LIMIT1_LOW_TIME",
895
+ "HOLD_GRID_FREQ_LIMIT2_HIGH",
896
+ "HOLD_GRID_FREQ_LIMIT2_HIGH_TIME",
897
+ "HOLD_GRID_FREQ_LIMIT2_LOW",
898
+ "HOLD_GRID_FREQ_LIMIT2_LOW_TIME",
899
+ "HOLD_GRID_FREQ_LIMIT3_HIGH",
900
+ "HOLD_GRID_FREQ_LIMIT3_HIGH_TIME",
901
+ "HOLD_GRID_FREQ_LIMIT3_LOW",
902
+ "HOLD_GRID_FREQ_LIMIT3_LOW_TIME",
903
+ "HOLD_GRID_VOLT_CONN_HIGH",
904
+ "HOLD_GRID_VOLT_CONN_LOW",
905
+ "HOLD_GRID_VOLT_LIMIT1_HIGH",
906
+ "HOLD_GRID_VOLT_LIMIT1_HIGH_TIME",
907
+ "HOLD_GRID_VOLT_LIMIT1_LOW",
908
+ "HOLD_GRID_VOLT_LIMIT1_LOW_TIME",
909
+ "HOLD_GRID_VOLT_LIMIT2_HIGH",
910
+ "HOLD_GRID_VOLT_LIMIT2_HIGH_TIME",
911
+ "HOLD_GRID_VOLT_LIMIT2_LOW",
912
+ "HOLD_GRID_VOLT_LIMIT2_LOW_TIME",
913
+ "HOLD_GRID_VOLT_LIMIT3_HIGH",
914
+ "HOLD_GRID_VOLT_LIMIT3_HIGH_TIME",
915
+ "HOLD_GRID_VOLT_LIMIT3_LOW",
916
+ "HOLD_GRID_VOLT_LIMIT3_LOW_TIME",
917
+ "HOLD_GRID_VOLT_MOV_AVG_HIGH",
918
+ "HOLD_LANGUAGE",
919
+ "HOLD_LEAD_ACID_CHARGE_RATE",
920
+ "HOLD_LEAD_ACID_CHARGE_VOLT_REF",
921
+ "HOLD_LEAD_ACID_DISCHARGE_CUT_OFF_VOLT",
922
+ "HOLD_LEAD_ACID_DISCHARGE_RATE",
923
+ "HOLD_LEAD_ACID_TEMPR_LOWER_LIMIT_CHG",
924
+ "HOLD_LEAD_ACID_TEMPR_LOWER_LIMIT_DISCHG",
925
+ "HOLD_LEAD_ACID_TEMPR_UPPER_LIMIT_CHG",
926
+ "HOLD_LEAD_ACID_TEMPR_UPPER_LIMIT_DISCHG",
927
+ "HOLD_LINE_MODE_INPUT",
928
+ "HOLD_MAINTENANCE_COUNT",
929
+ "HOLD_MAX_AC_INPUT_POWER",
930
+ "HOLD_MAX_GENERATOR_INPUT_POWER",
931
+ "HOLD_MAX_Q_PERCENT_FOR_QV",
932
+ "HOLD_MIDBOX_AC_COUPLE_1_END_HOUR_1",
933
+ "HOLD_MIDBOX_AC_COUPLE_1_END_HOUR_2",
934
+ "HOLD_MIDBOX_AC_COUPLE_1_END_HOUR_3",
935
+ "HOLD_MIDBOX_AC_COUPLE_1_END_MINUTE_1",
936
+ "HOLD_MIDBOX_AC_COUPLE_1_END_MINUTE_2",
937
+ "HOLD_MIDBOX_AC_COUPLE_1_END_MINUTE_3",
938
+ "HOLD_MIDBOX_AC_COUPLE_1_START_HOUR_1",
939
+ "HOLD_MIDBOX_AC_COUPLE_1_START_HOUR_2",
940
+ "HOLD_MIDBOX_AC_COUPLE_1_START_HOUR_3",
941
+ "HOLD_MIDBOX_AC_COUPLE_1_START_MINUTE_1",
942
+ "HOLD_MIDBOX_AC_COUPLE_1_START_MINUTE_2",
943
+ "HOLD_MIDBOX_AC_COUPLE_1_START_MINUTE_3",
944
+ "HOLD_MIDBOX_AC_COUPLE_2_END_HOUR_1",
945
+ "HOLD_MIDBOX_AC_COUPLE_2_END_HOUR_2",
946
+ "HOLD_MIDBOX_AC_COUPLE_2_END_HOUR_3",
947
+ "HOLD_MIDBOX_AC_COUPLE_2_END_MINUTE_1",
948
+ "HOLD_MIDBOX_AC_COUPLE_2_END_MINUTE_2",
949
+ "HOLD_MIDBOX_AC_COUPLE_2_END_MINUTE_3",
950
+ "HOLD_MIDBOX_AC_COUPLE_2_START_HOUR_1",
951
+ "HOLD_MIDBOX_AC_COUPLE_2_START_HOUR_2",
952
+ "HOLD_MIDBOX_AC_COUPLE_2_START_HOUR_3",
953
+ "HOLD_MIDBOX_AC_COUPLE_2_START_MINUTE_1",
954
+ "HOLD_MIDBOX_AC_COUPLE_2_START_MINUTE_2",
955
+ "HOLD_MIDBOX_AC_COUPLE_2_START_MINUTE_3",
956
+ "HOLD_MIDBOX_AC_COUPLE_3_END_HOUR_1",
957
+ "HOLD_MIDBOX_AC_COUPLE_3_END_HOUR_2",
958
+ "HOLD_MIDBOX_AC_COUPLE_3_END_HOUR_3",
959
+ "HOLD_MIDBOX_AC_COUPLE_3_END_MINUTE_1",
960
+ "HOLD_MIDBOX_AC_COUPLE_3_END_MINUTE_2",
961
+ "HOLD_MIDBOX_AC_COUPLE_3_END_MINUTE_3",
962
+ "HOLD_MIDBOX_AC_COUPLE_3_START_HOUR_1",
963
+ "HOLD_MIDBOX_AC_COUPLE_3_START_HOUR_2",
964
+ "HOLD_MIDBOX_AC_COUPLE_3_START_HOUR_3",
965
+ "HOLD_MIDBOX_AC_COUPLE_3_START_MINUTE_1",
966
+ "HOLD_MIDBOX_AC_COUPLE_3_START_MINUTE_2",
967
+ "HOLD_MIDBOX_AC_COUPLE_3_START_MINUTE_3",
968
+ "HOLD_MIDBOX_AC_COUPLE_4_END_HOUR_1",
969
+ "HOLD_MIDBOX_AC_COUPLE_4_END_HOUR_2",
970
+ "HOLD_MIDBOX_AC_COUPLE_4_END_HOUR_3",
971
+ "HOLD_MIDBOX_AC_COUPLE_4_END_MINUTE_1",
972
+ "HOLD_MIDBOX_AC_COUPLE_4_END_MINUTE_2",
973
+ "HOLD_MIDBOX_AC_COUPLE_4_END_MINUTE_3",
974
+ "HOLD_MIDBOX_AC_COUPLE_4_START_HOUR_1",
975
+ "HOLD_MIDBOX_AC_COUPLE_4_START_HOUR_2",
976
+ "HOLD_MIDBOX_AC_COUPLE_4_START_HOUR_3",
977
+ "HOLD_MIDBOX_AC_COUPLE_4_START_MINUTE_1",
978
+ "HOLD_MIDBOX_AC_COUPLE_4_START_MINUTE_2",
979
+ "HOLD_MIDBOX_AC_COUPLE_4_START_MINUTE_3",
980
+ "HOLD_MIDBOX_SL_1_END_HOUR_1",
981
+ "HOLD_MIDBOX_SL_1_END_HOUR_2",
982
+ "HOLD_MIDBOX_SL_1_END_HOUR_3",
983
+ "HOLD_MIDBOX_SL_1_END_MINUTE_1",
984
+ "HOLD_MIDBOX_SL_1_END_MINUTE_2",
985
+ "HOLD_MIDBOX_SL_1_END_MINUTE_3",
986
+ "HOLD_MIDBOX_SL_1_START_HOUR_1",
987
+ "HOLD_MIDBOX_SL_1_START_HOUR_2",
988
+ "HOLD_MIDBOX_SL_1_START_HOUR_3",
989
+ "HOLD_MIDBOX_SL_1_START_MINUTE_1",
990
+ "HOLD_MIDBOX_SL_1_START_MINUTE_2",
991
+ "HOLD_MIDBOX_SL_1_START_MINUTE_3",
992
+ "HOLD_MIDBOX_SL_2_END_HOUR_1",
993
+ "HOLD_MIDBOX_SL_2_END_HOUR_2",
994
+ "HOLD_MIDBOX_SL_2_END_HOUR_3",
995
+ "HOLD_MIDBOX_SL_2_END_MINUTE_1",
996
+ "HOLD_MIDBOX_SL_2_END_MINUTE_2",
997
+ "HOLD_MIDBOX_SL_2_END_MINUTE_3",
998
+ "HOLD_MIDBOX_SL_2_START_HOUR_1",
999
+ "HOLD_MIDBOX_SL_2_START_HOUR_2",
1000
+ "HOLD_MIDBOX_SL_2_START_HOUR_3",
1001
+ "HOLD_MIDBOX_SL_2_START_MINUTE_1",
1002
+ "HOLD_MIDBOX_SL_2_START_MINUTE_2",
1003
+ "HOLD_MIDBOX_SL_2_START_MINUTE_3",
1004
+ "HOLD_MIDBOX_SL_3_END_HOUR_1",
1005
+ "HOLD_MIDBOX_SL_3_END_HOUR_2",
1006
+ "HOLD_MIDBOX_SL_3_END_HOUR_3",
1007
+ "HOLD_MIDBOX_SL_3_END_MINUTE_1",
1008
+ "HOLD_MIDBOX_SL_3_END_MINUTE_2",
1009
+ "HOLD_MIDBOX_SL_3_END_MINUTE_3",
1010
+ "HOLD_MIDBOX_SL_3_START_HOUR_1",
1011
+ "HOLD_MIDBOX_SL_3_START_HOUR_2",
1012
+ "HOLD_MIDBOX_SL_3_START_HOUR_3",
1013
+ "HOLD_MIDBOX_SL_3_START_MINUTE_1",
1014
+ "HOLD_MIDBOX_SL_3_START_MINUTE_2",
1015
+ "HOLD_MIDBOX_SL_3_START_MINUTE_3",
1016
+ "HOLD_MIDBOX_SL_4_END_HOUR_1",
1017
+ "HOLD_MIDBOX_SL_4_END_HOUR_2",
1018
+ "HOLD_MIDBOX_SL_4_END_HOUR_3",
1019
+ "HOLD_MIDBOX_SL_4_END_MINUTE_1",
1020
+ "HOLD_MIDBOX_SL_4_END_MINUTE_2",
1021
+ "HOLD_MIDBOX_SL_4_END_MINUTE_3",
1022
+ "HOLD_MIDBOX_SL_4_START_HOUR_1",
1023
+ "HOLD_MIDBOX_SL_4_START_HOUR_2",
1024
+ "HOLD_MIDBOX_SL_4_START_HOUR_3",
1025
+ "HOLD_MIDBOX_SL_4_START_MINUTE_1",
1026
+ "HOLD_MIDBOX_SL_4_START_MINUTE_2",
1027
+ "HOLD_MIDBOX_SL_4_START_MINUTE_3",
1028
+ "HOLD_MODEL",
1029
+ "HOLD_MODEL_batteryType",
1030
+ "HOLD_MODEL_leadAcidType",
1031
+ "HOLD_MODEL_lithiumType",
1032
+ "HOLD_MODEL_measurement",
1033
+ "HOLD_MODEL_meterBrand",
1034
+ "HOLD_MODEL_meterType",
1035
+ "HOLD_MODEL_powerRating",
1036
+ "HOLD_MODEL_rule",
1037
+ "HOLD_MODEL_ruleMask",
1038
+ "HOLD_MODEL_usVersion",
1039
+ "HOLD_MODEL_wirelessMeter",
1040
+ "HOLD_NOMINAL_BATTERY_VOLTAGE",
1041
+ "HOLD_OFFLINE_TIMEOUT",
1042
+ "HOLD_ON_GRID_EOD_VOLTAGE",
1043
+ "HOLD_OUTPUT_CONFIGURATION",
1044
+ "HOLD_PF_CMD",
1045
+ "HOLD_PF_CMD_TEXT",
1046
+ "HOLD_POWER_SOFT_START_SLOPE",
1047
+ "HOLD_P_TO_USER_START_DISCHG",
1048
+ "HOLD_REACTIVE_POWER_CMD_TYPE",
1049
+ "HOLD_REACTIVE_POWER_PERCENT_CMD",
1050
+ "HOLD_RECONNECT_TIME",
1051
+ "HOLD_SERIAL_NUM",
1052
+ "HOLD_SET_COMPOSED_PHASE",
1053
+ "HOLD_SET_MASTER_OR_SLAVE",
1054
+ "HOLD_SOC_LOW_LIMIT_EPS_DISCHG",
1055
+ "HOLD_SPEC_LOAD_COMPENSATE",
1056
+ "HOLD_START_PV_VOLT",
1057
+ "HOLD_TIME",
1058
+ "HOLD_V1H",
1059
+ "HOLD_V1L",
1060
+ "HOLD_V2H",
1061
+ "HOLD_V2L",
1062
+ "HOLD_VBAT_START_DERATING",
1063
+ "MIDBOX_HOLD_AC_END_SOC_1",
1064
+ "MIDBOX_HOLD_AC_END_SOC_2",
1065
+ "MIDBOX_HOLD_AC_END_SOC_3",
1066
+ "MIDBOX_HOLD_AC_END_SOC_4",
1067
+ "MIDBOX_HOLD_AC_END_VOLT_1",
1068
+ "MIDBOX_HOLD_AC_END_VOLT_2",
1069
+ "MIDBOX_HOLD_AC_END_VOLT_3",
1070
+ "MIDBOX_HOLD_AC_END_VOLT_4",
1071
+ "MIDBOX_HOLD_AC_START_SOC_1",
1072
+ "MIDBOX_HOLD_AC_START_SOC_2",
1073
+ "MIDBOX_HOLD_AC_START_SOC_3",
1074
+ "MIDBOX_HOLD_AC_START_SOC_4",
1075
+ "MIDBOX_HOLD_AC_START_VOLT_1",
1076
+ "MIDBOX_HOLD_AC_START_VOLT_2",
1077
+ "MIDBOX_HOLD_AC_START_VOLT_3",
1078
+ "MIDBOX_HOLD_AC_START_VOLT_4",
1079
+ "MIDBOX_HOLD_GEN_COOL_DOWN_TIME",
1080
+ "MIDBOX_HOLD_GEN_REMOTE_CTRL",
1081
+ "MIDBOX_HOLD_GEN_REMOTE_TURN_OFF_TIME",
1082
+ "MIDBOX_HOLD_GEN_VOLT_SOC_ENABLE",
1083
+ "MIDBOX_HOLD_GEN_WARN_UP_TIME",
1084
+ "MIDBOX_HOLD_SL_END_SOC_1",
1085
+ "MIDBOX_HOLD_SL_END_SOC_2",
1086
+ "MIDBOX_HOLD_SL_END_SOC_3",
1087
+ "MIDBOX_HOLD_SL_END_SOC_4",
1088
+ "MIDBOX_HOLD_SL_END_VOLT_1",
1089
+ "MIDBOX_HOLD_SL_END_VOLT_2",
1090
+ "MIDBOX_HOLD_SL_END_VOLT_3",
1091
+ "MIDBOX_HOLD_SL_END_VOLT_4",
1092
+ "MIDBOX_HOLD_SL_PS_END_SOC_1",
1093
+ "MIDBOX_HOLD_SL_PS_END_SOC_2",
1094
+ "MIDBOX_HOLD_SL_PS_END_SOC_3",
1095
+ "MIDBOX_HOLD_SL_PS_END_SOC_4",
1096
+ "MIDBOX_HOLD_SL_PS_END_VOLT_1",
1097
+ "MIDBOX_HOLD_SL_PS_END_VOLT_2",
1098
+ "MIDBOX_HOLD_SL_PS_END_VOLT_3",
1099
+ "MIDBOX_HOLD_SL_PS_END_VOLT_4",
1100
+ "MIDBOX_HOLD_SL_PS_START_SOC_1",
1101
+ "MIDBOX_HOLD_SL_PS_START_SOC_2",
1102
+ "MIDBOX_HOLD_SL_PS_START_SOC_3",
1103
+ "MIDBOX_HOLD_SL_PS_START_SOC_4",
1104
+ "MIDBOX_HOLD_SL_PS_START_VOLT_1",
1105
+ "MIDBOX_HOLD_SL_PS_START_VOLT_2",
1106
+ "MIDBOX_HOLD_SL_PS_START_VOLT_3",
1107
+ "MIDBOX_HOLD_SL_PS_START_VOLT_4",
1108
+ "MIDBOX_HOLD_SL_START_PV_P_1",
1109
+ "MIDBOX_HOLD_SL_START_PV_P_2",
1110
+ "MIDBOX_HOLD_SL_START_PV_P_3",
1111
+ "MIDBOX_HOLD_SL_START_PV_P_4",
1112
+ "MIDBOX_HOLD_SL_START_SOC_1",
1113
+ "MIDBOX_HOLD_SL_START_SOC_2",
1114
+ "MIDBOX_HOLD_SL_START_SOC_3",
1115
+ "MIDBOX_HOLD_SL_START_SOC_4",
1116
+ "MIDBOX_HOLD_SL_START_VOLT_1",
1117
+ "MIDBOX_HOLD_SL_START_VOLT_2",
1118
+ "MIDBOX_HOLD_SL_START_VOLT_3",
1119
+ "MIDBOX_HOLD_SL_START_VOLT_4",
1120
+ "MIDBOX_HOLD_SMART_PORT_MODE",
1121
+ "OFF_GRID_HOLD_GEN_CHG_END_SOC",
1122
+ "OFF_GRID_HOLD_GEN_CHG_END_VOLT",
1123
+ "OFF_GRID_HOLD_GEN_CHG_START_SOC",
1124
+ "OFF_GRID_HOLD_GEN_CHG_START_VOLT",
1125
+ "OFF_GRID_HOLD_MAX_GEN_CHG_BAT_CURR",
1126
+ "_12K_HOLD_LEAD_CAPACITY",
1127
+ ]
1128
+
1129
+ # Statistics (GridBOSS verified via live API testing with range reads)
1130
+ GRIDBOSS_STATS = {
1131
+ "total_unique_parameters": 557,
1132
+ "range_1_parameters": 189, # startRegister=0, pointNumber=127
1133
+ "range_2_parameters": 252, # startRegister=127, pointNumber=127
1134
+ "range_3_parameters": 144, # startRegister=240, pointNumber=127 (mostly MIDBOX)
1135
+ "midbox_specific_parameters": 159, # Smart Load, AC Coupling, Generator control
1136
+ }
1137
+
1138
+ # ============================================================================
1139
+ # HELPER FUNCTIONS FOR PARAMETER OPERATIONS
1140
+ # ============================================================================
1141
+
1142
+
1143
+ def get_func_en_bit_mask(bit_number: int) -> int:
1144
+ """Get bit mask for FuncEn register (address 21).
1145
+
1146
+ Args:
1147
+ bit_number: Bit number (0-15)
1148
+
1149
+ Returns:
1150
+ Bit mask (e.g., bit 7 returns 0x0080)
1151
+ """
1152
+ return 1 << bit_number
1153
+
1154
+
1155
+ def set_func_en_bit(current_value: int, bit_number: int, enable: bool) -> int:
1156
+ """Set or clear a bit in FuncEn register.
1157
+
1158
+ Args:
1159
+ current_value: Current register value
1160
+ bit_number: Bit number to modify
1161
+ enable: True to set bit, False to clear
1162
+
1163
+ Returns:
1164
+ New register value
1165
+ """
1166
+ mask = get_func_en_bit_mask(bit_number)
1167
+ if enable:
1168
+ return current_value | mask
1169
+ return current_value & ~mask
1170
+
1171
+
1172
+ def get_func_en_bit(value: int, bit_number: int) -> bool:
1173
+ """Get state of a specific bit in FuncEn register.
1174
+
1175
+ Args:
1176
+ value: Register value
1177
+ bit_number: Bit number to check
1178
+
1179
+ Returns:
1180
+ True if bit is set, False otherwise
1181
+ """
1182
+ mask = get_func_en_bit_mask(bit_number)
1183
+ return bool(value & mask)