@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.
@@ -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 = exports.ENYO_DATA_BUS_SET_INVERTER_FEED_IN_LIMIT_V1 = void 0;
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.isConnected();
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
- try {
157
- this.applianceId = await this.applianceManager.createOrUpdateAppliance({
158
- name: this.name,
159
- type: enyo_appliance_js_1.EnyoApplianceTypeEnum.Inverter,
160
- networkDevices: [this.networkDevice],
161
- metadata: {
162
- connectionType: enyo_appliance_js_1.EnyoApplianceConnectionType.Connector,
163
- state: enyo_appliance_js_1.EnyoApplianceStateEnum.Connected,
164
- serialNumber: commonData?.serialNumber,
165
- modelName: commonData?.model,
166
- vendorName: commonData?.manufacturer,
167
- modbus: { unitId: this.unitId },
168
- },
169
- inverter: {
170
- dcStrings: this.mapDcStringToApplianceMetadata(this.mapMPPTToStrings(mpptDataList)),
171
- maxPvProductionW: inverterSettings?.WMax
172
- }
173
- });
174
- console.log(`Sunspec Inverter connected: ${this.networkDevice.hostname} (${this.applianceId})`);
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
- catch (error) {
177
- console.error(`Failed to create inverter appliance: ${error}`);
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([exports.ENYO_DATA_BUS_SET_INVERTER_FEED_IN_LIMIT_V1], (entry) => this.handleInverterCommand(entry));
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 === exports.ENYO_DATA_BUS_SET_INVERTER_FEED_IN_LIMIT_V1) {
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
- try {
407
- this.applianceId = await this.applianceManager.createOrUpdateAppliance({
408
- name: this.name,
409
- type: enyo_appliance_js_1.EnyoApplianceTypeEnum.Storage,
410
- networkDevices: [this.networkDevice],
411
- metadata: {
412
- connectionType: enyo_appliance_js_1.EnyoApplianceConnectionType.Connector,
413
- state: enyo_appliance_js_1.EnyoApplianceStateEnum.Connected,
414
- serialNumber: commonData?.serialNumber,
415
- modelName: commonData?.model,
416
- vendorName: commonData?.manufacturer,
417
- modbus: { unitId: this.unitId },
418
- },
419
- battery: {
420
- connectedToApplianceId: inverterApplianceId,
421
- storageMode: this.mapToEnyoStorageMode(storageMode),
422
- maxChargingPowerW: batteryData && batteryData.wChaMax !== undefined && batteryData.inWRte !== undefined ? batteryData.wChaMax * batteryData.inWRte : undefined,
423
- maxDischargePowerW: batteryData && batteryData.wChaMax !== undefined && batteryData.outWRte !== undefined ? batteryData.wChaMax * batteryData.outWRte : undefined,
424
- features,
425
- gridChargingEnabled: batteryData?.chaGriSet === 1
426
- }
427
- });
428
- console.log(`Sunspec Battery connected: ${this.networkDevice.hostname} (${this.applianceId})`);
429
- this.startDataBusListening();
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
- catch (error) {
432
- console.error(`Failed to create battery appliance: ${error}`);
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
- try {
896
- this.applianceId = await this.applianceManager.createOrUpdateAppliance({
897
- name: this.name,
898
- type: enyo_appliance_js_1.EnyoApplianceTypeEnum.Meter,
899
- networkDevices: [this.networkDevice],
900
- metadata: {
901
- connectionType: enyo_appliance_js_1.EnyoApplianceConnectionType.Connector,
902
- state: enyo_appliance_js_1.EnyoApplianceStateEnum.Connected,
903
- serialNumber: commonData?.serialNumber,
904
- modelName: commonData?.model,
905
- vendorName: commonData?.manufacturer,
906
- modbus: { unitId: this.unitId },
907
- },
908
- topology: {
909
- features: [enyo_appliance_js_1.EnyoApplianceTopologyFeatureEnum.IntermediateOfPrimaryMeter]
910
- },
911
- meter: {
912
- availableFeatures: [enyo_meter_appliance_js_1.EnyoMeterApplianceAvailableFeaturesEnum.LivePowerConsumption]
913
- }
914
- });
915
- console.log(`Sunspec Meter connected: ${this.networkDevice.hostname} unit ${this.unitId} (${this.applianceId})`);
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
- catch (error) {
918
- console.error(`Failed to create meter appliance: ${error}`);
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 SunspecBatteryBaseData, type SunspecBatteryControls, SunspecStorageMode, SunspecInverterCapability, SunspecBatteryCapability, SunspecMeterCapability } from "./sunspec-interfaces.cjs";
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
  */
@@ -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.42';
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
@@ -5,7 +5,7 @@
5
5
  /**
6
6
  * Current version of the enyo Energy App SDK.
7
7
  */
8
- export declare const SDK_VERSION = "0.0.42";
8
+ export declare const SDK_VERSION = "0.0.44";
9
9
  /**
10
10
  * Gets the current SDK version.
11
11
  * @returns The semantic version string of the SDK
@@ -1,22 +1,11 @@
1
- import { type SunspecBatteryBaseData, type SunspecBatteryControls, SunspecStorageMode, SunspecInverterCapability, SunspecBatteryCapability, SunspecMeterCapability } from "./sunspec-interfaces.js";
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
  */
@@ -1,4 +1,4 @@
1
- import { SunspecBatteryChargeState, SunspecModelId, SunspecMPPTOperatingState, SunspecStorageMode, SunspecInverterCapability } from "./sunspec-interfaces.js";
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.isConnected();
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
- try {
153
- this.applianceId = await this.applianceManager.createOrUpdateAppliance({
154
- name: this.name,
155
- type: EnyoApplianceTypeEnum.Inverter,
156
- networkDevices: [this.networkDevice],
157
- metadata: {
158
- connectionType: EnyoApplianceConnectionType.Connector,
159
- state: EnyoApplianceStateEnum.Connected,
160
- serialNumber: commonData?.serialNumber,
161
- modelName: commonData?.model,
162
- vendorName: commonData?.manufacturer,
163
- modbus: { unitId: this.unitId },
164
- },
165
- inverter: {
166
- dcStrings: this.mapDcStringToApplianceMetadata(this.mapMPPTToStrings(mpptDataList)),
167
- maxPvProductionW: inverterSettings?.WMax
168
- }
169
- });
170
- console.log(`Sunspec Inverter connected: ${this.networkDevice.hostname} (${this.applianceId})`);
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
- catch (error) {
173
- console.error(`Failed to create inverter appliance: ${error}`);
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([ENYO_DATA_BUS_SET_INVERTER_FEED_IN_LIMIT_V1], (entry) => this.handleInverterCommand(entry));
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 === ENYO_DATA_BUS_SET_INVERTER_FEED_IN_LIMIT_V1) {
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
- try {
402
- this.applianceId = await this.applianceManager.createOrUpdateAppliance({
403
- name: this.name,
404
- type: EnyoApplianceTypeEnum.Storage,
405
- networkDevices: [this.networkDevice],
406
- metadata: {
407
- connectionType: EnyoApplianceConnectionType.Connector,
408
- state: EnyoApplianceStateEnum.Connected,
409
- serialNumber: commonData?.serialNumber,
410
- modelName: commonData?.model,
411
- vendorName: commonData?.manufacturer,
412
- modbus: { unitId: this.unitId },
413
- },
414
- battery: {
415
- connectedToApplianceId: inverterApplianceId,
416
- storageMode: this.mapToEnyoStorageMode(storageMode),
417
- maxChargingPowerW: batteryData && batteryData.wChaMax !== undefined && batteryData.inWRte !== undefined ? batteryData.wChaMax * batteryData.inWRte : undefined,
418
- maxDischargePowerW: batteryData && batteryData.wChaMax !== undefined && batteryData.outWRte !== undefined ? batteryData.wChaMax * batteryData.outWRte : undefined,
419
- features,
420
- gridChargingEnabled: batteryData?.chaGriSet === 1
421
- }
422
- });
423
- console.log(`Sunspec Battery connected: ${this.networkDevice.hostname} (${this.applianceId})`);
424
- this.startDataBusListening();
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
- catch (error) {
427
- console.error(`Failed to create battery appliance: ${error}`);
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
- try {
890
- this.applianceId = await this.applianceManager.createOrUpdateAppliance({
891
- name: this.name,
892
- type: EnyoApplianceTypeEnum.Meter,
893
- networkDevices: [this.networkDevice],
894
- metadata: {
895
- connectionType: EnyoApplianceConnectionType.Connector,
896
- state: EnyoApplianceStateEnum.Connected,
897
- serialNumber: commonData?.serialNumber,
898
- modelName: commonData?.model,
899
- vendorName: commonData?.manufacturer,
900
- modbus: { unitId: this.unitId },
901
- },
902
- topology: {
903
- features: [EnyoApplianceTopologyFeatureEnum.IntermediateOfPrimaryMeter]
904
- },
905
- meter: {
906
- availableFeatures: [EnyoMeterApplianceAvailableFeaturesEnum.LivePowerConsumption]
907
- }
908
- });
909
- console.log(`Sunspec Meter connected: ${this.networkDevice.hostname} unit ${this.unitId} (${this.applianceId})`);
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
- catch (error) {
912
- console.error(`Failed to create meter appliance: ${error}`);
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
@@ -5,7 +5,7 @@
5
5
  /**
6
6
  * Current version of the enyo Energy App SDK.
7
7
  */
8
- export declare const SDK_VERSION = "0.0.42";
8
+ export declare const SDK_VERSION = "0.0.44";
9
9
  /**
10
10
  * Gets the current SDK version.
11
11
  * @returns The semantic version string of the SDK
package/dist/version.js CHANGED
@@ -5,7 +5,7 @@
5
5
  /**
6
6
  * Current version of the enyo Energy App SDK.
7
7
  */
8
- export const SDK_VERSION = '0.0.42';
8
+ export const SDK_VERSION = '0.0.44';
9
9
  /**
10
10
  * Gets the current SDK version.
11
11
  * @returns The semantic version string of the SDK
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@enyo-energy/sunspec-sdk",
3
- "version": "0.0.42",
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.85"
40
+ "@enyo-energy/energy-app-sdk": "^0.0.89"
41
41
  },
42
42
  "volta": {
43
43
  "node": "22.17.0"