homebridge-enphase-envoy 10.3.6 → 10.3.8

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
@@ -9,6 +9,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
9
9
 
10
10
  - after update to v10.0.0 and above the accessory and bridge need to be removed from the homebridge / Home.app and added again
11
11
 
12
+ ## [10.3.8] - (17.12.2025)
13
+
14
+ ## Changes
15
+
16
+ - fix [#222](https://github.com/grzegorz914/homebridge-enphase-envoy/issues/222)
17
+ - bump dependencies
18
+
19
+ ## [10.3.7] - (09.12.2025)
20
+
21
+ ## Changes
22
+
23
+ - moved MQTT to v5
24
+ - cleanup
25
+
12
26
  ## [10.3.5] - (13.11.2025)
13
27
 
14
28
  ## Changes
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.6",
5
+ "version": "10.3.8",
6
6
  "description": "Homebridge p7ugin for Photovoltaic Energy System manufactured by Enphase.",
7
7
  "license": "MIT",
8
8
  "author": "grzegorz914",
@@ -35,10 +35,10 @@
35
35
  "node": "^20 || ^22 || ^24 || ^25"
36
36
  },
37
37
  "dependencies": {
38
- "async-mqtt": "^2.6.3",
38
+ "mqtt": "^5.14.1",
39
39
  "axios": "^1.13.2",
40
40
  "express": "^5.2.1",
41
- "fast-xml-parser": "^5.3.2",
41
+ "fast-xml-parser": "^5.3.3",
42
42
  "fakegato-history": "^0.6.7"
43
43
  },
