homebridge-melcloud-control 4.2.5-beta.26 → 4.2.5-beta.28

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
@@ -27,6 +27,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
27
27
  ## Changes
28
28
 
29
29
  - fix device control stop working after some time
30
+ - updated presets, schedules, scenes characteristics
30
31
  - stability and performance improvements
31
32
  - config schema updated
32
33
  - readme updated
package/README.md CHANGED
@@ -31,12 +31,13 @@ Homebridge plugin for Air Conditioner, Heat Pump and Energy Recovery Ventilation
31
31
  * Support multiple accounts, buildings, floors, areas.
32
32
  * Support temperature display units `Celsius/Fahrenheit`.
33
33
  * Support assing inividual operating mode for `Heat/Cool/Auto`.
34
- * Support direct `Presets` control, only MELCloud.
35
- * Support direct `Schedules` control, only MELCloud Home.
36
- * Support direct `Frost protection` control, only MELCloud Home.
37
- * Support direct `Overheat Protection` control, only MELCloud Home.
38
- * Support direct `Holiday Mode` control.
39
- * Support direct `Functions` control using extra `Buttons`, switch it to `OFF` restore previous device state.
34
+ * Support direct `Presets`, only MELCloud.
35
+ * Support direct `Schedules`, only MELCloud Home.
36
+ * Support direct `Scenes`, only MELCloud Home.
37
+ * Support direct `Frost protection`, only MELCloud Home.
38
+ * Support direct `Overheat Protection`, only MELCloud Home.
39
+ * Support direct `Holiday Mode`.
40
+ * Support direct `Functions`, using extra `Buttons`, switch it to `OFF` restore previous device state.
40
41
  * Support automations, shortcuts and Siri.
