homebridge-melcloud-control 4.10.17 → 4.10.19-beta.0

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
@@ -24,6 +24,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
24
24
  - For plugin < v4.6.0 use Homebridge UI <= v5.5.0
25
25
  - For plugin >= v4.6.0 use Homebridge UI >= v5.13.0
26
26
 
27
+ ## [4.10.19] - (13.09.2026)
28
+
29
+ ### Changes
30
+
31
+ - fix: MQTT client had `protocolVersion: 5` hardcoded, so brokers that only support MQTT 3.1.1 (e.g. the ioBroker MQTT adapter) accepted the TCP connection, failed the handshake, and got disconnected every second forever, with nothing published and no error logged; added a `Protocol Version` option (5.0 / 3.1.1) in the MQTT section, and a one-time warning if no successful connection is established within 30 seconds
32
+ - bump dependencies
33
+
34
+ ## [4.10.18] - (17.06.2026)
35
+
36
+ ### Changes
37
+
38
+ - fix: [#256](https://github.com/grzegorz914/homebridge-melcloud-control/issues/256)
39
+ - bump dependencies
40
+
27
41
  ## [4.10.14] - (17.06.2026)
28
42
 
29
43
  ### Changes
@@ -2412,6 +2412,25 @@
2412
2412
  "functionBody": "return model.devices[arrayIndices].mqtt.enable === true;"
2413
2413
  }
2414
2414
  },
