@enyo-energy/sunspec-sdk 0.0.42 → 0.0.44
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 +158 -89
- package/dist/cjs/sunspec-devices.d.cts +6 -18
- package/dist/cjs/version.cjs +1 -1
- package/dist/cjs/version.d.cts +1 -1
- package/dist/sunspec-devices.d.ts +6 -18
- package/dist/sunspec-devices.js +158 -89
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +2 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.SunspecMeter = exports.SunspecBattery = exports.SunspecInverter = exports.BaseSunspecDevice =
|
|
3
|
+
exports.SunspecMeter = exports.SunspecBattery = exports.SunspecInverter = exports.BaseSunspecDevice = void 0;
|
|
4
4
|
const sunspec_interfaces_js_1 = require("./sunspec-interfaces.cjs");
|
|
5
5
|
const node_crypto_1 = require("node:crypto");
|
|
6
6
|
const enyo_appliance_js_1 = require("@enyo-energy/energy-app-sdk/dist/types/enyo-appliance.js");
|
|
@@ -9,8 +9,6 @@ const enyo_data_bus_value_js_1 = require("@enyo-energy/energy-app-sdk/dist/types
|
|
|
9
9
|
const enyo_source_enum_js_1 = require("@enyo-energy/energy-app-sdk/dist/types/enyo-source.enum.js");
|
|
10
10
|
const enyo_meter_appliance_js_1 = require("@enyo-energy/energy-app-sdk/dist/types/enyo-meter-appliance.js");
|
|
11
11
|
const enyo_battery_appliance_js_1 = require("@enyo-energy/energy-app-sdk/dist/types/enyo-battery-appliance.js");
|
|
12
|
-
// TODO: Remove once added to @enyo-energy/energy-app-sdk EnyoDataBusMessageEnum
|
|
13
|
-
exports.ENYO_DATA_BUS_SET_INVERTER_FEED_IN_LIMIT_V1 = 'SetInverterFeedInLimitV1';
|
|
14
12
|
/**
|
|
15
13
|
* Base abstract class for all Sunspec devices
|
|
16
14
|
*/
|
|
@@ -28,7 +26,7 @@ class BaseSunspecDevice {
|
|
|
28
26
|
dataBusListenerId;
|
|
29
27
|
dataBus;
|
|
30
28
|
retryManager;
|
|
31
|
-
constructor(energyApp, name, networkDevice, sunspecClient, applianceManager, unitId = 1, port = 502, baseAddress = 40000, retryConfig) {
|
|
29
|
+
constructor(energyApp, name, networkDevice, sunspecClient, applianceManager, unitId = 1, port = 502, baseAddress = 40000, retryConfig, appliance) {
|
|
32
30
|
this.energyApp = energyApp;
|
|
33
31
|
this.name = name;
|
|
34
32
|
this.networkDevice = networkDevice;
|
|
@@ -38,12 +36,15 @@ class BaseSunspecDevice {
|
|
|
38
36
|
this.port = port;
|
|
39
37
|
this.baseAddress = baseAddress;
|
|
40
38
|
this.retryManager = new connection_retry_manager_js_1.ConnectionRetryManager(retryConfig);
|
|
39
|
+
if (appliance) {
|
|
40
|
+
this.applianceId = appliance.id;
|
|
41
|
+
}
|
|
41
42
|
}
|
|
42
43
|
/**
|
|
43
44
|
* Check if the device is connected
|
|
44
45
|
*/
|
|
45
46
|
isConnected() {
|
|
46
|
-
return this.sunspecClient.
|
|
47
|
+
return this.sunspecClient.isHealthy();
|
|
47
48
|
}
|
|
48
49
|
/**
|
|
49
50
|
* Get the appliance IDs managed by this device
|
|
@@ -136,8 +137,8 @@ exports.BaseSunspecDevice = BaseSunspecDevice;
|
|
|
136
137
|
*/
|
|
137
138
|
class SunspecInverter extends BaseSunspecDevice {
|
|
138
139
|
capabilities;
|
|
139
|
-
constructor(energyApp, name, networkDevice, sunspecClient, applianceManager, unitId = 1, port = 502, baseAddress = 40000, capabilities = [], retryConfig) {
|
|
140
|
-
super(energyApp, name, networkDevice, sunspecClient, applianceManager, unitId, port, baseAddress, retryConfig);
|
|
140
|
+
constructor(energyApp, name, networkDevice, sunspecClient, applianceManager, unitId = 1, port = 502, baseAddress = 40000, capabilities = [], retryConfig, appliance) {
|
|
141
|
+
super(energyApp, name, networkDevice, sunspecClient, applianceManager, unitId, port, baseAddress, retryConfig, appliance);
|
|
141
142
|
this.capabilities = capabilities;
|
|
142
143
|
}
|
|
143
144
|
async connect() {
|
|
@@ -152,29 +153,53 @@ class SunspecInverter extends BaseSunspecDevice {
|
|
|
152
153
|
const commonData = await this.sunspecClient.readCommonBlock();
|
|
153
154
|
const inverterSettings = await this.sunspecClient.readInverterSettings();
|
|
154
155
|
const mpptDataList = await this.sunspecClient.readAllMPPTData();
|
|
155
|
-
// Create or update appliance
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
156
|
+
// Create or update appliance (skip if an existing appliance was provided)
|
|
157
|
+
if (!this.applianceId) {
|
|
158
|
+
try {
|
|
159
|
+
this.applianceId = await this.applianceManager.createOrUpdateAppliance({
|
|
160
|
+
name: this.name,
|
|
161
|
+
type: enyo_appliance_js_1.EnyoApplianceTypeEnum.Inverter,
|
|
162
|
+
networkDevices: [this.networkDevice],
|
|
163
|
+
metadata: {
|
|
164
|
+
connectionType: enyo_appliance_js_1.EnyoApplianceConnectionType.Connector,
|
|
165
|
+
state: enyo_appliance_js_1.EnyoApplianceStateEnum.Connected,
|
|
166
|
+
serialNumber: commonData?.serialNumber,
|
|
167
|
+
modelName: commonData?.model,
|
|
168
|
+
vendorName: commonData?.manufacturer,
|
|
169
|
+
modbus: { unitId: this.unitId, baseAddress: this.baseAddress },
|
|
170
|
+
},
|
|
171
|
+
inverter: {
|
|
172
|
+
dcStrings: this.mapDcStringToApplianceMetadata(this.mapMPPTToStrings(mpptDataList)),
|
|
173
|
+
maxPvProductionW: inverterSettings?.WMax
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
console.log(`Sunspec Inverter connected: ${this.networkDevice.hostname} (${this.applianceId})`);
|
|
177
|
+
}
|
|
178
|
+
catch (error) {
|
|
179
|
+
console.error(`Failed to create inverter appliance: ${error}`);
|
|
180
|
+
}
|
|
175
181
|
}
|
|
176
|
-
|
|
177
|
-
|
|
182
|
+
else {
|
|
183
|
+
try {
|
|
184
|
+
const existingAppliance = await this.applianceManager.findApplianceById(this.applianceId);
|
|
185
|
+
await this.applianceManager.updateAppliance(this.applianceId, {
|
|
186
|
+
metadata: {
|
|
187
|
+
...existingAppliance?.metadata,
|
|
188
|
+
connectionType: enyo_appliance_js_1.EnyoApplianceConnectionType.Connector,
|
|
189
|
+
state: enyo_appliance_js_1.EnyoApplianceStateEnum.Connected,
|
|
190
|
+
modbus: { unitId: this.unitId, baseAddress: this.baseAddress },
|
|
191
|
+
},
|
|
192
|
+
inverter: {
|
|
193
|
+
...existingAppliance?.inverter,
|
|
194
|
+
dcStrings: this.mapDcStringToApplianceMetadata(this.mapMPPTToStrings(mpptDataList)),
|
|
195
|
+
maxPvProductionW: inverterSettings?.WMax
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
console.log(`Sunspec Inverter connected: ${this.networkDevice.hostname} (${this.applianceId})`);
|
|
199
|
+
}
|
|
200
|
+
catch (error) {
|
|
201
|
+
console.error(`Failed to update inverter appliance: ${error}`);
|
|
202
|
+
}
|
|
178
203
|
}
|
|
179
204
|
// Check for MPPT models
|
|
180
205
|
const mpptModel = this.sunspecClient.findModel(sunspec_interfaces_js_1.SunspecModelId.MPPT);
|
|
@@ -190,9 +215,6 @@ class SunspecInverter extends BaseSunspecDevice {
|
|
|
190
215
|
}
|
|
191
216
|
// Note: We don't disconnect the sunspecClient as it may be shared
|
|
192
217
|
}
|
|
193
|
-
isConnected() {
|
|
194
|
-
return this.sunspecClient.isConnected();
|
|
195
|
-
}
|
|
196
218
|
async readData(clockId, resolution) {
|
|
197
219
|
if (!this.isConnected()) {
|
|
198
220
|
await this.tryReconnect();
|
|
@@ -324,7 +346,7 @@ class SunspecInverter extends BaseSunspecDevice {
|
|
|
324
346
|
return;
|
|
325
347
|
}
|
|
326
348
|
this.dataBus = this.energyApp.useDataBus();
|
|
327
|
-
this.dataBusListenerId = this.dataBus.listenForMessages([
|
|
349
|
+
this.dataBusListenerId = this.dataBus.listenForMessages([enyo_data_bus_value_js_1.EnyoDataBusMessageEnum.SetInverterFeedInLimitV1], (entry) => this.handleInverterCommand(entry));
|
|
328
350
|
console.log(`Inverter ${this.applianceId}: started data bus listening (listener ${this.dataBusListenerId})`);
|
|
329
351
|
}
|
|
330
352
|
/**
|
|
@@ -344,7 +366,7 @@ class SunspecInverter extends BaseSunspecDevice {
|
|
|
344
366
|
}
|
|
345
367
|
void (async () => {
|
|
346
368
|
try {
|
|
347
|
-
if (entry.message ===
|
|
369
|
+
if (entry.message === enyo_data_bus_value_js_1.EnyoDataBusMessageEnum.SetInverterFeedInLimitV1) {
|
|
348
370
|
await this.handleSetFeedInLimit(entry);
|
|
349
371
|
}
|
|
350
372
|
}
|
|
@@ -378,8 +400,8 @@ exports.SunspecInverter = SunspecInverter;
|
|
|
378
400
|
*/
|
|
379
401
|
class SunspecBattery extends BaseSunspecDevice {
|
|
380
402
|
capabilities;
|
|
381
|
-
constructor(energyApp, name, networkDevice, sunspecClient, applianceManager, unitId = 1, port = 502, baseAddress = 40000, capabilities = [], retryConfig) {
|
|
382
|
-
super(energyApp, name, networkDevice, sunspecClient, applianceManager, unitId, port, baseAddress, retryConfig);
|
|
403
|
+
constructor(energyApp, name, networkDevice, sunspecClient, applianceManager, unitId = 1, port = 502, baseAddress = 40000, capabilities = [], retryConfig, appliance) {
|
|
404
|
+
super(energyApp, name, networkDevice, sunspecClient, applianceManager, unitId, port, baseAddress, retryConfig, appliance);
|
|
383
405
|
this.capabilities = capabilities;
|
|
384
406
|
}
|
|
385
407
|
/**
|
|
@@ -399,38 +421,66 @@ class SunspecBattery extends BaseSunspecDevice {
|
|
|
399
421
|
const batteryData = await this.sunspecClient.readBatteryData();
|
|
400
422
|
const storageMode = this.determineStorageMode(batteryData);
|
|
401
423
|
const features = [];
|
|
402
|
-
// Create or update appliance
|
|
403
424
|
if (batteryData?.chaGriSet !== undefined) {
|
|
404
425
|
features.push(enyo_battery_appliance_js_1.EnyoBatteryFeature.GridCharging);
|
|
405
426
|
}
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
427
|
+
// Create or update appliance (skip if an existing appliance was provided)
|
|
428
|
+
if (!this.applianceId) {
|
|
429
|
+
try {
|
|
430
|
+
this.applianceId = await this.applianceManager.createOrUpdateAppliance({
|
|
431
|
+
name: this.name,
|
|
432
|
+
type: enyo_appliance_js_1.EnyoApplianceTypeEnum.Storage,
|
|
433
|
+
networkDevices: [this.networkDevice],
|
|
434
|
+
metadata: {
|
|
435
|
+
connectionType: enyo_appliance_js_1.EnyoApplianceConnectionType.Connector,
|
|
436
|
+
state: enyo_appliance_js_1.EnyoApplianceStateEnum.Connected,
|
|
437
|
+
serialNumber: commonData?.serialNumber,
|
|
438
|
+
modelName: commonData?.model,
|
|
439
|
+
vendorName: commonData?.manufacturer,
|
|
440
|
+
modbus: { unitId: this.unitId, baseAddress: this.baseAddress },
|
|
441
|
+
},
|
|
442
|
+
battery: {
|
|
443
|
+
connectedToApplianceId: inverterApplianceId,
|
|
444
|
+
storageMode: this.mapToEnyoStorageMode(storageMode),
|
|
445
|
+
maxChargingPowerW: batteryData && batteryData.wChaMax !== undefined && batteryData.inWRte !== undefined ? batteryData.wChaMax * batteryData.inWRte : undefined,
|
|
446
|
+
maxDischargePowerW: batteryData && batteryData.wChaMax !== undefined && batteryData.outWRte !== undefined ? batteryData.wChaMax * batteryData.outWRte : undefined,
|
|
447
|
+
features,
|
|
448
|
+
gridChargingEnabled: batteryData?.chaGriSet === 1
|
|
449
|
+
}
|
|
450
|
+
});
|
|
451
|
+
console.log(`Sunspec Battery connected: ${this.networkDevice.hostname} (${this.applianceId})`);
|
|
452
|
+
}
|
|
453
|
+
catch (error) {
|
|
454
|
+
console.error(`Failed to create battery appliance: ${error}`);
|
|
455
|
+
}
|
|
430
456
|
}
|
|
431
|
-
|
|
432
|
-
|
|
457
|
+
else {
|
|
458
|
+
try {
|
|
459
|
+
const existingAppliance = await this.applianceManager.findApplianceById(this.applianceId);
|
|
460
|
+
await this.applianceManager.updateAppliance(this.applianceId, {
|
|
461
|
+
metadata: {
|
|
462
|
+
...existingAppliance?.metadata,
|
|
463
|
+
connectionType: enyo_appliance_js_1.EnyoApplianceConnectionType.Connector,
|
|
464
|
+
state: enyo_appliance_js_1.EnyoApplianceStateEnum.Connected,
|
|
465
|
+
modbus: { unitId: this.unitId, baseAddress: this.baseAddress },
|
|
466
|
+
},
|
|
467
|
+
battery: {
|
|
468
|
+
...existingAppliance?.battery,
|
|
469
|
+
connectedToApplianceId: inverterApplianceId,
|
|
470
|
+
storageMode: this.mapToEnyoStorageMode(storageMode),
|
|
471
|
+
maxChargingPowerW: batteryData && batteryData.wChaMax !== undefined && batteryData.inWRte !== undefined ? batteryData.wChaMax * batteryData.inWRte : undefined,
|
|
472
|
+
maxDischargePowerW: batteryData && batteryData.wChaMax !== undefined && batteryData.outWRte !== undefined ? batteryData.wChaMax * batteryData.outWRte : undefined,
|
|
473
|
+
features,
|
|
474
|
+
gridChargingEnabled: batteryData?.chaGriSet === 1
|
|
475
|
+
}
|
|
476
|
+
});
|
|
477
|
+
console.log(`Sunspec Battery connected: ${this.networkDevice.hostname} (${this.applianceId})`);
|
|
478
|
+
}
|
|
479
|
+
catch (error) {
|
|
480
|
+
console.error(`Failed to update battery appliance: ${error}`);
|
|
481
|
+
}
|
|
433
482
|
}
|
|
483
|
+
this.startDataBusListening();
|
|
434
484
|
}
|
|
435
485
|
async disconnect() {
|
|
436
486
|
this.stopDataBusListening();
|
|
@@ -872,8 +922,8 @@ exports.SunspecBattery = SunspecBattery;
|
|
|
872
922
|
*/
|
|
873
923
|
class SunspecMeter extends BaseSunspecDevice {
|
|
874
924
|
capabilities;
|
|
875
|
-
constructor(energyApp, name, networkDevice, sunspecClient, applianceManager, unitId = 1, port = 502, baseAddress = 40000, capabilities = [], retryConfig) {
|
|
876
|
-
super(energyApp, name, networkDevice, sunspecClient, applianceManager, unitId, port, baseAddress, retryConfig);
|
|
925
|
+
constructor(energyApp, name, networkDevice, sunspecClient, applianceManager, unitId = 1, port = 502, baseAddress = 40000, capabilities = [], retryConfig, appliance) {
|
|
926
|
+
super(energyApp, name, networkDevice, sunspecClient, applianceManager, unitId, port, baseAddress, retryConfig, appliance);
|
|
877
927
|
this.capabilities = capabilities;
|
|
878
928
|
}
|
|
879
929
|
/**
|
|
@@ -891,31 +941,50 @@ class SunspecMeter extends BaseSunspecDevice {
|
|
|
891
941
|
}
|
|
892
942
|
// Get device info
|
|
893
943
|
const commonData = await this.sunspecClient.readCommonBlock();
|
|
894
|
-
// Create or update appliance
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
944
|
+
// Create or update appliance (skip if an existing appliance was provided)
|
|
945
|
+
if (!this.applianceId) {
|
|
946
|
+
try {
|
|
947
|
+
this.applianceId = await this.applianceManager.createOrUpdateAppliance({
|
|
948
|
+
name: this.name,
|
|
949
|
+
type: enyo_appliance_js_1.EnyoApplianceTypeEnum.Meter,
|
|
950
|
+
networkDevices: [this.networkDevice],
|
|
951
|
+
metadata: {
|
|
952
|
+
connectionType: enyo_appliance_js_1.EnyoApplianceConnectionType.Connector,
|
|
953
|
+
state: enyo_appliance_js_1.EnyoApplianceStateEnum.Connected,
|
|
954
|
+
serialNumber: commonData?.serialNumber,
|
|
955
|
+
modelName: commonData?.model,
|
|
956
|
+
vendorName: commonData?.manufacturer,
|
|
957
|
+
modbus: { unitId: this.unitId, baseAddress: this.baseAddress },
|
|
958
|
+
},
|
|
959
|
+
topology: {
|
|
960
|
+
features: [enyo_appliance_js_1.EnyoApplianceTopologyFeatureEnum.IntermediateOfPrimaryMeter]
|
|
961
|
+
},
|
|
962
|
+
meter: {
|
|
963
|
+
availableFeatures: [enyo_meter_appliance_js_1.EnyoMeterApplianceAvailableFeaturesEnum.LivePowerConsumption]
|
|
964
|
+
}
|
|
965
|
+
});
|
|
966
|
+
console.log(`Sunspec Meter connected: ${this.networkDevice.hostname} unit ${this.unitId} (${this.applianceId})`);
|
|
967
|
+
}
|
|
968
|
+
catch (error) {
|
|
969
|
+
console.error(`Failed to create meter appliance: ${error}`);
|
|
970
|
+
}
|
|
916
971
|
}
|
|
917
|
-
|
|
918
|
-
|
|
972
|
+
else {
|
|
973
|
+
try {
|
|
974
|
+
const existingAppliance = await this.applianceManager.findApplianceById(this.applianceId);
|
|
975
|
+
await this.applianceManager.updateAppliance(this.applianceId, {
|
|
976
|
+
metadata: {
|
|
977
|
+
...existingAppliance?.metadata,
|
|
978
|
+
connectionType: enyo_appliance_js_1.EnyoApplianceConnectionType.Connector,
|
|
979
|
+
state: enyo_appliance_js_1.EnyoApplianceStateEnum.Connected,
|
|
980
|
+
modbus: { unitId: this.unitId, baseAddress: this.baseAddress },
|
|
981
|
+
}
|
|
982
|
+
});
|
|
983
|
+
console.log(`Sunspec Meter connected: ${this.networkDevice.hostname} unit ${this.unitId} (${this.applianceId})`);
|
|
984
|
+
}
|
|
985
|
+
catch (error) {
|
|
986
|
+
console.error(`Failed to update meter appliance: ${error}`);
|
|
987
|
+
}
|
|
919
988
|
}
|
|
920
989
|
}
|
|
921
990
|
/**
|
|
@@ -1,22 +1,11 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type IRetryConfig, type SunspecBatteryBaseData, SunspecBatteryCapability, type SunspecBatteryControls, SunspecInverterCapability, SunspecMeterCapability, SunspecStorageMode } from "./sunspec-interfaces.cjs";
|
|
2
2
|
import { ApplianceManager, EnergyApp } from "@enyo-energy/energy-app-sdk";
|
|
3
|
-
import { EnyoApplianceName } from "@enyo-energy/energy-app-sdk/dist/types/enyo-appliance.js";
|
|
3
|
+
import { type EnyoAppliance, 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.cjs";
|
|
6
6
|
import { ConnectionRetryManager } from "./connection-retry-manager.cjs";
|
|
7
|
-
import { type IRetryConfig } from "./sunspec-interfaces.cjs";
|
|
8
7
|
import { EnyoCommandAcknowledgeAnswerEnum, EnyoDataBusMessage, EnyoDataBusMessageEnum, EnyoDataBusMessageResolution } from "@enyo-energy/energy-app-sdk/dist/types/enyo-data-bus-value.js";
|
|
9
8
|
import { EnergyAppDataBus } from "@enyo-energy/energy-app-sdk/dist/packages/energy-app-data-bus.js";
|
|
10
|
-
export declare const ENYO_DATA_BUS_SET_INVERTER_FEED_IN_LIMIT_V1 = "SetInverterFeedInLimitV1";
|
|
11
|
-
export interface EnyoDataBusSetInverterFeedInLimitV1 {
|
|
12
|
-
id: string;
|
|
13
|
-
type: 'message';
|
|
14
|
-
message: string;
|
|
15
|
-
applianceId: string;
|
|
16
|
-
data: {
|
|
17
|
-
feedInLimitW: number | null;
|
|
18
|
-
};
|
|
19
|
-
}
|
|
20
9
|
/**
|
|
21
10
|
* Base abstract class for all Sunspec devices
|
|
22
11
|
*/
|
|
@@ -34,7 +23,7 @@ export declare abstract class BaseSunspecDevice {
|
|
|
34
23
|
protected dataBusListenerId?: string;
|
|
35
24
|
protected dataBus?: EnergyAppDataBus;
|
|
36
25
|
protected retryManager: ConnectionRetryManager;
|
|
37
|
-
constructor(energyApp: EnergyApp, name: EnyoApplianceName[], networkDevice: EnyoNetworkDevice, sunspecClient: SunspecModbusClient, applianceManager: ApplianceManager, unitId?: number, port?: number, baseAddress?: number, retryConfig?: IRetryConfig);
|
|
26
|
+
constructor(energyApp: EnergyApp, name: EnyoApplianceName[], networkDevice: EnyoNetworkDevice, sunspecClient: SunspecModbusClient, applianceManager: ApplianceManager, unitId?: number, port?: number, baseAddress?: number, retryConfig?: IRetryConfig, appliance?: EnyoAppliance);
|
|
38
27
|
/**
|
|
39
28
|
* Connect to the device and create/update the appliance
|
|
40
29
|
*/
|
|
@@ -75,10 +64,9 @@ export declare abstract class BaseSunspecDevice {
|
|
|
75
64
|
*/
|
|
76
65
|
export declare class SunspecInverter extends BaseSunspecDevice {
|
|
77
66
|
private readonly capabilities;
|
|
78
|
-
constructor(energyApp: EnergyApp, name: EnyoApplianceName[], networkDevice: EnyoNetworkDevice, sunspecClient: SunspecModbusClient, applianceManager: ApplianceManager, unitId?: number, port?: number, baseAddress?: number, capabilities?: SunspecInverterCapability[], retryConfig?: IRetryConfig);
|
|
67
|
+
constructor(energyApp: EnergyApp, name: EnyoApplianceName[], networkDevice: EnyoNetworkDevice, sunspecClient: SunspecModbusClient, applianceManager: ApplianceManager, unitId?: number, port?: number, baseAddress?: number, capabilities?: SunspecInverterCapability[], retryConfig?: IRetryConfig, appliance?: EnyoAppliance);
|
|
79
68
|
connect(): Promise<void>;
|
|
80
69
|
disconnect(): Promise<void>;
|
|
81
|
-
isConnected(): boolean;
|
|
82
70
|
readData(clockId: string, resolution: '10s' | '30s' | '1m' | '15m'): Promise<EnyoDataBusMessage[]>;
|
|
83
71
|
private mapOperatingState;
|
|
84
72
|
/**
|
|
@@ -105,7 +93,7 @@ export declare class SunspecInverter extends BaseSunspecDevice {
|
|
|
105
93
|
*/
|
|
106
94
|
export declare class SunspecBattery extends BaseSunspecDevice {
|
|
107
95
|
private readonly capabilities;
|
|
108
|
-
constructor(energyApp: EnergyApp, name: EnyoApplianceName[], networkDevice: EnyoNetworkDevice, sunspecClient: SunspecModbusClient, applianceManager: ApplianceManager, unitId?: number, port?: number, baseAddress?: number, capabilities?: SunspecBatteryCapability[], retryConfig?: IRetryConfig);
|
|
96
|
+
constructor(energyApp: EnergyApp, name: EnyoApplianceName[], networkDevice: EnyoNetworkDevice, sunspecClient: SunspecModbusClient, applianceManager: ApplianceManager, unitId?: number, port?: number, baseAddress?: number, capabilities?: SunspecBatteryCapability[], retryConfig?: IRetryConfig, appliance?: EnyoAppliance);
|
|
109
97
|
/**
|
|
110
98
|
* Connect to the battery and create/update the appliance
|
|
111
99
|
*/
|
|
@@ -222,7 +210,7 @@ export declare class SunspecBattery extends BaseSunspecDevice {
|
|
|
222
210
|
*/
|
|
223
211
|
export declare class SunspecMeter extends BaseSunspecDevice {
|
|
224
212
|
private readonly capabilities;
|
|
225
|
-
constructor(energyApp: EnergyApp, name: EnyoApplianceName[], networkDevice: EnyoNetworkDevice, sunspecClient: SunspecModbusClient, applianceManager: ApplianceManager, unitId?: number, port?: number, baseAddress?: number, capabilities?: SunspecMeterCapability[], retryConfig?: IRetryConfig);
|
|
213
|
+
constructor(energyApp: EnergyApp, name: EnyoApplianceName[], networkDevice: EnyoNetworkDevice, sunspecClient: SunspecModbusClient, applianceManager: ApplianceManager, unitId?: number, port?: number, baseAddress?: number, capabilities?: SunspecMeterCapability[], retryConfig?: IRetryConfig, appliance?: EnyoAppliance);
|
|
226
214
|
/**
|
|
227
215
|
* Connect to the meter and create/update the appliance
|
|
228
216
|
*/
|
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.44';
|
|
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
|
@@ -1,22 +1,11 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type IRetryConfig, type SunspecBatteryBaseData, SunspecBatteryCapability, type SunspecBatteryControls, SunspecInverterCapability, SunspecMeterCapability, SunspecStorageMode } from "./sunspec-interfaces.js";
|
|
2
2
|
import { ApplianceManager, EnergyApp } from "@enyo-energy/energy-app-sdk";
|
|
3
|
-
import { EnyoApplianceName } from "@enyo-energy/energy-app-sdk/dist/types/enyo-appliance.js";
|
|
3
|
+
import { type EnyoAppliance, 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
|
-
import { type IRetryConfig } from "./sunspec-interfaces.js";
|
|
8
7
|
import { EnyoCommandAcknowledgeAnswerEnum, EnyoDataBusMessage, EnyoDataBusMessageEnum, EnyoDataBusMessageResolution } from "@enyo-energy/energy-app-sdk/dist/types/enyo-data-bus-value.js";
|
|
9
8
|
import { EnergyAppDataBus } from "@enyo-energy/energy-app-sdk/dist/packages/energy-app-data-bus.js";
|
|
10
|
-
export declare const ENYO_DATA_BUS_SET_INVERTER_FEED_IN_LIMIT_V1 = "SetInverterFeedInLimitV1";
|
|
11
|
-
export interface EnyoDataBusSetInverterFeedInLimitV1 {
|
|
12
|
-
id: string;
|
|
13
|
-
type: 'message';
|
|
14
|
-
message: string;
|
|
15
|
-
applianceId: string;
|
|
16
|
-
data: {
|
|
17
|
-
feedInLimitW: number | null;
|
|
18
|
-
};
|
|
19
|
-
}
|
|
20
9
|
/**
|
|
21
10
|
* Base abstract class for all Sunspec devices
|
|
22
11
|
*/
|
|
@@ -34,7 +23,7 @@ export declare abstract class BaseSunspecDevice {
|
|
|
34
23
|
protected dataBusListenerId?: string;
|
|
35
24
|
protected dataBus?: EnergyAppDataBus;
|
|
36
25
|
protected retryManager: ConnectionRetryManager;
|
|
37
|
-
constructor(energyApp: EnergyApp, name: EnyoApplianceName[], networkDevice: EnyoNetworkDevice, sunspecClient: SunspecModbusClient, applianceManager: ApplianceManager, unitId?: number, port?: number, baseAddress?: number, retryConfig?: IRetryConfig);
|
|
26
|
+
constructor(energyApp: EnergyApp, name: EnyoApplianceName[], networkDevice: EnyoNetworkDevice, sunspecClient: SunspecModbusClient, applianceManager: ApplianceManager, unitId?: number, port?: number, baseAddress?: number, retryConfig?: IRetryConfig, appliance?: EnyoAppliance);
|
|
38
27
|
/**
|
|
39
28
|
* Connect to the device and create/update the appliance
|
|
40
29
|
*/
|
|
@@ -75,10 +64,9 @@ export declare abstract class BaseSunspecDevice {
|
|
|
75
64
|
*/
|
|
76
65
|
export declare class SunspecInverter extends BaseSunspecDevice {
|
|
77
66
|
private readonly capabilities;
|
|
78
|
-
constructor(energyApp: EnergyApp, name: EnyoApplianceName[], networkDevice: EnyoNetworkDevice, sunspecClient: SunspecModbusClient, applianceManager: ApplianceManager, unitId?: number, port?: number, baseAddress?: number, capabilities?: SunspecInverterCapability[], retryConfig?: IRetryConfig);
|
|
67
|
+
constructor(energyApp: EnergyApp, name: EnyoApplianceName[], networkDevice: EnyoNetworkDevice, sunspecClient: SunspecModbusClient, applianceManager: ApplianceManager, unitId?: number, port?: number, baseAddress?: number, capabilities?: SunspecInverterCapability[], retryConfig?: IRetryConfig, appliance?: EnyoAppliance);
|
|
79
68
|
connect(): Promise<void>;
|
|
80
69
|
disconnect(): Promise<void>;
|
|
81
|
-
isConnected(): boolean;
|
|
82
70
|
readData(clockId: string, resolution: '10s' | '30s' | '1m' | '15m'): Promise<EnyoDataBusMessage[]>;
|
|
83
71
|
private mapOperatingState;
|
|
84
72
|
/**
|
|
@@ -105,7 +93,7 @@ export declare class SunspecInverter extends BaseSunspecDevice {
|
|
|
105
93
|
*/
|
|
106
94
|
export declare class SunspecBattery extends BaseSunspecDevice {
|
|
107
95
|
private readonly capabilities;
|
|
108
|
-
constructor(energyApp: EnergyApp, name: EnyoApplianceName[], networkDevice: EnyoNetworkDevice, sunspecClient: SunspecModbusClient, applianceManager: ApplianceManager, unitId?: number, port?: number, baseAddress?: number, capabilities?: SunspecBatteryCapability[], retryConfig?: IRetryConfig);
|
|
96
|
+
constructor(energyApp: EnergyApp, name: EnyoApplianceName[], networkDevice: EnyoNetworkDevice, sunspecClient: SunspecModbusClient, applianceManager: ApplianceManager, unitId?: number, port?: number, baseAddress?: number, capabilities?: SunspecBatteryCapability[], retryConfig?: IRetryConfig, appliance?: EnyoAppliance);
|
|
109
97
|
/**
|
|
110
98
|
* Connect to the battery and create/update the appliance
|
|
111
99
|
*/
|
|
@@ -222,7 +210,7 @@ export declare class SunspecBattery extends BaseSunspecDevice {
|
|
|
222
210
|
*/
|
|
223
211
|
export declare class SunspecMeter extends BaseSunspecDevice {
|
|
224
212
|
private readonly capabilities;
|
|
225
|
-
constructor(energyApp: EnergyApp, name: EnyoApplianceName[], networkDevice: EnyoNetworkDevice, sunspecClient: SunspecModbusClient, applianceManager: ApplianceManager, unitId?: number, port?: number, baseAddress?: number, capabilities?: SunspecMeterCapability[], retryConfig?: IRetryConfig);
|
|
213
|
+
constructor(energyApp: EnergyApp, name: EnyoApplianceName[], networkDevice: EnyoNetworkDevice, sunspecClient: SunspecModbusClient, applianceManager: ApplianceManager, unitId?: number, port?: number, baseAddress?: number, capabilities?: SunspecMeterCapability[], retryConfig?: IRetryConfig, appliance?: EnyoAppliance);
|
|
226
214
|
/**
|
|
227
215
|
* Connect to the meter and create/update the appliance
|
|
228
216
|
*/
|
package/dist/sunspec-devices.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SunspecBatteryChargeState, SunspecModelId, SunspecMPPTOperatingState, SunspecStorageMode
|
|
1
|
+
import { SunspecBatteryChargeState, SunspecInverterCapability, SunspecModelId, SunspecMPPTOperatingState, SunspecStorageMode } from "./sunspec-interfaces.js";
|
|
2
2
|
import { randomUUID } from "node:crypto";
|
|
3
3
|
import { EnyoApplianceConnectionType, EnyoApplianceStateEnum, EnyoApplianceTopologyFeatureEnum, EnyoApplianceTypeEnum } from "@enyo-energy/energy-app-sdk/dist/types/enyo-appliance.js";
|
|
4
4
|
import { ConnectionRetryManager } from "./connection-retry-manager.js";
|
|
@@ -6,8 +6,6 @@ import { EnyoBatteryStateEnum, EnyoCommandAcknowledgeAnswerEnum, EnyoDataBusMess
|
|
|
6
6
|
import { EnyoSourceEnum } from "@enyo-energy/energy-app-sdk/dist/types/enyo-source.enum.js";
|
|
7
7
|
import { EnyoMeterApplianceAvailableFeaturesEnum } from "@enyo-energy/energy-app-sdk/dist/types/enyo-meter-appliance.js";
|
|
8
8
|
import { EnyoBatteryFeature, EnyoBatteryStorageMode } from "@enyo-energy/energy-app-sdk/dist/types/enyo-battery-appliance.js";
|
|
9
|
-
// TODO: Remove once added to @enyo-energy/energy-app-sdk EnyoDataBusMessageEnum
|
|
10
|
-
export const ENYO_DATA_BUS_SET_INVERTER_FEED_IN_LIMIT_V1 = 'SetInverterFeedInLimitV1';
|
|
11
9
|
/**
|
|
12
10
|
* Base abstract class for all Sunspec devices
|
|
13
11
|
*/
|
|
@@ -25,7 +23,7 @@ export class BaseSunspecDevice {
|
|
|
25
23
|
dataBusListenerId;
|
|
26
24
|
dataBus;
|
|
27
25
|
retryManager;
|
|
28
|
-
constructor(energyApp, name, networkDevice, sunspecClient, applianceManager, unitId = 1, port = 502, baseAddress = 40000, retryConfig) {
|
|
26
|
+
constructor(energyApp, name, networkDevice, sunspecClient, applianceManager, unitId = 1, port = 502, baseAddress = 40000, retryConfig, appliance) {
|
|
29
27
|
this.energyApp = energyApp;
|
|
30
28
|
this.name = name;
|
|
31
29
|
this.networkDevice = networkDevice;
|
|
@@ -35,12 +33,15 @@ export class BaseSunspecDevice {
|
|
|
35
33
|
this.port = port;
|
|
36
34
|
this.baseAddress = baseAddress;
|
|
37
35
|
this.retryManager = new ConnectionRetryManager(retryConfig);
|
|
36
|
+
if (appliance) {
|
|
37
|
+
this.applianceId = appliance.id;
|
|
38
|
+
}
|
|
38
39
|
}
|
|
39
40
|
/**
|
|
40
41
|
* Check if the device is connected
|
|
41
42
|
*/
|
|
42
43
|
isConnected() {
|
|
43
|
-
return this.sunspecClient.
|
|
44
|
+
return this.sunspecClient.isHealthy();
|
|
44
45
|
}
|
|
45
46
|
/**
|
|
46
47
|
* Get the appliance IDs managed by this device
|
|
@@ -132,8 +133,8 @@ export class BaseSunspecDevice {
|
|
|
132
133
|
*/
|
|
133
134
|
export class SunspecInverter extends BaseSunspecDevice {
|
|
134
135
|
capabilities;
|
|
135
|
-
constructor(energyApp, name, networkDevice, sunspecClient, applianceManager, unitId = 1, port = 502, baseAddress = 40000, capabilities = [], retryConfig) {
|
|
136
|
-
super(energyApp, name, networkDevice, sunspecClient, applianceManager, unitId, port, baseAddress, retryConfig);
|
|
136
|
+
constructor(energyApp, name, networkDevice, sunspecClient, applianceManager, unitId = 1, port = 502, baseAddress = 40000, capabilities = [], retryConfig, appliance) {
|
|
137
|
+
super(energyApp, name, networkDevice, sunspecClient, applianceManager, unitId, port, baseAddress, retryConfig, appliance);
|
|
137
138
|
this.capabilities = capabilities;
|
|
138
139
|
}
|
|
139
140
|
async connect() {
|
|
@@ -148,29 +149,53 @@ export class SunspecInverter extends BaseSunspecDevice {
|
|
|
148
149
|
const commonData = await this.sunspecClient.readCommonBlock();
|
|
149
150
|
const inverterSettings = await this.sunspecClient.readInverterSettings();
|
|
150
151
|
const mpptDataList = await this.sunspecClient.readAllMPPTData();
|
|
151
|
-
// Create or update appliance
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
152
|
+
// Create or update appliance (skip if an existing appliance was provided)
|
|
153
|
+
if (!this.applianceId) {
|
|
154
|
+
try {
|
|
155
|
+
this.applianceId = await this.applianceManager.createOrUpdateAppliance({
|
|
156
|
+
name: this.name,
|
|
157
|
+
type: EnyoApplianceTypeEnum.Inverter,
|
|
158
|
+
networkDevices: [this.networkDevice],
|
|
159
|
+
metadata: {
|
|
160
|
+
connectionType: EnyoApplianceConnectionType.Connector,
|
|
161
|
+
state: EnyoApplianceStateEnum.Connected,
|
|
162
|
+
serialNumber: commonData?.serialNumber,
|
|
163
|
+
modelName: commonData?.model,
|
|
164
|
+
vendorName: commonData?.manufacturer,
|
|
165
|
+
modbus: { unitId: this.unitId, baseAddress: this.baseAddress },
|
|
166
|
+
},
|
|
167
|
+
inverter: {
|
|
168
|
+
dcStrings: this.mapDcStringToApplianceMetadata(this.mapMPPTToStrings(mpptDataList)),
|
|
169
|
+
maxPvProductionW: inverterSettings?.WMax
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
console.log(`Sunspec Inverter connected: ${this.networkDevice.hostname} (${this.applianceId})`);
|
|
173
|
+
}
|
|
174
|
+
catch (error) {
|
|
175
|
+
console.error(`Failed to create inverter appliance: ${error}`);
|
|
176
|
+
}
|
|
171
177
|
}
|
|
172
|
-
|
|
173
|
-
|
|
178
|
+
else {
|
|
179
|
+
try {
|
|
180
|
+
const existingAppliance = await this.applianceManager.findApplianceById(this.applianceId);
|
|
181
|
+
await this.applianceManager.updateAppliance(this.applianceId, {
|
|
182
|
+
metadata: {
|
|
183
|
+
...existingAppliance?.metadata,
|
|
184
|
+
connectionType: EnyoApplianceConnectionType.Connector,
|
|
185
|
+
state: EnyoApplianceStateEnum.Connected,
|
|
186
|
+
modbus: { unitId: this.unitId, baseAddress: this.baseAddress },
|
|
187
|
+
},
|
|
188
|
+
inverter: {
|
|
189
|
+
...existingAppliance?.inverter,
|
|
190
|
+
dcStrings: this.mapDcStringToApplianceMetadata(this.mapMPPTToStrings(mpptDataList)),
|
|
191
|
+
maxPvProductionW: inverterSettings?.WMax
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
console.log(`Sunspec Inverter connected: ${this.networkDevice.hostname} (${this.applianceId})`);
|
|
195
|
+
}
|
|
196
|
+
catch (error) {
|
|
197
|
+
console.error(`Failed to update inverter appliance: ${error}`);
|
|
198
|
+
}
|
|
174
199
|
}
|
|
175
200
|
// Check for MPPT models
|
|
176
201
|
const mpptModel = this.sunspecClient.findModel(SunspecModelId.MPPT);
|
|
@@ -186,9 +211,6 @@ export class SunspecInverter extends BaseSunspecDevice {
|
|
|
186
211
|
}
|
|
187
212
|
// Note: We don't disconnect the sunspecClient as it may be shared
|
|
188
213
|
}
|
|
189
|
-
isConnected() {
|
|
190
|
-
return this.sunspecClient.isConnected();
|
|
191
|
-
}
|
|
192
214
|
async readData(clockId, resolution) {
|
|
193
215
|
if (!this.isConnected()) {
|
|
194
216
|
await this.tryReconnect();
|
|
@@ -320,7 +342,7 @@ export class SunspecInverter extends BaseSunspecDevice {
|
|
|
320
342
|
return;
|
|
321
343
|
}
|
|
322
344
|
this.dataBus = this.energyApp.useDataBus();
|
|
323
|
-
this.dataBusListenerId = this.dataBus.listenForMessages([
|
|
345
|
+
this.dataBusListenerId = this.dataBus.listenForMessages([EnyoDataBusMessageEnum.SetInverterFeedInLimitV1], (entry) => this.handleInverterCommand(entry));
|
|
324
346
|
console.log(`Inverter ${this.applianceId}: started data bus listening (listener ${this.dataBusListenerId})`);
|
|
325
347
|
}
|
|
326
348
|
/**
|
|
@@ -340,7 +362,7 @@ export class SunspecInverter extends BaseSunspecDevice {
|
|
|
340
362
|
}
|
|
341
363
|
void (async () => {
|
|
342
364
|
try {
|
|
343
|
-
if (entry.message ===
|
|
365
|
+
if (entry.message === EnyoDataBusMessageEnum.SetInverterFeedInLimitV1) {
|
|
344
366
|
await this.handleSetFeedInLimit(entry);
|
|
345
367
|
}
|
|
346
368
|
}
|
|
@@ -373,8 +395,8 @@ export class SunspecInverter extends BaseSunspecDevice {
|
|
|
373
395
|
*/
|
|
374
396
|
export class SunspecBattery extends BaseSunspecDevice {
|
|
375
397
|
capabilities;
|
|
376
|
-
constructor(energyApp, name, networkDevice, sunspecClient, applianceManager, unitId = 1, port = 502, baseAddress = 40000, capabilities = [], retryConfig) {
|
|
377
|
-
super(energyApp, name, networkDevice, sunspecClient, applianceManager, unitId, port, baseAddress, retryConfig);
|
|
398
|
+
constructor(energyApp, name, networkDevice, sunspecClient, applianceManager, unitId = 1, port = 502, baseAddress = 40000, capabilities = [], retryConfig, appliance) {
|
|
399
|
+
super(energyApp, name, networkDevice, sunspecClient, applianceManager, unitId, port, baseAddress, retryConfig, appliance);
|
|
378
400
|
this.capabilities = capabilities;
|
|
379
401
|
}
|
|
380
402
|
/**
|
|
@@ -394,38 +416,66 @@ export class SunspecBattery extends BaseSunspecDevice {
|
|
|
394
416
|
const batteryData = await this.sunspecClient.readBatteryData();
|
|
395
417
|
const storageMode = this.determineStorageMode(batteryData);
|
|
396
418
|
const features = [];
|
|
397
|
-
// Create or update appliance
|
|
398
419
|
if (batteryData?.chaGriSet !== undefined) {
|
|
399
420
|
features.push(EnyoBatteryFeature.GridCharging);
|
|
400
421
|
}
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
422
|
+
// Create or update appliance (skip if an existing appliance was provided)
|
|
423
|
+
if (!this.applianceId) {
|
|
424
|
+
try {
|
|
425
|
+
this.applianceId = await this.applianceManager.createOrUpdateAppliance({
|
|
426
|
+
name: this.name,
|
|
427
|
+
type: EnyoApplianceTypeEnum.Storage,
|
|
428
|
+
networkDevices: [this.networkDevice],
|
|
429
|
+
metadata: {
|
|
430
|
+
connectionType: EnyoApplianceConnectionType.Connector,
|
|
431
|
+
state: EnyoApplianceStateEnum.Connected,
|
|
432
|
+
serialNumber: commonData?.serialNumber,
|
|
433
|
+
modelName: commonData?.model,
|
|
434
|
+
vendorName: commonData?.manufacturer,
|
|
435
|
+
modbus: { unitId: this.unitId, baseAddress: this.baseAddress },
|
|
436
|
+
},
|
|
437
|
+
battery: {
|
|
438
|
+
connectedToApplianceId: inverterApplianceId,
|
|
439
|
+
storageMode: this.mapToEnyoStorageMode(storageMode),
|
|
440
|
+
maxChargingPowerW: batteryData && batteryData.wChaMax !== undefined && batteryData.inWRte !== undefined ? batteryData.wChaMax * batteryData.inWRte : undefined,
|
|
441
|
+
maxDischargePowerW: batteryData && batteryData.wChaMax !== undefined && batteryData.outWRte !== undefined ? batteryData.wChaMax * batteryData.outWRte : undefined,
|
|
442
|
+
features,
|
|
443
|
+
gridChargingEnabled: batteryData?.chaGriSet === 1
|
|
444
|
+
}
|
|
445
|
+
});
|
|
446
|
+
console.log(`Sunspec Battery connected: ${this.networkDevice.hostname} (${this.applianceId})`);
|
|
447
|
+
}
|
|
448
|
+
catch (error) {
|
|
449
|
+
console.error(`Failed to create battery appliance: ${error}`);
|
|
450
|
+
}
|
|
425
451
|
}
|
|
426
|
-
|
|
427
|
-
|
|
452
|
+
else {
|
|
453
|
+
try {
|
|
454
|
+
const existingAppliance = await this.applianceManager.findApplianceById(this.applianceId);
|
|
455
|
+
await this.applianceManager.updateAppliance(this.applianceId, {
|
|
456
|
+
metadata: {
|
|
457
|
+
...existingAppliance?.metadata,
|
|
458
|
+
connectionType: EnyoApplianceConnectionType.Connector,
|
|
459
|
+
state: EnyoApplianceStateEnum.Connected,
|
|
460
|
+
modbus: { unitId: this.unitId, baseAddress: this.baseAddress },
|
|
461
|
+
},
|
|
462
|
+
battery: {
|
|
463
|
+
...existingAppliance?.battery,
|
|
464
|
+
connectedToApplianceId: inverterApplianceId,
|
|
465
|
+
storageMode: this.mapToEnyoStorageMode(storageMode),
|
|
466
|
+
maxChargingPowerW: batteryData && batteryData.wChaMax !== undefined && batteryData.inWRte !== undefined ? batteryData.wChaMax * batteryData.inWRte : undefined,
|
|
467
|
+
maxDischargePowerW: batteryData && batteryData.wChaMax !== undefined && batteryData.outWRte !== undefined ? batteryData.wChaMax * batteryData.outWRte : undefined,
|
|
468
|
+
features,
|
|
469
|
+
gridChargingEnabled: batteryData?.chaGriSet === 1
|
|
470
|
+
}
|
|
471
|
+
});
|
|
472
|
+
console.log(`Sunspec Battery connected: ${this.networkDevice.hostname} (${this.applianceId})`);
|
|
473
|
+
}
|
|
474
|
+
catch (error) {
|
|
475
|
+
console.error(`Failed to update battery appliance: ${error}`);
|
|
476
|
+
}
|
|
428
477
|
}
|
|
478
|
+
this.startDataBusListening();
|
|
429
479
|
}
|
|
430
480
|
async disconnect() {
|
|
431
481
|
this.stopDataBusListening();
|
|
@@ -866,8 +916,8 @@ export class SunspecBattery extends BaseSunspecDevice {
|
|
|
866
916
|
*/
|
|
867
917
|
export class SunspecMeter extends BaseSunspecDevice {
|
|
868
918
|
capabilities;
|
|
869
|
-
constructor(energyApp, name, networkDevice, sunspecClient, applianceManager, unitId = 1, port = 502, baseAddress = 40000, capabilities = [], retryConfig) {
|
|
870
|
-
super(energyApp, name, networkDevice, sunspecClient, applianceManager, unitId, port, baseAddress, retryConfig);
|
|
919
|
+
constructor(energyApp, name, networkDevice, sunspecClient, applianceManager, unitId = 1, port = 502, baseAddress = 40000, capabilities = [], retryConfig, appliance) {
|
|
920
|
+
super(energyApp, name, networkDevice, sunspecClient, applianceManager, unitId, port, baseAddress, retryConfig, appliance);
|
|
871
921
|
this.capabilities = capabilities;
|
|
872
922
|
}
|
|
873
923
|
/**
|
|
@@ -885,31 +935,50 @@ export class SunspecMeter extends BaseSunspecDevice {
|
|
|
885
935
|
}
|
|
886
936
|
// Get device info
|
|
887
937
|
const commonData = await this.sunspecClient.readCommonBlock();
|
|
888
|
-
// Create or update appliance
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
938
|
+
// Create or update appliance (skip if an existing appliance was provided)
|
|
939
|
+
if (!this.applianceId) {
|
|
940
|
+
try {
|
|
941
|
+
this.applianceId = await this.applianceManager.createOrUpdateAppliance({
|
|
942
|
+
name: this.name,
|
|
943
|
+
type: EnyoApplianceTypeEnum.Meter,
|
|
944
|
+
networkDevices: [this.networkDevice],
|
|
945
|
+
metadata: {
|
|
946
|
+
connectionType: EnyoApplianceConnectionType.Connector,
|
|
947
|
+
state: EnyoApplianceStateEnum.Connected,
|
|
948
|
+
serialNumber: commonData?.serialNumber,
|
|
949
|
+
modelName: commonData?.model,
|
|
950
|
+
vendorName: commonData?.manufacturer,
|
|
951
|
+
modbus: { unitId: this.unitId, baseAddress: this.baseAddress },
|
|
952
|
+
},
|
|
953
|
+
topology: {
|
|
954
|
+
features: [EnyoApplianceTopologyFeatureEnum.IntermediateOfPrimaryMeter]
|
|
955
|
+
},
|
|
956
|
+
meter: {
|
|
957
|
+
availableFeatures: [EnyoMeterApplianceAvailableFeaturesEnum.LivePowerConsumption]
|
|
958
|
+
}
|
|
959
|
+
});
|
|
960
|
+
console.log(`Sunspec Meter connected: ${this.networkDevice.hostname} unit ${this.unitId} (${this.applianceId})`);
|
|
961
|
+
}
|
|
962
|
+
catch (error) {
|
|
963
|
+
console.error(`Failed to create meter appliance: ${error}`);
|
|
964
|
+
}
|
|
910
965
|
}
|
|
911
|
-
|
|
912
|
-
|
|
966
|
+
else {
|
|
967
|
+
try {
|
|
968
|
+
const existingAppliance = await this.applianceManager.findApplianceById(this.applianceId);
|
|
969
|
+
await this.applianceManager.updateAppliance(this.applianceId, {
|
|
970
|
+
metadata: {
|
|
971
|
+
...existingAppliance?.metadata,
|
|
972
|
+
connectionType: EnyoApplianceConnectionType.Connector,
|
|
973
|
+
state: EnyoApplianceStateEnum.Connected,
|
|
974
|
+
modbus: { unitId: this.unitId, baseAddress: this.baseAddress },
|
|
975
|
+
}
|
|
976
|
+
});
|
|
977
|
+
console.log(`Sunspec Meter connected: ${this.networkDevice.hostname} unit ${this.unitId} (${this.applianceId})`);
|
|
978
|
+
}
|
|
979
|
+
catch (error) {
|
|
980
|
+
console.error(`Failed to update meter appliance: ${error}`);
|
|
981
|
+
}
|
|
913
982
|
}
|
|
914
983
|
}
|
|
915
984
|
/**
|
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.44",
|
|
4
4
|
"description": "enyo Energy Sunspec SDK",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"typescript": "^5.8.3"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@enyo-energy/energy-app-sdk": "^0.0.
|
|
40
|
+
"@enyo-energy/energy-app-sdk": "^0.0.89"
|
|
41
41
|
},
|
|
42
42
|
"volta": {
|
|
43
43
|
"node": "22.17.0"
|