41
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).
42
43
  * Control devices over local network You need use ESP module and [Tasmota Control](https://github.com/grzegorz914/homebridge-tasmota-control) plugin.
@@ -70,7 +71,7 @@ Homebridge plugin for Air Conditioner, Heat Pump and Energy Recovery Ventilation
70
71
  * Frost protection `ON/OFF`.
71
72
  * Overheat protection `ON/OFF`.
72
73
  * Holiday mode `ON/OFF`.
73
- * Schedule `ON/OFF`.
74
+ * Schedules `ON/OFF`.
74
75
  * Scene `ON/OFF`.
75
76
  * Sensors:
76
77
  * For automation and notifications.
@@ -88,7 +89,7 @@ Homebridge plugin for Air Conditioner, Heat Pump and Energy Recovery Ventilation
88
89
  * Frost protection.
89
90
  * Overheat protection.
90
91
  * Holiday mode.
91
- * Shedule control.
92
+ * Shedules control.
92
93
  * Shedule active.
93
94
  * Scene control.
94
95
  * Error.
@@ -129,7 +130,7 @@ Homebridge plugin for Air Conditioner, Heat Pump and Energy Recovery Ventilation
129
130
  * Physical lock controls `LOCK/UNLOCK`.
130
131
  * Presets `SET/UNSET`.
131
132
  * Holiday mode `ON/OFF`.
132
- * Schedule `ON/OFF`.
133
+ * Schedules `ON/OFF`.
133
134
  * Scene `ON/OFF`.
134
135
  * Sensors:
135
136
  * For automation and notifications.
@@ -144,7 +145,7 @@ Homebridge plugin for Air Conditioner, Heat Pump and Energy Recovery Ventilation
144
145
  * Flow Temperature Zone 1, 2, Hot Water.
145
146
  * Return Temperature Zone 1, 2, Hot Water.
146
147
  * Holiday mode.
147
- * Shedule control.
148
+ * Shedules control.
148
149
  * Shedule active.
149
150
  * Scene control.
150
151
  * Error.
@@ -165,7 +166,7 @@ Homebridge plugin for Air Conditioner, Heat Pump and Energy Recovery Ventilation
165
166
  * Fan speed mode `AUTO/1/2/3/4`.
166
167
  * Presets `SET/UNSET`.
167
168
  * Holiday mode `ON/OFF`.
168
- * Schedule `ON/OFF`.
169
+ * Schedules `ON/OFF`.
169
170
  * Scene `ON/OFF`.
170
171
  * Sensors:
171
172
  * For automation and notifications.
@@ -181,7 +182,7 @@ Homebridge plugin for Air Conditioner, Heat Pump and Energy Recovery Ventilation
181
182
  * CO2 detected and level.
182
183
  * PM2.5 air quality and level.
183
184
  * Holiday mode.
184
- * Shedule control.
185
+ * Shedules control.
185
186
  * Shedule active.
186
187
  * Scene control.
187
188
  * Error.
@@ -394,7 +395,7 @@ Homebridge plugin for Air Conditioner, Heat Pump and Energy Recovery Ventilation
394
395
  | | `http//ip:port` | `FrostProtection` | `true`, `false` | boolean | Frost protectin. |
395
396
  | | `http//ip:port` | `OverheatProtection` | `true`, `false` | boolean | Overheat protection. |
396
397
  | | `http//ip:port` | `HolidayMode` | `true`, `false` | boolean | Holiday mode. |
397
- | | `http//ip:port` | `ScheduleEnabled` | `true`, `false` | boolean | Schedules. |
398
+ | | `http//ip:port` | `Schedules` | `true`, `false` | boolean | Schedules. |
398
399
  | Heat Pump | | | | | |
399
400
  | POST | `http//ip:port` | `Power` | `true`, `false` | boolean | Power state. |
400
401
  | | `http//ip:port` | `ForcedHotWaterMode` | `true`, `false` | boolean | Force hot water. |
@@ -413,7 +414,7 @@ Homebridge plugin for Air Conditioner, Heat Pump and Energy Recovery Ventilation
413
414
  | | `http//ip:port` | `SetCoolFlowTemperatureZone2` | `0.0` | float | Cool flow temperature zone 2. |
414
415
  | | `http//ip:port` | `SetTankWaterTemperature` | `0.0` | float | Hot water temperature. |
415
416
  | | `http//ip:port` | `HolidayMode` | `true`, `false` | boolean | Holiday mode. |
416
- | | `http//ip:port` | `ScheduleEnabled` | `true`, `false` | boolean | Schedules. |
417
+ | | `http//ip:port` | `Schedules` | `true`, `false` | boolean | Schedules. |
417
418
  | Energy Recovery Ventilation | | | | | |
418
419
  | POST | `http//ip:port` | `Power` | `true`, `false` | boolean | Power state. |
419
420
  | | `http//ip:port` | `NightPurgeMode` | `true`, `false` | boolean | Night purge mode. |
@@ -427,7 +428,7 @@ Homebridge plugin for Air Conditioner, Heat Pump and Energy Recovery Ventilation
427
428
  | | `http//ip:port` | `DefaultCoolingSetTemperature` | `0.0` | float | Default cooling temperature. |
428
429
  | | `http//ip:port` | `DefaultHeatingSetTemperature` | `0.0` | float | Default heating temperature. |
429
430
  | | `http//ip:port` | `HolidayMode` | `true`, `false` | boolean | Holiday mode. |
430
- | | `http//ip:port` | `ScheduleEnabled` | `true`, `false` | boolean | Schedules. |
431
+ | | `http//ip:port` | `Schedules` | `true`, `false` | boolean | Schedules. |
431
432
 
432
433
  ### MQTT Integration
433
434
 
@@ -456,7 +457,7 @@ Homebridge plugin for Air Conditioner, Heat Pump and Energy Recovery Ventilation
456
457
  | | `Set` | `FrostProtection` | `true`, `false` | boolean | Frost protectin. |
457
458
  | | `Set` | `OverheatProtection` | `true`, `false` | boolean | Overheat protection. |
458
459
  | | `Set` | `HolidayMode` | `true`, `false` | boolean | Holiday mode. |
459
- | | `Set` | `ScheduleEnabled` | `true`, `false` | boolean | Schedules. |
460
+ | | `Set` | `Schedules` | `true`, `false` | boolean | Schedules. |
460
461
  | Heat Pump | | | | | |
461
462
  | Subscribe | `Set` | `Power` | `true`, `false` | boolean | Power state. |
462
463
  | | `Set` | `ForcedHotWaterMode` | `true`, `false` | boolean | Force hot water. |
@@ -475,7 +476,7 @@ Homebridge plugin for Air Conditioner, Heat Pump and Energy Recovery Ventilation
475
476
  | | `Set` | `SetCoolFlowTemperatureZone2` | `0.0` | float | Cool flow temperature zone 2. |
476
477
  | | `Set` | `SetTankWaterTemperature` | `0.0` | float | Hot water temperature. |
477
478
  | | `Set` | `HolidayMode` | `true`, `false` | boolean | Holiday mode. |
478
- | | `Set` | `ScheduleEnabled` | `true`, `false` | boolean | Schedules. |
479
+ | | `Set` | `Schedules` | `true`, `false` | boolean | Schedules. |
479
480
  | Energy Recovery Ventilation | | | | | |
480
481
  | Subscribe | `Set` | `Power` | `true`, `false` | boolean | Power state. |
481
482
  | | `Set` | `NightPurgeMode` | `true`, `false` | boolean | Night purge mode. |
@@ -489,4 +490,4 @@ Homebridge plugin for Air Conditioner, Heat Pump and Energy Recovery Ventilation
489
490
  | | `Set` | `DefaultCoolingSetTemperature` | `23.0` | float | Default cooling temperature. |
490
491
  | | `Set` | `DefaultHeatingSetTemperature` | `21.0` | float | Default heating temperature. |
491
492
  | | `Set` | `HolidayMode` | `true`, `false` | boolean | Holiday mode. |
492
- | | `Set` | `ScheduleEnabled` | `true`, `false` | boolean | Schedules. |
493
+ | | `Set` | `Schedules` | `true`, `false` | boolean | Schedules. |
package/index.js CHANGED
@@ -106,7 +106,6 @@ class MelCloudPlatform {
106
106
  return;
107
107
  }
108
108
  if (logLevel.success) log.success(accountInfo.Info);
109
- const useFahrenheit = accountInfo.UseFahrenheit;
110
109
 
111
110
  //check devices list
112
111
  let devicesList;
@@ -166,30 +165,22 @@ class MelCloudPlatform {
166
165
  let configuredDevice;
167
166
  switch (deviceType) {
168
167
  case 0: //ATA
169
- configuredDevice = new DeviceAta(api, account, device, devicesFile, defaultTempsFile, useFahrenheit);
168
+ configuredDevice = new DeviceAta(api, account, device, devicesFile, defaultTempsFile, accountInfo, accountFile);
170
169
  break;
171
170
  case 1: //ATW
172
- configuredDevice = new DeviceAtw(api, account, device, devicesFile, defaultTempsFile, useFahrenheit);
171
+ configuredDevice = new DeviceAtw(api, account, device, devicesFile, defaultTempsFile, accountInfo, accountFile);
173
172
  break;
174
173
  case 2:
175
174
  break;
176
175
  case 3: //ERV
177
- configuredDevice = new DeviceErv(api, account, device, devicesFile, defaultTempsFile, useFahrenheit);
176
+ configuredDevice = new DeviceErv(api, account, device, devicesFile, defaultTempsFile, accountInfo, accountFile);
178
177
  break;
179
178
  default:
180
179
  if (logLevel.warn) log.warn(`${accountName}, ${deviceTypeText}, ${deviceName}, unknown device: ${deviceType}.`);
181
180
  return;
182
181
  }
183
182
 
184
- configuredDevice.on('melCloud', async (key, value) => {
185
- try {
186
- const accountDate = account.type === 'melcloud' ? accountInfo.LoginData[key] = value : accountInfo[key];
187
- await melCloud.send(accountDate);
188
- } catch (error) {
189
- if (logLevel.error) log.error(`${accountName}, ${deviceTypeText}, ${deviceName}, ${error.message ?? error}.`);
190
- }
191
- })
192
- .on('devInfo', (info) => logLevel.devInfo && log.info(info))
183
+ configuredDevice.on('devInfo', (info) => logLevel.devInfo && log.info(info))
193
184
  .on('success', (msg) => logLevel.success && log.success(`${accountName}, ${deviceTypeText}, ${deviceName}, ${msg}`))
194
185
  .on('info', (msg) => logLevel.info && log.info(`${accountName}, ${deviceTypeText}, ${deviceName}, ${msg}`))
195
186
  .on('debug', (msg) => logLevel.debug && log.info(`${accountName}, ${deviceTypeText}, ${deviceName}, debug: ${msg}`))
@@ -202,9 +193,9 @@ class MelCloudPlatform {
202
193
  if (logLevel.success) log.success(`${accountName}, ${deviceTypeText}, ${deviceName}, Published as external accessory.`);
203
194
 
204
195
  //start impulse generators\
205
- const timmers = accountType === 'melcloudhome' ? [{ name: 'connect', sampling: 3000000 }, { name: 'checkDevicesList', sampling: deviceRefreshInterval }] : [{ name: 'checkDevicesList', sampling: refreshInterval }];
206
- await melCloud.impulseGenerator.state(true, timmers, false);
207
196
  await configuredDevice.startStopImpulseGenerator(true, [{ name: 'checkState', sampling: deviceRefreshInterval }]);
197
+ const timmers = accountType === 'melcloudhome' ? [{ name: 'connect', sampling: 3000000 }, { name: 'checkDevicesList', sampling: 3000 }] : [{ name: 'checkDevicesList', sampling: refreshInterval }];
198
+ await melCloud.impulseGenerator.state(true, timmers, false);
208
199
 
209
200
  //stop impulse generator
210
201
  await impulseGenerator.state(false);
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.5-beta.26",
4
+ "version": "4.2.5-beta.28",
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
@@ -6,7 +6,7 @@ import { TemperatureDisplayUnits, AirConditioner } from './constants.js';
6
6
  let Accessory, Characteristic, Service, Categories, AccessoryUUID;
7
7
 
8
8
  class DeviceAta extends EventEmitter {
9
- constructor(api, account, device, devicesFile, defaultTempsFile, useFahrenheit) {
9
+ constructor(api, account, device, devicesFile, defaultTempsFile, accountInfo, accountFile) {
10
10
  super();
11
11
 
12
12
  Accessory = api.platformAccessory;
@@ -49,6 +49,8 @@ class DeviceAta extends EventEmitter {
49
49
  //files
50
50
  this.devicesFile = devicesFile;
51
51
  this.defaultTempsFile = defaultTempsFile;
52
+ this.accountInfo = accountInfo;
53
+ this.accountFile = accountFile;
52
54
  this.displayDeviceInfo = true;
53
55
 
54
56
  //external integrations
@@ -99,7 +101,6 @@ class DeviceAta extends EventEmitter {
99
101
 
100
102
  //accessory
101
103
  this.accessory = {};
102
- this.useFahrenheit = useFahrenheit ? 1 : 0;
103
104
  };
104
105
 
105
106
  async externalIntegrations() {
@@ -260,7 +261,7 @@ class DeviceAta extends EventEmitter {
260
261
  deviceData.Device[key].Enabled = value;
261
262
  flag = 'overheatprotection';
262
263
  break;
263
- case 'ScheduleEnabled':
264
+ case 'Schedules':
264
265
  if (this.accountType === 'melcloud') return;
265
266
 
266
267
  deviceData.Device[key].Enabled = value;
@@ -524,10 +525,10 @@ class DeviceAta extends EventEmitter {
524
525
  if (this.account.type === 'melcloudhome') return;
525
526
 
526
527
  try {
527
- value = [false, true][value];
528
- this.accessory.useFahrenheit = value;
528
+ this.accessory.useFahrenheit = value ? true : false;
529
529
  if (this.logInfo) this.emit('info', `Set temperature display unit: ${TemperatureDisplayUnits[value]}`);
530
- this.emit('melCloud', 'UseFahrenheit', value);
530
+ this.accountInfo.UseFahrenheit = value ? true : false;
531
+ await this.melCloudAta.send(this.accountType, this.displayType, deviceData, 'account', this.accountInfo);
531
532
  } catch (error) {
532
533
  if (this.logWarn) this.emit('warn', `Set temperature display unit error: ${error}`);
533
534
  };
@@ -619,10 +620,10 @@ class DeviceAta extends EventEmitter {
619
620
  if (this.account.type === 'melcloudhome') return;
620
621
 
621
622
  try {
622
- value = value ? true : false;
623
- this.accessory.useFahrenheit = value;
623
+ this.accessory.useFahrenheit = value ? true : false;
624
624
  if (this.logInfo) this.emit('info', `Set temperature display unit: ${TemperatureDisplayUnits[value]}`);
625
- this.emit('melCloud', 'UseFahrenheit', value);
625
+ this.accountInfo.UseFahrenheit = value ? true : false;
626
+ await this.melCloudAta.send(this.accountType, this.displayType, deviceData, 'account', this.accountInfo);
626
627
  } catch (error) {
627
628
  if (this.logWarn) this.emit('warn', `Set temperature display unit error: ${error}`);
628
629
  };
@@ -1322,7 +1323,7 @@ class DeviceAta extends EventEmitter {
1322
1323
  async start() {
1323
1324
  try {
1324
1325
  //melcloud device
1325
- this.melCloudAta = new MelCloudAta(this.account, this.device, this.devicesFile, this.defaultTempsFile)
1326
+ this.melCloudAta = new MelCloudAta(this.account, this.device, this.devicesFile, this.defaultTempsFile, this.accountFile)
1326
1327
  .on('deviceInfo', (modelIndoor, modelOutdoor, serialNumber, firmwareAppVersion) => {
1327
1328
  if (this.logDeviceInfo && this.displayDeviceInfo) {
1328
1329
  this.emit('devInfo', `---- ${this.deviceTypeText}: ${this.deviceName} ----`);
@@ -1462,8 +1463,8 @@ class DeviceAta extends EventEmitter {
1462
1463
  currentSwingMode: supportsSwingFunction && vaneHorizontalDirection === 12 && vaneVerticalDirection === 7 ? 1 : 0,
1463
1464
  lockPhysicalControl: prohibitSetTemperature && prohibitOperationMode && prohibitPower ? 1 : 0,
1464
1465
  temperatureStep: temperatureStep,
1465
- useFahrenheit: this.useFahrenheit,
1466
- temperatureUnit: TemperatureDisplayUnits[this.useFahrenheit],
1466
+ useFahrenheit: this.accountInfo.useFahrenheit ? 1 : 0,
1467
+ temperatureUnit: TemperatureDisplayUnits[this.accountInfo.useFahrenheit ? 1 : 0],
1467
1468
  isConnected: isConnected,
1468
1469
  isInError: isInError,
1469
1470
  frostProtectionEnabled: frostProtectionEnabled,
package/src/deviceatw.js CHANGED
@@ -6,7 +6,7 @@ import { TemperatureDisplayUnits, HeatPump } from './constants.js';
6
6
  let Accessory, Characteristic, Service, Categories, AccessoryUUID;
7
7
 
8
8
  class DeviceAtw extends EventEmitter {
9
- constructor(api, account, device, devicesFile, defaultTempsFile, useFahrenheit) {
9
+ constructor(api, account, device, devicesFile, defaultTempsFile, accountInfo, accountFile) {
10
10
  super();
11
11
 
12
12
  Accessory = api.platformAccessory;
@@ -50,6 +50,8 @@ class DeviceAtw extends EventEmitter {
50
50
  this.deviceTypeText = device.typeString;
51
51
  this.devicesFile = devicesFile;
52
52
  this.defaultTempsFile = defaultTempsFile;
53
+ this.accountInfo = accountInfo;
54
+ this.accountFile = accountFile;
53
55
  this.displayDeviceInfo = true;
54
56
 
55
57
  //external integrations
@@ -100,7 +102,6 @@ class DeviceAtw extends EventEmitter {
100
102
 
101
103
  //accessory
102
104
  this.accessory = {};
103
- this.useFahrenheit = useFahrenheit ? 1 : 0;
104
105
  };
105
106
 
106
107
  async externalIntegrations() {
@@ -649,10 +650,10 @@ class DeviceAtw extends EventEmitter {
649
650
  if (this.account.type === 'melcloudhome') return;
650
651
 
651
652
  try {
652
- value = [false, true][value];
653
- this.accessory.useFahrenheit = value;
653
+ this.accessory.useFahrenheit = value ? true : false;
654
654
  if (this.logInfo) this.emit('info', `Set temperature display unit: ${TemperatureDisplayUnits[value]}`);
655
- this.emit('melCloud', 'UseFahrenheit', value);
655
+ this.accountInfo.UseFahrenheit = value ? true : false;
656
+ await this.melCloudAtw.send(this.accountType, this.displayType, deviceData, 'account', this.accountInfo);
656
657
  } catch (error) {
657
658
  if (this.logWarn) this.emit('warn', `Set temperature display unit error: ${error}`);
658
659
  };
@@ -835,10 +836,10 @@ class DeviceAtw extends EventEmitter {
835
836
  if (this.account.type === 'melcloudhome') return;
836
837
 
837
838
  try {
838
- value = value ? true : false;
839
- this.accessory.useFahrenheit = value;
839
+ this.accessory.useFahrenheit = value ? true : false;
840
840
  if (this.logInfo) this.emit('info', `Set temperature display unit: ${TemperatureDisplayUnits[value]}`);
841
- this.emit('melCloud', 'UseFahrenheit', value);
841
+ this.accountInfo.UseFahrenheit = value ? true : false;
842
+ await this.melCloudAtw.send(this.accountType, this.displayType, deviceData, 'account', this.accountInfo);
842
843
  } catch (error) {
843
844
  if (this.logWarn) this.emit('warn', `Set temperature display unit error: ${error}`);
844
845
  };
@@ -1572,7 +1573,7 @@ class DeviceAtw extends EventEmitter {
1572
1573
  async start() {
1573
1574
  try {
1574
1575
  //melcloud device
1575
- this.melCloudAtw = new MelCloudAtw(this.account, this.device, this.devicesFile, this.defaultTempsFile)
1576
+ this.melCloudAtw = new MelCloudAtw(this.account, this.device, this.devicesFile, this.defaultTempsFile, this.accountFile)
1576
1577
  .on('deviceInfo', (modelIndoor, modelOutdoor, serialNumber, firmwareAppVersion, supportsHotWaterTank, supportsZone2) => {
1577
1578
  if (this.logDeviceInfo && this.displayDeviceInfo) {
1578
1579
  this.emit('devInfo', `---- ${this.deviceTypeText}: ${this.deviceName} ----`);
@@ -1720,8 +1721,8 @@ class DeviceAtw extends EventEmitter {
1720
1721
  caseHotWaterSensor: caseHotWaterSensor,
1721
1722
  caseZone2Sensor: caseZone2Sensor,
1722
1723
  sensorsCount: zonesSensorsCount,
1723
- useFahrenheit: this.useFahrenheit,
1724
- temperatureUnit: TemperatureDisplayUnits[this.useFahrenheit],
1724
+ useFahrenheit: this.accountInfo.useFahrenheit ? 1 : 0,
1725
+ temperatureUnit: TemperatureDisplayUnits[this.accountInfo.useFahrenheit ? 1 : 0],
1725
1726
  isConnected: isConnected,
1726
1727
  isInError: isInError,
1727
1728
  scheduleEnabled: scheduleEnabled,
package/src/deviceerv.js CHANGED
@@ -6,7 +6,7 @@ import { TemperatureDisplayUnits, Ventilation } from './constants.js';
6
6
  let Accessory, Characteristic, Service, Categories, AccessoryUUID;
7
7
 
8
8
  class DeviceErv extends EventEmitter {
9
- constructor(api, account, device, devicesFile, defaultTempsFile, useFahrenheit) {
9
+ constructor(api, account, device, devicesFile, defaultTempsFile, accountInfo, accountFile) {
10
10
  super();
11
11
 
12
12
  Accessory = api.platformAccessory;
@@ -43,6 +43,8 @@ class DeviceErv extends EventEmitter {
43
43
  this.deviceTypeText = device.typeString;
44
44
  this.devicesFile = devicesFile;
45
45
  this.defaultTempsFile = defaultTempsFile;
46
+ this.accountInfo = accountInfo;
47
+ this.accountFile = accountFile;
46
48
  this.displayDeviceInfo = true;
47
49
 
48
50
  //external integrations
@@ -93,7 +95,6 @@ class DeviceErv extends EventEmitter {
93
95
 
94
96
  //accessory
95
97
  this.accessory = {};
96
- this.useFahrenheit = useFahrenheit ? 1 : 0;
97
98
  };
98
99
 
99
100
  async externalIntegrations() {
@@ -455,10 +456,10 @@ class DeviceErv extends EventEmitter {
455
456
  if (this.account.type === 'melcloudhome') return;
456
457
 
457
458
  try {
458
- value = [false, true][value];
459
- this.accessory.useFahrenheit = value;
459
+ this.accessory.useFahrenheit = value ? true : false;
460
460
  if (this.logInfo) this.emit('info', `Set temperature display unit: ${TemperatureDisplayUnits[value]}`);
461
- this.emit('melCloud', 'UseFahrenheit', value);
461
+ this.accountInfo.UseFahrenheit = value ? true : false;
462
+ await this.melCloudErv.send(this.accountType, this.displayType, deviceData, 'account', this.accountInfo);
462
463
  } catch (error) {
463
464
  if (this.logWarn) this.emit('warn', `Set temperature display unit error: ${error}`);
464
465
  };
@@ -548,10 +549,10 @@ class DeviceErv extends EventEmitter {
548
549
  if (this.account.type === 'melcloudhome') return;
549
550
 
550
551
  try {
551
- value = [false, true][value];
552
- this.accessory.useFahrenheit = value;
552
+ this.accessory.useFahrenheit = value ? true : false;
553
553
  if (this.logInfo) this.emit('info', `Set temperature display unit: ${TemperatureDisplayUnits[value]}`);
554
- this.emit('melCloud', 'UseFahrenheit', value);
554
+ this.accountInfo.UseFahrenheit = value ? true : false;
555
+ await this.melCloudErv.send(this.accountType, this.displayType, deviceData, 'account', this.accountInfo);
555
556
  } catch (error) {
556
557
  if (this.logWarn) this.emit('warn', `Set temperature display unit error: ${error}`);
557
558
  };
@@ -1117,7 +1118,7 @@ class DeviceErv extends EventEmitter {
1117
1118
  async start() {
1118
1119
  try {
1119
1120
  //melcloud device
1120
- this.melCloudErv = new MelCloudErv(this.account, this.device, this.devicesFile, this.defaultTempsFile)
1121
+ this.melCloudErv = new MelCloudErv(this.account, this.device, this.devicesFile, this.defaultTempsFile, this.accountFile)
1121
1122
  .on('deviceInfo', (modelIndoor, modelOutdoor, serialNumber, firmwareAppVersion) => {
1122
1123
  if (this.logDeviceInfo && this.displayDeviceInfo) {
1123
1124
  this.emit('devInfo', `---- ${this.deviceTypeText}: ${this.deviceName} ----`);
@@ -1251,8 +1252,8 @@ class DeviceErv extends EventEmitter {
1251
1252
  temperatureIncrement: maxTempHeat,
1252
1253
  minTempCoolDry: minTempCoolDry,
1253
1254
  maxTempCoolDry: maxTempCoolDry,
1254
- useFahrenheit: this.useFahrenheit,
1255
- temperatureUnit: TemperatureDisplayUnits[this.useFahrenheit],
1255
+ useFahrenheit: this.accountInfo.useFahrenheit ? 1 : 0,
1256
+ temperatureUnit: TemperatureDisplayUnits[this.accountInfo.useFahrenheit ? 1 : 0],
1256
1257
  isConnected: isConnected,
1257
1258
  isInError: isInError,
1258
1259
  scheduleEnabled: scheduleEnabled,
package/src/melcloud.js CHANGED
@@ -125,7 +125,7 @@ class MelCloud extends EventEmitter {
125
125
  if (this.logDebug) this.emit('debug', `Connecting to MELCloud`);
126
126
 
127
127
  try {
128
- const accountInfo = { State: false, Info: '', LoginData: null, UseFahrenheit: false }
128
+ const accountInfo = { State: false, Info: '', Account: null, UseFahrenheit: false }
129
129
 
130
130
  const payload = {
131
131
  Email: this.user,
@@ -175,7 +175,8 @@ class MelCloud extends EventEmitter {
175
175
 
176
176
  accountInfo.State = true;
177
177
  accountInfo.Info = 'Connect to MELCloud Success';
178
- accountInfo.LoginData = loginData;
178
+ accountInfo.UseFahrenheit = loginData.UseFahrenheit;
179
+ accountInfo.Account = account;
179
180
  await this.functions.saveData(this.accountFile, accountInfo);
180
181
 
181
182
  return accountInfo
@@ -183,17 +184,6 @@ class MelCloud extends EventEmitter {
183
184
  throw new Error(`Connect error: ${error.message}`);
184
185
  }
185
186
  }
186
-
187
- async send(accountInfo) {
188
- try {
189
- const payload = { data: accountInfo.LoginData };
190
- await this.axiosInstance(ApiUrls.UpdateApplicationOptions, { method: 'POST', data: payload });
191
- await this.functions.saveData(this.accountFile, accountInfo);
192
- return true;
193
- } catch (error) {
194
- throw new Error(`Send data error: ${error.message}`);
195
- }
196
- }
197
187
  }
198
188
 
199
189
  export default MelCloud;
@@ -5,7 +5,7 @@ import Functions from './functions.js';
5
5
  import { ApiUrls, ApiUrlsHome, AirConditioner } from './constants.js';
6
6
 
7
7
  class MelCloudAta extends EventEmitter {
8
- constructor(account, device, devicesFile, defaultTempsFile) {
8
+ constructor(account, device, devicesFile, defaultTempsFile, accountFile) {
9
9
  super();
10
10
  this.accountType = account.type;
11
11
  this.logWarn = account.log?.warn;
@@ -16,6 +16,7 @@ class MelCloudAta extends EventEmitter {
16
16
  this.deviceId = device.id;
17
17
  this.devicesFile = devicesFile;
18
18
  this.defaultTempsFile = defaultTempsFile;
19
+ this.accountFile = accountFile;
19
20
  this.functions = new Functions(this.logWarn, this.logError, this.logDebug)
20
21
  .on('warn', warn => this.emit('warn', warn))
21
22
  .on('error', error => this.emit('error', error))
@@ -136,33 +137,42 @@ class MelCloudAta extends EventEmitter {
136
137
  let path = '';
137
138
  switch (accountType) {
138
139
  case "melcloud":
139
-
140
- if (displayType === 1 && deviceData.Device.OperationMode === 8) {
141
- deviceData.Device.SetTemperature = (deviceData.Device.DefaultCoolingSetTemperature + deviceData.Device.DefaultHeatingSetTemperature) / 2;
140
+ switch (flag) {
141
+ case 'account':
142
+ flagData.Account.LoginData.UseFahrenheit = flagData.UseFahrenheit;
143
+ payload = { data: flagData.LoginData };
144
+ path = ApiUrls.UpdateApplicationOptions;
145
+ await this.functions.saveData(this.accountFile, flagData);
146
+ break;
147
+ default:
148
+ if (displayType === 1 && deviceData.Device.OperationMode === 8) {
149
+ deviceData.Device.SetTemperature = (deviceData.Device.DefaultCoolingSetTemperature + deviceData.Device.DefaultHeatingSetTemperature) / 2;
150
+ }
151
+ deviceData.Device.EffectiveFlags = flag;
152
+ payload = {
153
+ DeviceID: deviceData.Device.DeviceID,
154
+ EffectiveFlags: deviceData.Device.EffectiveFlags,
155
+ Power: deviceData.Device.Power,
156
+ SetTemperature: deviceData.Device.SetTemperature,
157
+ SetFanSpeed: deviceData.Device.FanSpeed,
158
+ OperationMode: deviceData.Device.OperationMode,
159
+ VaneHorizontal: deviceData.Device.VaneHorizontalDirection,
160
+ VaneVertical: deviceData.Device.VaneVerticalDirection,
161
+ DefaultHeatingSetTemperature: deviceData.Device.DefaultHeatingSetTemperature,
162
+ DefaultCoolingSetTemperature: deviceData.Device.DefaultCoolingSetTemperature,
163
+ ProhibitSetTemperature: deviceData.Device.ProhibitSetTemperature,
164
+ ProhibitOperationMode: deviceData.Device.ProhibitOperationMode,
165
+ ProhibitPower: deviceData.Device.ProhibitPower,
166
+ HideVaneControls: deviceData.HideVaneControls,
167
+ HideDryModeControl: deviceData.HideDryModeControl,
168
+ HasPendingCommand: true
169
+ };
170
+ path = ApiUrls.SetAta;
171
+ break;
142
172
  }
143
173
 
144
- deviceData.Device.EffectiveFlags = flag;
145
- payload = {
146
- DeviceID: deviceData.Device.DeviceID,
147
- EffectiveFlags: deviceData.Device.EffectiveFlags,
148
- Power: deviceData.Device.Power,
149
- SetTemperature: deviceData.Device.SetTemperature,
150
- SetFanSpeed: deviceData.Device.FanSpeed,
151
- OperationMode: deviceData.Device.OperationMode,
152
- VaneHorizontal: deviceData.Device.VaneHorizontalDirection,
153
- VaneVertical: deviceData.Device.VaneVerticalDirection,
154
- DefaultHeatingSetTemperature: deviceData.Device.DefaultHeatingSetTemperature,
155
- DefaultCoolingSetTemperature: deviceData.Device.DefaultCoolingSetTemperature,
156
- ProhibitSetTemperature: deviceData.Device.ProhibitSetTemperature,
157
- ProhibitOperationMode: deviceData.Device.ProhibitOperationMode,
158
- ProhibitPower: deviceData.Device.ProhibitPower,
159
- HideVaneControls: deviceData.HideVaneControls,
160
- HideDryModeControl: deviceData.HideDryModeControl,
161
- HasPendingCommand: true
162
- };
163
-
164
174
  if (this.logDebug) this.emit('debug', `Send Data: ${JSON.stringify(payload, null, 2)}`);
165
- await axios(ApiUrls.SetAta, {
175
+ await axios(path, {
166
176
  method: 'POST',
167
177
  baseURL: ApiUrls.BaseURL,
168
178
  timeout: 30000,
@@ -5,7 +5,7 @@ import Functions from './functions.js';
5
5
  import { ApiUrls, ApiUrlsHome, HeatPump } from './constants.js';
6
6
 
7
7
  class MelCloudAtw extends EventEmitter {
8
- constructor(account, device, devicesFile, defaultTempsFile) {
8
+ constructor(account, device, devicesFile, defaultTempsFile, accountFile) {
9
9
  super();
10
10
  this.accountType = account.type;
11
11
  this.logWarn = account.log?.warn;
@@ -16,6 +16,7 @@ class MelCloudAtw extends EventEmitter {
16
16
  this.deviceId = device.id;
17
17
  this.devicesFile = devicesFile;
18
18
  this.defaultTempsFile = defaultTempsFile;
19
+ this.accountFile = accountFile;
19
20
  this.functions = new Functions(this.logWarn, this.logError, this.logDebug)
20
21
  .on('warn', warn => this.emit('warn', warn))
21
22
  .on('error', error => this.emit('error', error))
@@ -143,32 +144,43 @@ class MelCloudAtw extends EventEmitter {
143
144
  let path = '';
144
145
  switch (accountType) {
145
146
  case "melcloud":
146
- deviceData.Device.EffectiveFlags = flag;
147
- payload = {
148
- DeviceID: deviceData.Device.DeviceID,
149
- EffectiveFlags: deviceData.Device.EffectiveFlags,
150
- Power: deviceData.Device.Power,
151
- SetTemperatureZone1: deviceData.Device.SetTemperatureZone1,
152
- SetTemperatureZone2: deviceData.Device.SetTemperatureZone2,
153
- OperationMode: deviceData.Device.OperationMode,
154
- OperationModeZone1: deviceData.Device.OperationModeZone1,
155
- OperationModeZone2: deviceData.Device.OperationModeZone2,
156
- SetHeatFlowTemperatureZone1: deviceData.Device.SetHeatFlowTemperatureZone1,
157
- SetHeatFlowTemperatureZone2: deviceData.Device.SetHeatFlowTemperatureZone2,
158
- SetCoolFlowTemperatureZone1: deviceData.Device.SetCoolFlowTemperatureZone1,
159
- SetCoolFlowTemperatureZone2: deviceData.Device.SetCoolFlowTemperatureZone2,
160
- SetTankWaterTemperature: deviceData.Device.SetTankWaterTemperature,
161
- ForcedHotWaterMode: deviceData.Device.ForcedHotWaterMode,
162
- EcoHotWater: deviceData.Device.EcoHotWater,
163
- HolidayMode: deviceData.Device.HolidayMode,
164
- ProhibitZone1: deviceData.Device.ProhibitHeatingZone1,
165
- ProhibitZone2: deviceData.Device.ProhibitHeatingZone2,
166
- ProhibitHotWater: deviceData.Device.ProhibitHotWater,
167
- HasPendingCommand: true
147
+ switch (flag) {
148
+ case 'account':
149
+ flagData.Account.LoginData.UseFahrenheit = flagData.UseFahrenheit;
150
+ payload = { data: flagData.LoginData };
151
+ path = ApiUrls.UpdateApplicationOptions;
152
+ await this.functions.saveData(this.accountFile, flagData);
153
+ break;
154
+ default:
155
+ deviceData.Device.EffectiveFlags = flag;
156
+ payload = {
157
+ DeviceID: deviceData.Device.DeviceID,
158
+ EffectiveFlags: deviceData.Device.EffectiveFlags,
159
+ Power: deviceData.Device.Power,
160
+ SetTemperatureZone1: deviceData.Device.SetTemperatureZone1,
161
+ SetTemperatureZone2: deviceData.Device.SetTemperatureZone2,
162
+ OperationMode: deviceData.Device.OperationMode,
163
+ OperationModeZone1: deviceData.Device.OperationModeZone1,
164
+ OperationModeZone2: deviceData.Device.OperationModeZone2,
165
+ SetHeatFlowTemperatureZone1: deviceData.Device.SetHeatFlowTemperatureZone1,
166
+ SetHeatFlowTemperatureZone2: deviceData.Device.SetHeatFlowTemperatureZone2,
167
+ SetCoolFlowTemperatureZone1: deviceData.Device.SetCoolFlowTemperatureZone1,
168
+ SetCoolFlowTemperatureZone2: deviceData.Device.SetCoolFlowTemperatureZone2,
169
+ SetTankWaterTemperature: deviceData.Device.SetTankWaterTemperature,
170
+ ForcedHotWaterMode: deviceData.Device.ForcedHotWaterMode,
171
+ EcoHotWater: deviceData.Device.EcoHotWater,
172
+ HolidayMode: deviceData.Device.HolidayMode,
173
+ ProhibitZone1: deviceData.Device.ProhibitHeatingZone1,
174
+ ProhibitZone2: deviceData.Device.ProhibitHeatingZone2,
175
+ ProhibitHotWater: deviceData.Device.ProhibitHotWater,
176
+ HasPendingCommand: true
177
+ }
178
+ path = ApiUrls.SetAtw;
179
+ break;
168
180
  }
169
181
 
170
182
  if (this.logDebug) this.emit('debug', `Send Data: ${JSON.stringify(payload, null, 2)}`);
171
- await axios(ApiUrls.SetAtw, {
183
+ await axios(path, {
172
184
  method: 'POST',
173
185
  baseURL: ApiUrls.BaseURL,
174
186
  timeout: 30000,
@@ -5,7 +5,7 @@ import Functions from './functions.js';
5
5
  import { ApiUrls, ApiUrlsHome, Ventilation } from './constants.js';
6
6
 
7
7
  class MelCloudErv extends EventEmitter {
8
- constructor(account, device, devicesFile, defaultTempsFile) {
8
+ constructor(account, device, devicesFile, defaultTempsFile, accountFile) {
9
9
  super();
10
10
  this.accountType = account.type;
11
11
  this.logWarn = account.log?.warn;
@@ -16,6 +16,7 @@ class MelCloudErv extends EventEmitter {
16
16
  this.deviceId = device.id;
17
17
  this.devicesFile = devicesFile;
18
18
  this.defaultTempsFile = defaultTempsFile;
19
+ this.accountFile = accountFile;
19
20
  this.functions = new Functions(this.logWarn, this.logError, this.logDebug)
20
21
  .on('warn', warn => this.emit('warn', warn))
21
22
  .on('error', error => this.emit('error', error))
@@ -131,47 +132,57 @@ class MelCloudErv extends EventEmitter {
131
132
  let path = '';
132
133
  switch (accountType) {
133
134
  case "melcloud":
134
- //set target temp based on display mode and ventilation mode
135
- switch (displayType) {
136
- case 1: //Heather/Cooler
137
- switch (deviceData.Device.VentilationMode) {
138
- case 0: //LOSNAY
139
- deviceData.Device.SetTemperature = deviceData.Device.DefaultHeatingSetTemperature;
140
- break;
141
- case 1: //BYPASS
142
- deviceData.Device.SetTemperature = deviceData.Device.DefaultCoolingSetTemperature;
143
- break;
144
- case 2: //AUTO
145
- const setTemperature = (deviceData.Device.DefaultCoolingSetTemperature + deviceData.Device.DefaultHeatingSetTemperature) / 2;
146
- deviceData.Device.SetTemperature = setTemperature;
135
+ switch (flag) {
136
+ case 'account':
137
+ flagData.Account.LoginData.UseFahrenheit = flagData.UseFahrenheit;
138
+ payload = { data: flagData.LoginData };
139
+ path = ApiUrls.UpdateApplicationOptions;
140
+ await this.functions.saveData(this.accountFile, flagData);
141
+ break;
142
+ default:
143
+ //set target temp based on display mode and ventilation mode
144
+ switch (displayType) {
145
+ case 1: //Heather/Cooler
146
+ switch (deviceData.Device.VentilationMode) {
147
+ case 0: //LOSNAY
148
+ deviceData.Device.SetTemperature = deviceData.Device.DefaultHeatingSetTemperature;
149
+ break;
150
+ case 1: //BYPASS
151
+ deviceData.Device.SetTemperature = deviceData.Device.DefaultCoolingSetTemperature;
152
+ break;
153
+ case 2: //AUTO
154
+ const setTemperature = (deviceData.Device.DefaultCoolingSetTemperature + deviceData.Device.DefaultHeatingSetTemperature) / 2;
155
+ deviceData.Device.SetTemperature = setTemperature;
156
+ break;
157
+ };
158
+ case 2: //Thermostat
159
+ deviceData.Device.SetTemperature = deviceData.Device.SetTemperature;
147
160
  break;
148
161
  };
149
- case 2: //Thermostat
150
- deviceData.Device.SetTemperature = deviceData.Device.SetTemperature;
151
- break;
152
- };
153
162
 
154
- //device state
155
- deviceData.Device.EffectiveFlags = flag;
156
- payload = {
157
- DeviceID: deviceData.Device.DeviceID,
158
- EffectiveFlags: deviceData.Device.EffectiveFlags,
159
- Power: deviceData.Device.Power,
160
- SetTemperature: deviceData.Device.SetTemperature,
161
- SetFanSpeed: deviceData.Device.SetFanSpeed,
162
- OperationMode: deviceData.Device.OperationMode,
163
- VentilationMode: deviceData.Device.VentilationMode,
164
- DefaultCoolingSetTemperature: deviceData.Device.DefaultCoolingSetTemperature,
165
- DefaultHeatingSetTemperature: deviceData.Device.DefaultHeatingSetTemperature,
166
- HideRoomTemperature: deviceData.Device.HideRoomTemperature,
167
- HideSupplyTemperature: deviceData.Device.HideSupplyTemperature,
168
- HideOutdoorTemperature: deviceData.Device.HideOutdoorTemperature,
169
- NightPurgeMode: deviceData.Device.NightPurgeMode,
170
- HasPendingCommand: true
163
+ //device state
164
+ deviceData.Device.EffectiveFlags = flag;
165
+ payload = {
166
+ DeviceID: deviceData.Device.DeviceID,
167
+ EffectiveFlags: deviceData.Device.EffectiveFlags,
168
+ Power: deviceData.Device.Power,
169
+ SetTemperature: deviceData.Device.SetTemperature,
170
+ SetFanSpeed: deviceData.Device.SetFanSpeed,
171
+ OperationMode: deviceData.Device.OperationMode,
172
+ VentilationMode: deviceData.Device.VentilationMode,
173
+ DefaultCoolingSetTemperature: deviceData.Device.DefaultCoolingSetTemperature,
174
+ DefaultHeatingSetTemperature: deviceData.Device.DefaultHeatingSetTemperature,
175
+ HideRoomTemperature: deviceData.Device.HideRoomTemperature,
176
+ HideSupplyTemperature: deviceData.Device.HideSupplyTemperature,
177
+ HideOutdoorTemperature: deviceData.Device.HideOutdoorTemperature,
178
+ NightPurgeMode: deviceData.Device.NightPurgeMode,
179
+ HasPendingCommand: true
180
+ }
181
+ path = ApiUrls.SetErv;
182
+ break;
171
183
  }
172
-
173
184
  if (this.logDebug) this.emit('debug', `Send Data: ${JSON.stringify(payload, null, 2)}`);
174
- await axios(ApiUrls.SetErv, {
185
+ await axios(path, {
175
186
  method: 'POST',
176
187
  baseURL: ApiUrls.BaseURL,
177
188
  timeout: 30000,
@@ -217,7 +217,7 @@ class MelCloud extends EventEmitter {
217
217
 
218
218
  let browser;
219
219
  try {
220
- const accountInfo = { State: false, Info: '', UseFahrenheit: false };
220
+ const accountInfo = { State: false, Info: '', Account: {}, UseFahrenheit: false };
221
221
  let chromiumPath = await this.functions.ensureChromiumInstalled();
222
222
 
223
223
  // === Fallback to Puppeteer's built-in Chromium ===
@@ -365,16 +365,6 @@ class MelCloud extends EventEmitter {
365
365
  }
366
366
  }
367
367
  }
368
-
369
- async send(accountInfo) {
370
- try {
371
- //await this.axiosInstance(ApiUrlsHome.UpdateApplicationOptions, { method: 'POST' });
372
- //await this.functions.saveData(this.accountFile, accountInfo);
373
- return true;
374
- } catch (error) {
375
- throw new Error(`Send data error: ${error.message}`);
376
- }
377
- }
378
368
  }
379
369
 
380
370
  export default MelCloud;