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 +12 -0
- package/LICENSE +1 -1
- package/README.md +1 -1
- package/index.js +19 -5
- package/package.json +1 -1
- package/src/deviceata.js +10 -3
- package/src/deviceatw.js +10 -3
- package/src/deviceerv.js +10 -3
- package/src/restful.js +16 -8
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
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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
|
-
//
|
|
28
|
+
// POST Route
|
|
27
29
|
restFul.post('/', (req, res) => {
|
|
28
30
|
try {
|
|
29
31
|
const obj = req.body;
|
|
30
|
-
|
|
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 =
|
|
37
|
+
const value = obj[key];
|
|
33
38
|
this.emit('set', key, value);
|
|
34
|
-
|
|
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
|
|
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
|
}
|