2415
+ "protocolVersion": {
2416
+ "title": "Protocol Version",
2417
+ "type": "integer",
2418
+ "default": 5,
2419
+ "oneOf": [
2420
+ {
2421
+ "title": "5.0",
2422
+ "enum": [5]
2423
+ },
2424
+ {
2425
+ "title": "3.1.1",
2426
+ "enum": [4]
2427
+ }
2428
+ ],
2429
+ "description": "MQTT protocol version used to connect to the broker. Some brokers (e.g. the ioBroker MQTT adapter) only support 3.1.1 and will silently reject 5.0 connections.",
2430
+ "condition": {
2431
+ "functionBody": "return model.devices[arrayIndices].mqtt.enable === true;"
2432
+ }
2433
+ },
2415
2434
  "auth": {
2416
2435
  "title": "Authorization",
2417
2436
  "type": "object",
package/index.js CHANGED
@@ -294,6 +294,7 @@ class MelCloudPlatform {
294
294
  port: mqtt.port || 1883,
295
295
  clientId: mqtt.clientId ? `melcloud_${mqtt.clientId}_${Math.random().toString(16).slice(3)}` : `melcloud_${Math.random().toString(16).slice(3)}`,
296
296
  prefix: mqtt.prefix ? `melcloud/${mqtt.prefix}/${deviceTypeString}/${deviceName}` : `melcloud/${deviceTypeString}/${deviceName}`,
297
+ protocolVersion: mqtt.protocolVersion,
297
298
  user: mqtt.auth?.user,
298
299
  passwd: mqtt.auth?.passwd,
299
300
  logWarn: logLevel.warn,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "displayName": "MELCloud Control",
3
3
  "name": "homebridge-melcloud-control",
4
- "version": "4.10.17",
4
+ "version": "4.10.19-beta.0",
5
5
  "description": "Homebridge plugin to control Mitsubishi Air Conditioner, Heat Pump and Energy Recovery Ventilation.",
6
6
  "license": "MIT",
7
7
  "author": "grzegorz914",
@@ -35,13 +35,13 @@
35
35
  "node": "^20 || ^22 || ^24 || ^25 || ^26"
36
36
  },
37
37
  "dependencies": {
38
- "@homebridge/plugin-ui-utils": "^2.2.4",
39
- "mqtt": "^5.15.1",
40
- "axios": "^1.18.0",
38
+ "@homebridge/plugin-ui-utils": "^2.2.6",
39
+ "mqtt": "^5.15.2",
40
+ "axios": "^1.20.0",
41
41
  "axios-cookiejar-support": "^7.0.0",
42
- "tough-cookie": "^6.0.1",
42
+ "tough-cookie": "^6.0.2",
43
43
  "express": "^5.2.1",
44
- "ws": "^8.21.0"
44
+ "ws": "^8.21.3"
45
45
  },
46
46
  "keywords": [
47
47
  "homebridge",
package/src/deviceata.js CHANGED
@@ -135,7 +135,7 @@ class DeviceAta extends EventEmitter {
135
135
  flag = AirConditioner.EffectiveFlags.SetTemperature;
136
136
  break;
137
137
  case 'FanSpeed':
138
- key = accountTypeMelCloud ? 'fanSpeed' : 'setFanSpeed';
138
+ key = 'setFanSpeed';
139
139
  payload[key] = value;
140
140
  flag = AirConditioner.EffectiveFlags.SetFanSpeed;
141
141
  break;
@@ -1143,7 +1143,7 @@ class DeviceAta extends EventEmitter {
1143
1143
  .onSet(async (state) => {
1144
1144
  try {
1145
1145
  const fanKey = accountTypeMelCloud ? 'FanSpeed' : 'SetFanSpeed';
1146
- const fanKeySet = accountTypeMelCloud ? 'fanSpeed' : 'setFanSpeed';
1146
+ const fanKeySet = 'setFanSpeed';
1147
1147
  let payload = {};
1148
1148
  let flag = null;
1149
1149
  switch (mode) {
package/src/mqtt.js CHANGED
@@ -8,35 +8,47 @@ class Mqtt extends EventEmitter {
8
8
 
9
9
  const url = `mqtt://${config.host}:${config.port}`;
10
10
  const subscribeTopic = `${config.prefix}/Set`;
11
+ const protocolVersion = config.protocolVersion === 4 ? 4 : 5;
12
+ const isV5 = protocolVersion === 5;
13
+ this.isV5 = isV5;
11
14
 
12
15
  const options = {
13
16
  clientId: config.clientId,
14
17
  username: config.user,
15
18
  password: config.passwd,
16
- protocolVersion: 5,
17
- clean: false,
18
- properties: {
19
- sessionExpiryInterval: 60 * 60,
20
- userProperties: {
21
- source: 'node-client'
19
+ protocolVersion,
20
+ clean: !isV5,
21
+ ...(isV5 ? {
22
+ properties: {
23
+ sessionExpiryInterval: 60 * 60,
24
+ userProperties: {
25
+ source: 'node-client'
26
+ }
22
27
  }
23
- }
28
+ } : {})
24
29
  };
25
30
 
31
+ const startTime = Date.now();
32
+ let hasConnected = false;
33
+ let warnedStalled = false;
34
+
26
35
  this.mqttClient = connect(url, options)
27
36
  .on('connect', async () => {
28
- this.emit('connected', 'MQTT v5 connected.');
37
+ hasConnected = true;
38
+ this.emit('connected', `MQTT v${protocolVersion} connected.`);
29
39
 
30
40
  try {
31
41
  await new Promise((resolve, reject) => {
32
42
  this.mqttClient.subscribe(subscribeTopic,
33
43
  {
34
44
  qos: 1,
35
- properties: {
36
- userProperties: {
37
- type: 'subscription'
45
+ ...(isV5 ? {
46
+ properties: {
47
+ userProperties: {
48
+ type: 'subscription'
49
+ }
38
50
  }
39
- }
51
+ } : {})
40
52
  },
41
53
  (error) => {
42
54
  if (error) return reject(error);
@@ -69,6 +81,10 @@ class Mqtt extends EventEmitter {
69
81
  if (config.logDebug) this.emit('debug', 'MQTT Reconnecting...');
70
82
  })
71
83
  .on('close', () => {
84
+ if (!hasConnected && !warnedStalled && Date.now() - startTime > 30000) {
85
+ warnedStalled = true;
86
+ this.emit('warn', `MQTT has not connected after 30s of retries using protocol v${protocolVersion}. Check broker address, credentials, and whether the broker supports this MQTT protocol version.`);
87
+ }
72
88
  if (config.logDebug) this.emit('debug', 'MQTT Connection closed.');
73
89
  });
74
90
  }
@@ -81,13 +97,15 @@ class Mqtt extends EventEmitter {
81
97
  this.mqttClient.publish(fullTopic, publishMessage,
82
98
  {
83
99
  qos: 1,
84
- properties: {
85
- contentType: 'application/json',
86
- userProperties: {
87
- source: 'node',
88
- action: 'set'
100
+ ...(this.isV5 ? {
101
+ properties: {
102
+ contentType: 'application/json',
103
+ userProperties: {
104
+ source: 'node',
105
+ action: 'set'
106
+ }
89
107
  }
90
- }
108
+ } : {})
91
109
  },
92
110
  (error) => {
93
111
  if (error) {