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 +10 -0
- package/index.js +47 -35
- package/package.json +3 -3
- package/src/envoydevice.js +13 -7
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
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
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
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
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.
|
|
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": ">=
|
|
32
|
+
"homebridge": ">=2.0.0"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
35
|
"async-mqtt": "^2.6.3",
|
|
36
|
-
"axios": "^1.7.
|
|
36
|
+
"axios": "^1.7.7",
|
|
37
37
|
"express": "^4.19.2",
|
|
38
38
|
"fast-xml-parser": "^4.4.1"
|
|
39
39
|
},
|
package/src/envoydevice.js
CHANGED
|
@@ -781,7 +781,7 @@ class EnvoyDevice extends EventEmitter {
|
|
|
781
781
|
headers: {
|
|
782
782
|
Accept: 'application/json'
|
|
783
783
|
},
|
|
784
|
-
timeout:
|
|
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.
|
|
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:
|
|
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:
|
|
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
|
-
|
|
1741
|
+
ensemblesInventory.forEach((ensemble, index) => {
|
|
1736
1742
|
const obj = {
|
|
1737
1743
|
type: type,
|
|
1738
1744
|
partNumber: CONSTANTS.PartNumbers[ensemble.part_num] ?? ensemble.part_num,
|