homebridge-melcloud-control 3.6.2 → 3.6.4

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
@@ -16,6 +16,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
16
16
  - do not configure it manually, always using Config UI X
17
17
  - required Homebridge v2.0.0 and above
18
18
 
19
+ ## [3.6.4] - (09.02.2025)
20
+
21
+ ## Changes
22
+
23
+ - fix plugin crash if config dosnt contain devices
24
+
25
+ ## [3.6.3] - (07.02.2025)
26
+
27
+ ## Changes
28
+
29
+ - stability and improvements
30
+
19
31
  ## [3.6.2] - (04.03.2025)
20
32
 
21
33
  ## Changes
package/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- MIT License
1
+ # MIT License
2
2
 
3
3
  Copyright (c) 2022 Grzegorz
4
4
 
package/README.md CHANGED
@@ -297,7 +297,7 @@ Homebridge plugin for Air Conditioner, Heat Pump and Energy Recovery Ventilation
297
297
  ### RESTful Integration
298
298
 
299
299
  * Port: last 4 numbers of `device Id`, displayed in HB log during start.
300
- * POST data as a JSON Object `{OperationMode: 8}`
300
+ * POST data as a JSON Object `{OperationMode: 8}`, content type must be `application/json`
301
301
 
302
302
  | Method | URL | Path | Response | Type |
303
303
  | --- | --- | --- | --- | --- |
package/index.js CHANGED
@@ -112,12 +112,13 @@ class MelCloudPlatform {
112
112
  }
113
113
 
114
114
  //start impulse generator
115
- const timers = [{ name: 'checkDevicesList', sampling: refreshInterval }];
116
- await melCloud.impulseGenerator.start(timers);
115
+ await melCloud.impulseGenerator.start([{ name: 'checkDevicesList', sampling: refreshInterval }]);
117
116
 
118
117
  //Air Conditioner 0
