@enyo-energy/sunspec-sdk 0.0.51 → 0.0.52
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/dist/cjs/sunspec-devices.cjs +45 -42
- package/dist/cjs/sunspec-modbus-client.cjs +374 -241
- package/dist/cjs/sunspec-modbus-client.d.cts +94 -52
- package/dist/cjs/version.cjs +1 -1
- package/dist/cjs/version.d.cts +1 -1
- package/dist/sunspec-devices.js +45 -42
- package/dist/sunspec-modbus-client.d.ts +94 -52
- package/dist/sunspec-modbus-client.js +372 -241
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +2 -2
|
@@ -19,23 +19,38 @@
|
|
|
19
19
|
import { type SunspecInverterControls, type SunspecInverterData, type SunspecInverterSettings, type SunspecMeterData, type SunspecModel, type SunspecMPPTData, type SunspecBatteryData, type SunspecBatteryBaseData, type SunspecBatteryControls, SunspecStorageMode } from "./sunspec-interfaces.js";
|
|
20
20
|
import { EnergyAppModbusDataType, IConnectionHealth } from "@enyo-energy/energy-app-sdk/dist/implementations/modbus/interfaces.js";
|
|
21
21
|
import { EnergyApp } from "@enyo-energy/energy-app-sdk";
|
|
22
|
+
/**
|
|
23
|
+
* Get (or create) the singleton SunspecModbusClient for this network device.
|
|
24
|
+
* Increments the refcount; pair with `releaseSunspecClient` on teardown.
|
|
25
|
+
*/
|
|
26
|
+
export declare function getOrCreateSunspecClient(energyApp: EnergyApp, host: string, port?: number): SunspecModbusClient;
|
|
27
|
+
/**
|
|
28
|
+
* Release a refcount on the network-device client. When the last consumer releases,
|
|
29
|
+
* the client is fully disconnected (all units closed) and removed from the registry.
|
|
30
|
+
*
|
|
31
|
+
* Releasing more times than acquired is a programming error and is logged; the count
|
|
32
|
+
* is clamped at zero so repeat releases are no-ops.
|
|
33
|
+
*/
|
|
34
|
+
export declare function releaseSunspecClient(host: string, port?: number): Promise<void>;
|
|
22
35
|
export declare class SunspecModbusClient {
|
|
23
36
|
private energyApp;
|
|
24
|
-
private
|
|
25
|
-
private
|
|
26
|
-
private
|
|
37
|
+
private modbusInstances;
|
|
38
|
+
private faultTolerantReaders;
|
|
39
|
+
private discoveredModelsByUnit;
|
|
27
40
|
private connectionHealth;
|
|
28
|
-
private faultTolerantReader;
|
|
29
41
|
private modbusDataTypeConverter;
|
|
30
42
|
private connectionParams;
|
|
43
|
+
private knownUnits;
|
|
31
44
|
private autoReconnectEnabled;
|
|
32
45
|
private openCount;
|
|
33
46
|
private closeCount;
|
|
34
|
-
private currentlyOpen;
|
|
35
47
|
private operationChain;
|
|
36
48
|
constructor(energyApp: EnergyApp);
|
|
37
49
|
/**
|
|
38
|
-
* Connect to Modbus device
|
|
50
|
+
* Connect to a Modbus device unit. Multiple unit IDs on the same network device share this
|
|
51
|
+
* client; calling connect() with different unit IDs adds each as a separately-managed unit.
|
|
52
|
+
* The first call locks in the host/port for this client; later calls for a different host
|
|
53
|
+
* are rejected.
|
|
39
54
|
* @param host Primary host (hostname) to connect to
|
|
40
55
|
* @param port Modbus port (default 502)
|
|
41
56
|
* @param unitId Modbus unit ID (default 1)
|
|
@@ -43,33 +58,47 @@ export declare class SunspecModbusClient {
|
|
|
43
58
|
*/
|
|
44
59
|
connect(host: string, port?: number, unitId?: number, secondaryHost?: string): Promise<void>;
|
|
45
60
|
/**
|
|
46
|
-
* Disconnect from
|
|
61
|
+
* Disconnect from all units of this network device.
|
|
47
62
|
*
|
|
48
|
-
* Note: connection parameters are preserved so reconnect() can
|
|
49
|
-
* They will be overwritten by the next connect() call anyway.
|
|
63
|
+
* Note: connection parameters and the set of known units are preserved so reconnect() can
|
|
64
|
+
* be called afterwards. They will be overwritten by the next connect() call anyway.
|
|
50
65
|
*/
|
|
51
66
|
disconnect(): Promise<void>;
|
|
52
67
|
/**
|
|
53
|
-
*
|
|
54
|
-
|
|
55
|
-
|
|
68
|
+
* Disconnect a single unit on this network device. Other units on the same device stay open.
|
|
69
|
+
*/
|
|
70
|
+
disconnectUnit(unitId: number): Promise<void>;
|
|
71
|
+
/**
|
|
72
|
+
* Reconnect every previously-known unit on this network device using stored connection
|
|
73
|
+
* parameters. First tries primaryHost (hostname), then falls back to secondaryHost
|
|
74
|
+
* (ipAddress) if available. Returns true only if every known unit reconnected successfully.
|
|
56
75
|
*/
|
|
57
76
|
reconnect(): Promise<boolean>;
|
|
58
77
|
/**
|
|
59
|
-
*
|
|
60
|
-
*
|
|
78
|
+
* Reconnect a single previously-known unit on this network device. Other units on the
|
|
79
|
+
* same client stay open. Useful when one device's polling loop detects a dropped
|
|
80
|
+
* connection and only needs to recover its own unit, not thrash siblings.
|
|
81
|
+
*
|
|
82
|
+
* Returns true if the unit reconnected successfully (on primary or secondary host).
|
|
83
|
+
*/
|
|
84
|
+
reconnectUnit(unitId: number): Promise<boolean>;
|
|
85
|
+
/**
|
|
86
|
+
* Attempt to (re)open every requested unit on a specific host. Caller must hold the
|
|
87
|
+
* connection lock. Closes any pre-existing per-unit instances first. Returns true only
|
|
88
|
+
* if every unit succeeded.
|
|
61
89
|
*/
|
|
62
90
|
private attemptConnection;
|
|
63
91
|
/**
|
|
64
|
-
* Open a new Modbus
|
|
65
|
-
* just-opened
|
|
66
|
-
* lock and ensure
|
|
92
|
+
* Open a new Modbus instance for one unit ID and wire up its fault-tolerant reader.
|
|
93
|
+
* On any failure, the just-opened instance (if any) is closed so we never leak. Caller must
|
|
94
|
+
* hold the connection lock and ensure the unit is not already open.
|
|
67
95
|
*/
|
|
68
|
-
private
|
|
96
|
+
private _openUnit;
|
|
69
97
|
/**
|
|
70
|
-
* Close the
|
|
98
|
+
* Close the Modbus instance for a single unit. Idempotent. Caller must hold the
|
|
99
|
+
* connection lock.
|
|
71
100
|
*/
|
|
72
|
-
private
|
|
101
|
+
private _closeUnit;
|
|
73
102
|
/**
|
|
74
103
|
* Run `fn` with exclusive access to connection-state transitions. Subsequent calls queue
|
|
75
104
|
* behind any in-flight one. A rejected `fn` does not poison the chain for later callers.
|
|
@@ -78,13 +107,26 @@ export declare class SunspecModbusClient {
|
|
|
78
107
|
private recordOpen;
|
|
79
108
|
private recordClose;
|
|
80
109
|
/**
|
|
81
|
-
* Get cumulative open/close counts for this client. Useful for
|
|
110
|
+
* Get cumulative open/close counts for this client (across all unit IDs). Useful for
|
|
111
|
+
* spotting connection leaks.
|
|
82
112
|
*/
|
|
83
113
|
getConnectionStats(): {
|
|
84
114
|
opens: number;
|
|
85
115
|
closes: number;
|
|
86
|
-
|
|
116
|
+
openUnits: number;
|
|
87
117
|
};
|
|
118
|
+
/**
|
|
119
|
+
* Get the EnergyAppModbusInstance for a unit, throwing if it isn't open.
|
|
120
|
+
*/
|
|
121
|
+
private getInstance;
|
|
122
|
+
/**
|
|
123
|
+
* Get the fault-tolerant reader for a unit, throwing if it isn't open.
|
|
124
|
+
*/
|
|
125
|
+
private getReader;
|
|
126
|
+
/**
|
|
127
|
+
* Get (or create) the discovered-models map for a unit.
|
|
128
|
+
*/
|
|
129
|
+
private getModelsMap;
|
|
88
130
|
/**
|
|
89
131
|
* Enable or disable automatic reconnection
|
|
90
132
|
*/
|
|
@@ -96,20 +138,20 @@ export declare class SunspecModbusClient {
|
|
|
96
138
|
/**
|
|
97
139
|
* Detect the base address and addressing mode (0-based or 1-based) for SunSpec
|
|
98
140
|
*/
|
|
99
|
-
detectSunspecBaseAddress(customBaseAddress?: number): Promise<{
|
|
141
|
+
detectSunspecBaseAddress(unitId: number, customBaseAddress?: number): Promise<{
|
|
100
142
|
baseAddress: number;
|
|
101
143
|
isZeroBased: boolean;
|
|
102
144
|
nextAddress: number;
|
|
103
145
|
}>;
|
|
104
146
|
/**
|
|
105
|
-
* Discover all available Sunspec models
|
|
147
|
+
* Discover all available Sunspec models for a unit
|
|
106
148
|
* Automatically detects base address (40000 or 40001) and scans from there
|
|
107
149
|
*/
|
|
108
|
-
discoverModels(customBaseAddress?: number): Promise<Map<number, SunspecModel>>;
|
|
150
|
+
discoverModels(unitId: number, customBaseAddress?: number): Promise<Map<number, SunspecModel>>;
|
|
109
151
|
/**
|
|
110
|
-
* Find a specific model by ID
|
|
152
|
+
* Find a specific model by ID for a given unit
|
|
111
153
|
*/
|
|
112
|
-
findModel(modelId: number): SunspecModel | undefined;
|
|
154
|
+
findModel(unitId: number, modelId: number): SunspecModel | undefined;
|
|
113
155
|
/**
|
|
114
156
|
* Check if a value is "unimplemented" according to Sunspec specification
|
|
115
157
|
* Returns true if the value represents an unimplemented/not applicable register
|
|
@@ -153,15 +195,15 @@ export declare class SunspecModbusClient {
|
|
|
153
195
|
/**
|
|
154
196
|
* Helper to read register value(s) using the fault-tolerant reader with data type conversion
|
|
155
197
|
*/
|
|
156
|
-
readRegisterValue(address: number, quantity: number | undefined, dataType: EnergyAppModbusDataType): Promise<number | string | number[]>;
|
|
198
|
+
readRegisterValue(unitId: number, address: number, quantity: number | undefined, dataType: EnergyAppModbusDataType): Promise<number | string | number[]>;
|
|
157
199
|
/**
|
|
158
200
|
* Helper to write register value(s)
|
|
159
201
|
*/
|
|
160
|
-
writeRegisterValue(address: number, value: number | number[], dataType?: EnergyAppModbusDataType): Promise<boolean>;
|
|
202
|
+
writeRegisterValue(unitId: number, address: number, value: number | number[], dataType?: EnergyAppModbusDataType): Promise<boolean>;
|
|
161
203
|
/**
|
|
162
204
|
* Read inverter data from Model 101 (Single Phase) / Model 103 (Three Phase)
|
|
163
205
|
*/
|
|
164
|
-
readInverterData(): Promise<SunspecInverterData | null>;
|
|
206
|
+
readInverterData(unitId: number): Promise<SunspecInverterData | null>;
|
|
165
207
|
/**
|
|
166
208
|
* Read single phase inverter data (Model 101)
|
|
167
209
|
*/
|
|
@@ -191,7 +233,7 @@ export declare class SunspecModbusClient {
|
|
|
191
233
|
* Extract MPPT scale factors from a pre-read model buffer
|
|
192
234
|
*/
|
|
193
235
|
private extractMPPTScaleFactors;
|
|
194
|
-
readMPPTScaleFactors(): Promise<{
|
|
236
|
+
readMPPTScaleFactors(unitId: number): Promise<{
|
|
195
237
|
DCA_SF: number;
|
|
196
238
|
DCV_SF: number;
|
|
197
239
|
DCW_SF: number;
|
|
@@ -204,11 +246,11 @@ export declare class SunspecModbusClient {
|
|
|
204
246
|
/**
|
|
205
247
|
* Read MPPT data from Model 160
|
|
206
248
|
*/
|
|
207
|
-
readMPPTData(moduleId?: number): Promise<SunspecMPPTData | null>;
|
|
249
|
+
readMPPTData(unitId: number, moduleId?: number): Promise<SunspecMPPTData | null>;
|
|
208
250
|
/**
|
|
209
251
|
* Read all MPPT strings from Model 160 (Multiple MPPT)
|
|
210
252
|
*/
|
|
211
|
-
readAllMPPTData(): Promise<SunspecMPPTData[]>;
|
|
253
|
+
readAllMPPTData(unitId: number): Promise<SunspecMPPTData[]>;
|
|
212
254
|
/**
|
|
213
255
|
* Map battery charge state to human-readable name
|
|
214
256
|
* @param state The numeric charge state value
|
|
@@ -230,67 +272,67 @@ export declare class SunspecModbusClient {
|
|
|
230
272
|
/**
|
|
231
273
|
* Read battery base data from Model 802 (Battery Base)
|
|
232
274
|
*/
|
|
233
|
-
readBatteryBaseData(): Promise<SunspecBatteryBaseData | null>;
|
|
275
|
+
readBatteryBaseData(unitId: number): Promise<SunspecBatteryBaseData | null>;
|
|
234
276
|
/**
|
|
235
277
|
* Read battery data from Model 124 (Basic Storage) with fallback to Model 802 / Model 803
|
|
236
278
|
*/
|
|
237
|
-
readBatteryData(): Promise<SunspecBatteryData | null>;
|
|
279
|
+
readBatteryData(unitId: number): Promise<SunspecBatteryData | null>;
|
|
238
280
|
/**
|
|
239
281
|
* Write battery control settings to Model 124
|
|
240
282
|
*/
|
|
241
|
-
writeBatteryControls(controls: Partial<SunspecBatteryControls>): Promise<boolean>;
|
|
283
|
+
writeBatteryControls(unitId: number, controls: Partial<SunspecBatteryControls>): Promise<boolean>;
|
|
242
284
|
/**
|
|
243
285
|
* Set battery storage mode (simplified interface)
|
|
244
286
|
*/
|
|
245
|
-
setStorageMode(mode: SunspecStorageMode): Promise<boolean>;
|
|
287
|
+
setStorageMode(unitId: number, mode: SunspecStorageMode): Promise<boolean>;
|
|
246
288
|
/**
|
|
247
289
|
* Enable or disable grid charging
|
|
248
290
|
*/
|
|
249
|
-
enableGridCharging(enable: boolean): Promise<boolean>;
|
|
291
|
+
enableGridCharging(unitId: number, enable: boolean): Promise<boolean>;
|
|
250
292
|
/**
|
|
251
293
|
* Read battery control settings from Model 124 (Basic Storage Controls)
|
|
252
294
|
*/
|
|
253
|
-
readBatteryControls(): Promise<SunspecBatteryControls | null>;
|
|
295
|
+
readBatteryControls(unitId: number): Promise<SunspecBatteryControls | null>;
|
|
254
296
|
/**
|
|
255
297
|
* Read meter data from Model 201 (Single Phase) / Model 203 (Three Phase) / Model 204 (Split Phase)
|
|
256
298
|
*/
|
|
257
|
-
readMeterData(): Promise<SunspecMeterData | null>;
|
|
299
|
+
readMeterData(unitId: number): Promise<SunspecMeterData | null>;
|
|
258
300
|
/**
|
|
259
301
|
* Read common block data (Model 1)
|
|
260
302
|
*/
|
|
261
|
-
readCommonBlock(): Promise<any>;
|
|
303
|
+
readCommonBlock(unitId: number): Promise<any>;
|
|
262
304
|
/**
|
|
263
305
|
* Get serial number from device
|
|
264
306
|
*/
|
|
265
|
-
getSerialNumber(): Promise<string | undefined>;
|
|
307
|
+
getSerialNumber(unitId: number): Promise<string | undefined>;
|
|
266
308
|
/**
|
|
267
|
-
* Check if connected
|
|
309
|
+
* Check if a specific unit is connected on this network device
|
|
268
310
|
*/
|
|
269
|
-
isConnected(): boolean;
|
|
311
|
+
isConnected(unitId: number): boolean;
|
|
270
312
|
/**
|
|
271
|
-
* Check if connection is healthy
|
|
313
|
+
* Check if a specific unit's connection is healthy
|
|
272
314
|
*/
|
|
273
|
-
isHealthy(): boolean;
|
|
315
|
+
isHealthy(unitId: number): boolean;
|
|
274
316
|
/**
|
|
275
|
-
* Get connection health details
|
|
317
|
+
* Get connection health details (shared across all units on this network device)
|
|
276
318
|
*/
|
|
277
319
|
getConnectionHealth(): IConnectionHealth;
|
|
278
320
|
/**
|
|
279
321
|
* Read inverter settings from Model 121 (Inverter Settings)
|
|
280
322
|
*/
|
|
281
|
-
readInverterSettings(): Promise<SunspecInverterSettings | null>;
|
|
323
|
+
readInverterSettings(unitId: number): Promise<SunspecInverterSettings | null>;
|
|
282
324
|
/**
|
|
283
325
|
* Read inverter controls from Model 123 (Immediate Inverter Controls)
|
|
284
326
|
*/
|
|
285
|
-
readInverterControls(): Promise<SunspecInverterControls | null>;
|
|
327
|
+
readInverterControls(unitId: number): Promise<SunspecInverterControls | null>;
|
|
286
328
|
/**
|
|
287
329
|
* Write Block 121 - Inverter Basic Settings
|
|
288
330
|
*/
|
|
289
|
-
writeInverterSettings(settings: Partial<SunspecInverterSettings>): Promise<boolean>;
|
|
331
|
+
writeInverterSettings(unitId: number, settings: Partial<SunspecInverterSettings>): Promise<boolean>;
|
|
290
332
|
/**
|
|
291
333
|
* Write inverter controls to Model 123 (Immediate Inverter Controls)
|
|
292
334
|
*/
|
|
293
|
-
writeInverterControls(controls: Partial<SunspecInverterControls>): Promise<boolean>;
|
|
335
|
+
writeInverterControls(unitId: number, controls: Partial<SunspecInverterControls>): Promise<boolean>;
|
|
294
336
|
/**
|
|
295
337
|
* Set the inverter feed-in power limit using Model 123 (Immediate Inverter Controls)
|
|
296
338
|
*
|
|
@@ -301,5 +343,5 @@ export declare class SunspecModbusClient {
|
|
|
301
343
|
* @param limitW - Power limit in Watts, or null to remove the limit
|
|
302
344
|
* @returns true if successful, false otherwise
|
|
303
345
|
*/
|
|
304
|
-
setFeedInLimit(limitW: number | null): Promise<boolean>;
|
|
346
|
+
setFeedInLimit(unitId: number, limitW: number | null): Promise<boolean>;
|
|
305
347
|
}
|