@enyo-energy/sunspec-sdk 0.0.76 → 0.0.78
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-battery-schedule-handler.cjs +16 -0
- package/dist/cjs/sunspec-devices.cjs +23 -0
- package/dist/cjs/sunspec-devices.d.cts +6 -0
- package/dist/cjs/version.cjs +1 -1
- package/dist/cjs/version.d.cts +1 -1
- package/dist/sunspec-battery-schedule-handler.js +16 -0
- package/dist/sunspec-devices.d.ts +6 -0
- package/dist/sunspec-devices.js +23 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +2 -2
|
@@ -133,6 +133,22 @@ class SunspecBatteryScheduleHandler extends storage_schedule_handler_js_1.Storag
|
|
|
133
133
|
}
|
|
134
134
|
async applyEntry(active) {
|
|
135
135
|
const { direction, powerW } = active.entry;
|
|
136
|
+
if (direction === enyo_data_bus_value_js_1.EnyoStorageScheduleDirectionEnum.Idle) {
|
|
137
|
+
// Idle entry: hand the battery back to its own autonomous logic
|
|
138
|
+
// by restoring the snapshotted pre-schedule registers (same write
|
|
139
|
+
// set as the `mode: auto` rollback path). The schedule itself
|
|
140
|
+
// keeps running, so a subsequent Charge / Discharge entry can
|
|
141
|
+
// resume external control.
|
|
142
|
+
const baselineRegisters = this.originalBaseline;
|
|
143
|
+
if (!baselineRegisters) {
|
|
144
|
+
throw new Error(`no usable baseline for idle entry (originalBaseline=undefined)`);
|
|
145
|
+
}
|
|
146
|
+
await this.sunspecClient.writeBatteryControls(this.unitId, baselineRegisters);
|
|
147
|
+
await this.getSnapshotService()?.recordModification([
|
|
148
|
+
'storCtlMod', 'chaGriSet', 'wChaMax', 'inWRte', 'outWRte',
|
|
149
|
+
]);
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
136
152
|
const baseline = this.installedWChaMax;
|
|
137
153
|
if (!baseline || baseline <= 0) {
|
|
138
154
|
throw new Error(`no usable wChaMax baseline (installedWChaMax=${baseline})`);
|
|
@@ -181,6 +181,7 @@ class BaseSunspecDevice {
|
|
|
181
181
|
if (this.applianceId) {
|
|
182
182
|
await this.applianceManager.updateApplianceState(this.applianceId, enyo_appliance_js_1.EnyoApplianceConnectionType.Connector, enyo_appliance_js_1.EnyoApplianceStateEnum.Connected);
|
|
183
183
|
}
|
|
184
|
+
await this.onConnectionRestored();
|
|
184
185
|
const postStats = this.sunspecClient.getConnectionStats();
|
|
185
186
|
console.log(`${this.constructor.name} ${this.applianceId}: Reconnection successful after ${attempt} attempt(s) (opens=${postStats.opens}, closes=${postStats.closes}, openUnits=${postStats.openUnits})`);
|
|
186
187
|
return true;
|
|
@@ -202,6 +203,14 @@ class BaseSunspecDevice {
|
|
|
202
203
|
async onConnectionFailure(_consecutiveFailures) {
|
|
203
204
|
// Default: no-op. SunspecInverter overrides to publish a faulted status.
|
|
204
205
|
}
|
|
206
|
+
/**
|
|
207
|
+
* Hook for subclasses to react to a successful reconnect. Called once
|
|
208
|
+
* after the appliance state has been updated to Connected.
|
|
209
|
+
*/
|
|
210
|
+
async onConnectionRestored() {
|
|
211
|
+
// Default: no-op. SunspecInverter overrides to publish a healthy status
|
|
212
|
+
// when recovering from a previously emitted connection-lost fault.
|
|
213
|
+
}
|
|
205
214
|
/**
|
|
206
215
|
* Detect a silent read failure: the SDK's per-model readers swallow modbus errors and
|
|
207
216
|
* return null/[] rather than throwing, so a readData() cycle can complete "successfully"
|
|
@@ -610,6 +619,20 @@ class SunspecInverter extends BaseSunspecDevice {
|
|
|
610
619
|
console.log(`Inverter ${this.applianceId}: emitting faulted (${sunspec_interfaces_js_1.SUNSPEC_CONNECTION_LOST_CODE}) after ${consecutiveFailures} consecutive reconnect failures`);
|
|
611
620
|
this.dataBus.sendMessage([message]);
|
|
612
621
|
}
|
|
622
|
+
async onConnectionRestored() {
|
|
623
|
+
if (!this.applianceId || !this.dataBus)
|
|
624
|
+
return;
|
|
625
|
+
if (this.errorState.lastStatus !== 'connection_lost')
|
|
626
|
+
return;
|
|
627
|
+
const message = this.buildStatusMessage(enyo_appliance_js_1.EnyoApplianceStatusEnum.Healthy, [], new Date());
|
|
628
|
+
this.errorState = {
|
|
629
|
+
activeCodes: [],
|
|
630
|
+
lastStatus: 'healthy',
|
|
631
|
+
};
|
|
632
|
+
await this.persistErrorState();
|
|
633
|
+
console.log(`Inverter ${this.applianceId}: emitting healthy after reconnect`);
|
|
634
|
+
this.dataBus.sendMessage([message]);
|
|
635
|
+
}
|
|
613
636
|
/**
|
|
614
637
|
* Compute the currently active feed-in / production limit in Watts from the
|
|
615
638
|
* Model 121 settings (WMax) and Model 123 controls (WMaxLim_Ena, WMaxLimPct).
|
|
@@ -69,6 +69,11 @@ export declare abstract class BaseSunspecDevice {
|
|
|
69
69
|
* per failed attempt with the running consecutive-failure count.
|
|
70
70
|
*/
|
|
71
71
|
protected onConnectionFailure(_consecutiveFailures: number): Promise<void>;
|
|
72
|
+
/**
|
|
73
|
+
* Hook for subclasses to react to a successful reconnect. Called once
|
|
74
|
+
* after the appliance state has been updated to Connected.
|
|
75
|
+
*/
|
|
76
|
+
protected onConnectionRestored(): Promise<void>;
|
|
72
77
|
/**
|
|
73
78
|
* Detect a silent read failure: the SDK's per-model readers swallow modbus errors and
|
|
74
79
|
* return null/[] rather than throwing, so a readData() cycle can complete "successfully"
|
|
@@ -145,6 +150,7 @@ export declare class SunspecInverter extends BaseSunspecDevice {
|
|
|
145
150
|
private persistErrorState;
|
|
146
151
|
private detectAndEmitStatusTransition;
|
|
147
152
|
protected onConnectionFailure(consecutiveFailures: number): Promise<void>;
|
|
153
|
+
protected onConnectionRestored(): Promise<void>;
|
|
148
154
|
/**
|
|
149
155
|
* Compute the currently active feed-in / production limit in Watts from the
|
|
150
156
|
* Model 121 settings (WMax) and Model 123 controls (WMaxLim_Ena, WMaxLimPct).
|
package/dist/cjs/version.cjs
CHANGED
|
@@ -9,7 +9,7 @@ exports.getSdkVersion = getSdkVersion;
|
|
|
9
9
|
/**
|
|
10
10
|
* Current version of the enyo Energy App SDK.
|
|
11
11
|
*/
|
|
12
|
-
exports.SDK_VERSION = '0.0.
|
|
12
|
+
exports.SDK_VERSION = '0.0.78';
|
|
13
13
|
/**
|
|
14
14
|
* Gets the current SDK version.
|
|
15
15
|
* @returns The semantic version string of the SDK
|
package/dist/cjs/version.d.cts
CHANGED
|
@@ -130,6 +130,22 @@ export class SunspecBatteryScheduleHandler extends StorageScheduleHandler {
|
|
|
130
130
|
}
|
|
131
131
|
async applyEntry(active) {
|
|
132
132
|
const { direction, powerW } = active.entry;
|
|
133
|
+
if (direction === EnyoStorageScheduleDirectionEnum.Idle) {
|
|
134
|
+
// Idle entry: hand the battery back to its own autonomous logic
|
|
135
|
+
// by restoring the snapshotted pre-schedule registers (same write
|
|
136
|
+
// set as the `mode: auto` rollback path). The schedule itself
|
|
137
|
+
// keeps running, so a subsequent Charge / Discharge entry can
|
|
138
|
+
// resume external control.
|
|
139
|
+
const baselineRegisters = this.originalBaseline;
|
|
140
|
+
if (!baselineRegisters) {
|
|
141
|
+
throw new Error(`no usable baseline for idle entry (originalBaseline=undefined)`);
|
|
142
|
+
}
|
|
143
|
+
await this.sunspecClient.writeBatteryControls(this.unitId, baselineRegisters);
|
|
144
|
+
await this.getSnapshotService()?.recordModification([
|
|
145
|
+
'storCtlMod', 'chaGriSet', 'wChaMax', 'inWRte', 'outWRte',
|
|
146
|
+
]);
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
133
149
|
const baseline = this.installedWChaMax;
|
|
134
150
|
if (!baseline || baseline <= 0) {
|
|
135
151
|
throw new Error(`no usable wChaMax baseline (installedWChaMax=${baseline})`);
|
|
@@ -69,6 +69,11 @@ export declare abstract class BaseSunspecDevice {
|
|
|
69
69
|
* per failed attempt with the running consecutive-failure count.
|
|
70
70
|
*/
|
|
71
71
|
protected onConnectionFailure(_consecutiveFailures: number): Promise<void>;
|
|
72
|
+
/**
|
|
73
|
+
* Hook for subclasses to react to a successful reconnect. Called once
|
|
74
|
+
* after the appliance state has been updated to Connected.
|
|
75
|
+
*/
|
|
76
|
+
protected onConnectionRestored(): Promise<void>;
|
|
72
77
|
/**
|
|
73
78
|
* Detect a silent read failure: the SDK's per-model readers swallow modbus errors and
|
|
74
79
|
* return null/[] rather than throwing, so a readData() cycle can complete "successfully"
|
|
@@ -145,6 +150,7 @@ export declare class SunspecInverter extends BaseSunspecDevice {
|
|
|
145
150
|
private persistErrorState;
|
|
146
151
|
private detectAndEmitStatusTransition;
|
|
147
152
|
protected onConnectionFailure(consecutiveFailures: number): Promise<void>;
|
|
153
|
+
protected onConnectionRestored(): Promise<void>;
|
|
148
154
|
/**
|
|
149
155
|
* Compute the currently active feed-in / production limit in Watts from the
|
|
150
156
|
* Model 121 settings (WMax) and Model 123 controls (WMaxLim_Ena, WMaxLimPct).
|
package/dist/sunspec-devices.js
CHANGED
|
@@ -175,6 +175,7 @@ export class BaseSunspecDevice {
|
|
|
175
175
|
if (this.applianceId) {
|
|
176
176
|
await this.applianceManager.updateApplianceState(this.applianceId, EnyoApplianceConnectionType.Connector, EnyoApplianceStateEnum.Connected);
|
|
177
177
|
}
|
|
178
|
+
await this.onConnectionRestored();
|
|
178
179
|
const postStats = this.sunspecClient.getConnectionStats();
|
|
179
180
|
console.log(`${this.constructor.name} ${this.applianceId}: Reconnection successful after ${attempt} attempt(s) (opens=${postStats.opens}, closes=${postStats.closes}, openUnits=${postStats.openUnits})`);
|
|
180
181
|
return true;
|
|
@@ -196,6 +197,14 @@ export class BaseSunspecDevice {
|
|
|
196
197
|
async onConnectionFailure(_consecutiveFailures) {
|
|
197
198
|
// Default: no-op. SunspecInverter overrides to publish a faulted status.
|
|
198
199
|
}
|
|
200
|
+
/**
|
|
201
|
+
* Hook for subclasses to react to a successful reconnect. Called once
|
|
202
|
+
* after the appliance state has been updated to Connected.
|
|
203
|
+
*/
|
|
204
|
+
async onConnectionRestored() {
|
|
205
|
+
// Default: no-op. SunspecInverter overrides to publish a healthy status
|
|
206
|
+
// when recovering from a previously emitted connection-lost fault.
|
|
207
|
+
}
|
|
199
208
|
/**
|
|
200
209
|
* Detect a silent read failure: the SDK's per-model readers swallow modbus errors and
|
|
201
210
|
* return null/[] rather than throwing, so a readData() cycle can complete "successfully"
|
|
@@ -603,6 +612,20 @@ export class SunspecInverter extends BaseSunspecDevice {
|
|
|
603
612
|
console.log(`Inverter ${this.applianceId}: emitting faulted (${SUNSPEC_CONNECTION_LOST_CODE}) after ${consecutiveFailures} consecutive reconnect failures`);
|
|
604
613
|
this.dataBus.sendMessage([message]);
|
|
605
614
|
}
|
|
615
|
+
async onConnectionRestored() {
|
|
616
|
+
if (!this.applianceId || !this.dataBus)
|
|
617
|
+
return;
|
|
618
|
+
if (this.errorState.lastStatus !== 'connection_lost')
|
|
619
|
+
return;
|
|
620
|
+
const message = this.buildStatusMessage(EnyoApplianceStatusEnum.Healthy, [], new Date());
|
|
621
|
+
this.errorState = {
|
|
622
|
+
activeCodes: [],
|
|
623
|
+
lastStatus: 'healthy',
|
|
624
|
+
};
|
|
625
|
+
await this.persistErrorState();
|
|
626
|
+
console.log(`Inverter ${this.applianceId}: emitting healthy after reconnect`);
|
|
627
|
+
this.dataBus.sendMessage([message]);
|
|
628
|
+
}
|
|
606
629
|
/**
|
|
607
630
|
* Compute the currently active feed-in / production limit in Watts from the
|
|
608
631
|
* Model 121 settings (WMax) and Model 123 controls (WMaxLim_Ena, WMaxLimPct).
|
package/dist/version.d.ts
CHANGED
package/dist/version.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@enyo-energy/sunspec-sdk",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.78",
|
|
4
4
|
"description": "enyo Energy Sunspec SDK",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
43
|
"@enyo-energy/appliance-calibration": "0.0.2",
|
|
44
|
-
"@enyo-energy/energy-app-sdk": "0.0.
|
|
44
|
+
"@enyo-energy/energy-app-sdk": "^0.0.149"
|
|
45
45
|
},
|
|
46
46
|
"volta": {
|
|
47
47
|
"node": "22.17.0"
|