119
118
  try {
120
- for (const device of account.ataDevices) {
119
+ const ataDevices = account.ataDevices ?? [];
120
+ const emitLog = !enableDebugMode ? false : log.info(`Found configured ATA devices: ${ataDevices.length}.`);
121
+ for (const device of ataDevices) {
121
122
  //chack device from config exist on melcloud
122
123
  const deviceId = device.id;
123
124
  const displayMode = device.displayMode > 0 ?? false;
@@ -161,6 +162,9 @@ class MelCloudPlatform {
161
162
  try {
162
163
  const startDone = await airConditioner.start();
163
164
  const stopImpulseGenerator = startDone ? await impulseGenerator.stop() : false;
165
+
166
+ //start impulse generator
167
+ const startImpulseGenerator = startDone ? await airConditioner.startImpulseGenerator() : false
164
168
  } catch (error) {
165
169
  const emitLog = disableLogError ? false : log.error(`${accountName}, ${deviceTypeText}, ${deviceName}, ${error}, trying again.`);
166
170
  };
@@ -177,7 +181,9 @@ class MelCloudPlatform {
177
181
 
178
182
  //Heat Pump 1
179
183
  try {
180
- for (const device of account.atwDevices) {
184
+ const atwDevices = account.atwDevices ?? [];
185
+ const emitLog = !enableDebugMode ? false : log.info(`Found configured ATW devices: ${atwDevices.length}.`);
186
+ for (const device of atwDevices) {
181
187
  //chack device from config exist on melcloud
182
188
  const deviceId = device.id;
183
189
  const displayMode = device.displayMode > 0 ?? false;
@@ -221,6 +227,9 @@ class MelCloudPlatform {
221
227
  try {
222
228
  const startDone = await heatPump.start();
223
229
  const stopImpulseGenerator = startDone ? await impulseGenerator.stop() : false;
230
+
231
+ //start impulse generator
232
+ const startImpulseGenerator = startDone ? await heatPump.startImpulseGenerator() : false
224
233
  } catch (error) {
225
234
  const emitLog = disableLogError ? false : log.error(`${accountName}, ${deviceTypeText}, ${deviceName}, ${error}, trying again.`);
226
235
  };
@@ -237,7 +246,9 @@ class MelCloudPlatform {
237
246
 
238
247
  //Energy Recovery Ventilation 3
239
248
  try {
240
- for (const device of account.ervDevices) {
249
+ const ervDevices = account.ervDevices ?? [];
250
+ const emitLog = !enableDebugMode ? false : log.info(`Found configured ERV devices: ${ervDevices.length}.`);
251
+ for (const device of ervDevices) {
241
252
  //chack device from config exist on melcloud
242
253
  const deviceId = device.id;
243
254
  const displayMode = device.displayMode > 0 ?? false;
@@ -281,6 +292,9 @@ class MelCloudPlatform {
281
292
  try {
282
293
  const startDone = await energyRecoveryVentilation.start();
283
294
  const stopImpulseGenerator = startDone ? await impulseGenerator.stop() : false;
295
+
296
+ //start impulse generator
297
+ const startImpulseGenerator = startDone ? await energyRecoveryVentilation.startImpulseGenerator() : false
284
298
  } catch (error) {
285
299
  const emitLog = disableLogError ? false : log.error(`${accountName}, ${deviceTypeText}, ${deviceName}, ${error}, trying again.`);
286
300
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "displayName": "MELCloud Control",
3
3
  "name": "homebridge-melcloud-control",
4
- "version": "3.6.2",
4
+ "version": "3.6.4",
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/deviceata.js CHANGED
@@ -250,6 +250,16 @@ class DeviceAta extends EventEmitter {
250
250
  };
251
251
  }
252
252
 
253
+ async startImpulseGenerator() {
254
+ try {
255
+ //start impule generator
256
+ await this.melCloudAta.impulseGenerator.start([{ name: 'checkState', sampling: this.refreshInterval }]);
257
+ return true;
258
+ } catch (error) {
259
+ throw new Error(`Impulse generator start error: ${error}`);
260
+ };
261
+ }
262
+
253
263
  //prepare accessory
254
264
  async prepareAccessory(accountInfo, deviceData, deviceId, deviceTypeText, deviceName, accountName) {
255
265
  try {
@@ -1399,9 +1409,6 @@ class DeviceAta extends EventEmitter {
1399
1409
  const accessory = await this.prepareAccessory(this.accountInfo, deviceData, this.deviceId, this.deviceTypeText, this.deviceName, this.accountName);
1400
1410
  this.emit('publishAccessory', accessory);
1401
1411
  this.startPrepareAccessory = false;
1402
-
1403
- //start impule generator
1404
- await this.melCloudAta.impulseGenerator.start([{ name: 'checkState', sampling: this.refreshInterval }]);
1405
1412
  }
1406
1413
 
1407
1414
  return true;
package/src/deviceatw.js CHANGED
@@ -274,6 +274,16 @@ class DeviceAtw extends EventEmitter {
274
274
  };
275
275
  }
276
276
 
277
+ async startImpulseGenerator() {
278
+ try {
279
+ //start impule generator
280
+ await this.melCloudAtw.impulseGenerator.start([{ name: 'checkState', sampling: this.refreshInterval }]);
281
+ return true;
282
+ } catch (error) {
283
+ throw new Error(`Impulse generator start error: ${error}`);
284
+ };
285
+ }
286
+
277
287
  //prepare accessory
278
288
  async prepareAccessory(accountInfo, deviceData, deviceId, deviceTypeText, deviceName, accountName) {
279
289
  try {
@@ -1941,9 +1951,6 @@ class DeviceAtw extends EventEmitter {
1941
1951
  const accessory = await this.prepareAccessory(this.accountInfo, deviceData, this.deviceId, this.deviceTypeText, this.deviceName, this.accountName);
1942
1952
  this.emit('publishAccessory', accessory);
1943
1953
  this.startPrepareAccessory = false;
1944
-
1945
- //start impule generator
1946
- await this.melCloudAtw.impulseGenerator.start([{ name: 'checkState', sampling: this.refreshInterval }]);
1947
1954
  }
1948
1955
 
1949
1956
  return true;
package/src/deviceerv.js CHANGED
@@ -166,6 +166,16 @@ class DeviceErv extends EventEmitter {
166
166
  };
167
167
  }
168
168
 
169
+ async startImpulseGenerator() {
170
+ try {
171
+ //start impule generator
172
+ await this.melCloudErv.impulseGenerator.start([{ name: 'checkState', sampling: this.refreshInterval }]);
173
+ return true;
174
+ } catch (error) {
175
+ throw new Error(`Impulse generator start error: ${error}`);
176
+ };
177
+ }
178
+
169
179
  //prepare accessory
170
180
  async prepareAccessory(accountInfo, deviceData, deviceId, deviceTypeText, deviceName, accountName) {
171
181
  try {
@@ -1192,9 +1202,6 @@ class DeviceErv extends EventEmitter {
1192
1202
  const accessory = await this.prepareAccessory(this.accountInfo, deviceData, this.deviceId, this.deviceTypeText, this.deviceName, this.accountName);
1193
1203
  this.emit('publishAccessory', accessory);
1194
1204
  this.startPrepareAccessory = false;
1195
-
1196
- //start impule generator
1197
- await this.melCloudErv.impulseGenerator.start([{ name: 'checkState', sampling: this.refreshInterval }]);
1198
1205
  }
1199
1206
 
1200
1207
  return true;
package/src/restful.js CHANGED
@@ -20,27 +20,35 @@ class RestFul extends EventEmitter {
20
20
  const restFul = express();
21
21
  restFul.set('json spaces', 2);
22
22
  restFul.use(json());
23
+
24
+ // GET Routes
23
25
  restFul.get('/info', (req, res) => { res.json(this.restFulData.info) });
24
26
  restFul.get('/state', (req, res) => { res.json(this.restFulData.state) });
25
27
 
26
- //post data
28
+ // POST Route
27
29
  restFul.post('/', (req, res) => {
28
30
  try {
29
31
  const obj = req.body;
30
- const emitDebug = this.restFulDebug ? this.emit('debug', `RESTFul post data: ${JSON.stringify(obj, null, 2)}`) : false;
32
+ if (!obj || typeof obj !== 'object' || Object.keys(obj).length === 0) {
33
+ this.emit('warn', `RESTFul Invalid JSON payload`);
34
+ return res.status(400).json({ error: 'RESTFul Invalid JSON payload' });
35
+ }
31
36
  const key = Object.keys(obj)[0];
32
- const value = Object.values(obj)[0];
37
+ const value = obj[key];
33
38
  this.emit('set', key, value);
34
- res.send('OK');
39
+
40
+ const emitDebug = this.restFulDebug ? this.emit('debug', `RESTFul post data: ${JSON.stringify(obj, null, 2)}`) : false;
41
+ res.json({ success: true, received: obj });
35
42
  } catch (error) {
36
- this.emit('warn', `RESTFul Parse object error: ${error}`);
37
- };
43
+ this.emit('warn', `RESTFul Parse error: ${error}`);
44
+ res.status(500).json({ error: 'RESTFul Internal Server Error' });
45
+ }
38
46
  });
39
47
 
48
+ // Start server
40
49
  restFul.listen(this.restFulPort, () => {
41
- this.emit('connected', `RESTful started on port: ${this.restFulPort}`)
50
+ this.emit('connected', `RESTful started on port: ${this.restFulPort}`);
42
51
  });
43
-
44
52
  } catch (error) {
45
53
  this.emit('warn', `RESTful Connect error: ${error}`)
46
54
  }