44
44
  "keywords": [
@@ -4023,7 +4023,6 @@ class EnvoyDevice extends EventEmitter {
4023
4023
  // Update system services
4024
4024
  for (const { type, value, valueKey } of characteristics1) {
4025
4025
  if (!this.functions.isValidValue(value)) continue;
4026
- this.emit('debug', `Power And Energy, ${measurementType}, power ${valueKey}: ${value}`);
4027
4026
  control[valueKey] = value;
4028
4027
  this.systemService?.updateCharacteristic(type, value);
4029
4028
  };
package/src/mqtt.js CHANGED
@@ -1,55 +1,103 @@
1
- import asyncMqtt from 'async-mqtt';
2
- const { connectAsync } = asyncMqtt;
1
+ import { connect } from 'mqtt';
3
2
  import EventEmitter from 'events';
4
3
 
5
4
  class Mqtt extends EventEmitter {
6
5
  constructor(config) {
7
6
  super();
7
+
8
+ const url = `mqtt://${config.host}:${config.port}`;
9
+ const subscribeTopic = `${config.prefix}/Set`;
10
+
8
11
  const options = {
9
12
  clientId: config.clientId,
10
13
  username: config.user,
11
- password: config.passwd
14
+ password: config.passwd,
15
+ protocolVersion: 5,
16
+ clean: false,
17
+ properties: {
18
+ sessionExpiryInterval: 60 * 60, // 1 hour
19
+ userProperties: {
20
+ source: 'node-client'
21
+ }
22
+ }
12
23
  };
13
- const url = `mqtt://${config.host}:${config.port}`;
14
- const subscribeTopic = `${config.prefix}/Set`;
15
24
 
16
- this.on('connect', async () => {
17
- try {
18
- //connect
19
- this.mqttClient = await connectAsync(url, options);
20
- this.emit('connected', 'MQTT Connected');
25
+ this.mqttClient = connect(url, options);
21
26
 
22
- //subscribe
23
- await this.mqttClient.subscribe(subscribeTopic);
24
- this.emit('subscribed', `MQTT Subscribe topic: ${subscribeTopic}`);
27
+ // === CONNECTED ===
28
+ this.mqttClient.on('connect', async (packet) => {
29
+ this.emit('connected', 'MQTT v5 connected.');
25
30
 
26
- //subscribed message
27
- this.mqttClient.on('message', (topic, message) => {
28
- try {
29
- const obj = JSON.parse(message.toString());
30
- if (config.logDebug) this.emit('debug', `MQTT Received topic: ${topic}, message: ${JSON.stringify(obj, null, 2)}`);
31
- const key = Object.keys(obj)[0];
32
- const value = Object.values(obj)[0];
33
- this.emit('set', key, value);
34
- } catch (error) {
35
- if (config.logWarn) this.emit('warn', `MQTT Parse object error: ${error}`);
31
+ try {
32
+ const result = await this.mqttClient.subscribeAsync(subscribeTopic, {
33
+ qos: 1,
34
+ properties: {
35
+ userProperties: {
36
+ type: 'subscription'
37
+ }
36
38
  }
37
39
  });
40
+
41
+ // MQTT v5 subscription results contain reason codes
42
+ if (config.logDebug) this.emit('debug', `Subscribed to ${subscribeTopic}, reason codes: ${JSON.stringify(result)}`);
43
+ this.emit('subscribed', `MQTT Subscribe topic: ${subscribeTopic}`);
44
+
45
+ } catch (error) {
46
+ if (config.logWarn) this.emit('warn', `MQTT Subscribe error: ${error}`);
47
+ }
48
+ });
49
+
50
+ // === MESSAGE ===
51
+ this.mqttClient.on('message', (topic, payload, packet) => {
52
+ try {
53
+ const obj = JSON.parse(payload.toString());
54
+ if (config.logDebug) this.emit('debug', `MQTT Received:\nTopic: ${topic}\nPayload: ${JSON.stringify(obj, null, 2)}\nProperties: ${JSON.stringify(packet.properties, null, 2)}`);
55
+
56
+ const key = Object.keys(obj)[0];
57
+ const value = Object.values(obj)[0];
58
+ this.emit('set', key, value);
59
+
38
60
  } catch (error) {
39
- if (config.logWarn) this.emit('warn', `MQTT Connect error: ${error}`);
61
+ if (config.logWarn) this.emit('warn', `MQTT Parse error: ${error}`);
40
62
  }
41
- }).on('publish', async (topic, message) => {
63
+ });
64
+
65
+ // === PUBLISH EVENT ===
66
+ this.on('publish', async (topic, message) => {
42
67
  try {
43
68
  const fullTopic = `${config.prefix}/${topic}`;
44
- const publishMessage = JSON.stringify(message, null, 2);
45
- await this.mqttClient.publish(fullTopic, publishMessage);
46
- if (config.logDebug) this.emit('debug', `MQTT Publish topic: ${fullTopic}, message: ${publishMessage}`);
69
+ const publishMessage = JSON.stringify(message);
70
+
71
+ await this.mqttClient.publishAsync(fullTopic, publishMessage, {
72
+ qos: 1,
73
+ properties: {
74
+ contentType: 'application/json',
75
+ userProperties: {
76
+ source: 'node',
77
+ action: 'set'
78
+ }
79
+ }
80
+ });
81
+
82
+ if (config.logDebug) this.emit('debug', `MQTT Publish:\nTopic: ${fullTopic}\nPayload: ${publishMessage}`);
47
83
  } catch (error) {
48
84
  if (config.logWarn) this.emit('warn', `MQTT Publish error: ${error}`);
49
85
  }
50
86
  });
51
87
 
52
- this.emit('connect');
88
+ // === ERRORS / STATE ===
89
+ this.mqttClient.on('error', (err) => {
90
+ this.emit('warn', `MQTT Error: ${err.message}`);
91
+ });
92
+
93
+ this.mqttClient.on('reconnect', () => {
94
+ if (config.logDebug) this.emit('debug', 'MQTT Reconnecting...');
95
+ });
96
+
97
+ this.mqttClient.on('close', () => {
98
+ if (config.logDebug) this.emit('debug', 'MQTT Connection closed.');
99
+ });
53
100
  }
54
101
  }
102
+
55
103
  export default Mqtt;