@enyo-energy/sunspec-sdk 0.0.67 → 0.0.68
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 +65 -3
- package/dist/cjs/sunspec-devices.d.cts +22 -0
- package/dist/cjs/version.cjs +1 -1
- package/dist/cjs/version.d.cts +1 -1
- package/dist/sunspec-devices.d.ts +22 -0
- package/dist/sunspec-devices.js +66 -4
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
|
@@ -278,7 +278,9 @@ class SunspecInverter extends BaseSunspecDevice {
|
|
|
278
278
|
// Get device info from common block
|
|
279
279
|
const commonData = await this.sunspecClient.readCommonBlock(this.unitId);
|
|
280
280
|
const inverterSettings = await this.sunspecClient.readInverterSettings(this.unitId);
|
|
281
|
+
const inverterControls = await this.sunspecClient.readInverterControls(this.unitId);
|
|
281
282
|
const mpptDataList = await this.sunspecClient.readAllMPPTData(this.unitId);
|
|
283
|
+
const activeProductionLimitationW = this.computeActiveProductionLimitW(inverterSettings, inverterControls);
|
|
282
284
|
// Create or update appliance (skip if an existing appliance was provided)
|
|
283
285
|
if (!this.applianceId) {
|
|
284
286
|
try {
|
|
@@ -296,7 +298,8 @@ class SunspecInverter extends BaseSunspecDevice {
|
|
|
296
298
|
},
|
|
297
299
|
inverter: {
|
|
298
300
|
dcStrings: this.mapDcStringToApplianceMetadata(this.mapMPPTToStrings(mpptDataList)),
|
|
299
|
-
maxPvProductionW: inverterSettings?.WMax
|
|
301
|
+
maxPvProductionW: inverterSettings?.WMax,
|
|
302
|
+
activeProductionLimitationW: activeProductionLimitationW
|
|
300
303
|
}
|
|
301
304
|
});
|
|
302
305
|
console.log(`Sunspec Inverter connected: ${this.networkDevice.hostname} (${this.applianceId})`);
|
|
@@ -318,7 +321,8 @@ class SunspecInverter extends BaseSunspecDevice {
|
|
|
318
321
|
inverter: {
|
|
319
322
|
...existingAppliance?.inverter,
|
|
320
323
|
dcStrings: this.mapDcStringToApplianceMetadata(this.mapMPPTToStrings(mpptDataList)),
|
|
321
|
-
maxPvProductionW: inverterSettings?.WMax
|
|
324
|
+
maxPvProductionW: inverterSettings?.WMax,
|
|
325
|
+
activeProductionLimitationW: activeProductionLimitationW
|
|
322
326
|
}
|
|
323
327
|
});
|
|
324
328
|
console.log(`Sunspec Inverter connected: ${this.networkDevice.hostname} (${this.applianceId})`);
|
|
@@ -355,7 +359,9 @@ class SunspecInverter extends BaseSunspecDevice {
|
|
|
355
359
|
const inverterData = await this.sunspecClient.readInverterData(this.unitId);
|
|
356
360
|
const mpptDataList = await this.sunspecClient.readAllMPPTData(this.unitId);
|
|
357
361
|
const inverterSettings = await this.sunspecClient.readInverterSettings(this.unitId);
|
|
362
|
+
const inverterControls = await this.sunspecClient.readInverterControls(this.unitId);
|
|
358
363
|
const dcStrings = this.mapMPPTToStrings(mpptDataList);
|
|
364
|
+
const activeProductionLimitationW = this.computeActiveProductionLimitW(inverterSettings, inverterControls);
|
|
359
365
|
// SDK readers swallow modbus errors and return null/[]; detect that here so the
|
|
360
366
|
// appliance is marked offline and the retry manager starts its backoff.
|
|
361
367
|
if (await this.markOfflineIfUnhealthy()) {
|
|
@@ -396,7 +402,8 @@ class SunspecInverter extends BaseSunspecDevice {
|
|
|
396
402
|
await this.applianceManager.updateAppliance(this.applianceId, {
|
|
397
403
|
inverter: {
|
|
398
404
|
...appliance?.inverter,
|
|
399
|
-
dcStrings: this.mapDcStringToApplianceMetadata(dcStrings)
|
|
405
|
+
dcStrings: this.mapDcStringToApplianceMetadata(dcStrings),
|
|
406
|
+
activeProductionLimitationW: activeProductionLimitationW
|
|
400
407
|
}
|
|
401
408
|
});
|
|
402
409
|
}
|
|
@@ -568,6 +575,25 @@ class SunspecInverter extends BaseSunspecDevice {
|
|
|
568
575
|
console.log(`Inverter ${this.applianceId}: emitting faulted (${sunspec_interfaces_js_1.SUNSPEC_CONNECTION_LOST_CODE}) after ${consecutiveFailures} consecutive reconnect failures`);
|
|
569
576
|
this.dataBus.sendMessage([message]);
|
|
570
577
|
}
|
|
578
|
+
/**
|
|
579
|
+
* Compute the currently active feed-in / production limit in Watts from the
|
|
580
|
+
* Model 121 settings (WMax) and Model 123 controls (WMaxLim_Ena, WMaxLimPct).
|
|
581
|
+
* Returns null when no limit is applied, when the registers cannot be read,
|
|
582
|
+
* or when the limit equals WMax (i.e. not actually throttling) — null is
|
|
583
|
+
* returned (not undefined) so the field is cleared on the appliance.
|
|
584
|
+
*/
|
|
585
|
+
computeActiveProductionLimitW(settings, controls) {
|
|
586
|
+
if (!settings?.WMax || !controls)
|
|
587
|
+
return null;
|
|
588
|
+
if (controls.WMaxLim_Ena !== sunspec_interfaces_js_1.SunspecEnableControl.ENABLED)
|
|
589
|
+
return null;
|
|
590
|
+
if (controls.WMaxLimPct === undefined)
|
|
591
|
+
return null;
|
|
592
|
+
const limitW = (settings.WMax * controls.WMaxLimPct) / 100;
|
|
593
|
+
if (limitW >= settings.WMax)
|
|
594
|
+
return null;
|
|
595
|
+
return limitW;
|
|
596
|
+
}
|
|
571
597
|
mapOperatingState(state) {
|
|
572
598
|
if (!state)
|
|
573
599
|
return enyo_data_bus_value_js_1.EnyoInverterStateEnum.Off;
|
|
@@ -726,6 +752,8 @@ class SunspecBattery extends BaseSunspecDevice {
|
|
|
726
752
|
if (batteryData?.wChaMax !== undefined) {
|
|
727
753
|
features.push(enyo_battery_appliance_js_1.EnyoBatteryFeature.ChargeLimitation);
|
|
728
754
|
}
|
|
755
|
+
const activeChargeLimitW = this.computeActiveChargeLimitW(batteryData);
|
|
756
|
+
const activeDischargeLimitW = this.computeActiveDischargeLimitW(batteryData);
|
|
729
757
|
// Create or update appliance (skip if an existing appliance was provided)
|
|
730
758
|
if (!this.applianceId) {
|
|
731
759
|
try {
|
|
@@ -746,6 +774,8 @@ class SunspecBattery extends BaseSunspecDevice {
|
|
|
746
774
|
storageMode: this.mapToEnyoStorageMode(storageMode),
|
|
747
775
|
maxChargingPowerW: batteryData && batteryData.wChaMax !== undefined && batteryData.inWRte !== undefined ? batteryData.wChaMax * batteryData.inWRte : undefined,
|
|
748
776
|
maxDischargePowerW: batteryData && batteryData.wChaMax !== undefined && batteryData.outWRte !== undefined ? batteryData.wChaMax * batteryData.outWRte : undefined,
|
|
777
|
+
activeChargeLimitW: activeChargeLimitW,
|
|
778
|
+
activeDischargeLimitW: activeDischargeLimitW,
|
|
749
779
|
features,
|
|
750
780
|
gridChargingEnabled: batteryData?.chaGriSet === 1
|
|
751
781
|
}
|
|
@@ -772,6 +802,8 @@ class SunspecBattery extends BaseSunspecDevice {
|
|
|
772
802
|
storageMode: this.mapToEnyoStorageMode(storageMode),
|
|
773
803
|
maxChargingPowerW: batteryData && batteryData.wChaMax !== undefined && batteryData.inWRte !== undefined ? batteryData.wChaMax * batteryData.inWRte : undefined,
|
|
774
804
|
maxDischargePowerW: batteryData && batteryData.wChaMax !== undefined && batteryData.outWRte !== undefined ? batteryData.wChaMax * batteryData.outWRte : undefined,
|
|
805
|
+
activeChargeLimitW: activeChargeLimitW,
|
|
806
|
+
activeDischargeLimitW: activeDischargeLimitW,
|
|
775
807
|
features,
|
|
776
808
|
gridChargingEnabled: batteryData?.chaGriSet === 1
|
|
777
809
|
}
|
|
@@ -878,6 +910,8 @@ class SunspecBattery extends BaseSunspecDevice {
|
|
|
878
910
|
storageMode: this.mapToEnyoStorageMode(storageMode),
|
|
879
911
|
maxChargingPowerW: batteryData && batteryData.wChaMax !== undefined && batteryData.inWRte !== undefined ? batteryData.wChaMax * batteryData.inWRte : undefined,
|
|
880
912
|
maxDischargePowerW: batteryData && batteryData.wChaMax !== undefined && batteryData.outWRte !== undefined ? batteryData.wChaMax * batteryData.outWRte : undefined,
|
|
913
|
+
activeChargeLimitW: this.computeActiveChargeLimitW(batteryData),
|
|
914
|
+
activeDischargeLimitW: this.computeActiveDischargeLimitW(batteryData),
|
|
881
915
|
gridChargingEnabled: batteryData?.chaGriSet === 1
|
|
882
916
|
}
|
|
883
917
|
});
|
|
@@ -1056,6 +1090,34 @@ class SunspecBattery extends BaseSunspecDevice {
|
|
|
1056
1090
|
const controls = await this.getBatteryControls();
|
|
1057
1091
|
return this.determineStorageMode(controls);
|
|
1058
1092
|
}
|
|
1093
|
+
/**
|
|
1094
|
+
* Compute the currently active charge limit in Watts from Model 124's
|
|
1095
|
+
* wChaMax and the charge rate setpoint inWRte (% of WChaMax). Returns
|
|
1096
|
+
* null when no limit is applied, when the registers cannot be read, or
|
|
1097
|
+
* when the rate is at 100% (no throttling) — null is returned (not
|
|
1098
|
+
* undefined) so the field is cleared on the appliance.
|
|
1099
|
+
*/
|
|
1100
|
+
computeActiveChargeLimitW(batteryData) {
|
|
1101
|
+
if (!batteryData || batteryData.wChaMax === undefined || batteryData.inWRte === undefined) {
|
|
1102
|
+
return null;
|
|
1103
|
+
}
|
|
1104
|
+
if (batteryData.inWRte >= 100)
|
|
1105
|
+
return null;
|
|
1106
|
+
return (batteryData.wChaMax * batteryData.inWRte) / 100;
|
|
1107
|
+
}
|
|
1108
|
+
/**
|
|
1109
|
+
* Compute the currently active discharge limit in Watts from Model 124's
|
|
1110
|
+
* wChaMax and the discharge rate setpoint outWRte (% of WDisChaMax).
|
|
1111
|
+
* Returns null when no limit is applied or the registers cannot be read.
|
|
1112
|
+
*/
|
|
1113
|
+
computeActiveDischargeLimitW(batteryData) {
|
|
1114
|
+
if (!batteryData || batteryData.wChaMax === undefined || batteryData.outWRte === undefined) {
|
|
1115
|
+
return null;
|
|
1116
|
+
}
|
|
1117
|
+
if (batteryData.outWRte >= 100)
|
|
1118
|
+
return null;
|
|
1119
|
+
return (batteryData.wChaMax * batteryData.outWRte) / 100;
|
|
1120
|
+
}
|
|
1059
1121
|
determineStorageMode(controls) {
|
|
1060
1122
|
if (!controls || controls.storCtlMod === undefined) {
|
|
1061
1123
|
return null;
|
|
@@ -129,6 +129,14 @@ export declare class SunspecInverter extends BaseSunspecDevice {
|
|
|
129
129
|
private persistErrorState;
|
|
130
130
|
private detectAndEmitStatusTransition;
|
|
131
131
|
protected onConnectionFailure(consecutiveFailures: number): Promise<void>;
|
|
132
|
+
/**
|
|
133
|
+
* Compute the currently active feed-in / production limit in Watts from the
|
|
134
|
+
* Model 121 settings (WMax) and Model 123 controls (WMaxLim_Ena, WMaxLimPct).
|
|
135
|
+
* Returns null when no limit is applied, when the registers cannot be read,
|
|
136
|
+
* or when the limit equals WMax (i.e. not actually throttling) — null is
|
|
137
|
+
* returned (not undefined) so the field is cleared on the appliance.
|
|
138
|
+
*/
|
|
139
|
+
private computeActiveProductionLimitW;
|
|
132
140
|
private mapOperatingState;
|
|
133
141
|
/**
|
|
134
142
|
* Map MPPT data to DC string structure for data bus
|
|
@@ -245,6 +253,20 @@ export declare class SunspecBattery extends BaseSunspecDevice {
|
|
|
245
253
|
* @returns Promise<SunspecStorageMode | null> - Current mode or null if error
|
|
246
254
|
*/
|
|
247
255
|
getStorageMode(): Promise<SunspecStorageMode | null>;
|
|
256
|
+
/**
|
|
257
|
+
* Compute the currently active charge limit in Watts from Model 124's
|
|
258
|
+
* wChaMax and the charge rate setpoint inWRte (% of WChaMax). Returns
|
|
259
|
+
* null when no limit is applied, when the registers cannot be read, or
|
|
260
|
+
* when the rate is at 100% (no throttling) — null is returned (not
|
|
261
|
+
* undefined) so the field is cleared on the appliance.
|
|
262
|
+
*/
|
|
263
|
+
private computeActiveChargeLimitW;
|
|
264
|
+
/**
|
|
265
|
+
* Compute the currently active discharge limit in Watts from Model 124's
|
|
266
|
+
* wChaMax and the discharge rate setpoint outWRte (% of WDisChaMax).
|
|
267
|
+
* Returns null when no limit is applied or the registers cannot be read.
|
|
268
|
+
*/
|
|
269
|
+
private computeActiveDischargeLimitW;
|
|
248
270
|
private determineStorageMode;
|
|
249
271
|
/**
|
|
250
272
|
* Check if grid charging is enabled
|
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.68';
|
|
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
|
@@ -129,6 +129,14 @@ export declare class SunspecInverter extends BaseSunspecDevice {
|
|
|
129
129
|
private persistErrorState;
|
|
130
130
|
private detectAndEmitStatusTransition;
|
|
131
131
|
protected onConnectionFailure(consecutiveFailures: number): Promise<void>;
|
|
132
|
+
/**
|
|
133
|
+
* Compute the currently active feed-in / production limit in Watts from the
|
|
134
|
+
* Model 121 settings (WMax) and Model 123 controls (WMaxLim_Ena, WMaxLimPct).
|
|
135
|
+
* Returns null when no limit is applied, when the registers cannot be read,
|
|
136
|
+
* or when the limit equals WMax (i.e. not actually throttling) — null is
|
|
137
|
+
* returned (not undefined) so the field is cleared on the appliance.
|
|
138
|
+
*/
|
|
139
|
+
private computeActiveProductionLimitW;
|
|
132
140
|
private mapOperatingState;
|
|
133
141
|
/**
|
|
134
142
|
* Map MPPT data to DC string structure for data bus
|
|
@@ -245,6 +253,20 @@ export declare class SunspecBattery extends BaseSunspecDevice {
|
|
|
245
253
|
* @returns Promise<SunspecStorageMode | null> - Current mode or null if error
|
|
246
254
|
*/
|
|
247
255
|
getStorageMode(): Promise<SunspecStorageMode | null>;
|
|
256
|
+
/**
|
|
257
|
+
* Compute the currently active charge limit in Watts from Model 124's
|
|
258
|
+
* wChaMax and the charge rate setpoint inWRte (% of WChaMax). Returns
|
|
259
|
+
* null when no limit is applied, when the registers cannot be read, or
|
|
260
|
+
* when the rate is at 100% (no throttling) — null is returned (not
|
|
261
|
+
* undefined) so the field is cleared on the appliance.
|
|
262
|
+
*/
|
|
263
|
+
private computeActiveChargeLimitW;
|
|
264
|
+
/**
|
|
265
|
+
* Compute the currently active discharge limit in Watts from Model 124's
|
|
266
|
+
* wChaMax and the discharge rate setpoint outWRte (% of WDisChaMax).
|
|
267
|
+
* Returns null when no limit is applied or the registers cannot be read.
|
|
268
|
+
*/
|
|
269
|
+
private computeActiveDischargeLimitW;
|
|
248
270
|
private determineStorageMode;
|
|
249
271
|
/**
|
|
250
272
|
* Check if grid charging is enabled
|
package/dist/sunspec-devices.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SunspecBatteryChargeState, SunspecInverterCapability, SunspecInverterEvent1, SunspecModelId, SunspecMPPTOperatingState, SunspecStorageMode, SUNSPEC_CONNECTION_LOST_CODE } from "./sunspec-interfaces.js";
|
|
1
|
+
import { SunspecBatteryChargeState, SunspecEnableControl, SunspecInverterCapability, SunspecInverterEvent1, SunspecModelId, SunspecMPPTOperatingState, SunspecStorageMode, SUNSPEC_CONNECTION_LOST_CODE } from "./sunspec-interfaces.js";
|
|
2
2
|
import { randomUUID } from "node:crypto";
|
|
3
3
|
import { EnyoApplianceConnectionType, EnyoApplianceStateEnum, EnyoApplianceStatusEnum, EnyoApplianceTopologyFeatureEnum, EnyoApplianceTypeEnum } from "@enyo-energy/energy-app-sdk/dist/types/enyo-appliance.js";
|
|
4
4
|
import { ConnectionRetryManager } from "./connection-retry-manager.js";
|
|
@@ -274,7 +274,9 @@ export class SunspecInverter extends BaseSunspecDevice {
|
|
|
274
274
|
// Get device info from common block
|
|
275
275
|
const commonData = await this.sunspecClient.readCommonBlock(this.unitId);
|
|
276
276
|
const inverterSettings = await this.sunspecClient.readInverterSettings(this.unitId);
|
|
277
|
+
const inverterControls = await this.sunspecClient.readInverterControls(this.unitId);
|
|
277
278
|
const mpptDataList = await this.sunspecClient.readAllMPPTData(this.unitId);
|
|
279
|
+
const activeProductionLimitationW = this.computeActiveProductionLimitW(inverterSettings, inverterControls);
|
|
278
280
|
// Create or update appliance (skip if an existing appliance was provided)
|
|
279
281
|
if (!this.applianceId) {
|
|
280
282
|
try {
|
|
@@ -292,7 +294,8 @@ export class SunspecInverter extends BaseSunspecDevice {
|
|
|
292
294
|
},
|
|
293
295
|
inverter: {
|
|
294
296
|
dcStrings: this.mapDcStringToApplianceMetadata(this.mapMPPTToStrings(mpptDataList)),
|
|
295
|
-
maxPvProductionW: inverterSettings?.WMax
|
|
297
|
+
maxPvProductionW: inverterSettings?.WMax,
|
|
298
|
+
activeProductionLimitationW: activeProductionLimitationW
|
|
296
299
|
}
|
|
297
300
|
});
|
|
298
301
|
console.log(`Sunspec Inverter connected: ${this.networkDevice.hostname} (${this.applianceId})`);
|
|
@@ -314,7 +317,8 @@ export class SunspecInverter extends BaseSunspecDevice {
|
|
|
314
317
|
inverter: {
|
|
315
318
|
...existingAppliance?.inverter,
|
|
316
319
|
dcStrings: this.mapDcStringToApplianceMetadata(this.mapMPPTToStrings(mpptDataList)),
|
|
317
|
-
maxPvProductionW: inverterSettings?.WMax
|
|
320
|
+
maxPvProductionW: inverterSettings?.WMax,
|
|
321
|
+
activeProductionLimitationW: activeProductionLimitationW
|
|
318
322
|
}
|
|
319
323
|
});
|
|
320
324
|
console.log(`Sunspec Inverter connected: ${this.networkDevice.hostname} (${this.applianceId})`);
|
|
@@ -351,7 +355,9 @@ export class SunspecInverter extends BaseSunspecDevice {
|
|
|
351
355
|
const inverterData = await this.sunspecClient.readInverterData(this.unitId);
|
|
352
356
|
const mpptDataList = await this.sunspecClient.readAllMPPTData(this.unitId);
|
|
353
357
|
const inverterSettings = await this.sunspecClient.readInverterSettings(this.unitId);
|
|
358
|
+
const inverterControls = await this.sunspecClient.readInverterControls(this.unitId);
|
|
354
359
|
const dcStrings = this.mapMPPTToStrings(mpptDataList);
|
|
360
|
+
const activeProductionLimitationW = this.computeActiveProductionLimitW(inverterSettings, inverterControls);
|
|
355
361
|
// SDK readers swallow modbus errors and return null/[]; detect that here so the
|
|
356
362
|
// appliance is marked offline and the retry manager starts its backoff.
|
|
357
363
|
if (await this.markOfflineIfUnhealthy()) {
|
|
@@ -392,7 +398,8 @@ export class SunspecInverter extends BaseSunspecDevice {
|
|
|
392
398
|
await this.applianceManager.updateAppliance(this.applianceId, {
|
|
393
399
|
inverter: {
|
|
394
400
|
...appliance?.inverter,
|
|
395
|
-
dcStrings: this.mapDcStringToApplianceMetadata(dcStrings)
|
|
401
|
+
dcStrings: this.mapDcStringToApplianceMetadata(dcStrings),
|
|
402
|
+
activeProductionLimitationW: activeProductionLimitationW
|
|
396
403
|
}
|
|
397
404
|
});
|
|
398
405
|
}
|
|
@@ -564,6 +571,25 @@ export class SunspecInverter extends BaseSunspecDevice {
|
|
|
564
571
|
console.log(`Inverter ${this.applianceId}: emitting faulted (${SUNSPEC_CONNECTION_LOST_CODE}) after ${consecutiveFailures} consecutive reconnect failures`);
|
|
565
572
|
this.dataBus.sendMessage([message]);
|
|
566
573
|
}
|
|
574
|
+
/**
|
|
575
|
+
* Compute the currently active feed-in / production limit in Watts from the
|
|
576
|
+
* Model 121 settings (WMax) and Model 123 controls (WMaxLim_Ena, WMaxLimPct).
|
|
577
|
+
* Returns null when no limit is applied, when the registers cannot be read,
|
|
578
|
+
* or when the limit equals WMax (i.e. not actually throttling) — null is
|
|
579
|
+
* returned (not undefined) so the field is cleared on the appliance.
|
|
580
|
+
*/
|
|
581
|
+
computeActiveProductionLimitW(settings, controls) {
|
|
582
|
+
if (!settings?.WMax || !controls)
|
|
583
|
+
return null;
|
|
584
|
+
if (controls.WMaxLim_Ena !== SunspecEnableControl.ENABLED)
|
|
585
|
+
return null;
|
|
586
|
+
if (controls.WMaxLimPct === undefined)
|
|
587
|
+
return null;
|
|
588
|
+
const limitW = (settings.WMax * controls.WMaxLimPct) / 100;
|
|
589
|
+
if (limitW >= settings.WMax)
|
|
590
|
+
return null;
|
|
591
|
+
return limitW;
|
|
592
|
+
}
|
|
567
593
|
mapOperatingState(state) {
|
|
568
594
|
if (!state)
|
|
569
595
|
return EnyoInverterStateEnum.Off;
|
|
@@ -721,6 +747,8 @@ export class SunspecBattery extends BaseSunspecDevice {
|
|
|
721
747
|
if (batteryData?.wChaMax !== undefined) {
|
|
722
748
|
features.push(EnyoBatteryFeature.ChargeLimitation);
|
|
723
749
|
}
|
|
750
|
+
const activeChargeLimitW = this.computeActiveChargeLimitW(batteryData);
|
|
751
|
+
const activeDischargeLimitW = this.computeActiveDischargeLimitW(batteryData);
|
|
724
752
|
// Create or update appliance (skip if an existing appliance was provided)
|
|
725
753
|
if (!this.applianceId) {
|
|
726
754
|
try {
|
|
@@ -741,6 +769,8 @@ export class SunspecBattery extends BaseSunspecDevice {
|
|
|
741
769
|
storageMode: this.mapToEnyoStorageMode(storageMode),
|
|
742
770
|
maxChargingPowerW: batteryData && batteryData.wChaMax !== undefined && batteryData.inWRte !== undefined ? batteryData.wChaMax * batteryData.inWRte : undefined,
|
|
743
771
|
maxDischargePowerW: batteryData && batteryData.wChaMax !== undefined && batteryData.outWRte !== undefined ? batteryData.wChaMax * batteryData.outWRte : undefined,
|
|
772
|
+
activeChargeLimitW: activeChargeLimitW,
|
|
773
|
+
activeDischargeLimitW: activeDischargeLimitW,
|
|
744
774
|
features,
|
|
745
775
|
gridChargingEnabled: batteryData?.chaGriSet === 1
|
|
746
776
|
}
|
|
@@ -767,6 +797,8 @@ export class SunspecBattery extends BaseSunspecDevice {
|
|
|
767
797
|
storageMode: this.mapToEnyoStorageMode(storageMode),
|
|
768
798
|
maxChargingPowerW: batteryData && batteryData.wChaMax !== undefined && batteryData.inWRte !== undefined ? batteryData.wChaMax * batteryData.inWRte : undefined,
|
|
769
799
|
maxDischargePowerW: batteryData && batteryData.wChaMax !== undefined && batteryData.outWRte !== undefined ? batteryData.wChaMax * batteryData.outWRte : undefined,
|
|
800
|
+
activeChargeLimitW: activeChargeLimitW,
|
|
801
|
+
activeDischargeLimitW: activeDischargeLimitW,
|
|
770
802
|
features,
|
|
771
803
|
gridChargingEnabled: batteryData?.chaGriSet === 1
|
|
772
804
|
}
|
|
@@ -873,6 +905,8 @@ export class SunspecBattery extends BaseSunspecDevice {
|
|
|
873
905
|
storageMode: this.mapToEnyoStorageMode(storageMode),
|
|
874
906
|
maxChargingPowerW: batteryData && batteryData.wChaMax !== undefined && batteryData.inWRte !== undefined ? batteryData.wChaMax * batteryData.inWRte : undefined,
|
|
875
907
|
maxDischargePowerW: batteryData && batteryData.wChaMax !== undefined && batteryData.outWRte !== undefined ? batteryData.wChaMax * batteryData.outWRte : undefined,
|
|
908
|
+
activeChargeLimitW: this.computeActiveChargeLimitW(batteryData),
|
|
909
|
+
activeDischargeLimitW: this.computeActiveDischargeLimitW(batteryData),
|
|
876
910
|
gridChargingEnabled: batteryData?.chaGriSet === 1
|
|
877
911
|
}
|
|
878
912
|
});
|
|
@@ -1051,6 +1085,34 @@ export class SunspecBattery extends BaseSunspecDevice {
|
|
|
1051
1085
|
const controls = await this.getBatteryControls();
|
|
1052
1086
|
return this.determineStorageMode(controls);
|
|
1053
1087
|
}
|
|
1088
|
+
/**
|
|
1089
|
+
* Compute the currently active charge limit in Watts from Model 124's
|
|
1090
|
+
* wChaMax and the charge rate setpoint inWRte (% of WChaMax). Returns
|
|
1091
|
+
* null when no limit is applied, when the registers cannot be read, or
|
|
1092
|
+
* when the rate is at 100% (no throttling) — null is returned (not
|
|
1093
|
+
* undefined) so the field is cleared on the appliance.
|
|
1094
|
+
*/
|
|
1095
|
+
computeActiveChargeLimitW(batteryData) {
|
|
1096
|
+
if (!batteryData || batteryData.wChaMax === undefined || batteryData.inWRte === undefined) {
|
|
1097
|
+
return null;
|
|
1098
|
+
}
|
|
1099
|
+
if (batteryData.inWRte >= 100)
|
|
1100
|
+
return null;
|
|
1101
|
+
return (batteryData.wChaMax * batteryData.inWRte) / 100;
|
|
1102
|
+
}
|
|
1103
|
+
/**
|
|
1104
|
+
* Compute the currently active discharge limit in Watts from Model 124's
|
|
1105
|
+
* wChaMax and the discharge rate setpoint outWRte (% of WDisChaMax).
|
|
1106
|
+
* Returns null when no limit is applied or the registers cannot be read.
|
|
1107
|
+
*/
|
|
1108
|
+
computeActiveDischargeLimitW(batteryData) {
|
|
1109
|
+
if (!batteryData || batteryData.wChaMax === undefined || batteryData.outWRte === undefined) {
|
|
1110
|
+
return null;
|
|
1111
|
+
}
|
|
1112
|
+
if (batteryData.outWRte >= 100)
|
|
1113
|
+
return null;
|
|
1114
|
+
return (batteryData.wChaMax * batteryData.outWRte) / 100;
|
|
1115
|
+
}
|
|
1054
1116
|
determineStorageMode(controls) {
|
|
1055
1117
|
if (!controls || controls.storCtlMod === undefined) {
|
|
1056
1118
|
return null;
|
package/dist/version.d.ts
CHANGED
package/dist/version.js
CHANGED