homebridge-melcloud-control 4.3.2-beta.2 → 4.3.2-beta.21
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/package.json +1 -1
- package/src/deviceata.js +11 -11
- package/src/deviceatw.js +33 -33
- package/src/deviceerv.js +12 -12
- package/src/functions.js +7 -0
- package/src/melcloudata.js +109 -96
- package/src/melcloudhome.js +1 -5
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"displayName": "MELCloud Control",
|
|
3
3
|
"name": "homebridge-melcloud-control",
|
|
4
|
-
"version": "4.3.2-beta.
|
|
4
|
+
"version": "4.3.2-beta.21",
|
|
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
|
@@ -649,7 +649,7 @@ class DeviceAta extends EventEmitter {
|
|
|
649
649
|
return state;
|
|
650
650
|
})
|
|
651
651
|
accessory.addService(this.roomTemperatureSensorService);
|
|
652
|
-
}
|
|
652
|
+
}
|
|
653
653
|
|
|
654
654
|
if (this.temperatureOutdoorSensor && supportsOutdoorTemperature && this.accessory.outdoorTemperature !== null) {
|
|
655
655
|
if (this.logDebug) this.emit('debug', `Prepare outdoor temperature sensor service`);
|
|
@@ -662,7 +662,7 @@ class DeviceAta extends EventEmitter {
|
|
|
662
662
|
return state;
|
|
663
663
|
})
|
|
664
664
|
accessory.addService(this.outdoorTemperatureSensorService);
|
|
665
|
-
}
|
|
665
|
+
}
|
|
666
666
|
|
|
667
667
|
//in standby sensor
|
|
668
668
|
if (this.inStandbySensor && this.accessory.inStandbyMode !== null) {
|
|
@@ -922,7 +922,7 @@ class DeviceAta extends EventEmitter {
|
|
|
922
922
|
accessory.addService(presetControlSensorService);
|
|
923
923
|
}
|
|
924
924
|
});
|
|
925
|
-
}
|
|
925
|
+
}
|
|
926
926
|
|
|
927
927
|
//schedules services
|
|
928
928
|
if (this.schedules.length > 0 && this.accessory.scheduleEnabled !== null) {
|
|
@@ -996,7 +996,7 @@ class DeviceAta extends EventEmitter {
|
|
|
996
996
|
accessory.addService(scheduleSensorService);
|
|
997
997
|
}
|
|
998
998
|
});
|
|
999
|
-
}
|
|
999
|
+
}
|
|
1000
1000
|
|
|
1001
1001
|
//scenes
|
|
1002
1002
|
if (this.scenes.length > 0) {
|
|
@@ -1055,7 +1055,7 @@ class DeviceAta extends EventEmitter {
|
|
|
1055
1055
|
accessory.addService(sceneControlSensorService);
|
|
1056
1056
|
}
|
|
1057
1057
|
});
|
|
1058
|
-
}
|
|
1058
|
+
}
|
|
1059
1059
|
|
|
1060
1060
|
//buttons services
|
|
1061
1061
|
if (this.buttons.length > 0) {
|
|
@@ -1318,7 +1318,7 @@ class DeviceAta extends EventEmitter {
|
|
|
1318
1318
|
accessory.addService(buttonControlSensorService);
|
|
1319
1319
|
}
|
|
1320
1320
|
});
|
|
1321
|
-
}
|
|
1321
|
+
}
|
|
1322
1322
|
|
|
1323
1323
|
return accessory;
|
|
1324
1324
|
} catch (error) {
|
|
@@ -1690,7 +1690,7 @@ class DeviceAta extends EventEmitter {
|
|
|
1690
1690
|
//sensor
|
|
1691
1691
|
if (preset.displayType < 7) this.presetControlSensorServices?.[i]?.updateCharacteristic(characteristicType, preset.state);
|
|
1692
1692
|
});
|
|
1693
|
-
}
|
|
1693
|
+
}
|
|
1694
1694
|
|
|
1695
1695
|
///schedules
|
|
1696
1696
|
if (this.schedules.length > 0 && scheduleEnabled !== null) {
|
|
@@ -1710,7 +1710,7 @@ class DeviceAta extends EventEmitter {
|
|
|
1710
1710
|
//sensor
|
|
1711
1711
|
if (schedule.displayType < 7) this.scheduleSensorServices?.[i]?.updateCharacteristic(characteristicType, schedule.state);
|
|
1712
1712
|
});
|
|
1713
|
-
}
|
|
1713
|
+
}
|
|
1714
1714
|
|
|
1715
1715
|
//scenes
|
|
1716
1716
|
if (this.scenes.length > 0) {
|
|
@@ -1727,7 +1727,7 @@ class DeviceAta extends EventEmitter {
|
|
|
1727
1727
|
//sensor
|
|
1728
1728
|
if (scene.displayType < 7) this.sceneControlSensorServices?.[i]?.updateCharacteristic(characteristicType, scene.state);
|
|
1729
1729
|
});
|
|
1730
|
-
}
|
|
1730
|
+
}
|
|
1731
1731
|
|
|
1732
1732
|
//buttons
|
|
1733
1733
|
if (this.buttons.length > 0) {
|
|
@@ -1851,7 +1851,7 @@ class DeviceAta extends EventEmitter {
|
|
|
1851
1851
|
//sensor
|
|
1852
1852
|
if (button.displayType < 7) this.buttonControlSensorServices?.[i]?.updateCharacteristic(characteristicType, button.state);
|
|
1853
1853
|
});
|
|
1854
|
-
}
|
|
1854
|
+
}
|
|
1855
1855
|
|
|
1856
1856
|
//log current state
|
|
1857
1857
|
if (this.logInfo) {
|
|
@@ -1869,7 +1869,7 @@ class DeviceAta extends EventEmitter {
|
|
|
1869
1869
|
this.emit('info', `Temperature display unit: ${obj.temperatureUnit}`);
|
|
1870
1870
|
this.emit('info', `Lock physical controls: ${obj.lockPhysicalControl ? 'Locked' : 'Unlocked'}`);
|
|
1871
1871
|
if (this.accountType === 'melcloudhome') this.emit('info', `Signal strength: ${deviceData.Rssi}dBm`);
|
|
1872
|
-
}
|
|
1872
|
+
}
|
|
1873
1873
|
})
|
|
1874
1874
|
.on('success', (success) => this.emit('success', success))
|
|
1875
1875
|
.on('info', (info) => this.emit('info', info))
|
package/src/deviceatw.js
CHANGED
|
@@ -852,7 +852,7 @@ class DeviceAtw extends EventEmitter {
|
|
|
852
852
|
break;
|
|
853
853
|
};
|
|
854
854
|
});
|
|
855
|
-
}
|
|
855
|
+
}
|
|
856
856
|
|
|
857
857
|
//sensor services
|
|
858
858
|
if (zonesSensorsCount > 0) {
|
|
@@ -1023,7 +1023,7 @@ class DeviceAtw extends EventEmitter {
|
|
|
1023
1023
|
break;
|
|
1024
1024
|
};
|
|
1025
1025
|
});
|
|
1026
|
-
}
|
|
1026
|
+
}
|
|
1027
1027
|
|
|
1028
1028
|
//in standby sensor
|
|
1029
1029
|
if (this.inStandbySensor && this.accessory.inStandbyMode !== null) {
|
|
@@ -1237,7 +1237,7 @@ class DeviceAtw extends EventEmitter {
|
|
|
1237
1237
|
accessory.addService(presetControlSensorService);
|
|
1238
1238
|
}
|
|
1239
1239
|
});
|
|
1240
|
-
}
|
|
1240
|
+
}
|
|
1241
1241
|
|
|
1242
1242
|
//schedules services
|
|
1243
1243
|
if (this.schedules.length > 0 && this.accessory.scheduleEnabled !== null) {
|
|
@@ -1311,7 +1311,7 @@ class DeviceAtw extends EventEmitter {
|
|
|
1311
1311
|
accessory.addService(scheduleSensorService);
|
|
1312
1312
|
}
|
|
1313
1313
|
});
|
|
1314
|
-
}
|
|
1314
|
+
}
|
|
1315
1315
|
|
|
1316
1316
|
//scenes
|
|
1317
1317
|
if (this.scenes.length > 0) {
|
|
@@ -1370,7 +1370,7 @@ class DeviceAtw extends EventEmitter {
|
|
|
1370
1370
|
accessory.addService(sceneControlSensorService);
|
|
1371
1371
|
}
|
|
1372
1372
|
});
|
|
1373
|
-
}
|
|
1373
|
+
}
|
|
1374
1374
|
|
|
1375
1375
|
//buttons services
|
|
1376
1376
|
if (this.buttons.length > 0) {
|
|
@@ -1565,7 +1565,7 @@ class DeviceAtw extends EventEmitter {
|
|
|
1565
1565
|
accessory.addService(buttonControlSensorService);
|
|
1566
1566
|
}
|
|
1567
1567
|
});
|
|
1568
|
-
}
|
|
1568
|
+
}
|
|
1569
1569
|
|
|
1570
1570
|
return accessory;
|
|
1571
1571
|
} catch (error) {
|
|
@@ -2001,40 +2001,40 @@ class DeviceAtw extends EventEmitter {
|
|
|
2001
2001
|
let operationModeText = '';
|
|
2002
2002
|
switch (i) {
|
|
2003
2003
|
case caseHeatPump: //Heat Pump - HEAT, COOL, OFF
|
|
2004
|
-
this.emit('info',
|
|
2005
|
-
this.emit('info',
|
|
2006
|
-
this.emit('info',
|
|
2007
|
-
this.emit('info',
|
|
2008
|
-
this.emit('info',
|
|
2004
|
+
this.emit('info', `Power: ${power ? 'On' : 'Off'}`)
|
|
2005
|
+
this.emit('info', `Operation mode: ${HeatPump.SystemMapEnumToString[unitStatus]}`);
|
|
2006
|
+
this.emit('info', `Outdoor temperature: ${roomTemperature}${obj.temperatureUnit}`);
|
|
2007
|
+
this.emit('info', `Temperature display unit: ${obj.temperatureUnit}`);
|
|
2008
|
+
this.emit('info', `Lock physical controls: ${lockPhysicalControl ? 'Locked' : 'Unlocked'}`);
|
|
2009
2009
|
if (this.accountType === 'melcloudhome') this.emit('info', `Signal strength: ${deviceData.Rssi}dBm`);
|
|
2010
2010
|
break;
|
|
2011
2011
|
case caseZone1: //Zone 1 - HEAT THERMOSTAT, HEAT FLOW, HEAT CURVE, COOL THERMOSTAT, COOL FLOW, FLOOR DRY UP
|
|
2012
2012
|
operationModeText = idleZone1 ? HeatPump.ZoneOperationMapEnumToString[6] : HeatPump.ZoneOperationMapEnumToString[operationModeZone1];
|
|
2013
|
-
this.emit('info',
|
|
2014
|
-
this.emit('info',
|
|
2015
|
-
this.emit('info',
|
|
2016
|
-
this.emit('info',
|
|
2017
|
-
this.emit('info',
|
|
2013
|
+
this.emit('info', `Operation mode: ${operationModeText}`);
|
|
2014
|
+
this.emit('info', `Temperature: ${roomTemperature}${obj.temperatureUnit}`);
|
|
2015
|
+
this.emit('info', `Target temperature: ${setTemperature}${obj.temperatureUnit}`)
|
|
2016
|
+
this.emit('info', `Temperature display unit: ${obj.temperatureUnit}`);
|
|
2017
|
+
this.emit('info', `Lock physical controls: ${lockPhysicalControl ? 'Locked' : 'Unlocked'}`);
|
|
2018
2018
|
break;
|
|
2019
2019
|
case caseHotWater: //Hot Water - AUTO, HEAT NOW
|
|
2020
2020
|
operationModeText = operationMode === 1 ? HeatPump.ForceDhwMapEnumToString[1] : HeatPump.ForceDhwMapEnumToString[forcedHotWaterMode ? 1 : 0];
|
|
2021
|
-
this.emit('info',
|
|
2022
|
-
this.emit('info',
|
|
2023
|
-
this.emit('info',
|
|
2024
|
-
this.emit('info',
|
|
2025
|
-
this.emit('info',
|
|
2021
|
+
this.emit('info', `Operation mode: ${operationModeText}`);
|
|
2022
|
+
this.emit('info', `Temperature: ${roomTemperature}${obj.temperatureUnit}`);
|
|
2023
|
+
this.emit('info', `Target temperature: ${setTemperature}${obj.temperatureUnit}`)
|
|
2024
|
+
this.emit('info', `Temperature display unit: ${obj.temperatureUnit}`);
|
|
2025
|
+
this.emit('info', `Lock physical controls: ${lockPhysicalControl ? 'Locked' : 'Unlocked'}`);
|
|
2026
2026
|
break;
|
|
2027
2027
|
case caseZone2: //Zone 2 - HEAT THERMOSTAT, HEAT FLOW, HEAT CURVE, COOL THERMOSTAT, COOL FLOW, FLOOR DRY UP
|
|
2028
2028
|
operationModeText = idleZone2 ? HeatPump.ZoneOperationMapEnumToString[6] : HeatPump.ZoneOperationMapEnumToString[operationModeZone2];
|
|
2029
|
-
this.emit('info',
|
|
2030
|
-
this.emit('info',
|
|
2031
|
-
this.emit('info',
|
|
2032
|
-
this.emit('info',
|
|
2033
|
-
this.emit('info',
|
|
2029
|
+
this.emit('info', `Operation mode: ${operationModeText}`);
|
|
2030
|
+
this.emit('info', `Temperature: ${roomTemperature}${obj.temperatureUnit}`);
|
|
2031
|
+
this.emit('info', `Target temperature: ${setTemperature}${obj.temperatureUnit}`)
|
|
2032
|
+
this.emit('info', `Temperature display unit: ${obj.temperatureUnit}`);
|
|
2033
|
+
this.emit('info', `Lock physical controls: ${lockPhysicalControl ? 'Locked' : 'Unlocked'}`);
|
|
2034
2034
|
break;
|
|
2035
2035
|
};
|
|
2036
|
-
}
|
|
2037
|
-
}
|
|
2036
|
+
}
|
|
2037
|
+
}
|
|
2038
2038
|
|
|
2039
2039
|
//update sensors characteristics
|
|
2040
2040
|
for (let i = 0; i < zonesSensorsCount; i++) {
|
|
@@ -2119,7 +2119,7 @@ class DeviceAtw extends EventEmitter {
|
|
|
2119
2119
|
break;
|
|
2120
2120
|
};
|
|
2121
2121
|
};
|
|
2122
|
-
}
|
|
2122
|
+
}
|
|
2123
2123
|
this.accessory = obj;
|
|
2124
2124
|
|
|
2125
2125
|
//update services
|
|
@@ -2174,7 +2174,7 @@ class DeviceAtw extends EventEmitter {
|
|
|
2174
2174
|
//sensor
|
|
2175
2175
|
if (preset.displayType < 7) this.presetControlSensorServices?.[i]?.updateCharacteristic(characteristicType, preset.state);
|
|
2176
2176
|
});
|
|
2177
|
-
}
|
|
2177
|
+
}
|
|
2178
2178
|
|
|
2179
2179
|
///schedules
|
|
2180
2180
|
if (this.schedules.length > 0 && scheduleEnabled !== null) {
|
|
@@ -2194,7 +2194,7 @@ class DeviceAtw extends EventEmitter {
|
|
|
2194
2194
|
//sensor
|
|
2195
2195
|
if (schedule.displayType < 7) this.scheduleSensorServices?.[i]?.updateCharacteristic(characteristicType, schedule.state);
|
|
2196
2196
|
});
|
|
2197
|
-
}
|
|
2197
|
+
}
|
|
2198
2198
|
|
|
2199
2199
|
//scenes
|
|
2200
2200
|
if (this.scenes.length > 0) {
|
|
@@ -2211,7 +2211,7 @@ class DeviceAtw extends EventEmitter {
|
|
|
2211
2211
|
//sensor
|
|
2212
2212
|
if (scene.displayType < 7) this.sceneControlSensorServices?.[i]?.updateCharacteristic(characteristicType, scene.state);
|
|
2213
2213
|
});
|
|
2214
|
-
}
|
|
2214
|
+
}
|
|
2215
2215
|
|
|
2216
2216
|
//buttons
|
|
2217
2217
|
if (this.buttons.length > 0) {
|
|
@@ -2299,7 +2299,7 @@ class DeviceAtw extends EventEmitter {
|
|
|
2299
2299
|
//sensor
|
|
2300
2300
|
if (button.displayType < 7) this.buttonControlSensorServices?.[i]?.updateCharacteristic(characteristicType, button.state);
|
|
2301
2301
|
});
|
|
2302
|
-
}
|
|
2302
|
+
}
|
|
2303
2303
|
})
|
|
2304
2304
|
.on('success', (success) => this.emit('success', success))
|
|
2305
2305
|
.on('info', (info) => this.emit('info', info))
|
package/src/deviceerv.js
CHANGED
|
@@ -586,7 +586,7 @@ class DeviceErv extends EventEmitter {
|
|
|
586
586
|
return state;
|
|
587
587
|
})
|
|
588
588
|
accessory.addService(this.roomTemperatureSensorService);
|
|
589
|
-
}
|
|
589
|
+
}
|
|
590
590
|
|
|
591
591
|
//temperature sensor service supply
|
|
592
592
|
if (this.temperatureSupplySensor && supportsSupplyTemperature && this.accessory.supplyTemperature !== null) {
|
|
@@ -600,7 +600,7 @@ class DeviceErv extends EventEmitter {
|
|
|
600
600
|
return state;
|
|
601
601
|
})
|
|
602
602
|
accessory.addService(this.supplyTemperatureSensorService);
|
|
603
|
-
}
|
|
603
|
+
}
|
|
604
604
|
|
|
605
605
|
//temperature sensor service outdoor
|
|
606
606
|
if (this.temperatureOutdoorSensor && supportsOutdoorTemperature && this.accessory.outdoorTemperature !== null) {
|
|
@@ -614,7 +614,7 @@ class DeviceErv extends EventEmitter {
|
|
|
614
614
|
return state;
|
|
615
615
|
})
|
|
616
616
|
accessory.addService(this.outdoorTemperatureSensorService);
|
|
617
|
-
}
|
|
617
|
+
}
|
|
618
618
|
|
|
619
619
|
//core maintenance
|
|
620
620
|
if (this.accessory.coreMaintenanceRequired !== null) {
|
|
@@ -849,7 +849,7 @@ class DeviceErv extends EventEmitter {
|
|
|
849
849
|
accessory.addService(presetControlSensorService);
|
|
850
850
|
}
|
|
851
851
|
});
|
|
852
|
-
}
|
|
852
|
+
}
|
|
853
853
|
|
|
854
854
|
//schedules services
|
|
855
855
|
if (this.schedules.length > 0 && this.accessory.scheduleEnabled !== null) {
|
|
@@ -923,7 +923,7 @@ class DeviceErv extends EventEmitter {
|
|
|
923
923
|
accessory.addService(scheduleSensorService);
|
|
924
924
|
}
|
|
925
925
|
});
|
|
926
|
-
}
|
|
926
|
+
}
|
|
927
927
|
|
|
928
928
|
//scenes
|
|
929
929
|
if (this.scenes.length > 0) {
|
|
@@ -982,7 +982,7 @@ class DeviceErv extends EventEmitter {
|
|
|
982
982
|
accessory.addService(sceneControlSensorService);
|
|
983
983
|
}
|
|
984
984
|
});
|
|
985
|
-
}
|
|
985
|
+
}
|
|
986
986
|
|
|
987
987
|
//buttons services
|
|
988
988
|
if (this.buttons.length > 0) {
|
|
@@ -1118,7 +1118,7 @@ class DeviceErv extends EventEmitter {
|
|
|
1118
1118
|
accessory.addService(buttonControlSensorService);
|
|
1119
1119
|
}
|
|
1120
1120
|
});
|
|
1121
|
-
}
|
|
1121
|
+
}
|
|
1122
1122
|
|
|
1123
1123
|
return accessory;
|
|
1124
1124
|
} catch (error) {
|
|
@@ -1454,7 +1454,7 @@ class DeviceErv extends EventEmitter {
|
|
|
1454
1454
|
//sensor
|
|
1455
1455
|
if (preset.displayType < 7) this.presetControlSensorServices?.[i]?.updateCharacteristic(characteristicType, preset.state);
|
|
1456
1456
|
});
|
|
1457
|
-
}
|
|
1457
|
+
}
|
|
1458
1458
|
|
|
1459
1459
|
///schedules
|
|
1460
1460
|
if (this.schedules.length > 0 && scheduleEnabled !== null) {
|
|
@@ -1474,7 +1474,7 @@ class DeviceErv extends EventEmitter {
|
|
|
1474
1474
|
//sensor
|
|
1475
1475
|
if (schedule.displayType < 7) this.scheduleSensorServices?.[i]?.updateCharacteristic(characteristicType, schedule.state);
|
|
1476
1476
|
});
|
|
1477
|
-
}
|
|
1477
|
+
}
|
|
1478
1478
|
|
|
1479
1479
|
//scenes
|
|
1480
1480
|
if (this.scenes.length > 0) {
|
|
@@ -1491,7 +1491,7 @@ class DeviceErv extends EventEmitter {
|
|
|
1491
1491
|
//sensor
|
|
1492
1492
|
if (scene.displayType < 7) this.sceneControlSensorServices?.[i]?.updateCharacteristic(characteristicType, scene.state);
|
|
1493
1493
|
});
|
|
1494
|
-
}
|
|
1494
|
+
}
|
|
1495
1495
|
|
|
1496
1496
|
//buttons
|
|
1497
1497
|
if (this.buttons.length > 0) {
|
|
@@ -1552,7 +1552,7 @@ class DeviceErv extends EventEmitter {
|
|
|
1552
1552
|
//sensor
|
|
1553
1553
|
if (button.displayType < 7) this.buttonControlSensorServices?.[i]?.updateCharacteristic(characteristicType, button.state);
|
|
1554
1554
|
});
|
|
1555
|
-
}
|
|
1555
|
+
}
|
|
1556
1556
|
|
|
1557
1557
|
//log current state
|
|
1558
1558
|
if (this.logInfo) {
|
|
@@ -1572,7 +1572,7 @@ class DeviceErv extends EventEmitter {
|
|
|
1572
1572
|
if (supportsPM25Sensor) this.emit('info', `PM2.5 air quality: ${Ventilation.PM25AirQualityMapEnumToString[pM25AirQuality]}`);
|
|
1573
1573
|
if (supportsPM25Sensor) this.emit('info', `PM2.5 level: ${pM25Level} µg/m`);
|
|
1574
1574
|
if (this.accountType === 'melcloudhome') this.emit('info', `Signal strength: ${deviceData.Rssi}dBm`);
|
|
1575
|
-
}
|
|
1575
|
+
}
|
|
1576
1576
|
})
|
|
1577
1577
|
.on('success', (success) => this.emit('success', success))
|
|
1578
1578
|
.on('info', (info) => this.emit('info', info))
|
package/src/functions.js
CHANGED
|
@@ -160,5 +160,12 @@ class Functions extends EventEmitter {
|
|
|
160
160
|
return v !== undefined && v !== null && !(typeof v === 'number' && Number.isNaN(v));
|
|
161
161
|
}
|
|
162
162
|
|
|
163
|
+
convertValue(v) {
|
|
164
|
+
let parsedValue = v;
|
|
165
|
+
if (v === "True") parsedValue = true;
|
|
166
|
+
else if (v === "False") parsedValue = false;
|
|
167
|
+
else if (!isNaN(v) && v !== "") parsedValue = Number(v);
|
|
168
|
+
return parsedValue;
|
|
169
|
+
}
|
|
163
170
|
}
|
|
164
171
|
export default Functions
|
package/src/melcloudata.js
CHANGED
|
@@ -70,17 +70,8 @@ class MelCloudAta extends EventEmitter {
|
|
|
70
70
|
this.socketConnected = false;
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
async
|
|
73
|
+
async updateState(deviceData) {
|
|
74
74
|
try {
|
|
75
|
-
|
|
76
|
-
//read device info from file
|
|
77
|
-
const devicesData = await this.functions.readData(this.devicesFile, true);
|
|
78
|
-
if (!devicesData) return;
|
|
79
|
-
|
|
80
|
-
this.headers = devicesData.Headers;
|
|
81
|
-
const deviceData = devicesData.Devices.find(device => device.DeviceID === this.deviceId);
|
|
82
|
-
deviceData.Scenes = devicesData.Scenes ?? [];
|
|
83
|
-
|
|
84
75
|
if (this.accountType === 'melcloudhome') {
|
|
85
76
|
deviceData.Device.OperationMode = AirConditioner.OperationModeMapStringToEnum[deviceData.Device.OperationMode] ?? deviceData.Device.OperationMode;
|
|
86
77
|
deviceData.Device.ActualFanSpeed = AirConditioner.FanSpeedMapStringToEnum[deviceData.Device.ActualFanSpeed] ?? deviceData.Device.ActualFanSpeed;
|
|
@@ -93,87 +84,6 @@ class MelCloudAta extends EventEmitter {
|
|
|
93
84
|
deviceData.Device.DefaultHeatingSetTemperature = temps?.defaultHeatingSetTemperature ?? 20;
|
|
94
85
|
deviceData.Device.DefaultCoolingSetTemperature = temps?.defaultCoolingSetTemperature ?? 24;
|
|
95
86
|
|
|
96
|
-
//web cocket connection
|
|
97
|
-
if (!this.connecting && !this.socketConnected) {
|
|
98
|
-
this.connecting = true;
|
|
99
|
-
|
|
100
|
-
const url = `${ApiUrlsHome.WebSocketURL}${devicesData.WebSocketOptions.Hash}`;
|
|
101
|
-
try {
|
|
102
|
-
const socket = new WebSocket(url, { headers: devicesData.WebSocketOptions.Headers })
|
|
103
|
-
.on('error', (error) => {
|
|
104
|
-
if (this.logError) this.emit('error', `Socket error: ${error}`);
|
|
105
|
-
socket.close();
|
|
106
|
-
})
|
|
107
|
-
.on('close', () => {
|
|
108
|
-
if (this.logDebug) this.emit('debug', `Socket closed`);
|
|
109
|
-
this.cleanupSocket();
|
|
110
|
-
})
|
|
111
|
-
.on('open', () => {
|
|
112
|
-
this.socket = socket;
|
|
113
|
-
this.socketConnected = true;
|
|
114
|
-
this.connecting = false;
|
|
115
|
-
if (this.logSuccess) this.emit('success', `Socket Connect Success`);
|
|
116
|
-
|
|
117
|
-
// heartbeat
|
|
118
|
-
this.heartbeat = setInterval(() => {
|
|
119
|
-
if (socket.readyState === socket.OPEN) {
|
|
120
|
-
if (this.logDebug) this.emit('debug', `Socket send heartbeat`);
|
|
121
|
-
socket.ping();
|
|
122
|
-
}
|
|
123
|
-
}, 30000);
|
|
124
|
-
})
|
|
125
|
-
.on('pong', () => {
|
|
126
|
-
if (this.logDebug) this.emit('debug', `Socket received heartbeat`);
|
|
127
|
-
})
|
|
128
|
-
.on('message', (message) => {
|
|
129
|
-
const parsedMessage = JSON.parse(message);
|
|
130
|
-
const stringifyMessage = JSON.stringify(parsedMessage, null, 2);
|
|
131
|
-
if (this.logDebug) this.emit('debug', `Incoming message: ${stringifyMessage}`);
|
|
132
|
-
if (parsedMessage.message === 'Forbidden') return;
|
|
133
|
-
|
|
134
|
-
const messageData = parsedMessage?.[0]?.Data;
|
|
135
|
-
if (!messageData) return;
|
|
136
|
-
|
|
137
|
-
let updateDeviceState = false;
|
|
138
|
-
const unitId = messageData?.id;
|
|
139
|
-
switch (unitId) {
|
|
140
|
-
case this.deviceId:
|
|
141
|
-
const messageType = parsedMessage[0].messageType;
|
|
142
|
-
switch (messageType) {
|
|
143
|
-
case 'unitStateChanged':
|
|
144
|
-
const settings = Object.fromEntries(
|
|
145
|
-
messageData.settings.map(({ name, value }) => {
|
|
146
|
-
let parsedValue = value;
|
|
147
|
-
if (value === "True") parsedValue = true;
|
|
148
|
-
else if (value === "False") parsedValue = false;
|
|
149
|
-
else if (!isNaN(value) && value !== "") parsedValue = Number(value);
|
|
150
|
-
return [name, parsedValue];
|
|
151
|
-
})
|
|
152
|
-
);
|
|
153
|
-
Object.assign(deviceData.Device, settings);
|
|
154
|
-
updateDeviceState = true;
|
|
155
|
-
break;
|
|
156
|
-
case 'unitWifiSignalChanged':
|
|
157
|
-
Object.assign(deviceData, messageData.rssi);
|
|
158
|
-
updateDeviceState = true;
|
|
159
|
-
break;
|
|
160
|
-
default:
|
|
161
|
-
if (!this.logDebug) this.emit('debug', `Unit ${unitId}, received unknown message type: ${stringifyMessage}`);
|
|
162
|
-
return;
|
|
163
|
-
}
|
|
164
|
-
break;
|
|
165
|
-
default:
|
|
166
|
-
if (!this.logDebug) this.emit('debug', `Incoming unknown unit id: ${stringifyMessage}`);
|
|
167
|
-
return;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
if (updateDeviceState) this.emit('deviceState', deviceData);
|
|
171
|
-
});
|
|
172
|
-
} catch (error) {
|
|
173
|
-
if (this.logError) this.emit('error', `Socket connection failed: ${error}`);
|
|
174
|
-
this.cleanupSocket();
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
87
|
}
|
|
178
88
|
if (this.logDebug) this.emit('debug', `Device Data: ${JSON.stringify(deviceData, null, 2)}`);
|
|
179
89
|
|
|
@@ -216,11 +126,6 @@ class MelCloudAta extends EventEmitter {
|
|
|
216
126
|
this.emit('mqtt', 'State', deviceData.Device);
|
|
217
127
|
}
|
|
218
128
|
|
|
219
|
-
//check state changes
|
|
220
|
-
const deviceDataHasNotChanged = JSON.stringify(deviceData) === JSON.stringify(this.deviceData);
|
|
221
|
-
if (deviceDataHasNotChanged) return;
|
|
222
|
-
this.deviceData = deviceData;
|
|
223
|
-
|
|
224
129
|
//emit info
|
|
225
130
|
this.emit('deviceInfo', indoor.model, outdoor.model, serialNumber, firmwareAppVersion);
|
|
226
131
|
|
|
@@ -233,6 +138,114 @@ class MelCloudAta extends EventEmitter {
|
|
|
233
138
|
};
|
|
234
139
|
};
|
|
235
140
|
|
|
141
|
+
async checkState() {
|
|
142
|
+
try {
|
|
143
|
+
|
|
144
|
+
//read device info from file
|
|
145
|
+
const devicesData = await this.functions.readData(this.devicesFile, true);
|
|
146
|
+
if (!devicesData) return;
|
|
147
|
+
|
|
148
|
+
this.headers = devicesData.Headers;
|
|
149
|
+
const deviceData = devicesData.Devices.find(device => device.DeviceID === this.deviceId);
|
|
150
|
+
deviceData.Scenes = devicesData.Scenes ?? [];
|
|
151
|
+
|
|
152
|
+
//web cocket connection
|
|
153
|
+
if (this.accountType === 'melcloudhome' && !this.connecting && !this.socketConnected) {
|
|
154
|
+
this.connecting = true;
|
|
155
|
+
|
|
156
|
+
const url = `${ApiUrlsHome.WebSocketURL}${devicesData.WebSocketOptions.Hash}`;
|
|
157
|
+
try {
|
|
158
|
+
const socket = new WebSocket(url, { headers: devicesData.WebSocketOptions.Headers })
|
|
159
|
+
.on('error', (error) => {
|
|
160
|
+
if (this.logError) this.emit('error', `Socket error: ${error}`);
|
|
161
|
+
socket.close();
|
|
162
|
+
})
|
|
163
|
+
.on('close', () => {
|
|
164
|
+
if (this.logDebug) this.emit('debug', `Socket closed`);
|
|
165
|
+
this.cleanupSocket();
|
|
166
|
+
})
|
|
167
|
+
.on('open', () => {
|
|
168
|
+
this.socket = socket;
|
|
169
|
+
this.socketConnected = true;
|
|
170
|
+
this.connecting = false;
|
|
171
|
+
if (this.logSuccess) this.emit('success', `Socket Connect Success`);
|
|
172
|
+
|
|
173
|
+
// heartbeat
|
|
174
|
+
this.heartbeat = setInterval(() => {
|
|
175
|
+
if (socket.readyState === socket.OPEN) {
|
|
176
|
+
if (this.logDebug) this.emit('debug', `Socket send heartbeat`);
|
|
177
|
+
socket.ping();
|
|
178
|
+
}
|
|
179
|
+
}, 30000);
|
|
180
|
+
})
|
|
181
|
+
.on('pong', () => {
|
|
182
|
+
if (this.logDebug) this.emit('debug', `Socket received heartbeat`);
|
|
183
|
+
})
|
|
184
|
+
.on('message', async (message) => {
|
|
185
|
+
const parsedMessage = JSON.parse(message);
|
|
186
|
+
const stringifyMessage = JSON.stringify(parsedMessage, null, 2);
|
|
187
|
+
if (this.logDebug) this.emit('debug', `Incoming message: ${stringifyMessage}`);
|
|
188
|
+
if (parsedMessage.message === 'Forbidden') return;
|
|
189
|
+
|
|
190
|
+
const messageData = parsedMessage?.[0]?.Data;
|
|
191
|
+
if (!messageData) return;
|
|
192
|
+
|
|
193
|
+
let updateState = false;
|
|
194
|
+
const unitId = messageData?.id;
|
|
195
|
+
switch (unitId) {
|
|
196
|
+
case this.deviceId:
|
|
197
|
+
const messageType = parsedMessage[0].messageType;
|
|
198
|
+
switch (messageType) {
|
|
199
|
+
case 'unitStateChanged':
|
|
200
|
+
const settings = Object.fromEntries(
|
|
201
|
+
messageData.settings.map(({ name, value }) => {
|
|
202
|
+
let parsedValue = this.functions.convertValue(value);
|
|
203
|
+
return [name, parsedValue];
|
|
204
|
+
})
|
|
205
|
+
);
|
|
206
|
+
Object.assign(deviceData.Device, settings);
|
|
207
|
+
updateState = true;
|
|
208
|
+
break;
|
|
209
|
+
case 'unitWifiSignalChanged':
|
|
210
|
+
deviceData.Rssi = messageData.rssi;
|
|
211
|
+
updateState = true;
|
|
212
|
+
break;
|
|
213
|
+
default:
|
|
214
|
+
if (!this.logDebug) this.emit('debug', `Unit ${unitId}, received unknown message type: ${stringifyMessage}`);
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
break;
|
|
218
|
+
default:
|
|
219
|
+
if (!this.logDebug) this.emit('debug', `Incoming unknown unit id: ${stringifyMessage}`);
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
//update state
|
|
224
|
+
if (updateState) {
|
|
225
|
+
this.deviceData = deviceData;
|
|
226
|
+
await this.updateState(deviceData);
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
} catch (error) {
|
|
230
|
+
if (this.logError) this.emit('error', `Socket connection failed: ${error}`);
|
|
231
|
+
this.cleanupSocket();
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
//check state changes
|
|
236
|
+
const deviceDataNotChanged = JSON.stringify(deviceData) === JSON.stringify(this.deviceData);
|
|
237
|
+
if (deviceDataNotChanged) return;
|
|
238
|
+
this.deviceData = deviceData;
|
|
239
|
+
|
|
240
|
+
//update state
|
|
241
|
+
await this.updateState(deviceData);
|
|
242
|
+
|
|
243
|
+
return true;
|
|
244
|
+
} catch (error) {
|
|
245
|
+
throw new Error(`Check state error: ${error.message}`);
|
|
246
|
+
};
|
|
247
|
+
};
|
|
248
|
+
|
|
236
249
|
async send(accountType, displayType, deviceData, flag, flagData) {
|
|
237
250
|
try {
|
|
238
251
|
let method = null
|
package/src/melcloudhome.js
CHANGED
|
@@ -145,11 +145,7 @@ class MelCloudHome extends EventEmitter {
|
|
|
145
145
|
|
|
146
146
|
const settingsObject = Object.fromEntries(
|
|
147
147
|
settingsArray.map(({ name, value }) => {
|
|
148
|
-
let parsedValue = value;
|
|
149
|
-
if (value === "True") parsedValue = true;
|
|
150
|
-
else if (value === "False") parsedValue = false;
|
|
151
|
-
else if (!isNaN(value) && value !== "") parsedValue = Number(value);
|
|
152
|
-
|
|
148
|
+
let parsedValue = this.functions.convertValue(value);
|
|
153
149
|
const key = name.charAt(0).toUpperCase() + name.slice(1);
|
|
154
150
|
return [key, parsedValue];
|
|
155
151
|
})
|