homebridge-melcloud-control 4.4.1-beta.20 → 4.4.1-beta.22

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
@@ -22,6 +22,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
22
22
 
23
23
  - Do not use Homebridge UI > v5.5.0 because of break config.json
24
24
 
25
+ # [4.4.1] - (xx.12.2025)
26
+
27
+ ## Changes
28
+
29
+ - bump dependencies
30
+ - config schema updated
31
+ - redme updated
32
+ - cleanup
33
+
25
34
  # [4.4.0] - (10.12.2025)
26
35
 
27
36
  ## Changes
package/README.md CHANGED
@@ -36,7 +36,7 @@ Homebridge plugin for Air Conditioner, Heat Pump and Energy Recovery Ventilation
36
36
  * Support direct `Scenes`, only MELCloud Home.
37
37
  * Support direct `Frost protection`, only MELCloud Home.
38
38
  * Support direct `Overheat Protection`, only MELCloud Home.
39
- * Support direct `Holiday Mode`.
39
+ * Support direct `Holiday Mode`, only MELCloud Home.
40
40
  * Support direct `Functions`, using extra `Buttons`, switch it to `OFF` restore previous device state.
41
41
  * Support automations, shortcuts and Siri.
42
42
  * Support external integrations, [RESTFul](https://github.com/grzegorz914/homebridge-melcloud-control?tab=readme-ov-file#restful-integration), [MQTT](https://github.com/grzegorz914/homebridge-melcloud-control?tab=readme-ov-file#mqtt-integration).
@@ -68,8 +68,8 @@ Homebridge plugin for Air Conditioner, Heat Pump and Energy Recovery Ventilation
68
68
  * Vane V mode `AUTO/1/2/3/4/5/SWING`.
69
69
  * Fan speed mode `AUTO/1/2/3/4/5`.
70
70
  * Presets `SET/UNSET`.
71
- * Frost protection `ON/OFF`.
72
- * Overheat protection `ON/OFF`.
71
+ * Frost protection `ON/OFF/MINTEMP/MAXTEMP`.
72
+ * Overheat protection `ON/OFF/MINTEMP/MAXTEMP`.
73
73
  * Holiday mode `ON/OFF`.
74
74
  * Schedules `ON/OFF`.
75
75
  * Scene `ON/OFF`.
@@ -129,7 +129,7 @@ Homebridge plugin for Air Conditioner, Heat Pump and Energy Recovery Ventilation
129
129
  * Operating mode `HEAT/COOL/CURVE/HOLIDAY/AUTO HOT WATER/ECO HOT WATER/FORCE HOT WATER`.
130
130
  * Physical lock controls `LOCK/UNLOCK`.
131
131
  * Presets `SET/UNSET`.
132
- * Frost protection `ON/OFF`.
132
+ * Frost protection `ON/OFF/MINTEMP/MAXTEMP`.
133
133
  * Holiday mode `ON/OFF`.
134
134
  * Schedules `ON/OFF`.
135
135
  * Scene `ON/OFF`.
@@ -210,7 +210,7 @@ Homebridge plugin for Air Conditioner, Heat Pump and Energy Recovery Ventilation
210
210
  * Target temperature is calculated as a middle value between `LO` and `HI` and the rest is calculated internally.
211
211
  * Thermostat
212
212
  * In this mode we can set only target temperature:
213
- * Target temperature issend to device and calculated internally:
213
+ * Target temperature is send to device and calculated internally:
214
214
  * Calculation method in device internally:
215
215
  * If the room temperature `<` Heating Setpoint, the unit will be set to HEAT with a setpoint of 23°C.
216
216
  * In HEAT, if the room temperature `>` Heating Setpoint `+` 1°C, the unit will be set to FAN.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "displayName": "MELCloud Control",
3
3
  "name": "homebridge-melcloud-control",
4
- "version": "4.4.1-beta.20",
4
+ "version": "4.4.1-beta.22",
5
5
  "description": "Homebridge plugin to control Mitsubishi Air Conditioner, Heat Pump and Energy Recovery Ventilation.",
6
6
  "license": "MIT",
7
7
  "author": "grzegorz914",
package/src/constants.js CHANGED
@@ -29,17 +29,17 @@ export const ApiUrls = {
29
29
  Scenes: "/api/user/scenes",
30
30
  },
31
31
  Post: {
32
- Schedule: "/api/cloudschedule/deviceid", // POST {"days":[2],"time":"17:59:00","enabled":true,"id":"53c5e804-0663-47d0-85c2-2d8ccd2573de","power":false,"operationMode":null,"setPoint":null,"vaneVerticalDirection":null,"vaneHorizontalDirection":null,"setFanSpeed":null}
33
- ProtectionFrost: "/api/protection/frost", // POST {"enabled":true,"min":13,"max":16,"units":{"ATA":["ef333525-2699-4290-af5a-2922566676da"]}}
34
- ProtectionOverheat: "/api/protection/overheat", // POST {"enabled":true,"min":32,"max":35,"units":{"ATA":["ef333525-2699-4290-af5a-2922566676da"]}}
35
- HolidayMode: "/api/holidaymode", // POST {"enabled":true,"startDate":"2025-11-11T17:42:24.913","endDate":"2026-06-01T09:18:00","units":{"ATA":["ef333525-2699-4290-af5a-2922566676da"]}}
36
- Scene: "/api/scene", // POST {"id": "8e484d50-528b-434a-9acb-7d7c81f06a12", "userId": "2db32d6f-c19c-4b1f-a0dd-1915420a5152","name": "Poza domem","enabled": false,"icon": "AwayIcon","ataSceneSettings": [{"unitId": "054dd950-f6e0-4195-bea7-59d8ea0668c2","ataSettings": { "power": false, "operationMode": "heat","setFanSpeed": "auto","vaneHorizontalDirection": "auto", "vaneVerticalDirection": "auto", "setTemperature": 21,"temperatureIncrementOverride": null,"inStandbyMode": null},"previousSettings": null}],"atwSceneSettings": []}
32
+ ProtectionFrost: "/api/protection/frost", //{"enabled":true,"min":13,"max":16,"units":{"ATA":["deviceid"]}}
33
+ ProtectionOverheat: "/api/protection/overheat", //{"enabled":true,"min":32,"max":35,"units":{"ATA":["deviceid"]}}
34
+ HolidayMode: "/api/holidaymode", //{"enabled":true,"startDate":"2025-11-11T17:42:24.913","endDate":"2026-06-01T09:18:00","units":{"ATA":["deviceid"]}}
35
+ Schedule: "/api/cloudschedule/deviceid", //{"days":[2],"time":"17:59:00","enabled":true,"id":"scheduleid","power":false,"operationMode":null,"setPoint":null,"vaneVerticalDirection":null,"vaneHorizontalDirection":null,"setFanSpeed":null}
36
+ Scene: "/api/scene", //{"id": "sceneid", "userId": "userid","name": "Poza domem","enabled": false,"icon": "AwayIcon","ataSceneSettings": [{"unitId": "deviceid","ataSettings": { "power": false, "operationMode": "heat","setFanSpeed": "auto","vaneHorizontalDirection": "auto", "vaneVerticalDirection": "auto", "setTemperature": 21,"temperatureIncrementOverride": null,"inStandbyMode": null},"previousSettings": null}],"atwSceneSettings": []}
37
37
  },
38
38
  Put: {
39
- Ata: "/api/ataunit/deviceid",
39
+ Ata: "/api/ataunit/deviceid", //{ power: true,setTemperature: 22, setFanSpeed: "auto", operationMode: "heat", vaneHorizontalDirection: "auto",vaneVerticalDirection: "auto", temperatureIncrementOverride: null, inStandbyMode: null}
40
40
  Atw: "/api/atwunit/deviceid",
41
41
  Erv: "/api/ervunit/deviceid",
42
- ScheduleEnableDisable: "/api/cloudschedule/deviceid/enabled", // PUT {"enabled":true}
42
+ ScheduleEnableDisable: "/api/cloudschedule/deviceid/enabled", // {"enabled": true}
43
43
  SceneEnableDisable: "/api/scene/sceneid/enabledisable",
44
44
  },
45
45
  Delete: {
package/src/functions.js CHANGED
@@ -78,12 +78,13 @@ class Functions extends EventEmitter {
78
78
  await access('/.dockerenv');
79
79
  isDocker = true;
80
80
  } catch { }
81
+
81
82
  try {
82
- const { stdout } = await execPromise('cat /proc/1/cgroup || true');
83
+ const { stdout } = await execPromise('cat /proc/1/cgroup');
83
84
  if (stdout.includes('docker') || stdout.includes('containerd')) isDocker = true;
84
85
  } catch { }
85
86
 
86
- const result = { path: null, arch, system: null };
87
+ const result = { path: null, arch, system: 'unknown' };
87
88
 
88
89
  /* ===================== macOS ===================== */
89
90
  if (isMac) {
@@ -109,7 +110,7 @@ class Functions extends EventEmitter {
109
110
  try {
110
111
  await access(path, fs.constants.X_OK);
111
112
  result.path = path;
112
- result.system = 'QNAP';
113
+ result.system = 'Qnap';
113
114
  return result;
114
115
  } catch { }
115
116
  }
@@ -119,13 +120,15 @@ class Functions extends EventEmitter {
119
120
  await execPromise('/opt/bin/opkg update');
120
121
  await execPromise('opkg install chromium nspr nss libx11 libxcomposite libxdamage libxrandr atk libcups libdrm libgbm alsa-lib');
121
122
  process.env.LD_LIBRARY_PATH = `/opt/lib:${process.env.LD_LIBRARY_PATH || ''}`;
122
- } catch { }
123
+ } catch (error) {
124
+ if (this.logError) this.emit('error', `Install package for Qnap error: ${error}`);
125
+ }
123
126
 
124
127
  for (const path of qnapCandidates) {
125
128
  try {
126
129
  await access(path, fs.constants.X_OK);
127
130
  result.path = path;
128
- result.system = 'QNAP';
131
+ result.system = 'Qnap';
129
132
  return result;
130
133
  } catch { }
131
134
  }
@@ -147,12 +150,11 @@ class Functions extends EventEmitter {
147
150
 
148
151
  if (!isDocker) {
149
152
  try {
150
- this.emit('debug', `Try install chromium`);
151
153
  await execPromise('sudo apt update -y');
152
- await execPromise('sudo apt install -y chromium chromium-browser chromium-codecs-ffmpeg || true');
153
- await execPromise('sudo apt install -y libnspr4 libnss3 libx11-6 libxcomposite1 libxdamage1 libxrandr2 libatk1.0-0 libcups2 libdrm2 libgbm1 libasound2 || true');
154
+ await execPromise('sudo apt install -y chromium chromium-browser chromium-codecs-ffmpeg');
155
+ await execPromise('sudo apt install -y libnspr4 libnss3 libx11-6 libxcomposite1 libxdamage1 libxrandr2 libatk1.0-0 libcups2 libdrm2 libgbm1 libasound2');
154
156
  } catch (error) {
155
- this.emit('debug', `Install chromium failed ${error}`);
157
+ if (this.logError) this.emit('error', `Install package for Linux ARM error: ${error}`);
156
158
  }
157
159
  }
158
160
 
@@ -171,7 +173,7 @@ class Functions extends EventEmitter {
171
173
  if (isLinux) {
172
174
  const linuxCandidates = ['/usr/bin/chromium', '/usr/bin/chromium-browser', '/usr/bin/google-chrome', '/snap/bin/chromium', '/usr/local/bin/chromium'];
173
175
  try {
174
- const { stdout } = await execPromise('which chromium || which chromium-browser || which google-chrome || true');
176
+ const { stdout } = await execPromise('which chromium || which chromium-browser || which google-chrome');
175
177
  if (stdout.trim()) {
176
178
  result.path = stdout.trim();
177
179
  return result;
@@ -189,19 +191,21 @@ class Functions extends EventEmitter {
189
191
 
190
192
  if (isDocker) {
191
193
  try {
192
- await execPromise('apt update -y && apt install -y chromium || true');
194
+ await execPromise('apt update -y && apt install -y chromium');
193
195
  await access('/usr/bin/chromium', fs.constants.X_OK);
194
196
  result.path = '/usr/bin/chromium';
195
197
  result.system = 'Linux Docker';
196
198
  return result;
197
- } catch { }
199
+ } catch (error) {
200
+ if (this.logError) this.emit('error', `Install package for Linux Docker error: ${error}`);
201
+ }
198
202
  }
199
203
  }
200
204
 
201
205
  return result;
202
- } catch (err) {
203
- if (this.logError) this.emit('error', `Chromium detection error: ${err.message}`);
204
- return { path: null, arch: 'unknown' };
206
+ } catch (error) {
207
+ if (this.logError) this.emit('error', `Chromium detection error: ${error.message}`);
208
+ return { path: null, arch: 'unknown', system: 'unknown' };
205
209
  }
206
210
  }
207
211
 
@@ -231,7 +231,7 @@ class MelCloudHome extends EventEmitter {
231
231
 
232
232
  // If path is found, use it
233
233
  if (chromiumPath) {
234
- if (!this.logDebug) this.emit('debug', `Using Chromium ${system} (${arch}) at ${chromiumPath}`);
234
+ if (!this.logDebug) this.emit('debug', `Using Chromium for ${system} (${arch}) at ${chromiumPath}`);
235
235
  } else {
236
236
  if (arch === 'arm') {
237
237
  accountInfo.Info = `No Chromium found for ${system} (${arch}). Please install it manually and try again.`;
@@ -247,7 +247,6 @@ class MelCloudHome extends EventEmitter {
247
247
  }
248
248
  }
249
249
 
250
-
251
250
  // Verify Chromium executable
252
251
  try {
253
252
  const { stdout } = await execPromise(`"${chromiumPath}" --version`);