@enyo-energy/sunspec-sdk 0.0.71 → 0.0.73
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 +302 -0
- package/dist/cjs/index.cjs +30 -2
- package/dist/cjs/index.d.cts +6 -1
- package/dist/cjs/sunspec-battery-calibration-driver.cjs +158 -0
- package/dist/cjs/sunspec-battery-calibration-driver.d.cts +63 -0
- package/dist/cjs/sunspec-battery-feature-calibrator.cjs +350 -0
- package/dist/cjs/sunspec-battery-feature-calibrator.d.cts +89 -0
- package/dist/cjs/sunspec-battery-schedule-handler.cjs +92 -0
- package/dist/cjs/sunspec-battery-schedule-handler.d.cts +67 -0
- package/dist/cjs/sunspec-calibration-storage.cjs +47 -0
- package/dist/cjs/sunspec-calibration-storage.d.cts +24 -0
- package/dist/cjs/sunspec-devices.cjs +305 -215
- package/dist/cjs/sunspec-devices.d.cts +129 -19
- package/dist/cjs/sunspec-interfaces.cjs +42 -1
- package/dist/cjs/sunspec-interfaces.d.cts +66 -0
- package/dist/cjs/version.cjs +1 -1
- package/dist/cjs/version.d.cts +1 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.js +12 -1
- package/dist/sunspec-battery-calibration-driver.d.ts +63 -0
- package/dist/sunspec-battery-calibration-driver.js +154 -0
- package/dist/sunspec-battery-feature-calibrator.d.ts +89 -0
- package/dist/sunspec-battery-feature-calibrator.js +345 -0
- package/dist/sunspec-battery-schedule-handler.d.ts +67 -0
- package/dist/sunspec-battery-schedule-handler.js +88 -0
- package/dist/sunspec-calibration-storage.d.ts +24 -0
- package/dist/sunspec-calibration-storage.js +42 -0
- package/dist/sunspec-devices.d.ts +129 -19
- package/dist/sunspec-devices.js +304 -216
- package/dist/sunspec-interfaces.d.ts +66 -0
- package/dist/sunspec-interfaces.js +41 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +7 -3
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import { type IRetryConfig, type SunspecBatteryBaseData, SunspecBatteryCapability, type SunspecBatteryControls, type SunspecInverterData, SunspecInverterCapability, SunspecMeterCapability, SunspecStorageMode } from "./sunspec-interfaces.js";
|
|
1
|
+
import { type IRetryConfig, type SunspecBatteryBaseData, SunspecBatteryCapability, type SunspecBatteryControls, type SunspecBatteryData, type SunspecBatteryFeatureMode, type SunspecInverterData, SunspecInverterCapability, SunspecMeterCapability, SunspecStorageMode } from "./sunspec-interfaces.js";
|
|
2
2
|
import { ApplianceManager, EnergyApp } from "@enyo-energy/energy-app-sdk";
|
|
3
3
|
import { type EnyoAppliance, type EnyoApplianceErrorCode, EnyoApplianceName } from "@enyo-energy/energy-app-sdk/dist/types/enyo-appliance.js";
|
|
4
4
|
import { EnyoNetworkDevice } from "@enyo-energy/energy-app-sdk/dist/types/enyo-network-device.js";
|
|
5
5
|
import { SunspecModbusClient } from "./sunspec-modbus-client.js";
|
|
6
6
|
import { ConnectionRetryManager } from "./connection-retry-manager.js";
|
|
7
7
|
import { EnyoCommandAcknowledgeAnswerEnum, EnyoDataBusMessage, EnyoDataBusMessageEnum, EnyoDataBusMessageResolution } from "@enyo-energy/energy-app-sdk/dist/types/enyo-data-bus-value.js";
|
|
8
|
-
import { type
|
|
8
|
+
import { BatteryCalibrator, type BatteryCalibratorConfig, type CalibrationResult, type CalibrationResultStore, type CalibrationSnapshot, type RestoreReason, SnapshotService } from "@enyo-energy/appliance-calibration";
|
|
9
|
+
import { EnyoBatteryFeature } from "@enyo-energy/energy-app-sdk/dist/types/enyo-battery-appliance.js";
|
|
9
10
|
import { EnergyAppDataBus } from "@enyo-energy/energy-app-sdk/dist/packages/energy-app-data-bus.js";
|
|
10
11
|
/**
|
|
11
12
|
* Base abstract class for all Sunspec devices
|
|
@@ -26,7 +27,13 @@ export declare abstract class BaseSunspecDevice {
|
|
|
26
27
|
protected dataBus?: EnergyAppDataBus;
|
|
27
28
|
protected retryManager: ConnectionRetryManager;
|
|
28
29
|
protected consecutiveReconnectFailures: number;
|
|
29
|
-
|
|
30
|
+
/**
|
|
31
|
+
* Prefix used when persisting calibration snapshots via the library's
|
|
32
|
+
* {@link SnapshotService}. Kept identical to the key the SDK used before
|
|
33
|
+
* the migration to `@enyo-energy/appliance-calibration` so existing
|
|
34
|
+
* snapshots stored by older builds are still picked up on startup.
|
|
35
|
+
*/
|
|
36
|
+
protected static readonly CALIBRATION_SNAPSHOT_KEY_PREFIX = "sunspec-calibration-snapshot-";
|
|
30
37
|
constructor(energyApp: EnergyApp, name: EnyoApplianceName[], networkDevice: EnyoNetworkDevice, sunspecClient: SunspecModbusClient, applianceManager: ApplianceManager, unitId?: number, port?: number, baseAddress?: number, retryConfig?: IRetryConfig, appliance?: EnyoAppliance, useTls?: boolean | undefined);
|
|
31
38
|
/**
|
|
32
39
|
* Connect to the device and create/update the appliance
|
|
@@ -80,16 +87,11 @@ export declare abstract class BaseSunspecDevice {
|
|
|
80
87
|
protected markOffline(): Promise<void>;
|
|
81
88
|
protected sendCommandAcknowledge(messageId: string, acknowledgeMessage: EnyoDataBusMessageEnum | string, answer: EnyoCommandAcknowledgeAnswerEnum, rejectionReason?: string): void;
|
|
82
89
|
/**
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*/
|
|
87
|
-
protected initCalibrationService(deviceType: CalibrationDeviceType): Promise<void>;
|
|
88
|
-
/**
|
|
89
|
-
* Subclasses implement how to write the modified fields of a snapshot back to the device.
|
|
90
|
-
* Called both on explicit StopCalibrationV1 and when the 5-minute auto-stop fires.
|
|
90
|
+
* Build a typed {@link SnapshotService} bound to this appliance's calibration storage,
|
|
91
|
+
* using the legacy SDK storage key prefix so prior installs upgrade seamlessly. Returns
|
|
92
|
+
* undefined if the appliance has not been registered yet.
|
|
91
93
|
*/
|
|
92
|
-
protected
|
|
94
|
+
protected buildSnapshotService<T>(onRestore: (snapshot: CalibrationSnapshot<T>, reason: RestoreReason) => Promise<void>): SnapshotService<T> | undefined;
|
|
93
95
|
}
|
|
94
96
|
/**
|
|
95
97
|
* Sunspec Inverter implementation using dynamic model discovery
|
|
@@ -100,6 +102,7 @@ export declare class SunspecInverter extends BaseSunspecDevice {
|
|
|
100
102
|
private static readonly CONNECTION_FAULT_THRESHOLD;
|
|
101
103
|
private storage?;
|
|
102
104
|
private errorState;
|
|
105
|
+
private snapshotService?;
|
|
103
106
|
constructor(energyApp: EnergyApp, name: EnyoApplianceName[], networkDevice: EnyoNetworkDevice, sunspecClient: SunspecModbusClient, applianceManager: ApplianceManager, unitId?: number, port?: number, baseAddress?: number, capabilities?: SunspecInverterCapability[], retryConfig?: IRetryConfig, appliance?: EnyoAppliance, useTls?: boolean);
|
|
104
107
|
connect(): Promise<void>;
|
|
105
108
|
disconnect(): Promise<void>;
|
|
@@ -169,16 +172,106 @@ export declare class SunspecInverter extends BaseSunspecDevice {
|
|
|
169
172
|
stopDataBusListening(): void;
|
|
170
173
|
private handleInverterCommand;
|
|
171
174
|
private handleSetFeedInLimit;
|
|
175
|
+
/**
|
|
176
|
+
* Lazily construct the per-appliance {@link SnapshotService}. Reloads any
|
|
177
|
+
* persisted snapshot from storage so an in-flight calibration survives
|
|
178
|
+
* process restarts. Idempotent.
|
|
179
|
+
*/
|
|
180
|
+
private initSnapshotService;
|
|
172
181
|
private handleStartCalibration;
|
|
173
182
|
private handleStopCalibration;
|
|
174
|
-
|
|
183
|
+
/**
|
|
184
|
+
* `onRestore` callback for the inverter's {@link SnapshotService}. Writes only the
|
|
185
|
+
* subset of writable inverter fields that other commands actually touched during the
|
|
186
|
+
* calibration. Catches and logs failures rather than throwing — the snapshot has
|
|
187
|
+
* already been removed from storage by the time this runs, so a throw is unrecoverable
|
|
188
|
+
* and is best logged for operator action.
|
|
189
|
+
*/
|
|
190
|
+
private restoreInverterSnapshot;
|
|
175
191
|
}
|
|
192
|
+
/**
|
|
193
|
+
* Pure register-presence detection — exported so it can be unit-tested
|
|
194
|
+
* without the full `SunspecBattery` scaffold. Maps each Model 124 writable
|
|
195
|
+
* register to the `EnyoBatteryFeature` it represents:
|
|
196
|
+
*
|
|
197
|
+
* - `chaGriSet` → `GridCharging` (charge source PV/GRID)
|
|
198
|
+
* - `wChaMax` → `ChargeLimitation` (max charge power)
|
|
199
|
+
* - `outWRte` → `DischargeLimitation` (discharge rate %)
|
|
200
|
+
* - `storCtlMod` → `GridDischarging` (closest signal that external discharge
|
|
201
|
+
* control is available; the inverter decides where it goes)
|
|
202
|
+
*/
|
|
203
|
+
export declare function detectFeaturesFromRegisters(batteryData: SunspecBatteryData | null): EnyoBatteryFeature[];
|
|
204
|
+
/**
|
|
205
|
+
* Apply the per-feature calibration filter to a register-detected set.
|
|
206
|
+
* Exported for unit-test access to the legacy-result fallback branch.
|
|
207
|
+
*
|
|
208
|
+
* The contract:
|
|
209
|
+
* - No `result` or `result.state !== 'calibrated'` → strip every controllable
|
|
210
|
+
* feature (safe fallback while waiting for calibration).
|
|
211
|
+
* - `result.state === 'calibrated'` with a decodable per-feature payload →
|
|
212
|
+
* publish only the controllable features whose probes passed.
|
|
213
|
+
* - `result.state === 'calibrated'` with **no** decodable payload → legacy
|
|
214
|
+
* data (pre-feature-calibrator SDK). The new calibrator only marks
|
|
215
|
+
* `state=calibrated` when at least one probe passes, so an empty decoded
|
|
216
|
+
* set with `state=calibrated` unambiguously signals legacy results. Publish
|
|
217
|
+
* the full detected set to preserve the old all-or-nothing semantics on
|
|
218
|
+
* upgrade.
|
|
219
|
+
*/
|
|
220
|
+
export declare function filterFeaturesByCalibrationResult(detected: EnyoBatteryFeature[], result: CalibrationResult | undefined, controllable: readonly EnyoBatteryFeature[]): EnyoBatteryFeature[];
|
|
176
221
|
/**
|
|
177
222
|
* Sunspec Battery implementation
|
|
178
223
|
*/
|
|
179
224
|
export declare class SunspecBattery extends BaseSunspecDevice {
|
|
225
|
+
private readonly featureMode;
|
|
180
226
|
private readonly capabilities;
|
|
181
|
-
|
|
227
|
+
private snapshotService?;
|
|
228
|
+
private calibrationDriver?;
|
|
229
|
+
private batteryCalibrator?;
|
|
230
|
+
private calibrationResultStore?;
|
|
231
|
+
private scheduleHandler;
|
|
232
|
+
/**
|
|
233
|
+
* Battery features that imply outbound control writes from the host action-taker.
|
|
234
|
+
* These are stripped from `appliance.battery.features` until the calibration result
|
|
235
|
+
* store says this battery has been successfully calibrated — see
|
|
236
|
+
* {@link computeAdvertisedFeatures}.
|
|
237
|
+
*/
|
|
238
|
+
private static readonly CONTROLLABLE_FEATURES;
|
|
239
|
+
constructor(energyApp: EnergyApp, name: EnyoApplianceName[], networkDevice: EnyoNetworkDevice, sunspecClient: SunspecModbusClient, applianceManager: ApplianceManager, featureMode: SunspecBatteryFeatureMode, unitId?: number, port?: number, baseAddress?: number, capabilities?: SunspecBatteryCapability[], retryConfig?: IRetryConfig, appliance?: EnyoAppliance, useTls?: boolean);
|
|
240
|
+
/**
|
|
241
|
+
* Wire the battery into `@enyo-energy/appliance-calibration`'s
|
|
242
|
+
* `BatteryCalibrator` test-charge flow. Call once after {@link connect}.
|
|
243
|
+
*
|
|
244
|
+
* Consumers own the `CalibrationResultStore` (shared across appliances so
|
|
245
|
+
* the persisted result map doesn't get clobbered) and the
|
|
246
|
+
* `CalibrationTrigger` that drives `runCalibration()` on whatever schedule
|
|
247
|
+
* makes sense for the host. Pass overrides for the calibrator's defaults
|
|
248
|
+
* (`testPowerW`, response thresholds, etc.) via `opts.config`.
|
|
249
|
+
*/
|
|
250
|
+
configureCalibration(opts: {
|
|
251
|
+
resultStore: CalibrationResultStore;
|
|
252
|
+
config?: Partial<BatteryCalibratorConfig>;
|
|
253
|
+
}): BatteryCalibrator<SunspecBatteryControls>;
|
|
254
|
+
/**
|
|
255
|
+
* Detect which battery features the device's registers expose. This is the
|
|
256
|
+
* raw, register-only view; the {@link featureMode} configured at
|
|
257
|
+
* construction decides what is actually published — see
|
|
258
|
+
* {@link resolveAdvertisedFeatures}.
|
|
259
|
+
*/
|
|
260
|
+
private detectFromRegisters;
|
|
261
|
+
/**
|
|
262
|
+
* Resolve `appliance.battery.features` for the configured mode. Called on
|
|
263
|
+
* every connect() and readData() cycle so that, in calibration-based mode,
|
|
264
|
+
* the controllable features appear as soon as the calibrator flips
|
|
265
|
+
* `isCalibrated` (no synchronous push).
|
|
266
|
+
*/
|
|
267
|
+
private resolveAdvertisedFeatures;
|
|
268
|
+
/**
|
|
269
|
+
* Returns the per-battery `BatteryCalibrator` created by
|
|
270
|
+
* {@link configureCalibration}, or `undefined` if calibration was never
|
|
271
|
+
* configured. Consumers register the returned instance with their own
|
|
272
|
+
* `CalibrationTrigger`.
|
|
273
|
+
*/
|
|
274
|
+
getBatteryCalibrator(): BatteryCalibrator<SunspecBatteryControls> | undefined;
|
|
182
275
|
/**
|
|
183
276
|
* Connect to the battery and create/update the appliance
|
|
184
277
|
*/
|
|
@@ -300,13 +393,30 @@ export declare class SunspecBattery extends BaseSunspecDevice {
|
|
|
300
393
|
*/
|
|
301
394
|
stopDataBusListening(): void;
|
|
302
395
|
private handleStorageCommand;
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
396
|
+
/**
|
|
397
|
+
* Acknowledge a SetStorageScheduleV1 message. The actual schedule application
|
|
398
|
+
* is owned by `this.scheduleHandler` (subscribed independently via its own
|
|
399
|
+
* data-bus listener registered in its constructor). The ack reports "received
|
|
400
|
+
* & queued" rather than "applied" — schedule entries play out over time, and
|
|
401
|
+
* per-entry write failures land in `console.error` via the handler's
|
|
402
|
+
* onChange wrapper.
|
|
403
|
+
*/
|
|
404
|
+
private handleSetStorageScheduleAck;
|
|
405
|
+
/**
|
|
406
|
+
* Lazily construct the per-appliance {@link SnapshotService}. Reloads any
|
|
407
|
+
* persisted snapshot from storage so an in-flight calibration survives
|
|
408
|
+
* process restarts. Idempotent.
|
|
409
|
+
*/
|
|
410
|
+
private initSnapshotService;
|
|
307
411
|
private handleStartCalibration;
|
|
308
412
|
private handleStopCalibration;
|
|
309
|
-
|
|
413
|
+
/**
|
|
414
|
+
* `onRestore` callback for the battery's {@link SnapshotService}. Writes only the
|
|
415
|
+
* subset of writable battery fields touched during the calibration. Errors are
|
|
416
|
+
* caught and logged — by the time this fires the snapshot is gone from storage,
|
|
417
|
+
* so a throw would just propagate into the void.
|
|
418
|
+
*/
|
|
419
|
+
private restoreBatterySnapshot;
|
|
310
420
|
}
|
|
311
421
|
/**
|
|
312
422
|
* Sunspec Meter implementation
|