homebridge-melcloud-control 4.2.3-beta.44 → 4.2.3-beta.46
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/config.schema.json +285 -0
- package/homebridge-ui/public/index.html +45 -7
- package/package.json +1 -1
- package/src/deviceata.js +83 -2
- package/src/deviceatw.js +1 -0
- package/src/deviceerv.js +1 -0
- package/src/melcloudata.js +3 -1
package/config.schema.json
CHANGED
|
@@ -598,6 +598,75 @@
|
|
|
598
598
|
]
|
|
599
599
|
}
|
|
600
600
|
},
|
|
601
|
+
"scenes": {
|
|
602
|
+
"title": "Scenes",
|
|
603
|
+
"type": "array",
|
|
604
|
+
"items": {
|
|
605
|
+
"type": "object",
|
|
606
|
+
"properties": {
|
|
607
|
+
"id": {
|
|
608
|
+
"title": "Id",
|
|
609
|
+
"type": "string",
|
|
610
|
+
"default": "0"
|
|
611
|
+
},
|
|
612
|
+
"displayType": {
|
|
613
|
+
"title": "Display Type",
|
|
614
|
+
"type": "integer",
|
|
615
|
+
"minimum": 0,
|
|
616
|
+
"maximum": 3,
|
|
617
|
+
"default": 0,
|
|
618
|
+
"description": "Select the characteristic type to be displayed in HomeKit app.",
|
|
619
|
+
"anyOf": [
|
|
620
|
+
{
|
|
621
|
+
"title": "None/Disabled",
|
|
622
|
+
"enum": [
|
|
623
|
+
0
|
|
624
|
+
]
|
|
625
|
+
},
|
|
626
|
+
{
|
|
627
|
+
"title": "Motion Sensor",
|
|
628
|
+
"enum": [
|
|
629
|
+
1
|
|
630
|
+
]
|
|
631
|
+
},
|
|
632
|
+
{
|
|
633
|
+
"title": "Occupancy Sensor",
|
|
634
|
+
"enum": [
|
|
635
|
+
2
|
|
636
|
+
]
|
|
637
|
+
},
|
|
638
|
+
{
|
|
639
|
+
"title": "Contact Sensor",
|
|
640
|
+
"enum": [
|
|
641
|
+
3
|
|
642
|
+
]
|
|
643
|
+
}
|
|
644
|
+
]
|
|
645
|
+
},
|
|
646
|
+
"name": {
|
|
647
|
+
"title": "Name",
|
|
648
|
+
"type": "string",
|
|
649
|
+
"default": "Schedule",
|
|
650
|
+
"description": "Your own name displayed in Homebridge/HomeKit app.",
|
|
651
|
+
"condition": {
|
|
652
|
+
"functionBody": "return model.accounts[arrayIndices[0]].ataDevices[arrayIndices[1]].scenes[arrayIndices[2]].displayType > 0;"
|
|
653
|
+
}
|
|
654
|
+
},
|
|
655
|
+
"namePrefix": {
|
|
656
|
+
"title": "Prefix",
|
|
657
|
+
"type": "boolean",
|
|
658
|
+
"default": false,
|
|
659
|
+
"description": "Enable/disable the accessory name as a prefix for schedule name.",
|
|
660
|
+
"condition": {
|
|
661
|
+
"functionBody": "return model.accounts[arrayIndices[0]].ataDevices[arrayIndices[1]].scenes[arrayIndices[2]].displayType > 0;"
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
},
|
|
665
|
+
"required": [
|
|
666
|
+
"displayType"
|
|
667
|
+
]
|
|
668
|
+
}
|
|
669
|
+
},
|
|
601
670
|
"buttonsSensors": {
|
|
602
671
|
"title": "Button / Sensor",
|
|
603
672
|
"type": "array",
|
|
@@ -1304,6 +1373,75 @@
|
|
|
1304
1373
|
]
|
|
1305
1374
|
}
|
|
1306
1375
|
},
|
|
1376
|
+
"scenes": {
|
|
1377
|
+
"title": "Scenes",
|
|
1378
|
+
"type": "array",
|
|
1379
|
+
"items": {
|
|
1380
|
+
"type": "object",
|
|
1381
|
+
"properties": {
|
|
1382
|
+
"id": {
|
|
1383
|
+
"title": "Id",
|
|
1384
|
+
"type": "string",
|
|
1385
|
+
"default": "0"
|
|
1386
|
+
},
|
|
1387
|
+
"displayType": {
|
|
1388
|
+
"title": "Display Type",
|
|
1389
|
+
"type": "integer",
|
|
1390
|
+
"minimum": 0,
|
|
1391
|
+
"maximum": 3,
|
|
1392
|
+
"default": 0,
|
|
1393
|
+
"description": "Select the characteristic type to be displayed in HomeKit app.",
|
|
1394
|
+
"anyOf": [
|
|
1395
|
+
{
|
|
1396
|
+
"title": "None/Disabled",
|
|
1397
|
+
"enum": [
|
|
1398
|
+
0
|
|
1399
|
+
]
|
|
1400
|
+
},
|
|
1401
|
+
{
|
|
1402
|
+
"title": "Motion Sensor",
|
|
1403
|
+
"enum": [
|
|
1404
|
+
1
|
|
1405
|
+
]
|
|
1406
|
+
},
|
|
1407
|
+
{
|
|
1408
|
+
"title": "Occupancy Sensor",
|
|
1409
|
+
"enum": [
|
|
1410
|
+
2
|
|
1411
|
+
]
|
|
1412
|
+
},
|
|
1413
|
+
{
|
|
1414
|
+
"title": "Contact Sensor",
|
|
1415
|
+
"enum": [
|
|
1416
|
+
3
|
|
1417
|
+
]
|
|
1418
|
+
}
|
|
1419
|
+
]
|
|
1420
|
+
},
|
|
1421
|
+
"name": {
|
|
1422
|
+
"title": "Name",
|
|
1423
|
+
"type": "string",
|
|
1424
|
+
"default": "Schedule",
|
|
1425
|
+
"description": "Your own name displayed in Homebridge/HomeKit app.",
|
|
1426
|
+
"condition": {
|
|
1427
|
+
"functionBody": "return model.accounts[arrayIndices[0]].atwDevices[arrayIndices[1]].scenes[arrayIndices[2]].displayType > 0;"
|
|
1428
|
+
}
|
|
1429
|
+
},
|
|
1430
|
+
"namePrefix": {
|
|
1431
|
+
"title": "Prefix",
|
|
1432
|
+
"type": "boolean",
|
|
1433
|
+
"default": false,
|
|
1434
|
+
"description": "Enable/disable the accessory name as a prefix for schedule name.",
|
|
1435
|
+
"condition": {
|
|
1436
|
+
"functionBody": "return model.accounts[arrayIndices[0]].atwDevices[arrayIndices[1]].scenes[arrayIndices[2]].displayType > 0;"
|
|
1437
|
+
}
|
|
1438
|
+
}
|
|
1439
|
+
},
|
|
1440
|
+
"required": [
|
|
1441
|
+
"displayType"
|
|
1442
|
+
]
|
|
1443
|
+
}
|
|
1444
|
+
},
|
|
1307
1445
|
"buttonsSensors": {
|
|
1308
1446
|
"title": "Button",
|
|
1309
1447
|
"type": "array",
|
|
@@ -1792,6 +1930,75 @@
|
|
|
1792
1930
|
]
|
|
1793
1931
|
}
|
|
1794
1932
|
},
|
|
1933
|
+
"scenes": {
|
|
1934
|
+
"title": "Scenes",
|
|
1935
|
+
"type": "array",
|
|
1936
|
+
"items": {
|
|
1937
|
+
"type": "object",
|
|
1938
|
+
"properties": {
|
|
1939
|
+
"id": {
|
|
1940
|
+
"title": "Id",
|
|
1941
|
+
"type": "string",
|
|
1942
|
+
"default": "0"
|
|
1943
|
+
},
|
|
1944
|
+
"displayType": {
|
|
1945
|
+
"title": "Display Type",
|
|
1946
|
+
"type": "integer",
|
|
1947
|
+
"minimum": 0,
|
|
1948
|
+
"maximum": 3,
|
|
1949
|
+
"default": 0,
|
|
1950
|
+
"description": "Select the characteristic type to be displayed in HomeKit app.",
|
|
1951
|
+
"anyOf": [
|
|
1952
|
+
{
|
|
1953
|
+
"title": "None/Disabled",
|
|
1954
|
+
"enum": [
|
|
1955
|
+
0
|
|
1956
|
+
]
|
|
1957
|
+
},
|
|
1958
|
+
{
|
|
1959
|
+
"title": "Motion Sensor",
|
|
1960
|
+
"enum": [
|
|
1961
|
+
1
|
|
1962
|
+
]
|
|
1963
|
+
},
|
|
1964
|
+
{
|
|
1965
|
+
"title": "Occupancy Sensor",
|
|
1966
|
+
"enum": [
|
|
1967
|
+
2
|
|
1968
|
+
]
|
|
1969
|
+
},
|
|
1970
|
+
{
|
|
1971
|
+
"title": "Contact Sensor",
|
|
1972
|
+
"enum": [
|
|
1973
|
+
3
|
|
1974
|
+
]
|
|
1975
|
+
}
|
|
1976
|
+
]
|
|
1977
|
+
},
|
|
1978
|
+
"name": {
|
|
1979
|
+
"title": "Name",
|
|
1980
|
+
"type": "string",
|
|
1981
|
+
"default": "Schedule",
|
|
1982
|
+
"description": "Your own name displayed in Homebridge/HomeKit app.",
|
|
1983
|
+
"condition": {
|
|
1984
|
+
"functionBody": "return model.accounts[arrayIndices[0]].ervDevices[arrayIndices[1]].scenes[arrayIndices[2]].displayType > 0;"
|
|
1985
|
+
}
|
|
1986
|
+
},
|
|
1987
|
+
"namePrefix": {
|
|
1988
|
+
"title": "Prefix",
|
|
1989
|
+
"type": "boolean",
|
|
1990
|
+
"default": false,
|
|
1991
|
+
"description": "Enable/disable the accessory name as a prefix for schedule name.",
|
|
1992
|
+
"condition": {
|
|
1993
|
+
"functionBody": "return model.accounts[arrayIndices[0]].ervDevices[arrayIndices[1]].scenes[arrayIndices[2]].displayType > 0;"
|
|
1994
|
+
}
|
|
1995
|
+
}
|
|
1996
|
+
},
|
|
1997
|
+
"required": [
|
|
1998
|
+
"displayType"
|
|
1999
|
+
]
|
|
2000
|
+
}
|
|
2001
|
+
},
|
|
1795
2002
|
"buttonsSensors": {
|
|
1796
2003
|
"title": "Buttons",
|
|
1797
2004
|
"type": "array",
|
|
@@ -2236,6 +2443,32 @@
|
|
|
2236
2443
|
"functionBody": "return model.accounts[arrayIndices[0]].type === 'melcloudhome' && model.accounts[arrayIndices[0]].ataDevices[arrayIndices[1]].displayType > 0;"
|
|
2237
2444
|
}
|
|
2238
2445
|
},
|
|
2446
|
+
{
|
|
2447
|
+
"title": "Scenes",
|
|
2448
|
+
"type": "section",
|
|
2449
|
+
"description": "Section for setup device scenes",
|
|
2450
|
+
"expandable": true,
|
|
2451
|
+
"expanded": false,
|
|
2452
|
+
"items": [
|
|
2453
|
+
{
|
|
2454
|
+
"key": "accounts[].ataDevices[].scenes",
|
|
2455
|
+
"type": "tabarray",
|
|
2456
|
+
"title": "{{ value.name }}",
|
|
2457
|
+
"items": [
|
|
2458
|
+
{
|
|
2459
|
+
"key": "accounts[].ataDevices[].scenes[].id",
|
|
2460
|
+
"readonly": true
|
|
2461
|
+
},
|
|
2462
|
+
"accounts[].ataDevices[].scenes[].displayType",
|
|
2463
|
+
"accounts[].ataDevices[].scenes[].name",
|
|
2464
|
+
"accounts[].ataDevices[].scenes[].namePrefix"
|
|
2465
|
+
]
|
|
2466
|
+
}
|
|
2467
|
+
],
|
|
2468
|
+
"condition": {
|
|
2469
|
+
"functionBody": "return model.accounts[arrayIndices[0]].type === 'melcloudhome' && model.accounts[arrayIndices[0]].ataDevices[arrayIndices[1]].displayType > 0;"
|
|
2470
|
+
}
|
|
2471
|
+
},
|
|
2239
2472
|
{
|
|
2240
2473
|
"title": "Buttons / Sensors",
|
|
2241
2474
|
"type": "section",
|
|
@@ -2382,6 +2615,32 @@
|
|
|
2382
2615
|
"functionBody": "return model.accounts[arrayIndices[0]].type === 'melcloudhome' && model.accounts[arrayIndices[0]].atwDevices[arrayIndices[1]].displayType > 0;"
|
|
2383
2616
|
}
|
|
2384
2617
|
},
|
|
2618
|
+
{
|
|
2619
|
+
"title": "Scenes",
|
|
2620
|
+
"type": "section",
|
|
2621
|
+
"description": "Section for setup device scenes",
|
|
2622
|
+
"expandable": true,
|
|
2623
|
+
"expanded": false,
|
|
2624
|
+
"items": [
|
|
2625
|
+
{
|
|
2626
|
+
"key": "accounts[].atwDevices[].scenes",
|
|
2627
|
+
"type": "tabarray",
|
|
2628
|
+
"title": "{{ value.name }}",
|
|
2629
|
+
"items": [
|
|
2630
|
+
{
|
|
2631
|
+
"key": "accounts[].atwDevices[].scenes[].id",
|
|
2632
|
+
"readonly": true
|
|
2633
|
+
},
|
|
2634
|
+
"accounts[].atwDevices[].scenes[].displayType",
|
|
2635
|
+
"accounts[].atwDevices[].scenes[].name",
|
|
2636
|
+
"accounts[].atwDevices[].scenes[].namePrefix"
|
|
2637
|
+
]
|
|
2638
|
+
}
|
|
2639
|
+
],
|
|
2640
|
+
"condition": {
|
|
2641
|
+
"functionBody": "return model.accounts[arrayIndices[0]].type === 'melcloudhome' && model.accounts[arrayIndices[0]].atwDevices[arrayIndices[1]].displayType > 0;"
|
|
2642
|
+
}
|
|
2643
|
+
},
|
|
2385
2644
|
{
|
|
2386
2645
|
"title": "Buttons / Sensors",
|
|
2387
2646
|
"type": "section",
|
|
@@ -2534,6 +2793,32 @@
|
|
|
2534
2793
|
"functionBody": "return model.accounts[arrayIndices[0]].type === 'melcloudhome' && model.accounts[arrayIndices[0]].ervDevices[arrayIndices[1]].displayType > 0;"
|
|
2535
2794
|
}
|
|
2536
2795
|
},
|
|
2796
|
+
{
|
|
2797
|
+
"title": "Scenes",
|
|
2798
|
+
"type": "section",
|
|
2799
|
+
"description": "Section for setup device scenes",
|
|
2800
|
+
"expandable": true,
|
|
2801
|
+
"expanded": false,
|
|
2802
|
+
"items": [
|
|
2803
|
+
{
|
|
2804
|
+
"key": "accounts[].ervDevices[].scenes",
|
|
2805
|
+
"type": "tabarray",
|
|
2806
|
+
"title": "{{ value.name }}",
|
|
2807
|
+
"items": [
|
|
2808
|
+
{
|
|
2809
|
+
"key": "accounts[].ervDevices[].scenes[].id",
|
|
2810
|
+
"readonly": true
|
|
2811
|
+
},
|
|
2812
|
+
"accounts[].ervDevices[].scenes[].displayType",
|
|
2813
|
+
"accounts[].ervDevices[].scenes[].name",
|
|
2814
|
+
"accounts[].ervDevices[].scenes[].namePrefix"
|
|
2815
|
+
]
|
|
2816
|
+
}
|
|
2817
|
+
],
|
|
2818
|
+
"condition": {
|
|
2819
|
+
"functionBody": "return model.accounts[arrayIndices[0]].type === 'melcloudhome' && model.accounts[arrayIndices[0]].ervDevices[arrayIndices[1]].displayType > 0;"
|
|
2820
|
+
}
|
|
2821
|
+
},
|
|
2537
2822
|
{
|
|
2538
2823
|
"title": "Buttons / Sensors",
|
|
2539
2824
|
"type": "section",
|
|
@@ -246,10 +246,11 @@
|
|
|
246
246
|
}
|
|
247
247
|
|
|
248
248
|
// Initialize devices arrays
|
|
249
|
-
const newDevices = { ata: [], ataPresets: [], atw: [], atwPresets: [], erv: [], ervPresets: [] };
|
|
249
|
+
const newDevices = { ata: [], ataPresets: [], atw: [], atwPresets: [], erv: [], ervPresets: [], scenes: [] };
|
|
250
250
|
const devicesByType = { ata: [], atw: [], erv: [] };
|
|
251
251
|
|
|
252
252
|
response.Devices.forEach(d => {
|
|
253
|
+
d.Scenes = response.Scenes ?? [];
|
|
253
254
|
if (d.Type === 0) devicesByType.ata.push(d);
|
|
254
255
|
if (d.Type === 1) devicesByType.atw.push(d);
|
|
255
256
|
if (d.Type === 3) devicesByType.erv.push(d);
|
|
@@ -263,7 +264,7 @@
|
|
|
263
264
|
const removedAtw = removeStaleDevices(account.atwDevices, devicesByType.atw);
|
|
264
265
|
const removedErv = removeStaleDevices(account.ervDevices, devicesByType.erv);
|
|
265
266
|
|
|
266
|
-
const handleDevices = (devicesInMelCloud, devicesInConfig, typeString, newArr, newPresets) => {
|
|
267
|
+
const handleDevices = (devicesInMelCloud, devicesInConfig, typeString, newArr, newPresets, newScenes) => {
|
|
267
268
|
try {
|
|
268
269
|
const configDevicesMap = new Map(devicesInConfig.map(dev => [String(dev.id), dev]));
|
|
269
270
|
const isMelcloud = account.type === 'melcloud';
|
|
@@ -286,6 +287,7 @@
|
|
|
286
287
|
name: device.DeviceName,
|
|
287
288
|
presets: [],
|
|
288
289
|
schedules: [],
|
|
290
|
+
scenes: [],
|
|
289
291
|
buttonsSensors: []
|
|
290
292
|
};
|
|
291
293
|
devicesInConfig.push(deviceInConfig);
|
|
@@ -326,6 +328,41 @@
|
|
|
326
328
|
updateInfo('info2', `Removed ${removedCount} placeholder ${typeKey1} from device ${device.DeviceID}`, 'yellow');
|
|
327
329
|
}
|
|
328
330
|
}
|
|
331
|
+
|
|
332
|
+
// === Process scenes ===
|
|
333
|
+
const scenes = device.Scenes || [];
|
|
334
|
+
const scenesInConfig = deviceInConfig.Scenes || [];
|
|
335
|
+
const scenesIds = new Set(scenesInConfig.map(s => String(s.id)));
|
|
336
|
+
|
|
337
|
+
let addedNewScenes = false;
|
|
338
|
+
|
|
339
|
+
scenes.forEach((scene, index) => {
|
|
340
|
+
const sceneId = String(scene.id);
|
|
341
|
+
if (!scenesIds.has(sceneId)) {
|
|
342
|
+
const sceneObj = {
|
|
343
|
+
id: sceneId,
|
|
344
|
+
displayType: 0,
|
|
345
|
+
name: scene.Name || `Scene ${index}`,
|
|
346
|
+
namePrefix: false
|
|
347
|
+
};
|
|
348
|
+
scenesInConfig.push(sceneObj);
|
|
349
|
+
newScenes.push(sceneObj);
|
|
350
|
+
scenesIds.add(sceneObj);
|
|
351
|
+
addedNewScenes = true;
|
|
352
|
+
}
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
// === Remove placeholder scenes (id === '0') if new ones were added ===
|
|
356
|
+
if (addedNewScenes) {
|
|
357
|
+
const beforeCount = scenesInConfig.length;
|
|
358
|
+
deviceInConfig.Scenes = scenesInConfig.filter(s => String(s.id) !== '0');
|
|
359
|
+
const removedCount = beforeCount - deviceInConfig.Scenes.length;
|
|
360
|
+
|
|
361
|
+
if (removedCount > 0 && removedCount < beforeCount) {
|
|
362
|
+
updateInfo('info2', `Removed ${removedCount} placeholder scene from device ${device.DeviceID}`, 'yellow');
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
|
|
329
366
|
});
|
|
330
367
|
|
|
331
368
|
// Return filtered devicesInConfig to make sure upstream code uses it
|
|
@@ -336,12 +373,13 @@
|
|
|
336
373
|
}
|
|
337
374
|
};
|
|
338
375
|
|
|
339
|
-
account.ataDevices = handleDevices(devicesByType.ata, account.ataDevices, "Air Conditioner", newDevices.ata, newDevices.ataPresets);
|
|
340
|
-
account.atwDevices = handleDevices(devicesByType.atw, account.atwDevices, "Heat Pump", newDevices.atw, newDevices.atwPresets);
|
|
341
|
-
account.ervDevices = handleDevices(devicesByType.erv, account.ervDevices, "Energy Recovery Ventilation", newDevices.erv, newDevices.ervPresets);
|
|
376
|
+
account.ataDevices = handleDevices(devicesByType.ata, account.ataDevices, "Air Conditioner", newDevices.ata, newDevices.ataPresets, newDevices.scenes);
|
|
377
|
+
account.atwDevices = handleDevices(devicesByType.atw, account.atwDevices, "Heat Pump", newDevices.atw, newDevices.atwPresets, newDevices.scenes);
|
|
378
|
+
account.ervDevices = handleDevices(devicesByType.erv, account.ervDevices, "Energy Recovery Ventilation", newDevices.erv, newDevices.ervPresets, newDevices.scenes);
|
|
342
379
|
|
|
343
380
|
const newDevicesCount = newDevices.ata.length + newDevices.atw.length + newDevices.erv.length;
|
|
344
381
|
const newPresetsCount = newDevices.ataPresets.length + newDevices.atwPresets.length + newDevices.ervPresets.length;
|
|
382
|
+
const newScenesCount = newDevices.scenes.length;
|
|
345
383
|
const removedDevicesCount = removedAta.length + removedAtw.length + removedErv.length;
|
|
346
384
|
|
|
347
385
|
if (!newDevicesCount && !newPresetsCount && !removedDevicesCount) {
|
|
@@ -349,8 +387,8 @@
|
|
|
349
387
|
} else {
|
|
350
388
|
if (newDevicesCount)
|
|
351
389
|
updateInfo('info', `Found new devices: ATA: ${newDevices.ata.length}, ATW: ${newDevices.atw.length}, ERV: ${newDevices.erv.length}.`, 'green');
|
|
352
|
-
if (newPresetsCount)
|
|
353
|
-
updateInfo('info1', `Found new ${account.type === 'melcloud' ? 'presets' : 'schedules'}: ATA: ${newDevices.ataPresets.length}, ATW: ${newDevices.atwPresets.length}, ERV: ${newDevices.ervPresets.length}.`, 'green');
|
|
390
|
+
if (newPresetsCount || newScenesCount)
|
|
391
|
+
updateInfo('info1', `Found new ${account.type === 'melcloud' ? 'presets' : 'schedules'}: ATA: ${newDevices.ataPresets.length}, ATW: ${newDevices.atwPresets.length}, ERV: ${newDevices.ervPresets.length}, Scenes: ${newDevices.scenes.length}.`, 'green');
|
|
354
392
|
if (removedDevicesCount)
|
|
355
393
|
updateInfo('info2', `Removed devices: ATA: ${removedAta.length}, ATW: ${removedAtw.length}, ERV: ${removedErv.length}.`, 'orange');
|
|
356
394
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"displayName": "MELCloud Control",
|
|
3
3
|
"name": "homebridge-melcloud-control",
|
|
4
|
-
"version": "4.2.3-beta.
|
|
4
|
+
"version": "4.2.3-beta.46",
|
|
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
|
@@ -43,6 +43,7 @@ class DeviceAta extends EventEmitter {
|
|
|
43
43
|
this.holidayModeSupport = device.holidayModeSupport || false;
|
|
44
44
|
this.presets = this.accountType === 'melcloud' ? (device.presets || []).filter(preset => (preset.displayType ?? 0) > 0 && preset.id !== '0') : [];
|
|
45
45
|
this.schedules = this.accountType === 'melcloudhome' ? (device.schedules || []).filter(schedule => (schedule.displayType ?? 0) > 0 && schedule.id !== '0') : [];
|
|
46
|
+
this.scenes = this.accountType === 'melcloudhome' ? (device.scenes || []).filter(scene => (scene.displayType ?? 0) > 0 && scene.id !== '0') : [];
|
|
46
47
|
this.buttons = (device.buttonsSensors || []).filter(sensor => (sensor.displayType ?? 0) > 0);
|
|
47
48
|
|
|
48
49
|
//files
|
|
@@ -73,6 +74,14 @@ class DeviceAta extends EventEmitter {
|
|
|
73
74
|
schedule.state = false;
|
|
74
75
|
}
|
|
75
76
|
|
|
77
|
+
//scenes configured
|
|
78
|
+
for (const scene of this.scenes) {
|
|
79
|
+
scene.name = schedule.name || 'Schedule'
|
|
80
|
+
scene.serviceType = [null, Service.MotionSensor, Service.OccupancySensor, Service.ContactSensor][scene.displayType];
|
|
81
|
+
scene.characteristicType = [null, Characteristic.MotionDetected, Characteristic.OccupancyDetected, Characteristic.ContactSensorState][scene.displayType];
|
|
82
|
+
scene.state = false;
|
|
83
|
+
}
|
|
84
|
+
|
|
76
85
|
//buttons configured
|
|
77
86
|
for (const button of this.buttons) {
|
|
78
87
|
button.name = button.name || 'Button'
|
|
@@ -292,6 +301,7 @@ class DeviceAta extends EventEmitter {
|
|
|
292
301
|
const accountName = this.accountName;
|
|
293
302
|
const presetsOnServer = this.accessory.presets;
|
|
294
303
|
const schedulesOnServer = this.accessory.schedules;
|
|
304
|
+
const scenesOnServer = this.accessory.scenes;
|
|
295
305
|
const supportsHeat = this.accessory.supportsHeat;
|
|
296
306
|
const supportsDry = this.accessory.supportsDry;
|
|
297
307
|
const supportsCool = this.accessory.supportsCool;
|
|
@@ -908,7 +918,7 @@ class DeviceAta extends EventEmitter {
|
|
|
908
918
|
//control
|
|
909
919
|
if (i === 0) {
|
|
910
920
|
if (this.logDebug) this.emit('debug', `Prepare schedule control service`);
|
|
911
|
-
this.schedulesControlService = new Service.Switch(`${serviceName} Schedule`, `schedulesControlService${deviceId}
|
|
921
|
+
this.schedulesControlService = new Service.Switch(`${serviceName} Schedule`, `schedulesControlService${deviceId}`);
|
|
912
922
|
this.schedulesControlService.addOptionalCharacteristic(Characteristic.ConfiguredName);
|
|
913
923
|
this.schedulesControlService.setCharacteristic(Characteristic.ConfiguredName, `${accessoryName} Schedule`);
|
|
914
924
|
this.schedulesControlService.getCharacteristic(Characteristic.On)
|
|
@@ -956,6 +966,60 @@ class DeviceAta extends EventEmitter {
|
|
|
956
966
|
});
|
|
957
967
|
};
|
|
958
968
|
|
|
969
|
+
//scenes
|
|
970
|
+
if (this.scenes.length > 0) {
|
|
971
|
+
if (this.logDebug) this.emit('debug', `Prepare scenes services`);
|
|
972
|
+
this.scenesControlServices = [];
|
|
973
|
+
this.scenesControlSensorServices = [];
|
|
974
|
+
this.sccenes.forEach((scene, i) => {
|
|
975
|
+
const sceneData = scenesOnServer.find(s => s.Id === scene.id);
|
|
976
|
+
|
|
977
|
+
//get id
|
|
978
|
+
const id = scene.id;
|
|
979
|
+
|
|
980
|
+
//get preset name
|
|
981
|
+
const name = scene.name;
|
|
982
|
+
|
|
983
|
+
//get preset name prefix
|
|
984
|
+
const namePrefix = scene.namePrefix;
|
|
985
|
+
|
|
986
|
+
//control
|
|
987
|
+
if (this.logDebug) this.emit('debug', `Prepare scene control service`);
|
|
988
|
+
const serviceName1 = namePrefix ? `${accessoryName} ${name}` : name;
|
|
989
|
+
const sceneControlService = new Service.Switch(serviceName1, `sceneControlService${id}`);
|
|
990
|
+
sceneControlService.addOptionalCharacteristic(Characteristic.ConfiguredName);
|
|
991
|
+
sceneControlService.setCharacteristic(Characteristic.ConfiguredName, serviceName1);
|
|
992
|
+
sceneControlService.getCharacteristic(Characteristic.On)
|
|
993
|
+
.onGet(async () => {
|
|
994
|
+
const state = scene.state;
|
|
995
|
+
return state;
|
|
996
|
+
})
|
|
997
|
+
.onSet(async (state) => {
|
|
998
|
+
try {
|
|
999
|
+
sceneData.Enabled = state;
|
|
1000
|
+
await this.melCloudAta.send(this.accountType, this.displayType, sceneData, 'scene');
|
|
1001
|
+
if (this.logInfo) this.emit('info', `Scene ${name}: ${state ? 'Enabled' : 'Disabled'}`);
|
|
1002
|
+
} catch (error) {
|
|
1003
|
+
if (this.logWarn) this.emit('warn', `Set scene error: ${error}`);
|
|
1004
|
+
};
|
|
1005
|
+
});
|
|
1006
|
+
this.scenesControlServices.push(sceneControlService);
|
|
1007
|
+
accessory.addService(sceneControlService);
|
|
1008
|
+
|
|
1009
|
+
if (this.logDebug) this.emit('debug', `Prepare scene control sensor service`);
|
|
1010
|
+
const sceneControlSensorService = new Service.ContactSensor(serviceName1, `sceneControlSensorService${id}`);
|
|
1011
|
+
sceneControlSensorService.addOptionalCharacteristic(Characteristic.ConfiguredName);
|
|
1012
|
+
sceneControlSensorService.setCharacteristic(Characteristic.ConfiguredName, serviceName1);
|
|
1013
|
+
sceneControlSensorService.getCharacteristic(Characteristic.ContactSensorState)
|
|
1014
|
+
.onGet(async () => {
|
|
1015
|
+
const state = scene.state;
|
|
1016
|
+
return state;
|
|
1017
|
+
})
|
|
1018
|
+
this.scenesControlSensorServices.push(sceneControlSensorService);
|
|
1019
|
+
accessory.addService(sceneControlSensorService);
|
|
1020
|
+
});
|
|
1021
|
+
};
|
|
1022
|
+
|
|
959
1023
|
//buttons services
|
|
960
1024
|
if (this.buttons.length > 0) {
|
|
961
1025
|
if (this.logDebug) this.emit('debug', `Prepare buttons/sensors services`);
|
|
@@ -1249,9 +1313,10 @@ class DeviceAta extends EventEmitter {
|
|
|
1249
1313
|
const supportStandbyKey = accountTypeMelcloud ? 'ModelSupportsStandbyMode' : 'HasStandby';
|
|
1250
1314
|
|
|
1251
1315
|
//presets schedules
|
|
1316
|
+
const presetsOnServer = deviceData.Presets ?? [];
|
|
1252
1317
|
const scheduleEnabled = deviceData.ScheduleEnabled;
|
|
1253
1318
|
const schedulesOnServer = deviceData.Schedule ?? [];
|
|
1254
|
-
const
|
|
1319
|
+
const scenesOnServer = deviceData.Scenes ?? [];
|
|
1255
1320
|
const holidayModeEnabled = deviceData.HolidayMode?.Enabled;
|
|
1256
1321
|
const holidayModeActive = deviceData.HolidayMode?.Active ?? false;
|
|
1257
1322
|
|
|
@@ -1313,6 +1378,7 @@ class DeviceAta extends EventEmitter {
|
|
|
1313
1378
|
const obj = {
|
|
1314
1379
|
presets: presetsOnServer,
|
|
1315
1380
|
schedules: schedulesOnServer,
|
|
1381
|
+
scenes: scenesOnServer,
|
|
1316
1382
|
supportsAutomaticFanSpeed: supportsAutomaticFanSpeed,
|
|
1317
1383
|
supportsAirDirectionFunction: supportsAirDirectionFunction,
|
|
1318
1384
|
supportsSwingFunction: supportsSwingFunction,
|
|
@@ -1568,6 +1634,21 @@ class DeviceAta extends EventEmitter {
|
|
|
1568
1634
|
});
|
|
1569
1635
|
};
|
|
1570
1636
|
|
|
1637
|
+
//schedules
|
|
1638
|
+
if (this.scenes.length > 0) {
|
|
1639
|
+
this.scenes.forEach((scene, i) => {
|
|
1640
|
+
const sceneData = scenesOnServer.find(s => s.Id === scene.id);
|
|
1641
|
+
scene.state = sceneData.Enabled;
|
|
1642
|
+
|
|
1643
|
+
//control
|
|
1644
|
+
this.scenesControlServices?.[i]?.updateCharacteristic(Characteristic.On, scene.state);
|
|
1645
|
+
|
|
1646
|
+
//sensors
|
|
1647
|
+
const characteristicType = scene.characteristicType;
|
|
1648
|
+
this.scenesControlSensorServices?.[i]?.updateCharacteristic(characteristicType, scene.state);
|
|
1649
|
+
});
|
|
1650
|
+
};
|
|
1651
|
+
|
|
1571
1652
|
//buttons
|
|
1572
1653
|
if (this.buttons.length > 0) {
|
|
1573
1654
|
this.buttons.forEach((button, i) => {
|
package/src/deviceatw.js
CHANGED
|
@@ -43,6 +43,7 @@ class DeviceAtw extends EventEmitter {
|
|
|
43
43
|
this.holidayModeSupport = device.holidayModeSupport || false;
|
|
44
44
|
this.presets = this.accountType === 'melcloud' ? (device.presets || []).filter(preset => (preset.displayType ?? 0) > 0 && preset.id !== '0') : [];
|
|
45
45
|
this.schedules = this.accountType === 'melcloudhome' ? (device.schedules || []).filter(schedule => (schedule.displayType ?? 0) > 0 && schedule.id !== '0') : [];
|
|
46
|
+
this.scenes = this.accountType === 'melcloudhome' ? (device.scenes || []).filter(scene => (scene.displayType ?? 0) > 0 && scene.id !== '0') : [];
|
|
46
47
|
this.buttons = (device.buttonsSensors || []).filter(button => (button.displayType ?? 0) > 0);
|
|
47
48
|
this.deviceId = device.id;
|
|
48
49
|
this.deviceName = device.name;
|
package/src/deviceerv.js
CHANGED
|
@@ -36,6 +36,7 @@ class DeviceErv extends EventEmitter {
|
|
|
36
36
|
this.holidayModeSupport = device.holidayModeSupport || false;
|
|
37
37
|
this.presets = this.accountType === 'melcloud' ? (device.presets || []).filter(preset => (preset.displayType ?? 0) > 0 && preset.id !== '0') : [];
|
|
38
38
|
this.schedules = this.accountType === 'melcloudhome' ? (device.schedules || []).filter(schedule => (schedule.displayType ?? 0) > 0 && schedule.id !== '0') : [];
|
|
39
|
+
this.scenes = this.accountType === 'melcloudhome' ? (device.scenes || []).filter(scene => (scene.displayType ?? 0) > 0 && scene.id !== '0') : [];
|
|
39
40
|
this.buttons = (device.buttonsSensors || []).filter(button => (button.displayType ?? 0) > 0);
|
|
40
41
|
this.deviceId = device.id;
|
|
41
42
|
this.deviceName = device.name;
|
package/src/melcloudata.js
CHANGED
|
@@ -52,9 +52,11 @@ class MelCloudAta extends EventEmitter {
|
|
|
52
52
|
try {
|
|
53
53
|
//read device info from file
|
|
54
54
|
const devicesData = await this.functions.readData(this.devicesFile, true);
|
|
55
|
+
const scenes = devicesData.Scenes ?? [];
|
|
55
56
|
const deviceData = devicesData.Devices.find(device => device.DeviceID === this.deviceId);
|
|
56
57
|
|
|
57
58
|
if (this.accountType === 'melcloudhome') {
|
|
59
|
+
deviceData.Scenes = scenes;
|
|
58
60
|
deviceData.Device.OperationMode = AirConditioner.OperationModeMapStringToEnum[deviceData.Device.OperationMode] ?? deviceData.Device.OperationMode;
|
|
59
61
|
deviceData.Device.ActualFanSpeed = AirConditioner.FanSpeedMapStringToEnum[deviceData.Device.ActualFanSpeed] ?? deviceData.Device.ActualFanSpeed;
|
|
60
62
|
deviceData.Device.SetFanSpeed = AirConditioner.FanSpeedMapStringToEnum[deviceData.Device.SetFanSpeed] ?? deviceData.Device.SetFanSpeed;
|
|
@@ -223,7 +225,7 @@ class MelCloudAta extends EventEmitter {
|
|
|
223
225
|
break;
|
|
224
226
|
case 'scene':
|
|
225
227
|
method = 'PUT';
|
|
226
|
-
path = ApiUrlsHome.PutScene[deviceData.
|
|
228
|
+
path = ApiUrlsHome.PutScene[deviceData.Enabled ? 'Eneble' : 'Disable'].replace('sceneid', deviceData.Id);
|
|
227
229
|
deviceData.Headers.Referer = ApiUrlsHome.Referers.GetPutScenes;
|
|
228
230
|
break;
|
|
229
231
|
default:
|