homebridge-enphase-envoy 9.3.4 → 9.3.5

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/CHANGELOG.md CHANGED
@@ -5,6 +5,16 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [9.3.5] - (31.08.2024)
9
+
10
+ ## Changes
11
+
12
+ - required upcomming homebridge 2.x.x required
13
+ - fix [#153](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/153)
14
+ - error handle improvements
15
+ - increase axios timeout to 25sec
16
+ - cleanup
17
+
8
18
  ## [9.3.4] - (27.08.2024)
9
19
 
10
20
  ## Changes
package/index.js CHANGED
@@ -14,7 +14,7 @@ class EnvoyPlatform {
14
14
  }
15
15
  this.accessories = [];
16
16
 
17
- api.on('didFinishLaunching', () => {
17
+ api.on('didFinishLaunching', async () => {
18
18
  for (const device of config.devices) {
19
19
  const deviceName = device.name ?? false;
20
20
  const envoyFirmware7xx = device.envoyFirmware7xx || false;
@@ -83,41 +83,53 @@ class EnvoyPlatform {
83
83
  }
84
84
 
85
85
  //envoy device
86
- const envoyDevice = new EnvoyDevice(api, deviceName, host, envoyFirmware7xx, envoyFirmware7xxTokenGenerationMode, envoyPasswd, envoyToken, envoySerialNumber, enlightenUser, enlightenPasswd, envoyIdFile, envoyTokenFile, envoyInstallerPasswordFile, device);
87
- envoyDevice.on('publishAccessory', (accessory) => {
88
- api.publishExternalAccessories(CONSTANTS.PluginName, [accessory]);
89
- log.success(`Device: ${host} ${deviceName}, published as external accessory.`);
90
- })
91
- .on('devInfo', (devInfo) => {
92
- log.info(devInfo);
93
- })
94
- .on('success', (message) => {
95
- log.success(`Device: ${host} ${deviceName}, ${message}`);
96
- })
97
- .on('message', (message) => {
98
- log.info(`Device: ${host} ${deviceName}, ${message}`);
99
- })
100
- .on('debug', (message, debug) => {
101
- debug = (debug !== null && debug !== undefined) ? `debug: ${message} ${JSON.stringify(debug, null, 2)}` : `${message}`
102
- log.info(`Device: ${host} ${deviceName}, ${debug}`);
103
- })
104
- .on('warn', (message) => {
105
- log.warn(`Device: ${host} ${deviceName}, ${message}`);
86
+ try {
87
+ this.envoyDevice = new EnvoyDevice(api, deviceName, host, envoyFirmware7xx, envoyFirmware7xxTokenGenerationMode, envoyPasswd, envoyToken, envoySerialNumber, enlightenUser, enlightenPasswd, envoyIdFile, envoyTokenFile, envoyInstallerPasswordFile, device);
88
+ this.envoyDevice.on('publishAccessory', (accessory) => {
89
+ api.publishExternalAccessories(CONSTANTS.PluginName, [accessory]);
90
+ log.success(`Device: ${host} ${deviceName}, published as external accessory.`);
106
91
  })
107
- .on('error', async (error) => {
108
- //stop impulse generator
109
- envoyDevice.impulseGenerator.stop();
110
-
111
- //handle error
112
- const errorString = error.toString();
113
- const tokenNotValid = envoyFirmware7xx && errorString.includes('status code 401');
114
- const tokenExpired = envoyFirmware7xx && errorString.includes('JWT token expired');
115
- const displayError = tokenNotValid ? log.warn(`Device: ${host} ${deviceName}, JWT token not valid, refreshing.`) : tokenExpired ? log.warn(`Device: ${host} ${deviceName}, ${error}, refreshing.`) : log.error(`Device: ${host} ${deviceName}, ${error}, trying again.`);
116
-
117
- //wait and try connect again
118
- await new Promise(resolve => setTimeout(resolve, 20000));
119
- envoyDevice.start();
120
- });
92
+ .on('devInfo', (devInfo) => {
93
+ log.info(devInfo);
94
+ })
95
+ .on('success', (message) => {
96
+ log.success(`Device: ${host} ${deviceName}, ${message}`);
97
+ })
98
+ .on('message', (message) => {
99
+ log.info(`Device: ${host} ${deviceName}, ${message}`);
100
+ })
101
+ .on('debug', (message, debug) => {
102
+ debug = (debug !== null && debug !== undefined) ? `debug: ${message} ${JSON.stringify(debug, null, 2)}` : `${message}`
103
+ log.info(`Device: ${host} ${deviceName}, ${debug}`);
104
+ })
105
+ .on('warn', (message) => {
106
+ log.warn(`Device: ${host} ${deviceName}, ${message}`);
107
+ })
108
+ .on('error', async (error) => {
109
+ //handle error
110
+ const errorString = error.toString();
111
+ const tokenNotValid = envoyFirmware7xx && errorString.includes('status code 401');
112
+ const tokenExpired = envoyFirmware7xx && errorString.includes('JWT token expired');
113
+ const displayError = tokenNotValid ? log.warn(`Device: ${host} ${deviceName}, JWT token not valid, refreshing.`) : tokenExpired ? log.warn(`Device: ${host} ${deviceName}, ${error}, refreshing.`) : log.error(`Device: ${host} ${deviceName}, ${error}, trying again.`);
114
+
115
+ //wait and try connect again
116
+ await new Promise(resolve => setTimeout(resolve, 20000));
117
+ await this.envoyDevice.start();
118
+ });
119
+
120
+ //start
121
+ await this.envoyDevice.start();
122
+ } catch (error) { //stop impulse generator
123
+ //handle error
124
+ const errorString = error.toString();
125
+ const tokenNotValid = envoyFirmware7xx && errorString.includes('status code 401');
126
+ const tokenExpired = envoyFirmware7xx && errorString.includes('JWT token expired');
127
+ const displayError = tokenNotValid ? log.warn(`Device: ${host} ${deviceName}, JWT token not valid, refreshing.`) : tokenExpired ? log.warn(`Device: ${host} ${deviceName}, ${error}, refreshing.`) : log.error(`Device: ${host} ${deviceName}, ${error}, trying again.`);
128
+
129
+ //wait and try connect again
130
+ await new Promise(resolve => setTimeout(resolve, 20000));
131
+ await this.envoyDevice.start();
132
+ }
121
133
  }
122
134
  });
123
135
  }
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": "9.3.4",
5
+ "version": "9.3.5",
6
6
  "description": "Homebridge plugin for Photovoltaic Energy System manufactured by Enphase.",
7
7
  "license": "MIT",
8
8
  "author": "grzegorz914",
@@ -29,11 +29,11 @@
29
29
  ],
30
30
  "engines": {
31
31
  "node": ">=18.0.0",
32
- "homebridge": ">=1.8.0"
32
+ "homebridge": ">=2.0.0"
33
33
  },
34
34
  "dependencies": {
35
35
  "async-mqtt": "^2.6.3",
36
- "axios": "^1.7.5",
36
+ "axios": "^1.7.7",
37
37
  "express": "^4.19.2",
38
38
  "fast-xml-parser": "^4.4.1"
39
39
  },
@@ -781,7 +781,7 @@ class EnvoyDevice extends EventEmitter {
781
781
  headers: {
782
782
  Accept: 'application/json'
783
783
  },
784
- timeout: 20000
784
+ timeout: 25000
785
785
  });
786
786
 
787
787
  //RESTFul server
@@ -853,6 +853,7 @@ class EnvoyDevice extends EventEmitter {
853
853
  const updateHome = tokenExpired ? false : await this.updateHome();
854
854
  const updateInventory = updateHome ? await this.updateInventory() : false;
855
855
  } catch (error) {
856
+ this.impulseGenerator.stop();
856
857
  this.emit('error', error);
857
858
  };
858
859
  }).on('updateMeters', async () => {
@@ -861,6 +862,7 @@ class EnvoyDevice extends EventEmitter {
861
862
  const updateMeters = tokenExpired ? false : await this.updateMeters();
862
863
  const updateMetersReading = updateMeters ? await this.updateMetersReading() : false;
863
864
  } catch (error) {
865
+ this.impulseGenerator.stop();
864
866
  this.emit('error', error);
865
867
  };
866
868
  }).on('updateMicroinvertersStatus', async () => {
@@ -868,6 +870,7 @@ class EnvoyDevice extends EventEmitter {
868
870
  const tokenExpired = await this.checkJwtToken();
869
871
  const updateMicroinvertersStatus = tokenExpired ? false : await this.updateMicroinvertersStatus();
870
872
  } catch (error) {
873
+ this.impulseGenerator.stop();
871
874
  this.emit('error', error);
872
875
  };
873
876
  }).on('updateProduction', async () => {
@@ -876,6 +879,7 @@ class EnvoyDevice extends EventEmitter {
876
879
  const updateProduction = tokenExpired ? false : await this.updateProduction();
877
880
  const updateProductionCt = updateProduction ? await this.updateProductionCt() : false;
878
881
  } catch (error) {
882
+ this.impulseGenerator.stop();
879
883
  this.emit('error', error);
880
884
  };
881
885
  }).on('updateEnsemble', async () => {
@@ -890,6 +894,7 @@ class EnvoyDevice extends EventEmitter {
890
894
  const updateGenerator = updateEnsemble ? await this.updateGenerator() : false;
891
895
  const updateGeneratorSettings = updateGenerator ? await this.updateGeneratorSettings() : false;
892
896
  } catch (error) {
897
+ this.impulseGenerator.stop();
893
898
  this.emit('error', error);
894
899
  };
895
900
  }).on('updateLiveData', async () => {
@@ -897,6 +902,7 @@ class EnvoyDevice extends EventEmitter {
897
902
  const tokenExpired = await this.checkJwtToken();
898
903
  const updateLiveData = tokenExpired ? false : await this.updateLiveData();
899
904
  } catch (error) {
905
+ this.impulseGenerator.stop();
900
906
  this.emit('error', error);
901
907
  };
902
908
  }).on('state', (state) => {
@@ -937,8 +943,6 @@ class EnvoyDevice extends EventEmitter {
937
943
  //mqtt
938
944
  const mqtt = this.mqttConnected ? this.mqtt.emit('publish', 'Data Sampling', { state: state }) : false;
939
945
  });
940
-
941
- this.start();
942
946
  };
