@enyo-energy/sunspec-sdk 0.0.38 → 0.0.40

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.
package/README.md CHANGED
@@ -1 +1,626 @@
1
- # enyo Sunspec SDK
1
+ # enyo SunSpec SDK
2
+
3
+ SunSpec Modbus client for reading data from solar inverters, batteries, meters, and other energy devices over Modbus TCP/RTU.
4
+
5
+ ## Table of Contents
6
+
7
+ - [How Addressing Works](#how-addressing-works)
8
+ - [Bulk Register Reading](#bulk-register-reading)
9
+ - [Data Types](#data-types)
10
+ - [Scale Factors](#scale-factors)
11
+ - [Model 1 — Common Block](#model-1--common-block)
12
+ - [Model 101 — Single-Phase Inverter](#model-101--single-phase-inverter)
13
+ - [Model 103 — Three-Phase Inverter](#model-103--three-phase-inverter)
14
+ - [Model 121 — Inverter Settings](#model-121--inverter-settings)
15
+ - [Model 123 — Inverter Controls](#model-123--inverter-controls)
16
+ - [Model 124 — Battery Basic Storage Controls](#model-124--battery-basic-storage-controls)
17
+ - [Model 160 — MPPT](#model-160--mppt-multiple-maximum-power-point-tracker)
18
+ - [Models 201/203/204 — Meters](#models-201203204--meters)
19
+ - [Model 802 — Battery Base](#model-802--battery-base)
20
+ - [Writable Registers](#writable-registers)
21
+ - [Enum Reference](#enum-reference)
22
+
23
+ ---
24
+
25
+ ## How Addressing Works
26
+
27
+ ### Base Address Detection
28
+
29
+ SunSpec devices expose a `"SunS"` identifier at a known base address. The SDK auto-detects:
30
+
31
+ | Mode | Base Address | `"SunS"` Location | First Model Address |
32
+ |------|-------------|-------------------|---------------------|
33
+ | 1-based (most common) | 40001 | 40001–40002 | 40003 |
34
+ | 0-based | 40000 | 40000–40001 | 40002 |
35
+ | Custom | user-provided | user-provided | base + 2 |
36
+
37
+ ### Model Discovery
38
+
39
+ Starting from the first model address, the SDK scans through contiguous model blocks:
40
+
41
+ ```
42
+ ┌──────────────┬──────────────┬─────────────────────────┐
43
+ │ Model ID │ Model Length │ Model Data Registers │
44
+ │ (1 register) │ (1 register) │ (Length registers) │
45
+ ├──────────────┼──────────────┼─────────────────────────┤
46
+ │ offset 0 │ offset 1 │ offset 2 ... Length+1 │
47
+ └──────────────┴──────────────┴─────────────────────────┘
48
+ ▲ ▲
49
+ model.address model.address + 2
50
+ ```
51
+
52
+ - **`model.address`** — Modbus address of the model ID register (start of the 2-register header)
53
+ - **`model.length`** — Number of data registers (does NOT include the 2-register header)
54
+ - **Next model** — Located at `model.address + 2 + model.length`
55
+ - **End marker** — Model ID `0xFFFF` (65535) signals end of model chain
56
+
57
+ ### Register Offsets
58
+
59
+ All register offsets in this document are relative to `model.address`:
60
+
61
+ - **Offset 0** = Model ID register
62
+ - **Offset 1** = Model Length register
63
+ - **Offset 2** = First data register (for most models)
64
+
65
+ ---
66
+
67
+ ## Bulk Register Reading
68
+
69
+ Each model is read in a **single Modbus call** via `readModelBlock()`, which reads `model.length + 2` contiguous registers starting at `model.address`. Individual fields are then extracted from the resulting buffer — no additional network round trips.
70
+
71
+ ---
72
+
73
+ ## Data Types
74
+
75
+ | Type | Registers | Bytes | Description |
76
+ |------|-----------|-------|-------------|
77
+ | `uint16` | 1 | 2 | Unsigned 16-bit integer |
78
+ | `int16` | 1 | 2 | Signed 16-bit integer (two's complement) |
79
+ | `uint32` | 2 | 4 | Unsigned 32-bit integer (big-endian) |
80
+ | `acc32` | 2 | 4 | 32-bit accumulator (unsigned, monotonically increasing) |
81
+ | `string` | N | 2N | UTF-8 string, null-padded |
82
+ | `enum16` | 1 | 2 | Enumerated value (uint16) |
83
+ | `enum32` | 2 | 4 | Enumerated value (uint32) |
84
+ | `bitfield16` | 1 | 2 | Bit flags (uint16) |
85
+ | `bitfield32` | 2 | 4 | Bit flags (uint32) |
86
+
87
+ ### NOT_IMPLEMENTED Sentinel Values
88
+
89
+ Registers may return sentinel values indicating the field is not implemented:
90
+
91
+ | Type | Sentinel Value | Hex |
92
+ |------|---------------|-----|
93
+ | int16 | -32768 | `0x8000` |
94
+ | uint16 | 65535 | `0xFFFF` |
95
+ | int32 | -2147483648 | `0x80000000` |
96
+ | uint32 | 4294967295 | `0xFFFFFFFF` |
97
+ | enum16 / bitfield16 | 65535 | `0xFFFF` |
98
+ | enum32 / bitfield32 | 4294967295 | `0xFFFFFFFF` |
99
+ | acc16 | 0 | `0x0000` (NOT_ACCUMULATED) |
100
+ | acc32 | 0 | `0x00000000` (NOT_ACCUMULATED) |
101
+ | string | all NULLs | `0x0000` per register |
102
+
103
+ ---
104
+
105
+ ## Scale Factors
106
+
107
+ Many numeric fields have an associated **scale factor** (SF) register. The final value is:
108
+
109
+ ```
110
+ scaled_value = raw_value × 10^SF
111
+ ```
112
+
113
+ Scale factor registers are `int16` and typically contain values like `-2`, `-1`, `0`, `1`, `2`.
114
+
115
+ For example: raw value `2345` with SF `-1` → `2345 × 10⁻¹` = `234.5`
116
+
117
+ ---
118
+
119
+ ## Model 1 — Common Block
120
+
121
+ **Method:** `readCommonBlock()`
122
+
123
+ | Offset | Field | Type | Qty | Description |
124
+ |--------|-------|------|-----|-------------|
125
+ | 0 | ID | uint16 | 1 | Model ID (= 1) |
126
+ | 1 | L | uint16 | 1 | Model length (typically 65–66) |
127
+ | 2–17 | Mn | string | 16 | Manufacturer name |
128
+ | 18–33 | Md | string | 16 | Model name |
129
+ | 34–41 | Opt | string | 8 | Options |
130
+ | 42–49 | Vr | string | 8 | Firmware version |
131
+ | 50–65 | SN | string | 16 | Serial number |
132
+ | 66 | DA | uint16 | 1 | Modbus device address |
133
+
134
+ ---
135
+
136
+ ## Model 101 — Single-Phase Inverter
137
+
138
+ **Method:** `readSinglePhaseInverterData()`
139
+
140
+ ### Scale Factors
141
+
142
+ | Offset | Field | Type | Description |
143
+ |--------|-------|------|-------------|
144
+ | 6 | A_SF | int16 | Current SF |
145
+ | 10 | W_SF | int16 | Power SF |
146
+ | 12 | Hz_SF | int16 | Frequency SF |
147
+ | 13 | V_SF | int16 | Voltage SF |
148
+ | 18 | DCA_SF | int16 | DC current SF |
149
+ | 19 | DCV_SF | int16 | DC voltage SF |
150
+ | 21 | DCW_SF | int16 | DC power SF |
151
+
152
+ ### Data Registers
153
+
154
+ | Offset | Field | Type | SF | Description |
155
+ |--------|-------|------|----|-------------|
156
+ | 2 | A | uint16 | A_SF | AC current (A) |
157
+ | 7 | PhVphA | uint16 | V_SF | Phase voltage AN (V) |
158
+ | 9 | W | int16 | W_SF | AC power (W) |
159
+ | 11 | Hz | uint16 | Hz_SF | Frequency (Hz) |
160
+ | 14 | DCA | uint16 | DCA_SF | DC current (A) |
161
+ | 15 | DCV | uint16 | DCV_SF | DC voltage (V) |
162
+ | 20 | DCW | int16 | DCW_SF | DC power (W) |
163
+ | 24 | St | uint16 | — | Operating state (enum) |
164
+
165
+ ---
166
+
167
+ ## Model 103 — Three-Phase Inverter
168
+
169
+ **Method:** `readInverterData()`
170
+
171
+ ### Scale Factors
172
+
173
+ | Offset | Field | Type | Description |
174
+ |--------|-------|------|-------------|
175
+ | 6 | A_SF | int16 | Current SF |
176
+ | 13 | V_SF | int16 | Voltage SF |
177
+ | 15 | W_SF | int16 | Power SF |
178
+ | 17 | Hz_SF | int16 | Frequency SF |
179
+ | 19 | VA_SF | int16 | Apparent power SF |
180
+ | 21 | VAr_SF | int16 | Reactive power SF |
181
+ | 23 | PF_SF | int16 | Power factor SF |
182
+ | 26 | WH_SF | int16 | Energy SF |
183
+ | 28 | DCA_SF | int16 | DC current SF |
184
+ | 29 | DCV_SF | int16 | DC voltage SF |
185
+ | 31 | DCW_SF | int16 | DC power SF |
186
+ | 36 | Tmp_SF | int16 | Temperature SF |
187
+
188
+ ### Data Registers
189
+
190
+ | Offset | Field | Type | SF | Description |
191
+ |--------|-------|------|----|-------------|
192
+ | 2 | A | uint16 | A_SF | Total AC current (A) |
193
+ | 3 | AphA | uint16 | A_SF | Phase A current (A) |
194
+ | 4 | AphB | uint16 | A_SF | Phase B current (A) |
195
+ | 5 | AphC | uint16 | A_SF | Phase C current (A) |
196
+ | 7 | PPVphAB | uint16 | V_SF | Line voltage AB (V) |
197
+ | 8 | PPVphBC | uint16 | V_SF | Line voltage BC (V) |
198
+ | 9 | PPVphCA | uint16 | V_SF | Line voltage CA (V) |
199
+ | 10 | PhVphA | uint16 | V_SF | Phase voltage AN (V) |
200
+ | 11 | PhVphB | uint16 | V_SF | Phase voltage BN (V) |
201
+ | 12 | PhVphC | uint16 | V_SF | Phase voltage CN (V) |
202
+ | 14 | W | int16 | W_SF | AC power (W) |
203
+ | 16 | Hz | uint16 | Hz_SF | Frequency (Hz) |
204
+ | 18 | VA | uint16 | VA_SF | Apparent power (VA) |
205
+ | 20 | VAr | int16 | VAr_SF | Reactive power (VAr) |
206
+ | 22 | PF | int16 | PF_SF | Power factor |
207
+ | 24–25 | WH | acc32 | WH_SF | Cumulative energy (Wh) |
208
+ | 27 | DCA | uint16 | DCA_SF | DC current (A) |
209
+ | 28 | DCV | uint16 | DCV_SF | DC voltage (V) |
210
+ | 30 | DCW | int16 | DCW_SF | DC power (W) |
211
+ | 32 | TmpCab | int16 | Tmp_SF | Cabinet temperature (°C) |
212
+ | 34 | TmpSnk | int16 | Tmp_SF | Heat sink temperature (°C) |
213
+ | 35 | TmpTrns | int16 | Tmp_SF | Transformer temperature (°C) |
214
+ | 36 | TmpOt | int16 | Tmp_SF | Other temperature (°C) |
215
+ | 38 | St | uint16 | — | Operating state (enum) |
216
+ | 39 | StVnd | uint16 | — | Vendor-specific state |
217
+ | 40–41 | Evt1 | bitfield32 | — | Event flags 1 |
218
+ | 42–43 | Evt2 | bitfield32 | — | Event flags 2 |
219
+ | 44–45 | EvtVnd1 | bitfield32 | — | Vendor events 1 |
220
+ | 46–47 | EvtVnd2 | bitfield32 | — | Vendor events 2 |
221
+ | 48–49 | EvtVnd3 | bitfield32 | — | Vendor events 3 |
222
+ | 50–51 | EvtVnd4 | bitfield32 | — | Vendor events 4 |
223
+
224
+ ---
225
+
226
+ ## Model 121 — Inverter Settings
227
+
228
+ **Method:** `readInverterSettings()`
229
+
230
+ ### Scale Factors
231
+
232
+ | Offset | Field | Type | Description |
233
+ |--------|-------|------|-------------|
234
+ | 22 | WMax_SF | int16 | Power SF |
235
+ | 23 | VRef_SF | int16 | Voltage reference SF |
236
+ | 24 | VRefOfs_SF | int16 | Voltage offset SF |
237
+ | 25 | VMinMax_SF | int16 | Min/max voltage SF |
238
+ | 26 | VAMax_SF | int16 | Apparent power SF |
239
+ | 27 | VArMax_SF | int16 | Reactive power SF |
240
+ | 28 | WGra_SF | int16 | Ramp rate SF |
241
+ | 29 | PFMin_SF | int16 | Power factor SF |
242
+ | 30 | MaxRmpRte_SF | int16 | Max ramp rate SF |
243
+ | 31 | ECPNomHz_SF | int16 | Frequency SF |
244
+
245
+ ### Data Registers
246
+
247
+ | Offset | Field | Type | SF | Description |
248
+ |--------|-------|------|----|-------------|
249
+ | 2 | WMax | uint16 | WMax_SF | Maximum power output (W) |
250
+ | 3 | VRef | uint16 | VRef_SF | Voltage at PCC (V) |
251
+ | 4 | VRefOfs | int16 | VRefOfs_SF | Voltage offset from PCC (V) |
252
+ | 5 | VMax | uint16 | VMinMax_SF | Maximum voltage (V) |
253
+ | 6 | VMin | uint16 | VMinMax_SF | Minimum voltage (V) |
254
+ | 7 | VAMax | uint16 | VAMax_SF | Maximum apparent power (VA) |
255
+ | 8 | VArMaxQ1 | int16 | VArMax_SF | Max reactive power Q1 (VAr) |
256
+ | 9 | VArMaxQ2 | int16 | VArMax_SF | Max reactive power Q2 (VAr) |
257
+ | 10 | VArMaxQ3 | int16 | VArMax_SF | Max reactive power Q3 (VAr) |
258
+ | 11 | VArMaxQ4 | int16 | VArMax_SF | Max reactive power Q4 (VAr) |
259
+ | 12 | WGra | uint16 | WGra_SF | Default ramp rate (%WMax/sec) |
260
+ | 13 | PFMinQ1 | int16 | PFMin_SF | Min power factor Q1 |
261
+ | 14 | PFMinQ2 | int16 | PFMin_SF | Min power factor Q2 |
262
+ | 15 | PFMinQ3 | int16 | PFMin_SF | Min power factor Q3 |
263
+ | 16 | PFMinQ4 | int16 | PFMin_SF | Min power factor Q4 |
264
+ | 17 | VArAct | enum16 | — | VAR action on mode change |
265
+ | 18 | ClcTotVA | enum16 | — | Total VA calculation method |
266
+ | 19 | MaxRmpRte | uint16 | MaxRmpRte_SF | Maximum ramp rate (%WGra) |
267
+ | 20 | ECPNomHz | uint16 | ECPNomHz_SF | Nominal frequency (Hz) |
268
+ | 21 | ConnPh | enum16 | — | Connected phase (single phase) |
269
+
270
+ ---
271
+
272
+ ## Model 123 — Inverter Controls
273
+
274
+ **Method:** `readInverterControls()` / `writeInverterControls()`
275
+
276
+ ### Scale Factors
277
+
278
+ | Offset | Field | Type | Description |
279
+ |--------|-------|------|-------------|
280
+ | 21 | WMaxLimPct_SF | int16 | Power limit SF |
281
+ | 22 | OutPFSet_SF | int16 | Power factor SF |
282
+ | 23 | VArPct_SF | int16 | VAR percentage SF |
283
+
284
+ ### Connection Control
285
+
286
+ | Offset | Field | Type | R/W | Description |
287
+ |--------|-------|------|-----|-------------|
288
+ | 0 | Conn_WinTms | uint16 | R | Time window for connect/disconnect (sec) |
289
+ | 1 | Conn_RvrtTms | uint16 | R | Timeout for connect/disconnect (sec) |
290
+ | 2 | Conn | enum16 | **W** | Connect/disconnect (0=DISCONNECT, 1=CONNECT) |
291
+
292
+ ### Power Limit Control
293
+
294
+ | Offset | Field | Type | R/W | SF | Description |
295
+ |--------|-------|------|-----|----|-------------|
296
+ | 3 | WMaxLimPct | uint16 | **W** | WMaxLimPct_SF | Power limit (%WMax) |
297
+ | 4 | WMaxLimPct_WinTms | uint16 | R | — | Time window (sec) |
298
+ | 5 | WMaxLimPct_RvrtTms | uint16 | R | — | Timeout (sec) |
299
+ | 6 | WMaxLimPct_RmpTms | uint16 | R | — | Ramp time (sec) |
300
+ | 7 | WMaxLim_Ena | enum16 | **W** | — | Enable (0=DISABLED, 1=ENABLED) |
301
+
302
+ ### Power Factor Control
303
+
304
+ | Offset | Field | Type | R/W | SF | Description |
305
+ |--------|-------|------|-----|----|-------------|
306
+ | 8 | OutPFSet | int16 | **W** | OutPFSet_SF | Power factor setpoint |
307
+ | 9 | OutPFSet_WinTms | uint16 | R | — | Time window (sec) |
308
+ | 10 | OutPFSet_RvrtTms | uint16 | R | — | Timeout (sec) |
309
+ | 11 | OutPFSet_RmpTms | uint16 | R | — | Ramp time (sec) |
310
+ | 12 | OutPFSet_Ena | enum16 | **W** | — | Enable (0=DISABLED, 1=ENABLED) |
311
+
312
+ ### Reactive Power Control
313
+
314
+ | Offset | Field | Type | R/W | SF | Description |
315
+ |--------|-------|------|-----|----|-------------|
316
+ | 13 | VArWMaxPct | int16 | R | VArPct_SF | Reactive power at max W (%) |
317
+ | 14 | VArMaxPct | int16 | R | VArPct_SF | Max reactive power (%) |
318
+ | 15 | VArAvalPct | int16 | R | VArPct_SF | Available reactive power (%) |
319
+ | 16 | VArPct_WinTms | uint16 | R | — | Time window (sec) |
320
+ | 17 | VArPct_RvrtTms | uint16 | R | — | Timeout (sec) |
321
+ | 18 | VArPct_RmpTms | uint16 | R | — | Ramp time (sec) |
322
+ | 19 | VArPct_Mod | enum16 | R | — | Mode (0=NONE, 1=WMAX, 2=VARMAX) |
323
+ | 20 | VArPct_Ena | enum16 | R | — | Enable (0=DISABLED, 1=ENABLED) |
324
+
325
+ ---
326
+
327
+ ## Model 124 — Battery Basic Storage Controls
328
+
329
+ **Method:** `readBatteryData()` / `writeBatteryControls()`
330
+
331
+ ### Scale Factors
332
+
333
+ | Offset | Field | Type | Description |
334
+ |--------|-------|------|-------------|
335
+ | 18 | WChaMax_SF | int16 | Max charge power SF |
336
+ | 19 | WChaDisChaGra_SF | int16 | Charge/discharge gradient SF |
337
+ | 20 | VAChaMax_SF | int16 | Max charging VA SF |
338
+ | 21 | MinRsvPct_SF | int16 | Min reserve percentage SF |
339
+ | 22 | ChaState_SF | int16 | Charge state SF |
340
+ | 23 | StorAval_SF | int16 | Available storage SF |
341
+ | 24 | InBatV_SF | int16 | Battery voltage SF |
342
+ | 25 | InOutWRte_SF | int16 | Charge/discharge rate SF |
343
+
344
+ ### Data Registers
345
+
346
+ | Offset | Field | Type | R/W | SF | Description |
347
+ |--------|-------|------|-----|----|-------------|
348
+ | 2 | WChaMax | uint16 | **W** | WChaMax_SF | Max charge power (W) |
349
+ | 3 | WChaGra | uint16 | R | WChaDisChaGra_SF | Charge rate gradient (%/sec) |
350
+ | 4 | WDisChaGra | uint16 | R | WChaDisChaGra_SF | Discharge rate gradient (%/sec) |
351
+ | 5 | StorCtlMod | bitfield16 | **W** | — | Storage control mode (see enum) |
352
+ | 6 | VAChaMax | uint16 | R | VAChaMax_SF | Max charging VA |
353
+ | 7 | MinRsvPct | uint16 | **W** | MinRsvPct_SF | Min reserve (%) |
354
+ | 8 | ChaState | uint16 | R | ChaState_SF | State of charge (%AhrRtg) |
355
+ | 9 | StorAval | uint16 | R | StorAval_SF | Available storage (AH) |
356
+ | 10 | InBatV | uint16 | R | InBatV_SF | Battery voltage (V) |
357
+ | 11 | ChaSt | enum16 | R | — | Charge status (see enum) |
358
+ | 12 | OutWRte | int16 | **W** | InOutWRte_SF | Discharge rate (%WDisChaMax) |
359
+ | 13 | InWRte | int16 | **W** | InOutWRte_SF | Charge rate (%WChaMax) |
360
+ | 14 | InOutWRteWinTms | uint16 | R | — | Rate change time window (sec) |
361
+ | 15 | InOutWRteRvrtTms | uint16 | R | — | Rate change timeout (sec) |
362
+ | 16 | InOutWRteRmpTms | uint16 | R | — | Rate change ramp time (sec) |
363
+ | 17 | ChaGriSet | enum16 | **W** | — | Charge source (0=PV, 1=GRID) |
364
+
365
+ ---
366
+
367
+ ## Model 160 — MPPT (Multiple Maximum Power Point Tracker)
368
+
369
+ **Method:** `readAllMPPTData()` / `readMPPTData(moduleId)`
370
+
371
+ ### Fixed Block (Scale Factors)
372
+
373
+ | Offset | Field | Type | Description |
374
+ |--------|-------|------|-------------|
375
+ | 2 | DCA_SF | int16 | DC current SF |
376
+ | 3 | DCV_SF | int16 | DC voltage SF |
377
+ | 4 | DCW_SF | int16 | DC power SF |
378
+ | 5 | DCWH_SF | int16 | DC energy SF |
379
+ | 8 | N | uint16 | Number of MPPT modules |
380
+
381
+ ### Repeating Module Block (20 registers each)
382
+
383
+ Module 1 starts at offset **10**, Module 2 at offset **30**, Module N at offset `10 + (N-1) × 20`.
384
+
385
+ | Relative Offset | Field | Type | SF | Description |
386
+ |-----------------|-------|------|----|-------------|
387
+ | 0 | ID | uint16 | — | Module ID |
388
+ | 1–8 | IDStr | string (8 regs) | — | Module string identifier |
389
+ | 9 | DCA | uint16 | DCA_SF | DC current (A) |
390
+ | 10 | DCV | uint16 | DCV_SF | DC voltage (V) |
391
+ | 11 | DCW | uint16 | DCW_SF | DC power (W) |
392
+ | 12–13 | DCWH | acc32 | DCWH_SF | Cumulative DC energy (Wh) |
393
+ | 14–15 | Tms | uint32 | — | Timestamp (seconds since epoch) |
394
+ | 16 | Tmp | int16 | fixed (−1) | Module temperature (°C) |
395
+ | 17 | DCSt | enum16 | — | Operating state |
396
+
397
+ ---
398
+
399
+ ## Models 201/203/204 — Meters
400
+
401
+ **Method:** `readMeterData()`
402
+
403
+ The SDK reads Model 203 (3-Phase Delta), 204 (3-Phase Wye), or 201 (Single-Phase) — trying in that order. All three share the same register offsets for the fields we read:
404
+
405
+ ### Scale Factors
406
+
407
+ | Offset | Field | Type | Description |
408
+ |--------|-------|------|-------------|
409
+ | 17 | Hz_SF | int16 | Frequency SF |
410
+ | 22 | W_SF | int16 | Power SF |
411
+ | 54 | TotWh_SF | int16 | Energy SF |
412
+
413
+ ### Data Registers
414
+
415
+ | Offset | Field | Type | SF | Description |
416
+ |--------|-------|------|----|-------------|
417
+ | 16 | Hz | uint16 | Hz_SF | Frequency (Hz) |
418
+ | 18 | W | int16 | W_SF | Total real power (W) |
419
+ | 38–39 | TotWhExp | acc32 | TotWh_SF | Total exported energy (Wh) |
420
+ | 46–47 | TotWhImp | acc32 | TotWh_SF | Total imported energy (Wh) |
421
+
422
+ ---
423
+
424
+ ## Model 802 — Battery Base
425
+
426
+ **Method:** `readBatteryBaseData()`
427
+
428
+ ### Scale Factors
429
+
430
+ | Offset | Field | Type | Description |
431
+ |--------|-------|------|-------------|
432
+ | 52 | AHRtg_SF | int16 | Amp-hour rating SF |
433
+ | 53 | WHRtg_SF | int16 | Watt-hour rating SF |
434
+ | 54 | WChaDisChaMax_SF | int16 | Charge/discharge max rate SF |
435
+ | 55 | DisChaRte_SF | int16 | Self-discharge rate SF |
436
+ | 56 | SoC_SF | int16 | State of charge SF |
437
+ | 57 | DoD_SF | int16 | Depth of discharge SF |
438
+ | 58 | SoH_SF | int16 | State of health SF |
439
+ | 59 | V_SF | int16 | Voltage SF |
440
+ | 60 | CellV_SF | int16 | Cell voltage SF |
441
+ | 61 | A_SF | int16 | Current SF |
442
+ | 62 | AMax_SF | int16 | Max current SF |
443
+ | 63 | W_SF | int16 | Power SF |
444
+
445
+ ### Nameplate (Offsets 2–5)
446
+
447
+ | Offset | Field | Type | SF | Description |
448
+ |--------|-------|------|----|-------------|
449
+ | 2 | AHRtg | uint16 | AHRtg_SF | Nameplate charge capacity (AH) |
450
+ | 3 | WHRtg | uint16 | WHRtg_SF | Nameplate energy capacity (WH) |
451
+ | 4 | WChaRteMax | uint16 | WChaDisChaMax_SF | Max charge rate (W) |
452
+ | 5 | WDisChaRteMax | uint16 | WChaDisChaMax_SF | Max discharge rate (W) |
453
+
454
+ ### State of Charge / Health (Offsets 6–13)
455
+
456
+ | Offset | Field | Type | SF | Description |
457
+ |--------|-------|------|----|-------------|
458
+ | 6 | DisChaRte | uint16 | DisChaRte_SF | Self-discharge rate (%) |
459
+ | 7 | SoCMax | uint16 | SoC_SF | Max state of charge (%) |
460
+ | 8 | SoCMin | uint16 | SoC_SF | Min state of charge (%) |
461
+ | 9 | SoCRsvMax | uint16 | SoC_SF | Max reserve SOC (%) |
462
+ | 10 | SoCRsvMin | uint16 | SoC_SF | Min reserve SOC (%) |
463
+ | 11 | SoC | uint16 | SoC_SF | Current state of charge (%) |
464
+ | 12 | DoD | uint16 | DoD_SF | Depth of discharge (%) |
465
+ | 13 | SoH | uint16 | SoH_SF | State of health (%) |
466
+
467
+ ### Status (Offsets 14–22)
468
+
469
+ | Offset | Field | Type | Description |
470
+ |--------|-------|------|-------------|
471
+ | 14–15 | NCyc | uint32 | Cycle count |
472
+ | 16 | ChaSt | enum16 | Charge status (see enum) |
473
+ | 17 | LocRemCtl | enum16 | Local/remote control mode |
474
+ | 21 | Typ | enum16 | Battery type (see enum) |
475
+ | 22 | State | enum16 | Battery bank state (see enum) |
476
+
477
+ ### Events (Offsets 26–33)
478
+
479
+ | Offset | Field | Type | Description |
480
+ |--------|-------|------|-------------|
481
+ | 26–27 | Evt1 | bitfield32 | Event bitfield 1 |
482
+ | 28–29 | Evt2 | bitfield32 | Event bitfield 2 |
483
+ | 30–31 | EvtVnd1 | bitfield32 | Vendor event bitfield 1 |
484
+ | 32–33 | EvtVnd2 | bitfield32 | Vendor event bitfield 2 |
485
+
486
+ ### Voltage (Offsets 34–43)
487
+
488
+ | Offset | Field | Type | SF | Description |
489
+ |--------|-------|------|----|-------------|
490
+ | 34 | V | uint16 | V_SF | Battery voltage (V) |
491
+ | 35 | VMax | uint16 | V_SF | Max battery voltage (V) |
492
+ | 36 | VMin | uint16 | V_SF | Min battery voltage (V) |
493
+ | 37 | CellVMax | uint16 | CellV_SF | Max cell voltage (V) |
494
+ | 38 | CellVMaxStr | uint16 | — | String containing max cell |
495
+ | 39 | CellVMaxMod | uint16 | — | Module containing max cell |
496
+ | 40 | CellVMin | uint16 | CellV_SF | Min cell voltage (V) |
497
+ | 41 | CellVMinStr | uint16 | — | String containing min cell |
498
+ | 42 | CellVMinMod | uint16 | — | Module containing min cell |
499
+ | 43 | CellVAvg | uint16 | CellV_SF | Average cell voltage (V) |
500
+
501
+ ### Current (Offsets 44–46)
502
+
503
+ | Offset | Field | Type | SF | Description |
504
+ |--------|-------|------|----|-------------|
505
+ | 44 | A | int16 | A_SF | Battery current (A) |
506
+ | 45 | AChaMax | uint16 | AMax_SF | Max charge current (A) |
507
+ | 46 | ADisChaMax | uint16 | AMax_SF | Max discharge current (A) |
508
+
509
+ ### Power / Control (Offsets 47–51)
510
+
511
+ | Offset | Field | Type | SF | Description |
512
+ |--------|-------|------|----|-------------|
513
+ | 47 | W | int16 | W_SF | Battery power (W, +charge/−discharge) |
514
+ | 48 | ReqInvState | enum16 | — | Requested inverter state |
515
+ | 49 | ReqW | int16 | W_SF | Requested power (W) |
516
+ | 50 | SetOp | enum16 | — | Set operation |
517
+ | 51 | SetInvState | enum16 | — | Set inverter state |
518
+
519
+ ---
520
+
521
+ ## Writable Registers
522
+
523
+ ### Model 123 — Inverter Controls (`writeInverterControls`)
524
+
525
+ | Register Offset | Field | Scale Factor Offset | Description |
526
+ |----------------|-------|---------------------|-------------|
527
+ | 2 | Conn | — | Connect/disconnect |
528
+ | 3 | WMaxLimPct | 21 (WMaxLimPct_SF) | Power limit percentage |
529
+ | 7 | WMaxLim_Ena | — | Throttle enable/disable |
530
+ | 8 | OutPFSet | 22 (OutPFSet_SF) | Power factor setpoint |
531
+ | 12 | OutPFSet_Ena | — | PF control enable/disable |
532
+
533
+ ### Model 124 — Battery Controls (`writeBatteryControls`)
534
+
535
+ | Register Offset | Field | Scale Factor Offset | Description |
536
+ |----------------|-------|---------------------|-------------|
537
+ | 2 | WChaMax | 18 (WChaMax_SF) | Max charge power (W) |
538
+ | 5 | StorCtlMod | — | Storage control mode bits |
539
+ | 7 | MinRsvPct | 21 (MinRsvPct_SF) | Min reserve percentage |
540
+ | 12 | OutWRte | 25 (InOutWRte_SF) | Discharge rate (%) |
541
+ | 13 | InWRte | 25 (InOutWRte_SF) | Charge rate (%) |
542
+ | 17 | ChaGriSet | — | Charge source (PV/Grid) |
543
+
544
+ ### Helper: `setFeedInLimit(limitW)`
545
+
546
+ Reads `WMax` from Model 121, computes `(limitW / WMax) × 100`, then writes `WMaxLimPct` + enables `WMaxLim_Ena` via Model 123. Pass `null` to disable the limit.
547
+
548
+ ### Helper: `setStorageMode(mode)` / `enableGridCharging(enable)`
549
+
550
+ Convenience wrappers around `writeBatteryControls()` for common battery operations.
551
+
552
+ ---
553
+
554
+ ## Enum Reference
555
+
556
+ ### SunspecBatteryChargeState (Model 124 offset 11 / Model 802 offset 16)
557
+
558
+ | Value | Name | Description |
559
+ |-------|------|-------------|
560
+ | 1 | OFF | Battery off |
561
+ | 2 | EMPTY | Battery empty |
562
+ | 3 | DISCHARGING | Discharging |
563
+ | 4 | CHARGING | Charging |
564
+ | 5 | FULL | Fully charged |
565
+ | 6 | HOLDING | Holding charge |
566
+ | 7 | TESTING | Under test |
567
+
568
+ ### SunspecStorageControlMode (Model 124 offset 5 — bitfield)
569
+
570
+ | Bit | Value | Name | Description |
571
+ |-----|-------|------|-------------|
572
+ | 0 | 0x0001 | CHARGE | Enable charging |
573
+ | 1 | 0x0002 | DISCHARGE | Enable discharging |
574
+
575
+ **Derived modes via `setStorageMode()`:**
576
+
577
+ | Mode | Bits | Description |
578
+ |------|------|-------------|
579
+ | CHARGE | 0x01 | Charge only |
580
+ | DISCHARGE | 0x02 | Discharge only |
581
+ | HOLDING | 0x00 | Neither charge nor discharge |
582
+ | AUTO | 0x03 | Both charge and discharge |
583
+
584
+ ### SunspecChargeSource (Model 124 offset 17)
585
+
586
+ | Value | Name | Description |
587
+ |-------|------|-------------|
588
+ | 0 | PV | Charge from PV only |
589
+ | 1 | GRID | Charge from grid |
590
+
591
+ ### SunspecEnableControl (Model 123 — various enable fields)
592
+
593
+ | Value | Name |
594
+ |-------|------|
595
+ | 0 | DISABLED |
596
+ | 1 | ENABLED |
597
+
598
+ ### SunspecBatteryType (Model 802 offset 21)
599
+
600
+ | Value | Name |
601
+ |-------|------|
602
+ | 0 | NOT_APPLICABLE_UNKNOWN |
603
+ | 1 | LEAD_ACID |
604
+ | 2 | NICKEL_METAL_HYDRIDE |
605
+ | 3 | NICKEL_CADMIUM |
606
+ | 4 | LITHIUM_ION |
607
+ | 5 | CARBON_ZINC |
608
+ | 6 | ZINC_CHLORIDE |
609
+ | 7 | ALKALINE |
610
+ | 8 | RECHARGEABLE_ALKALINE |
611
+ | 9 | SODIUM_SULFUR |
612
+ | 10 | FLOW |
613
+ | 11 | SUPER_CAPACITOR |
614
+ | 99 | OTHER |
615
+
616
+ ### SunspecBatteryBankState (Model 802 offset 22)
617
+
618
+ | Value | Name |
619
+ |-------|------|
620
+ | 1 | DISCONNECTED |
621
+ | 2 | INITIALIZING |
622
+ | 3 | CONNECTED |
623
+ | 4 | STANDBY |
624
+ | 5 | SOC_PROTECTION |
625
+ | 6 | SUSPENDING |
626
+ | 99 | FAULT |