homebridge-melcloud-control 4.3.16-beta.2 → 4.3.16-beta.3

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.
Files changed (2) hide show
  1. package/package.json +2 -2
  2. package/src/mqtt.js +100 -33
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "displayName": "MELCloud Control",
3
3
  "name": "homebridge-melcloud-control",
4
- "version": "4.3.16-beta.2",
4
+ "version": "4.3.16-beta.3",
5
5
  "description": "Homebridge plugin to control Mitsubishi Air Conditioner, Heat Pump and Energy Recovery Ventilation.",
6
6
  "license": "MIT",
7
7
  "author": "grzegorz914",
@@ -36,7 +36,7 @@
36
36
  },
37
37
  "dependencies": {
38
38
  "@homebridge/plugin-ui-utils": "^2.1.2",
39
- "async-mqtt": "^2.6.3",
39
+ "mqtt": "^5.14.1",
40
40
  "axios": "^1.13.2",
41
41
  "express": "^5.2.1",
42
42
  "puppeteer": "^24.32.1",
package/src/mqtt.js CHANGED
@@ -1,56 +1,123 @@
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
12
- }
13
- const url = `mqtt://${config.host}:${config.port}`;
14
- const subscribeTopic = `${config.prefix}/Set`;
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
+ }
23
+ };
24
+
25
+ this.mqttClient = connect(url, options);
26
+
27
+ // === CONNECTED ===
28
+ this.mqttClient.on('connect', async (packet) => {
29
+ this.emit('connected', 'MQTT v5 connected.');
15
30
 
16
- this.on('connect', async () => {
17
31
  try {
18
- //connect
19
- this.mqttClient = await connectAsync(url, options);
20
- this.emit('connected', 'MQTT Connected.');
32
+ const result = await this.mqttClient.subscribeAsync(subscribeTopic, {
33
+ qos: 1,
34
+ properties: {
35
+ userProperties: {
36
+ type: 'subscription'
37
+ }
38
+ }
39
+ });
40
+
41
+ // MQTT v5 subscription results contain reason codes
42
+ if (config.logDebug) {
43
+ this.emit(
44
+ 'debug',
45
+ `Subscribed to ${subscribeTopic}, reason codes: ${JSON.stringify(result)}`
46
+ );
47
+ }
21
48
 
22
- //subscribe
23
- await this.mqttClient.subscribe(subscribeTopic);
24
49
  this.emit('subscribed', `MQTT Subscribe topic: ${subscribeTopic}`);
25
50
 
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}`);
36
- };
37
- });
38
51
  } catch (error) {
39
- if (config.logWarn) this.emit('warn', `MQTT Connect error: ${error}`);
40
- };
41
- }).on('publish', async (topic, message) => {
52
+ if (config.logWarn) this.emit('warn', `MQTT Subscribe error: ${error}`);
53
+ }
54
+ });
55
+
56
+ // === MESSAGE ===
57
+ this.mqttClient.on('message', (topic, payload, packet) => {
58
+ try {
59
+ const obj = JSON.parse(payload.toString());
60
+
61
+ if (config.logDebug) {
62
+ this.emit(
63
+ 'debug',
64
+ `MQTT Received:\nTopic: ${topic}\nPayload: ${JSON.stringify(obj, null, 2)}\nProperties: ${JSON.stringify(packet.properties, null, 2)}`
65
+ );
66
+ }
67
+
68
+ const key = Object.keys(obj)[0];
69
+ const value = Object.values(obj)[0];
70
+ this.emit('set', key, value);
71
+
72
+ } catch (error) {
73
+ if (config.logWarn) {
74
+ this.emit('warn', `MQTT Parse error: ${error}`);
75
+ }
76
+ }
77
+ });
78
+
79
+ // === PUBLISH EVENT ===
80
+ this.on('publish', async (topic, message) => {
42
81
  try {
43
82
  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}`);
83
+ const publishMessage = JSON.stringify(message);
84
+
85
+ await this.mqttClient.publishAsync(fullTopic, publishMessage, {
86
+ qos: 1,
87
+ properties: {
88
+ contentType: 'application/json',
89
+ userProperties: {
90
+ source: 'node',
91
+ action: 'set'
92
+ }
93
+ }
94
+ });
95
+
96
+ if (config.logDebug) {
97
+ this.emit(
98
+ 'debug',
99
+ `MQTT Publish:\nTopic: ${fullTopic}\nPayload: ${publishMessage}`
100
+ );
101
+ }
102
+
47
103
  } catch (error) {
48
104
  if (config.logWarn) this.emit('warn', `MQTT Publish error: ${error}`);
49
- };
105
+ }
106
+ });
107
+
108
+ // === ERRORS / STATE ===
109
+ this.mqttClient.on('error', (err) => {
110
+ this.emit('warn', `MQTT Error: ${err.message}`);
50
111
  });
51
112
 
52
- this.emit('connect');
113
+ this.mqttClient.on('reconnect', () => {
114
+ if (config.logDebug) this.emit('debug', 'MQTT Reconnecting...');
115
+ });
116
+
117
+ this.mqttClient.on('close', () => {
118
+ if (config.logDebug) this.emit('debug', 'MQTT Connection closed.');
119
+ });
53
120
  }
54
121
  }
55
122
 
56
- export default Mqtt;
123
+ export default Mqtt;