943
947
 
944
948
  async start() {
@@ -1014,8 +1018,10 @@ class EnvoyDevice extends EventEmitter {
1014
1018
  const pushTimer4 = updateEnsemble ? this.timers.push({ name: 'updateEnsemble', sampling: this.ensembleDataRefreshTime }) : false;
1015
1019
  const pushTimer5 = updateLiveData ? this.timers.push({ name: 'updateLiveData', sampling: this.liveDataRefreshTime }) : false;
1016
1020
  this.impulseGenerator.start(this.timers);
1021
+ return true;
1017
1022
  } catch (error) {
1018
- this.emit('error', error);
1023
+ this.impulseGenerator.stop();
1024
+ throw new Error(error);
1019
1025
  };
1020
1026
  };
1021
1027
 
@@ -1080,7 +1086,7 @@ class EnvoyDevice extends EventEmitter {
1080
1086
  keepAlive: false,
1081
1087
  rejectUnauthorized: false
1082
1088
  }),
1083
- timeout: 20000
1089
+ timeout: 25000
1084
1090
  });
1085
1091
 
1086
1092
  const response = await axiosInstanceToken(CONSTANTS.ApiUrls.CheckJwt);
@@ -1100,7 +1106,7 @@ class EnvoyDevice extends EventEmitter {
1100
1106
  keepAlive: false,
1101
1107
  rejectUnauthorized: false
1102
1108
  }),
1103
- timeout: 20000
1109
+ timeout: 25000
1104
1110
  });
1105
1111
 
1106
1112
  this.cookie = cookie;
@@ -1732,7 +1738,7 @@ class EnvoyDevice extends EventEmitter {
1732
1738
  const ensemblesInventoryInstalled = ensemblesInventory.length > 0;
1733
1739
  if (ensemblesInventoryInstalled) {
1734
1740
  const type = CONSTANTS.ApiCodes[inventory[3].type] ?? 'Unknown';
1735
- ensembles.forEach((ensemble, index) => {
1741
+ ensemblesInventory.forEach((ensemble, index) => {
1736
1742
  const obj = {
1737
1743
  type: type,
1738
1744
  partNumber: CONSTANTS.PartNumbers[ensemble.part_num] ?? ensemble.part_num,