homebridge-enphase-envoy 10.3.1-beta.1 → 10.3.1-beta.11

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.
@@ -1432,8 +1432,7 @@
1432
1432
  ]
1433
1433
  }
1434
1434
  ],
1435
- "description": "Accessory type for Home app",
1436
- "required": true
1435
+ "description": "Accessory type for Home app"
1437
1436
  },
1438
1437
  "name": {
1439
1438
  "title": "Accessory name",
@@ -3066,7 +3065,6 @@
3066
3065
  ]
3067
3066
  }
3068
3067
  ],
3069
- "required": true,
3070
3068
  "condition": {
3071
3069
  "functionBody": "return model.devices[arrayIndices[0]].generatorModeControls[arrayIndices[1]].displayType > 0;"
3072
3070
  }
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "private": false,
3
3
  "displayName": "Enphase Envoy",
4
4
  "name": "homebridge-enphase-envoy",
5
- "version": "10.3.1-beta.1",
5
+ "version": "10.3.1-beta.11",
6
6
  "description": "Homebridge p7ugin for Photovoltaic Energy System manufactured by Enphase.",
7
7
  "license": "MIT",
8
8
  "author": "grzegorz914",
@@ -36,7 +36,7 @@
36
36
  },
37
37
  "dependencies": {
38
38
  "async-mqtt": "^2.6.3",
39
- "axios": "^1.12.2",
39
+ "axios": "^1.13.1",
40
40
  "express": "^5.1.0",
41
41
  "fast-xml-parser": "^5.3.0",
42
42
  "fakegato-history": "^0.6.7"
package/src/constants.js CHANGED
@@ -174,13 +174,10 @@ export const ApiCodes = {
174
174
  "ENCHG_STATE_DISCHARGING": "Encharge state discharging",
175
175
  "ENCHG_STATE_IDLE": "Encharge state idle",
176
176
  "ENCHG_STATE_READY": "Encharge state ready",
177
- "ENCMN_MDE_BMU_READY": "Encharge BMU ready",
178
177
  "ENCMN_MDE_ENCHARGE_READY": "Encharge mode ready",
179
178
  "ENCMN_MDE_ON_GRID": "Encharge mode on grid",
180
179
  "ENCMN_MDE_OFF_GRID": "Encharge mode off grid",
181
- "ENCMN_MDE_PCU_READY": "Encharge Microinverter ready",
182
180
  "ENCMN_C6_CC_READY": "C6 Combiner Controller ready",
183
- "ENCMN_C6_RGM_DEV_CONNECTED": "C6 Revenue Grade Meter connected",
184
181
  "ENPOWER": "Enpower",
185
182
  "ENS_DEVICE_STATE_READY": "Ensemble state ready",
186
183
  "ENPWR_STATE_GRIDMODE_CONFIRM": "Enpower state grid mode confirm",
@@ -205,7 +202,6 @@ export const ApiCodes = {
205
202
  "check-wiring": "Check Wiring",
206
203
  "close": "Close",
207
204
  "closed": "Closed",
208
- "configured": "Configured",
209
205
  "connected": "Connected",
210
206
  "consumption": "Consumption Net",
211
207
  "discharging": "Discharging",
@@ -1554,6 +1554,22 @@ export default (api) => {
1554
1554
  }
1555
1555
  Characteristic.EncAggSoc = EncAggSoc;
1556
1556
 
1557
+ class EncAggRatedPower extends Characteristic {
1558
+ constructor() {
1559
+ super('ENC rated power', '00000208-000B-1000-8000-0026BB765291');
1560
+ this.setProps({
1561
+ format: Formats.FLOAT,
1562
+ unit: 'kW',
1563
+ maxValue: 1000,
1564
+ minValue: -1000,
1565
+ minStep: 0.001,
1566
+ perms: [Perms.PAIRED_READ, Perms.NOTIFY]
1567
+ });
1568
+ this.value = this.getDefaultValue();
1569
+ }
1570
+ }
1571
+ Characteristic.EncAggRatedPower = EncAggRatedPower;
1572
+
1557
1573
  class EncAggBackupEnergy extends Characteristic {
1558
1574
  constructor() {
1559
1575
  super('ENC backup energy', '00000209-000B-1000-8000-0026BB765291');
package/src/envoydata.js CHANGED
@@ -338,6 +338,7 @@ class EnvoyData extends EventEmitter {
338
338
  devices: [],
339
339
  settings: {},
340
340
  tariff: {},
341
+ tariffRaw: {},
341
342
  ratedPowerSumKw: null,
342
343
  realPowerSumKw: null,
343
344
  phaseA: false,
@@ -412,7 +413,7 @@ class EnvoyData extends EventEmitter {
412
413
  .on('updateEnsemble', () => this.handleWithLock('updateEnsemble', async () => {
413
414
  const updateEnsemble = this.feature.ensemble.inventory.supported ? await this.updateEnsembleInventory() : false;
414
415
  if (updateEnsemble && this.feature.ensemble.status.supported) await this.updateEnsembleStatus();
415
- if (updateEnsemble && this.feature.ensemble.power.supported) await this.updateEnsemblePower();
416
+ if (updateEnsemble && this.feature.inventory.esubs.encharges.power.supported) await this.updateEnsemblePower();
416
417
 
417
418
  const updateEnchargeSettings = updateEnsemble && this.feature.inventory.esubs.encharges.settings.supported ? await this.updateEnchargesSettings() : false;
418
419
  if (updateEnchargeSettings && this.feature.inventory.esubs.encharges.tariff.supported) await this.updateTariff();
@@ -587,13 +588,12 @@ class EnvoyData extends EventEmitter {
587
588
  // Load token from file on startup, only if mode is 1
588
589
  if (this.envoyFirmware7xxTokenGenerationMode === 1 && start) {
589
590
  try {
590
- const data = await this.functions.readData(this.envoyTokenFile);
591
+ const data = await this.functions.readData(this.envoyTokenFile, true);
591
592
  try {
592
- const parsedData = JSON.parse(data);
593
- const fileTokenExist = parsedData.token ? 'Exist' : 'Missing';
593
+ const fileTokenExist = data.token ? 'Exist' : 'Missing';
594
594
  if (this.logDebug) this.emit('debug', `Token from file: ${fileTokenExist}`);
595
- if (parsedData.token) {
596
- this.feature.info.jwtToken = parsedData;
595
+ if (data.token) {
596
+ this.feature.info.jwtToken = data;
597
597
  }
598
598
  } catch (error) {
599
599
  if (this.logWarn) this.emit('warn', `Token parse error: ${error}`);
@@ -1962,7 +1962,7 @@ class EnvoyData extends EventEmitter {
1962
1962
  };
1963
1963
 
1964
1964
  // Calculate encharges rated power summary in kW
1965
- this.pv.inventory.esubs.encharges.ratedPowerSumKw = enchargesRatedPowerSummary.length > 0 ? enchargesRatedPowerSummary.reduce((total, num) => total + num, 0) / 1000 : null;
1965
+ this.pv.inventory.esubs.encharges.ratedPowerSumKw = enchargesRatedPowerSummary.length > 0 ? (enchargesRatedPowerSummary.reduce((total, num) => total + num, 0) / enchargesRatedPowerSummary.length) / 1000 : null;
1966
1966
  }
1967
1967
 
1968
1968
  // Update enpowers statuses if installed
@@ -2038,17 +2038,18 @@ class EnvoyData extends EventEmitter {
2038
2038
 
2039
2039
  try {
2040
2040
  const response = await this.axiosInstance.get(ApiUrls.EnsemblePower);
2041
- const responseData = response.data ?? {};
2041
+ const responseData = response.data;
2042
2042
  if (this.logDebug) this.emit('debug', `Ensemble power response:`, responseData);
2043
2043
 
2044
- const devices = responseData.devices || [];
2045
- if (devices.length === 0) return false;
2044
+ const devices = responseData.devices ?? [];
2045
+ if (!devices.length === 0) return false;
2046
2046
 
2047
2047
  // update encharges
2048
2048
  const enchargesRealPowerSummary = [];
2049
2049
  const encharges = this.pv.inventory.esubs.encharges.devices || [];
2050
- for (const encharge of encharges) {
2051
- const device = devices.find(device => device.serial_num === encharge.serialNumber);
2050
+ for (const device of devices) {
2051
+ const serialNumber = device.serial_num;
2052
+ const encharge = encharges.find(device => device.serialNumber === serialNumber);
2052
2053
  if (this.logDebug) this.emit('debug', `Ensemble device power:`, device);
2053
2054
  if (!device) continue;
2054
2055
 
@@ -2059,12 +2060,12 @@ class EnvoyData extends EventEmitter {
2059
2060
  soc: device.soc,
2060
2061
  };
2061
2062
 
2062
- this.feature.inventory.esubs.encharges.power.supported = true;
2063
2063
  if (this.functions.isValidValue(encharge.power.realPower)) enchargesRealPowerSummary.push(encharge.power.realPower);
2064
+ this.feature.inventory.esubs.encharges.power.supported = true;
2064
2065
  }
2065
2066
 
2066
2067
  // Calculate encharges real power summary in kW
2067
- this.pv.inventory.esubs.encharges.realPowerSumKw = enchargesRealPowerSummary.length > 0 ? enchargesRealPowerSummary.reduce((total, num) => total + num, 0) / 1000000 : null;
2068
+ this.pv.inventory.esubs.encharges.realPowerSumKw = enchargesRealPowerSummary.length > 0 ? (enchargesRealPowerSummary.reduce((total, num) => total + num, 0) / enchargesRealPowerSummary.length) / 1000 : null;
2068
2069
 
2069
2070
  // ensemble power supported
2070
2071
  this.feature.ensemble.power.supported = true;
@@ -2090,14 +2091,15 @@ class EnvoyData extends EventEmitter {
2090
2091
  const enchargesSettingsSupported = 'enc_settings' in enchargesSettings;
2091
2092
  if (!enchargesSettingsSupported) return false;
2092
2093
 
2093
- const settings = {
2094
- enable: enchargesSettings.enc_settings.enable, // boolean
2095
- country: enchargesSettings.enc_settings.country, // string
2096
- currentLimit: enchargesSettings.enc_settings.current_limit, // float
2097
- perPhase: enchargesSettings.enc_settings.per_phase // boolean
2094
+ const settings = enchargesSettings.enc_settings;
2095
+ const encharges = this.pv.inventory.esubs.encharges;
2096
+ encharges.settings = {
2097
+ enable: settings.enable, // boolean
2098
+ country: settings.country, // string
2099
+ currentLimit: settings.current_limit, // float
2100
+ perPhase: settings.per_phase // boolean
2098
2101
  };
2099
2102
 
2100
- this.pv.inventory.esubs.encharges.settings = settings;
2101
2103
  this.feature.inventory.esubs.encharges.settings.supported = true;
2102
2104
 
2103
2105
  // RESTFul and MQTT update
@@ -2116,11 +2118,12 @@ class EnvoyData extends EventEmitter {
2116
2118
  try {
2117
2119
  const response = await this.axiosInstance.get(ApiUrls.TariffSettingsGetPut);
2118
2120
  const tariffSettings = response.data;
2121
+
2119
2122
  if (this.logDebug) this.emit('debug', 'Tariff:', tariffSettings);
2120
2123
 
2121
2124
  const enchargesTariffSupported = 'tariff' in tariffSettings;
2122
2125
  if (!enchargesTariffSupported) return false;
2123
-
2126
+ this.pv.inventory.esubs.encharges.tariffRaw = tariffSettings;
2124
2127
  this.pv.inventory.esubs.encharges.tariff = tariffSettings;
2125
2128
  this.feature.inventory.esubs.encharges.tariff.supported = true;
2126
2129
 
@@ -2545,7 +2548,7 @@ class EnvoyData extends EventEmitter {
2545
2548
  if (this.logDebug) this.emit('debug', `Requesting set encharge settings`);
2546
2549
 
2547
2550
  try {
2548
- const tariff = this.pv.inventory.esubs.encharges.tariff.tariff;
2551
+ const tariff = this.pv.inventory.esubs.encharges.tariffRaw.tariff;
2549
2552
  tariff.storage_settings.mode = profile;
2550
2553
  tariff.storage_settings.reserved_soc = reservedSoc;
2551
2554
  tariff.storage_settings.charge_from_grid = chargeFromGrid;
@@ -2771,16 +2774,12 @@ class EnvoyData extends EventEmitter {
2771
2774
  const getEnsemble = tokenRequired && this.feature.inventory.esubs.supported ? await this.updateEnsembleInventory() : false;
2772
2775
  if (getEnsemble) {
2773
2776
  await this.updateEnsembleStatus();
2774
- if (this.feature.inventory.esubs.encharges.installed) {
2775
- await this.updateEnsemblePower();
2776
- await this.updateEnchargesSettings();
2777
- await this.updateTariff();
2778
- }
2777
+ if (this.feature.inventory.esubs.encharges.installed) await this.updateEnsemblePower();
2778
+ const getEnchargeSettings = this.feature.inventory.esubs.encharges.installed ? await this.updateEnchargesSettings() : false;
2779
+ if (getEnchargeSettings) await this.updateTariff();
2779
2780
 
2780
- if (this.feature.inventory.esubs.enpowers.installed) {
2781
- await this.updateDryContacts();
2782
- await this.updateDryContactsSettings();
2783
- }
2781
+ const getDryContacts = this.feature.inventory.esubs.enpowers.installed ? await this.updateDryContacts() : false;
2782
+ if (getDryContacts) await this.updateDryContactsSettings();
2784
2783
 
2785
2784
  const getGenerator = await this.updateGenerator();
2786
2785
  if (getGenerator && this.feature.inventory.esubs.generator.installed) await this.updateGeneratorSettings();
@@ -1988,8 +1988,8 @@ class EnvoyDevice extends EventEmitter {
1988
1988
  }
1989
1989
 
1990
1990
  if (ensemblesCountersSupported) characteristics.push({ type: Characteristic.RestPower, label: 'rest power', value: counters.restPowerKw, unit: 'kW' });
1991
- if (enchargesStatusSupported) characteristics.push({ type: Characteristic.RatedPower, label: 'rated power', value: this.pv.inventoryData.esubs.encharges.ratedPowerSumKw, unit: 'kW' });
1992
- if (enchargesPowerSupported) characteristics.push({ type: Characteristic.RealPower, label: 'real power', value: this.pv.inventoryData.esubs.encharges.realPowerSumKw, unit: 'kW' });
1991
+ if (enchargesStatusSupported) characteristics.push({ type: Characteristic.RatedPower, label: 'rated power', value: this.pv.inventoryData.esubs.ratedPowerSumKw, unit: 'kW' });
1992
+ if (enchargesPowerSupported) characteristics.push({ type: Characteristic.RealPower, label: 'real power', value: this.pv.inventoryData.esubs.realPowerSumKw, unit: 'kW' });
1993
1993
 
1994
1994
  for (const { type, label, value, unit = '', postfix = '' } of characteristics) {
1995
1995
  if (!this.functions.isValidValue(value)) continue;
@@ -2257,14 +2257,22 @@ class EnvoyDevice extends EventEmitter {
2257
2257
  { type: Characteristic.ReadingTime, label: 'reading time', value: encharge.readingTime },
2258
2258
  ];
2259
2259
 
2260
- if (gridProfileSupported) characteristics.push({ type: Characteristic.GridProfile, label: 'grid profile', value: encharge.gridProfile });
2260
+ if (gridProfileSupported) {
2261
+ characteristics.push(
2262
+ { type: Characteristic.GridProfile, label: 'grid profile', value: encharge.gridProfile }
2263
+ );
2264
+ }
2265
+
2261
2266
  if (enchargesStatusSupported && encharge.status) {
2262
2267
  characteristics.push(
2263
2268
  { type: Characteristic.CommInterface, label: 'comm interface', value: encharge.status.commInterfaceStr },
2264
2269
  { type: Characteristic.RatedPower, label: 'rated power', value: encharge.status.ratedPowerKw, unit: 'kW' }
2265
2270
  );
2266
2271
  }
2267
- if (enchargesPowerSupported && encharge.power) characteristics.push({ type: Characteristic.RealPower, label: 'real power', value: encharge.power.realPowerKw, unit: 'kW' });
2272
+
2273
+ if (enchargesPowerSupported && encharge.power) {
2274
+ characteristics.push({ type: Characteristic.RealPower, label: 'real power', value: encharge.power.realPowerKw, unit: 'kW' });
2275
+ }
2268
2276
 
2269
2277
  for (const { type, label, value, unit = '', postfix = '' } of characteristics) {
2270
2278
  if (!this.functions.isValidValue(value)) continue;
@@ -2391,23 +2399,24 @@ class EnvoyDevice extends EventEmitter {
2391
2399
  if (this.logDebug) this.emit('debug', `Prepare ${enchargeName} Profile Sensor Services`);
2392
2400
 
2393
2401
  this.enchargeProfileSensorsServices = [];
2402
+
2394
2403
  for (let i = 0; i < this.enchargeProfileSensors.length; i++) {
2395
2404
  const sensor = this.enchargeProfileSensors[i];
2396
2405
  const { namePrefix, name, serviceType, characteristicType } = sensor;
2397
2406
  const serviceName = namePrefix ? `${accessoryName} ${name}` : name;
2398
2407
 
2399
- const sensorService = accessory.addService(serviceType, serviceName, `enchargeProfileSensorService${i}`);
2400
- sensorService.addOptionalCharacteristic(Characteristic.ConfiguredName);
2401
- sensorService.setCharacteristic(Characteristic.ConfiguredName, serviceName);
2408
+ const service = accessory.addService(serviceType, serviceName, `enchargeProfileSensorService${i}`);
2409
+ service.addOptionalCharacteristic(Characteristic.ConfiguredName);
2410
+ service.setCharacteristic(Characteristic.ConfiguredName, serviceName);
2402
2411
 
2403
- sensorService.getCharacteristic(characteristicType)
2412
+ service.getCharacteristic(characteristicType)
2404
2413
  .onGet(async () => {
2405
2414
  const currentState = sensor.state;
2406
2415
  if (this.logInfo) this.emit('info', `${enchargeName} profile: ${name}, state: ${currentState ? 'Active' : 'Not Active'}`);
2407
2416
  return currentState;
2408
2417
  });
2409
2418
 
2410
- this.enchargeProfileSensorsServices.push(sensorService);
2419
+ this.enchargeProfileSensorsServices.push(service);
2411
2420
  }
2412
2421
  }
2413
2422
  }
@@ -2686,7 +2695,7 @@ class EnvoyDevice extends EventEmitter {
2686
2695
  { type: Characteristic.AdminState, label: 'admin state', value: collar.adminStateStr },
2687
2696
  { type: Characteristic.Status, label: 'status', value: collar.deviceStatus },
2688
2697
  { type: Characteristic.MidState, label: 'mid state', value: collar.midState },
2689
- { type: Characteristic.GridState, label: 'grid state', value: collar.gridState },
2698
+ { type: Characteristic.GridState, label: 'mid state', value: collar.gridState },
2690
2699
  { type: Characteristic.Communicating, label: 'communicating', value: collar.communicating, postfix: collar.communicating ? 'Yes' : 'No' },
2691
2700
  { type: Characteristic.Temperature, label: 'temperature', value: collar.temperature, unit: '°C' },
2692
2701
  { type: Characteristic.ReadingTime, label: 'reading time', value: collar.readingTime }
@@ -3518,16 +3527,10 @@ class EnvoyDevice extends EventEmitter {
3518
3527
  powerPeak: pcu.powerPeak,
3519
3528
  });
3520
3529
 
3521
- if (this.logInfo) {
3522
- this.emit('info', `Microinverter, ${pcuData.serialNumber}, power: ${pcuData.power} W`);
3523
- this.emit('info', `Microinverter, ${pcuData.serialNumber}, phase: ${pcuData.phase}`);
3524
- }
3525
-
3526
3530
  // Add characteristics
3527
3531
  characteristics.push(
3528
3532
  { type: Characteristic.PowerW, value: pcuData.power },
3529
- { type: Characteristic.PowerPeakW, value: pcuData.powerPeak }
3530
- );
3533
+ { type: Characteristic.PowerPeakW, value: pcuData.powerPeak });
3531
3534
  }
3532
3535
 
3533
3536
  // Add detailed info if supported
@@ -3627,9 +3630,9 @@ class EnvoyDevice extends EventEmitter {
3627
3630
  plcLevel: nsrb.plcLevel,
3628
3631
  };
3629
3632
 
3630
- if (this.logInfo) {
3631
- this.emit('info', `Q-Relay, ${nsrbData.serialNumber}, state: ${nsrbData.relay}`);
3632
- this.emit('info', `Q-Relay, ${nsrbData.serialNumber}, lines: ${nsrbData.linesCount}`);
3633
+ if (this.logDebug) {
3634
+ this.emit('debug', `Q-Rela state:`, nsrbData.relay);
3635
+ this.emit('debug', `Q-Relay lines:`, nsrbData.linesCount);
3633
3636
  }
3634
3637
 
3635
3638
  // Create characteristics
@@ -4332,10 +4335,10 @@ class EnvoyDevice extends EventEmitter {
4332
4335
  // Add to ensemble summary characteristics if live data not supported
4333
4336
  if (!this.feature.liveData.supported || !this.feature.meters.storage.enabled) {
4334
4337
  ensembleSummaryCharacteristics.push(
4335
- { type: Characteristic.AggSoc, value: secctrl.aggSoc },
4336
4338
  { type: Characteristic.AggMaxEnergy, value: secctrl.aggMaxEnergyKw },
4337
- { type: Characteristic.EncAggSoc, value: secctrl.encAggSoc },
4338
- { type: Characteristic.EncAggBackupEnergy, value: secctrl.encAggBackupEnergy });
4339
+ { type: Characteristic.EncAggBackupEnergy, value: secctrl.encAggBackupEnergy },
4340
+ { type: Characteristic.AggSoc, value: secctrl.aggSoc },
4341
+ { type: Characteristic.encAggSoc, value: secctrl.encAggSoc });
4339
4342
  }
4340
4343
 
4341
4344
  if (phaseA) {
@@ -4833,8 +4836,8 @@ class EnvoyDevice extends EventEmitter {
4833
4836
  const info = tariffData.tariff ?? {};
4834
4837
  const tariff = {};
4835
4838
  tariff.info = {
4836
- currencyCode: info.currency.code,
4837
- logger: info.logger,
4839
+ currencyCode: info.currency.code ?? '',
4840
+ logger: info.logger ?? '',
4838
4841
  date: this.functions.formatTimestamp(info.date, this.pv.homeData.timeZone),
4839
4842
  };
4840
4843
 
@@ -4842,7 +4845,7 @@ class EnvoyDevice extends EventEmitter {
4842
4845
  const s = info.storage_settings ?? {};
4843
4846
  tariff.storageSettings = {
4844
4847
  mode: s.mode,
4845
- operationModeSubType: s.operation_mode_sub_type,
4848
+ operationModeSubType: s.operation_mode_sub_type ?? '',
4846
4849
  reservedSoc: s.reserved_soc,
4847
4850
  veryLowSoc: s.very_low_soc,
4848
4851
  chargeFromGrid: !!s.charge_from_grid,
@@ -4889,16 +4892,16 @@ class EnvoyDevice extends EventEmitter {
4889
4892
  // Schedule
4890
4893
  const sched = tariffData.schedule ?? {};
4891
4894
  tariff.schedule = {
4892
- fileName: sched.filename,
4893
- source: sched.source,
4895
+ fileName: sched.filename ?? '',
4896
+ source: sched.source ?? '',
4894
4897
  date: this.functions.formatTimestamp(sched.date, this.pv.homeData.timeZone),
4895
- version: sched.version,
4898
+ version: sched.version ?? '',
4896
4899
  reservedSoc: sched.reserved_soc,
4897
4900
  veryLowSoc: sched.very_low_soc,
4898
4901
  chargeFromGrid: !!sched.charge_from_grid,
4899
- battMode: sched.batt_mode,
4900
- batteryMode: sched.battery_mode,
4901
- operationModeSubType: sched.operation_mode_sub_type,
4902
+ battMode: sched.batt_mode ?? '',
4903
+ batteryMode: sched.battery_mode ?? '',
4904
+ operationModeSubType: sched.operation_mode_sub_type ?? '',
4902
4905
  override: !!sched.override,
4903
4906
  overrideBackupSoc: sched.override_backup_soc,
4904
4907
  overrideChgDischargeRate: sched.override_chg_discharge_rate,
@@ -5071,8 +5074,8 @@ class EnvoyDevice extends EventEmitter {
5071
5074
  gridActionBool: settings.gridAction !== 'none',
5072
5075
  microGridAction: settings.microGridAction,
5073
5076
  genAction: settings.genAction,
5074
- essentialStartTime: settings.essentialStartTime,
5075
- essentialEndTime: settings.essentialEndTime,
5077
+ essentialStartTime: settings.essentialStartTime ?? '',
5078
+ essentialEndTime: settings.essentialEndTime ?? '',
5076
5079
  priority: settings.priority,
5077
5080
  blackSStart: settings.blackSStart,
5078
5081
  override: settings.override ?? 'false',
@@ -5590,8 +5593,8 @@ class EnvoyDevice extends EventEmitter {
5590
5593
 
5591
5594
  // Agg Energy and Soc
5592
5595
  const characteristics = [
5593
- { type: Characteristic.AggSoc, value: percentFullSum, valueKey: 'aggSoc' },
5594
5596
  { type: Characteristic.AggMaxEnergy, value: energySumKw, valueKey: 'aggMaxEnergyKw' },
5597
+ { type: Characteristic.AggSoc, value: percentFullSum, valueKey: 'aggSoc' },
5595
5598
  ];
5596
5599
 
5597
5600
  // Update storage summary services
@@ -5660,8 +5663,8 @@ class EnvoyDevice extends EventEmitter {
5660
5663
  // Update ensemble summary service
5661
5664
  if (this.feature.inventory.esubs.secctrl.supported) {
5662
5665
  const characteristics = [
5663
- { type: Characteristic.EncAggSoc, value: percentFullSumEnc, valueKey: 'encAggSoc' },
5664
5666
  { type: Characteristic.EncAggBackupEnergy, value: energySumEncKw, valueKey: 'encAggBackupEnergy' },
5667
+ { type: Characteristic.EncAggSoc, value: percentFullSumEnc, valueKey: 'encAggSoc' },
5665
5668
  ];
5666
5669
 
5667
5670
  // Update storage summary services
package/src/functions.js CHANGED
@@ -17,12 +17,33 @@ class Functions {
17
17
  }
18
18
  }
19
19
 
20
- async readData(path) {
20
+ async readData(path, parseJson = false) {
21
21
  try {
22
- const data = await fsPromises.readFile(path);
22
+ const data = await fsPromises.readFile(path, 'utf8');
23
+
24
+ if (parseJson) {
25
+ if (!data.trim()) {
26
+ // Empty file when expecting JSON
27
+ return null;
28
+ }
29
+ try {
30
+ return JSON.parse(data);
31
+ } catch (jsonError) {
32
+ throw new Error(`JSON parse error in file "${path}": ${jsonError.message}`);
33
+ }
34
+ }
35
+
36
+ // For non-JSON, just return file content (can be empty string)
23
37
  return data;
24
38
  } catch (error) {
25
- throw new Error(`Read data error: ${error}`);
39
+ if (error.code === 'ENOENT') {
40
+ // File does not exist
41
+ return null;
42
+ }
43
+ // Preserve original error details
44
+ const wrappedError = new Error(`Read data error for "${path}": ${error.message}`);
45
+ wrappedError.original = error;
46
+ throw wrappedError;
26
47
  }
27
48
  }
28
49