homebridge-melcloud-control 4.0.0-beta.43 → 4.0.0-beta.430

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/src/deviceata.js CHANGED
@@ -2,11 +2,11 @@ import EventEmitter from 'events';
2
2
  import MelCloudAta from './melcloudata.js';
3
3
  import RestFul from './restful.js';
4
4
  import Mqtt from './mqtt.js';
5
- import { TemperatureDisplayUnits, AirConditioner } from './constants.js';
5
+ import { TemperatureDisplayUnits, AirConditioner, ApiUrlsHome } from './constants.js';
6
6
  let Accessory, Characteristic, Service, Categories, AccessoryUUID;
7
7
 
8
8
  class DeviceAta extends EventEmitter {
9
- constructor(api, account, device, contextKey, devicesFile, useFahrenheit, restFul, mqtt) {
9
+ constructor(api, account, device, devicesFile, defaultTempsFile, useFahrenheit, restFul, mqtt) {
10
10
  super();
11
11
 
12
12
  Accessory = api.platformAccessory;
@@ -16,8 +16,17 @@ class DeviceAta extends EventEmitter {
16
16
  AccessoryUUID = api.hap.uuid;
17
17
 
18
18
  //account config
19
+ this.account = account;
20
+ this.accountType = account.type;
21
+ this.accountName = account.name;
22
+ this.logDeviceInfo = account.log?.deviceInfo || false;
23
+ this.logInfo = account.log?.info || false;
24
+ this.logWarn = account.log?.warn || false;
25
+ this.logDebug = account.log?.debug || false;
26
+
27
+ //device config
19
28
  this.device = device;
20
- this.displayMode = device.displayMode;
29
+ this.displayType = device.displayType;
21
30
  this.temperatureSensor = device.temperatureSensor || false;
22
31
  this.temperatureSensorOutdoor = device.temperatureSensorOutdoor || false;
23
32
  this.heatDryFanMode = device.heatDryFanMode || 1; //NONE, HEAT, DRY, FAN
@@ -25,16 +34,11 @@ class DeviceAta extends EventEmitter {
25
34
  this.autoDryFanMode = device.autoDryFanMode || 1; //NONE, AUTO, DRY, FAN
26
35
  this.presets = (device.presets || []).filter(preset => (preset.displayType ?? 0) > 0);
27
36
  this.buttons = (device.buttonsSensors || []).filter(sensor => (sensor.displayType ?? 0) > 0);
28
- this.logDeviceInfo = account.log?.deviceInfo || false;
29
- this.logInfo = account.log?.info || false;
30
- this.logWarn = account.log?.warn || false;
31
- this.logDebug = account.log?.debug || false;
32
- this.contextKey = contextKey;
33
- this.accountName = account.name;
34
37
  this.deviceId = device.id;
35
38
  this.deviceName = device.name;
36
39
  this.deviceTypeText = device.typeString;
37
40
  this.devicesFile = devicesFile;
41
+ this.defaultTempsFile = defaultTempsFile;
38
42
  this.displayDeviceInfo = true;
39
43
 
40
44
  //external integrations
@@ -154,67 +158,67 @@ class DeviceAta extends EventEmitter {
154
158
  case 'Power':
155
159
  deviceData.Device[key] = value;
156
160
  deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.Power;
157
- set = await this.melCloudAta.send(deviceData, this.displayMode);
161
+ set = await this.melCloudAta.send(this.accountType, this.displayType, deviceData);
158
162
  break;
159
163
  case 'OperationMode':
160
164
  deviceData.Device[key] = value;
161
- deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.OperationModeSetTemperature;
162
- set = await this.melCloudAta.send(deviceData, this.displayMode);
165
+ deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.OperationMode
166
+ set = await this.melCloudAta.send(this.accountType, this.displayType, deviceData);
163
167
  break;
164
168
  case 'SetTemperature':
165
169
  deviceData.Device[key] = value;
166
170
  deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.SetTemperature;
167
- set = await this.melCloudAta.send(deviceData, this.displayMode);
171
+ set = await this.melCloudAta.send(this.accountType, this.displayType, deviceData);
168
172
  break;
169
173
  case 'DefaultCoolingSetTemperature':
170
174
  deviceData.Device[key] = value;
171
175
  deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.SetTemperature;
172
- set = await this.melCloudAta.send(deviceData, this.displayMode);
176
+ set = await this.melCloudAta.send(this.accountType, this.displayType, deviceData);
173
177
  break;
174
178
  case 'DefaultHeatingSetTemperature':
175
179
  deviceData.Device[key] = value;
176
180
  deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.SetTemperature;
177
- set = await this.melCloudAta.send(deviceData, this.displayMode);
181
+ set = await this.melCloudAta.send(this.accountType, this.displayType, deviceData);
178
182
  break;
179
183
  case 'FanSpeed':
180
184
  deviceData.Device[key] = value;
181
185
  deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.SetFanSpeed;
182
- set = await this.melCloudAta.send(deviceData, this.displayMode);
186
+ set = await this.melCloudAta.send(this.accountType, this.displayType, deviceData);
183
187
  break;
184
188
  case 'VaneHorizontalDirection':
185
189
  deviceData.Device[key] = value;
186
- deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.VaneHorizontal;
187
- set = await this.melCloudAta.send(deviceData, this.displayMode);
190
+ deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.VaneHorizontalDirection;
191
+ set = await this.melCloudAta.send(this.accountType, this.displayType, deviceData);
188
192
  break;
189
193
  case 'VaneVerticalDirection':
190
194
  deviceData.Device[key] = value;
191
- deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.VaneVertical;
192
- set = await this.melCloudAta.send(deviceData, this.displayMode);
195
+ deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.VaneVerticalDirection;
196
+ set = await this.melCloudAta.send(this.accountType, this.displayType, deviceData);
193
197
  break;
194
198
  case 'HideVaneControls':
195
199
  deviceData[key] = value;
196
200
  deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.Prohibit;
197
- set = await this.melCloudAta.send(deviceData, this.displayMode);
201
+ set = await this.melCloudAta.send(this.accountType, this.displayType, deviceData);
198
202
  break;
199
203
  case 'HideDryModeControl':
200
204
  deviceData[key] = value;
201
205
  deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.Prohibit;
202
- await this.melCloudAta.send(deviceData, this.displayMode);
206
+ await this.melCloudAta.send(this.accountType, this.displayType, deviceData);
203
207
  break;
204
208
  case 'ProhibitSetTemperature':
205
209
  deviceData.Device[key] = value;
206
210
  deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.Prohibit;
207
- set = await this.melCloudAta.send(deviceData, this.displayMode);
211
+ set = await this.melCloudAta.send(this.accountType, this.displayType, deviceData);
208
212
  break;
209
213
  case 'ProhibitOperationMode':
210
214
  deviceData.Device[key] = value;
211
215
  deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.Prohibit;
212
- await this.melCloudAta.send(deviceData, this.displayMode);
216
+ await this.melCloudAta.send(this.accountType, this.displayType, deviceData);
213
217
  break;
214
218
  case 'ProhibitPower':
215
219
  deviceData.Device[key] = value;
216
220
  deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.Prohibit;
217
- set = await this.melCloudAta.send(deviceData, this.displayMode);
221
+ set = await this.melCloudAta.send(this.accountType, this.displayType, deviceData);
218
222
  break;
219
223
  default:
220
224
  this.emit('warn', `${integration}, received key: ${key}, value: ${value}`);
@@ -245,18 +249,18 @@ class DeviceAta extends EventEmitter {
245
249
  const deviceName = this.deviceName;
246
250
  const accountName = this.accountName;
247
251
  const presetsOnServer = this.accessory.presets;
248
- const modelSupportsHeat = this.accessory.modelSupportsHeat;
249
- const modelSupportsDry = this.accessory.modelSupportsDry;
250
- const modelSupportsCool = this.accessory.modelSupportsCool;
251
- const modelSupportsAuto = this.accessory.modelSupportsAuto;
252
- const modelSupportsFanSpeed = this.accessory.modelSupportsFanSpeed;
253
- const hasAutomaticFanSpeed = this.accessory.hasAutomaticFanSpeed;
254
- const hasOutdoorTemperature = this.accessory.hasOutdoorTemperature;
252
+ const supportsHeat = this.accessory.supportsHeat;
253
+ const supportsDry = this.accessory.supportsDry;
254
+ const supportsCool = this.accessory.supportsCool;
255
+ const supportsAuto = this.accessory.supportsAuto;
256
+ const supportsFanSpeed = this.accessory.supportsFanSpeed;
257
+ const supportsAutomaticFanSpeed = this.accessory.supportsAutomaticFanSpeed;
258
+ const supportsOutdoorTemperature = this.accessory.supportsOutdoorTemperature;
255
259
  const numberOfFanSpeeds = this.accessory.numberOfFanSpeeds;
256
- const swingFunction = this.accessory.swingFunction;
257
- const autoDryFanMode = [this.accessory.operationMode, 8, modelSupportsDry ? 2 : 8, 7][this.autoDryFanMode]; //NONE, AUTO - 8, DRY - 2, FAN - 7
258
- const heatDryFanMode = [this.accessory.operationMode, 1, modelSupportsDry ? 2 : 1, 7][this.heatDryFanMode]; //NONE, HEAT - 1, DRY - 2, FAN - 7
259
- const coolDryFanMode = [this.accessory.operationMode, 3, modelSupportsDry ? 2 : 3, 7][this.coolDryFanMode]; //NONE, COOL - 3, DRY - 2, FAN - 7
260
+ const supportsSwingFunction = this.accessory.supportsSwingFunction;
261
+ const autoDryFanMode = [this.accessory.operationMode, 8, supportsDry ? 2 : 8, 7][this.autoDryFanMode]; //NONE, AUTO - 8, DRY - 2, FAN - 7
262
+ const heatDryFanMode = [this.accessory.operationMode, 1, supportsDry ? 2 : 1, 7][this.heatDryFanMode]; //NONE, HEAT - 1, DRY - 2, FAN - 7
263
+ const coolDryFanMode = [this.accessory.operationMode, 3, supportsDry ? 2 : 3, 7][this.coolDryFanMode]; //NONE, COOL - 3, DRY - 2, FAN - 7
260
264
 
261
265
  //accessory
262
266
  if (this.logDebug) this.emit('debug', `Prepare accessory`);
@@ -276,7 +280,7 @@ class DeviceAta extends EventEmitter {
276
280
 
277
281
  //melcloud services
278
282
  const serviceName = `${deviceTypeText} ${accessoryName}`;
279
- switch (this.displayMode) {
283
+ switch (this.displayType) {
280
284
  case 1: //Heater Cooler
281
285
  if (this.logDebug) this.emit('debug', `Prepare heater/cooler service`);
282
286
  this.melCloudService = new Service.HeaterCooler(serviceName, `HeaterCooler ${deviceId}`);
@@ -287,10 +291,13 @@ class DeviceAta extends EventEmitter {
287
291
  return state;
288
292
  })
289
293
  .onSet(async (state) => {
294
+ state = state ? true : false;
295
+ if (state === deviceData.Device.Power) return;
296
+
290
297
  try {
291
- deviceData.Device.Power = [false, true][state];
298
+ deviceData.Device.Power = state
292
299
  deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.Power;
293
- await this.melCloudAta.send(deviceData, this.displayMode);
300
+ await this.melCloudAta.send(this.accountType, this.displayType, deviceData);
294
301
  if (this.logInfo) this.emit('info', `Set power: ${state ? 'ON' : 'OFF'}`);
295
302
  } catch (error) {
296
303
  if (this.logWarn) this.emit('warn', `Set power error: ${error}`);
@@ -315,20 +322,22 @@ class DeviceAta extends EventEmitter {
315
322
  try {
316
323
  switch (value) {
317
324
  case 0: //AUTO - AUTO
318
- deviceData.Device.OperationMode = autoDryFanMode;
325
+ value = autoDryFanMode;
326
+ deviceData.Device.OperationMode = value;
319
327
  break;
320
328
  case 1: //HEAT - HEAT
321
- deviceData.Device.OperationMode = heatDryFanMode;
329
+ value = heatDryFanMode;
330
+ deviceData.Device.OperationMode = value;
322
331
  break;
323
332
  case 2: //COOL - COOL
324
- deviceData.Device.OperationMode = coolDryFanMode;
333
+ value = coolDryFanMode;
334
+ deviceData.Device.OperationMode = value;
325
335
  break;
326
336
  };
327
337
 
328
- deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.OperationModeSetTemperature;
329
- await this.melCloudAta.send(deviceData, this.displayMode);
330
- const operationModeText = AirConditioner.DriveMode[deviceData.Device.OperationMode];
331
- if (this.logInfo) this.emit('info', `Set operation mode: ${operationModeText}`);
338
+ deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.OperationMode;
339
+ await this.melCloudAta.send(this.accountType, this.displayType, deviceData);
340
+ if (this.logInfo) this.emit('info', `Set operation mode: ${AirConditioner.OperationModeMapEnumToString[value]}`);
332
341
  } catch (error) {
333
342
  if (this.logWarn) this.emit('warn', `Set operation mode error: ${error}`);
334
343
  };
@@ -338,7 +347,7 @@ class DeviceAta extends EventEmitter {
338
347
  const value = this.accessory.roomTemperature;
339
348
  return value;
340
349
  });
341
- if (modelSupportsFanSpeed) {
350
+ if (supportsFanSpeed) {
342
351
  this.melCloudService.getCharacteristic(Characteristic.RotationSpeed)
343
352
  .setProps({
344
353
  minValue: 0,
@@ -346,56 +355,50 @@ class DeviceAta extends EventEmitter {
346
355
  minStep: 1
347
356
  })
348
357
  .onGet(async () => {
349
- const value = this.accessory.fanSpeed; //AUTO, 1, 2, 3, 4, 5, 6, OFF
358
+ const value = this.accessory.currentFanSpeed; //AUTO, 1, 2, 3, 4, 5, 6, OFF
350
359
  return value;
351
360
  })
352
361
  .onSet(async (value) => {
353
362
  try {
354
- let fanSpeedModeText = '';
363
+ const fanKey = this.accountType === 'melcloud' ? 'FanSpeed' : 'SetFanSpeed';
355
364
  switch (numberOfFanSpeeds) {
356
365
  case 2: //Fan speed mode 2
357
- fanSpeedModeText = hasAutomaticFanSpeed ? [7, 1, 2, 0][value] : [7, 1, 2][value];
358
- deviceData.Device.FanSpeed = hasAutomaticFanSpeed ? [0, 1, 2, 0][value] : [1, 1, 2][value];
366
+ value = supportsAutomaticFanSpeed ? [0, 1, 2, 0][value] : [1, 1, 2][value];
359
367
  break;
360
368
  case 3: //Fan speed mode 3
361
- fanSpeedModeText = hasAutomaticFanSpeed ? [7, 1, 2, 3, 0][value] : [7, 1, 2, 3][value];
362
- deviceData.Device.FanSpeed = hasAutomaticFanSpeed ? [0, 1, 2, 3, 0][value] : [1, 1, 2, 3][value];
369
+ value = supportsAutomaticFanSpeed ? [0, 1, 2, 3, 0][value] : [1, 1, 2, 3][value];
363
370
  break;
364
371
  case 4: //Fan speed mode 4
365
- fanSpeedModeText = hasAutomaticFanSpeed ? [7, 1, 2, 3, 4, 0][value] : [7, 1, 2, 3, 4][value];
366
- deviceData.Device.FanSpeed = hasAutomaticFanSpeed ? [0, 1, 2, 3, 4, 0][value] : [1, 1, 2, 3, 4][value];
372
+ value = supportsAutomaticFanSpeed ? [0, 1, 2, 3, 4, 0][value] : [1, 1, 2, 3, 4][value];
367
373
  break;
368
374
  case 5: //Fan speed mode 5
369
- 5; fanSpeedModeText = hasAutomaticFanSpeed ? [7, 1, 2, 3, 4, 5, 0][value] : [7, 1, 2, 3, 4, 5][value];
370
- deviceData.Device.FanSpeed = hasAutomaticFanSpeed ? [0, 1, 2, 3, 4, 5, 0][value] : [1, 1, 2, 3, 4, 5][value];
371
- break;
372
- case 6: //Fan speed mode 6
373
- fanSpeedModeText = hasAutomaticFanSpeed ? [7, 1, 2, 3, 4, 5, 6, 0][value] : [7, 1, 2, 3, 4, 5, 6][value];
374
- deviceData.Device.FanSpeed = hasAutomaticFanSpeed ? [0, 1, 2, 3, 4, 5, 6, 0][value] : [1, 1, 2, 3, 4, 5, 6][value];
375
+ value = supportsAutomaticFanSpeed ? [0, 1, 2, 3, 4, 5, 0][value] : [1, 1, 2, 3, 4, 5][value];
375
376
  break;
376
377
  };
378
+
379
+ deviceData.Device[fanKey] = value
377
380
  deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.SetFanSpeed;
378
- await this.melCloudAta.send(deviceData, this.displayMode);
379
- if (this.logInfo) this.emit('info', `Set fan speed mode: ${AirConditioner.FanSpeed[fanSpeedModeText]}`);
381
+ await this.melCloudAta.send(this.accountType, this.displayType, deviceData);
382
+ if (this.logInfo) this.emit('info', `Set fan speed mode: ${AirConditioner.FanSpeedMapEnumToString[value]}`);
380
383
  } catch (error) {
381
384
  if (this.logWarn) this.emit('warn', `Set fan speed mode error: ${error}`);
382
385
  };
383
386
  });
384
387
  };
385
- if (swingFunction) {
388
+ if (supportsSwingFunction) {
386
389
  this.melCloudService.getCharacteristic(Characteristic.SwingMode)
387
390
  .onGet(async () => {
388
- //Vane Horizontal: Auto, 1, 2, 3, 4, 5, 6, 12 = Swing //Vertical: Auto, 1, 2, 3, 4, 5, 7 = Swing
389
- const value = this.accessory.swingMode;
391
+ //Vane Horizontal: Auto, 1, 2, 3, 4, 5, 6, 7 = Sp;it, 12 = Swing //Vertical: Auto, 1, 2, 3, 4, 5, 7 = Swing
392
+ const value = this.accessory.currentSwingMode;
390
393
  return value;
391
394
  })
392
395
  .onSet(async (value) => {
393
396
  try {
394
- deviceData.Device.VaneHorizontal = value ? 12 : 0;
395
- deviceData.Device.VaneVertical = value ? 7 : 0;
397
+ deviceData.Device.VaneHorizontalDirection = value ? 12 : 0;
398
+ deviceData.Device.VaneVerticalDirection = value ? 7 : 0;
396
399
  deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.VaneVerticalVaneHorizontal;
397
- await this.melCloudAta.send(deviceData, this.displayMode);
398
- if (this.logInfo) this.emit('info', `Set air direction mode: ${AirConditioner.AirDirection[value]}`);
400
+ await this.melCloudAta.send(this.accountType, this.displayType, deviceData);
401
+ if (this.logInfo) this.emit('info', `Set air direction mode: ${AirConditioner.AirDirectionMapEnumToString[value]}`);
399
402
  } catch (error) {
400
403
  if (this.logWarn) this.emit('warn', `Set vane swing mode error: ${error}`);
401
404
  };
@@ -403,9 +406,9 @@ class DeviceAta extends EventEmitter {
403
406
  };
404
407
  this.melCloudService.getCharacteristic(Characteristic.CoolingThresholdTemperature)
405
408
  .setProps({
406
- minValue: this.accessory.minTempCoolDry,
407
- maxValue: this.accessory.maxTempCoolDry,
408
- minStep: this.accessory.temperatureIncrement
409
+ minValue: this.accessory.minTempCoolDryAuto,
410
+ maxValue: this.accessory.maxTempCoolDryAuto,
411
+ minStep: this.accessory.temperatureStep
409
412
  })
410
413
  .onGet(async () => {
411
414
  const value = this.accessory.operationMode === 8 ? this.accessory.defaultCoolingSetTemperature : this.accessory.setTemperature;
@@ -413,20 +416,21 @@ class DeviceAta extends EventEmitter {
413
416
  })
414
417
  .onSet(async (value) => {
415
418
  try {
416
- deviceData.Device.DefaultCoolingSetTemperature = value;
419
+ const tempKey = this.accessory.operationMode === 8 ? 'DefaultCoolingSetTemperature' : 'SetTemperature';
420
+ deviceData.Device[tempKey] = value;
417
421
  deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.SetTemperature;
418
- await this.melCloudAta.send(deviceData, this.displayMode);
422
+ await this.melCloudAta.send(this.accountType, this.displayType, deviceData);
419
423
  if (this.logInfo) this.emit('info', `Set cooling threshold temperature: ${value}${this.accessory.temperatureUnit}`);
420
424
  } catch (error) {
421
425
  if (this.logWarn) this.emit('warn', `Set cooling threshold temperature error: ${error}`);
422
426
  };
423
427
  });
424
- if (modelSupportsHeat) {
428
+ if (supportsHeat) {
425
429
  this.melCloudService.getCharacteristic(Characteristic.HeatingThresholdTemperature)
426
430
  .setProps({
427
431
  minValue: this.accessory.minTempHeat,
428
432
  maxValue: this.accessory.maxTempHeat,
429
- minStep: this.accessory.temperatureIncrement
433
+ minStep: this.accessory.temperatureStep
430
434
  })
431
435
  .onGet(async () => {
432
436
  const value = this.accessory.operationMode === 8 ? this.accessory.defaultHeatingSetTemperature : this.accessory.setTemperature;
@@ -434,9 +438,10 @@ class DeviceAta extends EventEmitter {
434
438
  })
435
439
  .onSet(async (value) => {
436
440
  try {
437
- deviceData.Device.DefaultHeatingSetTemperature = value;
441
+ const tempKey = this.accessory.operationMode === 8 ? 'DefaultHeatingSetTemperature' : 'SetTemperature';
442
+ deviceData.Device[tempKey] = value;
438
443
  deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.SetTemperature;
439
- await this.melCloudAta.send(deviceData, this.displayMode);
444
+ await this.melCloudAta.send(this.accountType, this.displayType, deviceData);
440
445
  if (this.logInfo) this.emit('info', `Set heating threshold temperature: ${value}${this.accessory.temperatureUnit}`);
441
446
  } catch (error) {
442
447
  if (this.logWarn) this.emit('warn', `Set heating threshold temperature error: ${error}`);
@@ -455,7 +460,7 @@ class DeviceAta extends EventEmitter {
455
460
  deviceData.Device.ProhibitOperationMode = value;
456
461
  deviceData.Device.ProhibitPower = value;
457
462
  deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.Prohibit;
458
- await this.melCloudAta.send(deviceData, this.displayMode);
463
+ await this.melCloudAta.send(this.accountType, this.displayType, deviceData);
459
464
  if (this.logInfo) this.emit('info', `Set local physical controls: ${value ? 'LOCK' : 'UNLOCK'}`);
460
465
  } catch (error) {
461
466
  if (this.logWarn) this.emit('warn', `Set lock physical controls error: ${error}`);
@@ -501,28 +506,30 @@ class DeviceAta extends EventEmitter {
501
506
  try {
502
507
  switch (value) {
503
508
  case 0: //OFF - POWER OFF
509
+ value = deviceData.Device.OperationMode;
504
510
  deviceData.Device.Power = false;
505
511
  deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.Power;
506
512
  break;
507
513
  case 1: //HEAT - HEAT
508
514
  deviceData.Device.Power = true;
509
- deviceData.Device.OperationMode = heatDryFanMode;
515
+ value = heatDryFanMode;
510
516
  deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerOperationModeSetTemperature;
511
517
  break;
512
518
  case 2: //COOL - COOL
519
+ value = coolDryFanMode;
513
520
  deviceData.Device.Power = true;
514
- deviceData.Device.OperationMode = coolDryFanMode;
515
521
  deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerOperationModeSetTemperature
516
522
  break;
517
523
  case 3: //AUTO - AUTO
524
+ value = autoDryFanMode;
518
525
  deviceData.Device.Power = true;
519
- deviceData.Device.OperationMode = autoDryFanMode;
520
526
  deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerOperationModeSetTemperature;
521
527
  break;
522
528
  };
523
529
 
524
- await this.melCloudAta.send(deviceData, this.displayMode);
525
- const operationModeText = AirConditioner.DriveMode[deviceData.Device.OperationMode];
530
+ deviceData.Device.OperationMode = value;
531
+ await this.melCloudAta.send(this.accountType, this.displayType, deviceData);
532
+ const operationModeText = AirConditioner.OperationModeMapEnumToString[value];
526
533
  if (this.logInfo) this.emit('info', `Set operation mode: ${operationModeText}`);
527
534
  } catch (error) {
528
535
  if (this.logWarn) this.emit('warn', `Set operation mode error: ${error}`);
@@ -537,7 +544,7 @@ class DeviceAta extends EventEmitter {
537
544
  .setProps({
538
545
  minValue: this.accessory.minTempHeat,
539
546
  maxValue: this.accessory.maxTempHeat,
540
- minStep: this.accessory.temperatureIncrement
547
+ minStep: this.accessory.temperatureStep
541
548
  })
542
549
  .onGet(async () => {
543
550
  const value = this.accessory.setTemperature;
@@ -547,7 +554,7 @@ class DeviceAta extends EventEmitter {
547
554
  try {
548
555
  deviceData.Device.SetTemperature = value;
549
556
  deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.SetTemperature;
550
- await this.melCloudAta.send(deviceData, this.displayMode);
557
+ await this.melCloudAta.send(this.accountType, this.displayType, deviceData);
551
558
  if (this.logInfo) this.emit('info', `Set temperature: ${value}${this.accessory.temperatureUnit}`);
552
559
  } catch (error) {
553
560
  if (this.logWarn) this.emit('warn', `Set temperature error: ${error}`);
@@ -591,7 +598,7 @@ class DeviceAta extends EventEmitter {
591
598
  accessory.addService(this.roomTemperatureSensorService);
592
599
  };
593
600
 
594
- if (this.temperatureSensorOutdoor && hasOutdoorTemperature && this.accessory.outdoorTemperature !== null) {
601
+ if (this.temperatureSensorOutdoor && supportsOutdoorTemperature && this.accessory.outdoorTemperature !== null) {
595
602
  if (this.logDebug) this.emit('debug', `Prepare outdoor temperature sensor service`);
596
603
  this.outdoorTemperatureSensorService = new Service.TemperatureSensor(`${serviceName} Outdoor`, `Outdoor Temperature Sensor ${deviceId}`);
597
604
  this.outdoorTemperatureSensorService.addOptionalCharacteristic(Characteristic.ConfiguredName);
@@ -635,15 +642,16 @@ class DeviceAta extends EventEmitter {
635
642
  })
636
643
  .onSet(async (state) => {
637
644
  try {
645
+ const fanKey = this.accountType === 'melcloud' ? 'FanSpeed' : 'SetFanSpeed';
638
646
  switch (state) {
639
647
  case true:
640
648
  preset.previousSettings = deviceData.Device;
641
649
  deviceData.Device.Power = presetData.Power;
642
650
  deviceData.Device.OperationMode = presetData.OperationMode;
643
651
  deviceData.Device.SetTemperature = presetData.SetTemperature;
644
- deviceData.Device.VaneHorizontalDirection = presetData.VaneHorizontal;
645
- deviceData.Device.VaneVerticalDirection = presetData.VaneVertical;
646
- deviceData.Device.FanSpeed = presetData.FanSpeed;
652
+ deviceData.Device.VaneHorizontalDirection = presetData.VaneHorizontalDirection;
653
+ deviceData.Device.VaneVerticalDirection = presetData.VaneVerticalDirection;
654
+ deviceData.Device[fanKey] = presetData[fanKey];
647
655
  deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.Presets;
648
656
  break;
649
657
  case false:
@@ -652,12 +660,12 @@ class DeviceAta extends EventEmitter {
652
660
  deviceData.Device.SetTemperature = preset.previousSettings.SetTemperature;
653
661
  deviceData.Device.VaneHorizontalDirection = preset.previousSettings.VaneHorizontalDirection;
654
662
  deviceData.Device.VaneVerticalDirection = preset.previousSettings.VaneVerticalDirection;
655
- deviceData.Device.FanSpeed = preset.previousSettings.FanSpeed;
663
+ deviceData.Device[fanKey] = preset.previousSettings[fanKey];
656
664
  deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.Presets;
657
665
  break;
658
666
  };
659
667
 
660
- await this.melCloudAta.send(deviceData, this.displayMode);
668
+ await this.melCloudAta.send(this.accountType, this.displayType, deviceData);
661
669
  if (this.logInfo) this.emit('info', `${state ? 'Set:' : 'Unset:'} ${name}`);
662
670
  } catch (error) {
663
671
  if (this.logWarn) this.emit('warn', `Set preset error: ${error}`);
@@ -695,6 +703,7 @@ class DeviceAta extends EventEmitter {
695
703
  })
696
704
  .onSet(async (state) => {
697
705
  try {
706
+ const key = this.accountType === 'melcloud' ? 'FanSpeed' : 'SetFanSpeed';
698
707
  switch (mode) {
699
708
  case 0: //POWER ON,OFF
700
709
  deviceData.Device.Power = state;
@@ -833,45 +842,45 @@ class DeviceAta extends EventEmitter {
833
842
  deviceData.HideVaneControls = state;
834
843
  break;
835
844
  case 30: //FAN SPEED MODE AUTO
836
- button.previousValue = state ? deviceData.Device.FanSpeed : button.previousValue ?? deviceData.Device.FanSpeed;
845
+ button.previousValue = state ? deviceData.Device[fanKey] : button.previousValue ?? deviceData.Device[fanKey];
837
846
  deviceData.Device.Power = true;
838
- deviceData.Device.FanSpeed = state ? 0 : button.previousValue;
847
+ deviceData.Device[fanKey] = state ? 0 : button.previousValue;
839
848
  deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerSetFanSpeed;
840
849
  break;
841
850
  case 31: //FAN SPEED MODE 1
842
- button.previousValue = state ? deviceData.Device.FanSpeed : button.previousValue ?? deviceData.Device.FanSpeed;
851
+ button.previousValue = state ? deviceData.Device[fanKey] : button.previousValue ?? deviceData.Device[fanKey];
843
852
  deviceData.Device.Power = true;
844
- deviceData.Device.FanSpeed = state ? 1 : button.previousValue;
853
+ deviceData.Device[fanKey] = state ? 1 : button.previousValue;
845
854
  deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerSetFanSpeed;
846
855
  break;
847
856
  case 32: //FAN SPEED MODE 2
848
- button.previousValue = state ? deviceData.Device.FanSpeed : button.previousValue ?? deviceData.Device.FanSpeed;
857
+ button.previousValue = state ? deviceData.Device[fanKey] : button.previousValue ?? deviceData.Device[fanKey];
849
858
  deviceData.Device.Power = true;
850
- deviceData.Device.FanSpeed = state ? 2 : button.previousValue;
859
+ deviceData.Device[fanKey] = state ? 2 : button.previousValue;
851
860
  deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerSetFanSpeed;
852
861
  break;
853
862
  case 33: //FAN SPEED MODE 3
854
- button.previousValue = state ? deviceData.Device.FanSpeed : button.previousValue ?? deviceData.Device.FanSpeed;
863
+ button.previousValue = state ? deviceData.Device[fanKey] : button.previousValue ?? deviceData.Device[fanKey];
855
864
  deviceData.Device.Power = true;
856
- deviceData.Device.FanSpeed = state ? 3 : button.previousValue;
865
+ deviceData.Device[fanKey] = state ? 3 : button.previousValue;
857
866
  deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerSetFanSpeed;
858
867
  break;
859
868
  case 34: //FAN MODE 4
860
- button.previousValue = state ? deviceData.Device.FanSpeed : button.previousValue ?? deviceData.Device.FanSpeed;
869
+ button.previousValue = state ? deviceData.Device[fanKey] : button.previousValue ?? deviceData.Device[fanKey];
861
870
  deviceData.Device.Power = true;
862
- deviceData.Device.FanSpeed = state ? 4 : button.previousValue;
871
+ deviceData.Device[fanKey] = state ? 4 : button.previousValue;
863
872
  deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerSetFanSpeed;
864
873
  break;
865
874
  case 35: //FAN SPEED MODE 5
866
- button.previousValue = state ? deviceData.Device.FanSpeed : button.previousValue ?? deviceData.Device.FanSpeed;
875
+ button.previousValue = state ? deviceData.Device[fanKey] : button.previousValue ?? deviceData.Device[fanKey];
867
876
  deviceData.Device.Power = true;
868
- deviceData.Device.FanSpeed = state ? 5 : button.previousValue;
877
+ deviceData.Device[fanKey] = state ? 5 : button.previousValue;
869
878
  deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerSetFanSpeed;
870
879
  break;
871
880
  case 36: //FAN SPEED MODE 6
872
- button.previousValue = state ? deviceData.Device.FanSpeed : button.previousValue ?? deviceData.Device.FanSpeed;
881
+ button.previousValue = state ? deviceData.Device[fanKey] : button.previousValue ?? deviceData.Device[fanKey];
873
882
  deviceData.Device.Power = true;
874
- deviceData.Device.FanSpeed = state ? 6 : button.previousValue;
883
+ deviceData.Device[fanKey] = state ? 6 : button.previousValue;
875
884
  deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerSetFanSpeed;
876
885
  break;
877
886
  case 37: //PHYSICAL LOCK CONTROLS
@@ -897,7 +906,7 @@ class DeviceAta extends EventEmitter {
897
906
  break;
898
907
  };
899
908
 
900
- await this.melCloudAta.send(deviceData, this.displayMode);
909
+ await this.melCloudAta.send(this.accountType, this.displayType, deviceData);
901
910
  if (this.logInfo) this.emit('info', `${state ? `Set: ${name}` : `Unset: ${name}, Set: ${button.previousValue}`}`);
902
911
  } catch (error) {
903
912
  if (this.logWarn) this.emit('warn', `Set button error: ${error}`);
@@ -918,15 +927,15 @@ class DeviceAta extends EventEmitter {
918
927
  async start() {
919
928
  try {
920
929
  //melcloud device
921
- this.melCloudAta = new MelCloudAta(this.device, this.contextKey, this.devicesFile)
930
+ this.melCloudAta = new MelCloudAta(this.account, this.device, this.devicesFile, this.defaultTempsFile)
922
931
  .on('deviceInfo', (manufacturer, modelIndoor, modelOutdoor, serialNumber, firmwareAppVersion) => {
923
932
  if (this.logDeviceInfo && this.displayDeviceInfo) {
924
933
  this.emit('devInfo', `---- ${this.deviceTypeText}: ${this.deviceName} ----`);
925
934
  this.emit('devInfo', `Account: ${this.accountName}`);
926
935
  if (modelIndoor) this.emit('devInfo', `Indoor: ${modelIndoor}`);
927
936
  if (modelOutdoor) this.emit('devInfo', `Outdoor: ${modelOutdoor}`);
928
- this.emit('devInfo', `Serial: ${serialNumber}`);
929
- this.emit('devInfo', `Firmware: ${firmwareAppVersion}`);
937
+ if (serialNumber) this.emit('devInfo', `Serial: ${serialNumber}`);
938
+ if (firmwareAppVersion) this.emit('devInfo', `Firmware: ${firmwareAppVersion}`);
930
939
  this.emit('devInfo', `Manufacturer: ${manufacturer}`);
931
940
  this.emit('devInfo', '----------------------------------');
932
941
  this.displayDeviceInfo = false;
@@ -934,11 +943,11 @@ class DeviceAta extends EventEmitter {
934
943
 
935
944
  //accessory info
936
945
  this.manufacturer = manufacturer;
937
- this.model = modelIndoor ? modelIndoor : modelOutdoor ? modelOutdoor : `${this.deviceTypeText} ${this.deviceId}`;
938
- this.serialNumber = serialNumber;
939
- this.firmwareRevision = firmwareAppVersion;
946
+ this.model = modelIndoor ? modelIndoor : modelOutdoor ? modelOutdoor : `${this.deviceTypeText}`;
947
+ this.serialNumber = serialNumber.toString();
948
+ this.firmwareRevision = firmwareAppVersion.toString();
940
949
 
941
- this.informationService?.setCharacteristic(Characteristic.FirmwareRevision, firmwareAppVersion);
950
+ this.informationService?.setCharacteristic(Characteristic.FirmwareRevision, this.firmwareAppVersion);
942
951
  })
943
952
  .on('deviceState', async (deviceData) => {
944
953
  this.deviceData = deviceData;
@@ -951,33 +960,38 @@ class DeviceAta extends EventEmitter {
951
960
  const hideDryModeControl = deviceData.HideDryModeControl ?? false;
952
961
 
953
962
  //device info
954
- const hasAutomaticFanSpeed = deviceData.Device.HasAutomaticFanSpeed ?? false;
955
- const airDirectionFunction = deviceData.Device.AirDirectionFunction ?? false;
956
- const swingFunction = deviceData.Device.SwingFunction ?? false;
957
- const hasOutdoorTemperature = deviceData.Device.HasOutdoorTemperature ?? false;
958
- const numberOfFanSpeeds = deviceData.Device.NumberOfFanSpeeds ?? 0;
959
- const modelSupportsFanSpeed = deviceData.Device.ModelSupportsFanSpeed ?? false;
960
- const modelSupportsAuto1 = deviceData.Device.ModelSupportsAuto ?? false;
961
- const modelSupportsAuto = this.autoDryFanMode >= 1 && modelSupportsAuto1
962
- const modelSupportsHeat1 = deviceData.Device.ModelSupportsHeat ?? false;
963
- const modelSupportsHeat = this.heatDryFanMode >= 1 && modelSupportsHeat1;
964
- const modelSupportsDry = deviceData.Device.ModelSupportsDry ?? false;
965
- const modelSupportsCool = this.coolDryFanMode >= 1;
963
+ const accountTypeMelcloud = this.accountType === 'melcloud';
964
+ const supportsAutomaticFanSpeed = deviceData.Device.HasAutomaticFanSpeed ?? false;
965
+ const supportsAirDirectionFunction = accountTypeMelcloud ? deviceData.Device.AirDirectionFunction : deviceData.Device.HasAirDirectionFunction;;
966
+ const supportsSwingFunction = accountTypeMelcloud ? deviceData.Device.SwingFunction : deviceData.Device.HasSwing;
967
+ const supportsWideVane = accountTypeMelcloud ? deviceData.Device.ModelSupportsWideVane : deviceData.Device.SupportsWideVane;
968
+ const supportsOutdoorTemperature = deviceData.Device.HasOutdoorTemperature ?? false;
969
+ const supportsFanSpeed = accountTypeMelcloud ? deviceData.Device.ModelSupportsFanSpeed : deviceData.Device.NumberOfFanSpeeds > 0;
970
+ const supportsAuto1 = accountTypeMelcloud ? deviceData.Device.ModelSupportsAuto : deviceData.Device.HasAutoOperationMode;
971
+ const supportsAuto = this.autoDryFanMode >= 1 && supportsAuto1
972
+ const supportsHeat1 = accountTypeMelcloud ? deviceData.Device.ModelSupportsHeat : deviceData.Device.HasHeatOperationMode
973
+ const supportsHeat = this.heatDryFanMode >= 1 && supportsHeat1;
974
+ const supportsDry = accountTypeMelcloud ? deviceData.Device.ModelSupportsDry : deviceData.Device.HasDryOperationMode;
975
+ const supportsCool1 = accountTypeMelcloud ? deviceData.Device.ModelSupportsCool : deviceData.Device.HasCoolOperationMode;
976
+ const supportsCool = this.coolDryFanMode >= 1 && supportsCool1;
977
+ const numberOfFanSpeeds = supportsFanSpeed ? deviceData.Device.NumberOfFanSpeeds : 0;
966
978
  const minTempHeat = 10;
967
979
  const maxTempHeat = 31;
968
- const minTempCoolDry = 16;
969
- const maxTempCoolDry = 31;
980
+ const minTempCoolDryAuto = 16;
981
+ const maxTempCoolDryAuto = 31;
970
982
 
971
983
  //device state
984
+ const fanKey = this.accountType === 'melcloud' ? 'FanSpeed' : 'SetFanSpeed';
985
+ const tempStepKey = this.accountType === 'melcloud' ? 'TemperatureIncrement' : 'HasHalfDegreeIncrements';
972
986
  const power = deviceData.Device.Power ?? false;
973
987
  const inStandbyMode = deviceData.Device.InStandbyMode ?? false;
974
988
  const roomTemperature = deviceData.Device.RoomTemperature;
975
- const setTemperature = deviceData.Device.SetTemperature ?? 20;
976
- const defaultHeatingSetTemperature = deviceData.Device.DefaultHeatingSetTemperature ?? 20;
977
- const defaultCoolingSetTemperature = deviceData.Device.DefaultCoolingSetTemperature ?? 23;
989
+ const setTemperature = deviceData.Device.SetTemperature;
990
+ const defaultHeatingSetTemperature = deviceData.Device.DefaultHeatingSetTemperature;
991
+ const defaultCoolingSetTemperature = deviceData.Device.DefaultCoolingSetTemperature;
978
992
  const actualFanSpeed = deviceData.Device.ActualFanSpeed;
979
993
  const automaticFanSpeed = deviceData.Device.AutomaticFanSpeed;
980
- const fanSpeed = deviceData.Device.FanSpeed ?? 0;
994
+ const setFanSpeed = deviceData.Device[fanKey];
981
995
  const operationMode = deviceData.Device.OperationMode;
982
996
  const vaneVerticalDirection = deviceData.Device.VaneVerticalDirection;
983
997
  const vaneVerticalSwing = deviceData.Device.VaneVerticalSwing;
@@ -986,26 +1000,27 @@ class DeviceAta extends EventEmitter {
986
1000
  const prohibitSetTemperature = deviceData.Device.ProhibitSetTemperature ?? false;
987
1001
  const prohibitOperationMode = deviceData.Device.ProhibitOperationMode ?? false;
988
1002
  const prohibitPower = deviceData.Device.ProhibitPower ?? false;
989
- const temperatureIncrement = deviceData.Device.TemperatureIncrement ?? 1;
1003
+ const temperatureStep = deviceData.Device[tempStepKey] ? 0.5 : 1;
990
1004
  const outdoorTemperature = deviceData.Device.OutdoorTemperature;
991
1005
 
992
1006
  //accessory
993
1007
  const obj = {
994
1008
  presets: presetsOnServer,
995
- hasAutomaticFanSpeed: hasAutomaticFanSpeed,
996
- airDirectionFunction: airDirectionFunction,
997
- swingFunction: swingFunction,
998
- hasOutdoorTemperature: hasOutdoorTemperature,
1009
+ supportsAutomaticFanSpeed: supportsAutomaticFanSpeed,
1010
+ supportsAirDirectionFunction: supportsAirDirectionFunction,
1011
+ supportsSwingFunction: supportsSwingFunction,
1012
+ supportsWideVane: supportsWideVane,
1013
+ supportsOutdoorTemperature: supportsOutdoorTemperature,
999
1014
  numberOfFanSpeeds: numberOfFanSpeeds,
1000
- modelSupportsFanSpeed: modelSupportsFanSpeed,
1001
- modelSupportsAuto: modelSupportsAuto,
1002
- modelSupportsHeat: modelSupportsHeat,
1003
- modelSupportsDry: modelSupportsDry,
1004
- modelSupportsCool: modelSupportsCool,
1015
+ supportsFanSpeed: supportsFanSpeed,
1016
+ supportsAuto: supportsAuto,
1017
+ supportsHeat: supportsHeat,
1018
+ supportsDry: supportsDry,
1019
+ supportsCool: supportsCool,
1005
1020
  minTempHeat: minTempHeat,
1006
1021
  maxTempHeat: maxTempHeat,
1007
- minTempCoolDry: minTempCoolDry,
1008
- maxTempCoolDry: maxTempCoolDry,
1022
+ minTempCoolDryAuto: minTempCoolDryAuto,
1023
+ maxTempCoolDryAuto: maxTempCoolDryAuto,
1009
1024
  power: power ? 1 : 0,
1010
1025
  inStandbyMode: inStandbyMode,
1011
1026
  operationMode: operationMode,
@@ -1020,15 +1035,15 @@ class DeviceAta extends EventEmitter {
1020
1035
  automaticFanSpeed: automaticFanSpeed,
1021
1036
  vaneVerticalSwing: vaneVerticalSwing,
1022
1037
  vaneHorizontalSwing: vaneHorizontalSwing,
1023
- swingMode: swingFunction && vaneHorizontalDirection === 12 && vaneVerticalDirection === 7 ? 1 : 0,
1038
+ currentSwingMode: supportsSwingFunction && vaneHorizontalDirection === 12 && vaneVerticalDirection === 7 ? 1 : 0,
1024
1039
  lockPhysicalControl: prohibitSetTemperature && prohibitOperationMode && prohibitPower ? 1 : 0,
1025
- temperatureIncrement: temperatureIncrement,
1040
+ temperatureStep: temperatureStep,
1026
1041
  useFahrenheit: this.useFahrenheit,
1027
1042
  temperatureUnit: TemperatureDisplayUnits[this.useFahrenheit]
1028
1043
  };
1029
1044
 
1030
1045
  //operating mode 0, HEAT, DRY, COOL, 4, 5, 6, FAN, AUTO, ISEE HEAT, ISEE DRY, ISEE COOL
1031
- switch (this.displayMode) {
1046
+ switch (this.displayType) {
1032
1047
  case 1: //Heater Cooler
1033
1048
  switch (operationMode) {
1034
1049
  case 1: //HEAT
@@ -1069,32 +1084,28 @@ class DeviceAta extends EventEmitter {
1069
1084
  };
1070
1085
 
1071
1086
  obj.currentOperationMode = !power ? 0 : inStandbyMode ? 1 : obj.currentOperationMode;
1072
- obj.operationModeSetPropsMinValue = modelSupportsAuto && modelSupportsHeat ? 0 : !modelSupportsAuto && modelSupportsHeat ? 1 : modelSupportsAuto && !modelSupportsHeat ? 0 : 2;
1087
+ obj.operationModeSetPropsMinValue = supportsAuto && supportsHeat ? 0 : !supportsAuto && supportsHeat ? 1 : supportsAuto && !supportsHeat ? 0 : 2;
1073
1088
  obj.operationModeSetPropsMaxValue = 2
1074
- obj.operationModeSetPropsValidValues = modelSupportsAuto && modelSupportsHeat ? [0, 1, 2] : !modelSupportsAuto && modelSupportsHeat ? [1, 2] : modelSupportsAuto && !modelSupportsHeat ? [0, 2] : [2];
1089
+ obj.operationModeSetPropsValidValues = supportsAuto && supportsHeat ? [0, 1, 2] : !supportsAuto && supportsHeat ? [1, 2] : supportsAuto && !supportsHeat ? [0, 2] : [2];
1075
1090
 
1076
1091
  //fan speed mode
1077
- if (modelSupportsFanSpeed) {
1092
+ if (supportsFanSpeed) {
1078
1093
  switch (numberOfFanSpeeds) {
1079
1094
  case 2: //Fan speed mode 2
1080
- obj.fanSpeed = hasAutomaticFanSpeed ? [3, 1, 2][fanSpeed] : [0, 1, 2][fanSpeed];
1081
- obj.fanSpeedSetPropsMaxValue = hasAutomaticFanSpeed ? 3 : 2;
1095
+ obj.currentFanSpeed = supportsAutomaticFanSpeed ? [3, 1, 2][setFanSpeed] : [0, 1, 2][setFanSpeed];
1096
+ obj.fanSpeedSetPropsMaxValue = supportsAutomaticFanSpeed ? 3 : 2;
1082
1097
  break;
1083
1098
  case 3: //Fan speed mode 3
1084
- obj.fanSpeed = hasAutomaticFanSpeed ? [4, 1, 2, 3][fanSpeed] : [0, 1, 2, 3][fanSpeed];
1085
- obj.fanSpeedSetPropsMaxValue = hasAutomaticFanSpeed ? 4 : 3;
1099
+ obj.currentFanSpeed = supportsAutomaticFanSpeed ? [4, 1, 2, 3][setFanSpeed] : [0, 1, 2, 3][setFanSpeed];
1100
+ obj.fanSpeedSetPropsMaxValue = supportsAutomaticFanSpeed ? 4 : 3;
1086
1101
  break;
1087
1102
  case 4: //Fan speed mode 4
1088
- obj.fanSpeed = hasAutomaticFanSpeed ? [5, 1, 2, 3, 4][fanSpeed] : [0, 1, 2, 3, 4][fanSpeed];
1089
- obj.fanSpeedSetPropsMaxValue = hasAutomaticFanSpeed ? 5 : 4;
1103
+ obj.currentFanSpeed = supportsAutomaticFanSpeed ? [5, 1, 2, 3, 4][setFanSpeed] : [0, 1, 2, 3, 4][setFanSpeed];
1104
+ obj.fanSpeedSetPropsMaxValue = supportsAutomaticFanSpeed ? 5 : 4;
1090
1105
  break;
1091
1106
  case 5: //Fan speed mode 5
1092
- obj.fanSpeed = hasAutomaticFanSpeed ? [6, 1, 2, 3, 4, 5][fanSpeed] : [0, 1, 2, 3, 4, 5][fanSpeed];
1093
- obj.fanSpeedSetPropsMaxValue = hasAutomaticFanSpeed ? 6 : 5;
1094
- break;
1095
- case 6: //Fan speed mode 6
1096
- obj.fanSpeed = hasAutomaticFanSpeed ? [7, 1, 2, 3, 4, 5, 6][fanSpeed] : [0, 1, 2, 3, 4, 5, 6][fanSpeed];
1097
- obj.fanSpeedSetPropsMaxValue = hasAutomaticFanSpeed ? 7 : 6;
1107
+ obj.currentFanSpeed = supportsAutomaticFanSpeed ? [6, 1, 2, 3, 4, 5][setFanSpeed] : [0, 1, 2, 3, 4, 5][setFanSpeed];
1108
+ obj.fanSpeedSetPropsMaxValue = supportsAutomaticFanSpeed ? 6 : 5;
1098
1109
  break;
1099
1110
  };
1100
1111
  };
@@ -1107,10 +1118,10 @@ class DeviceAta extends EventEmitter {
1107
1118
  .updateCharacteristic(Characteristic.CurrentTemperature, roomTemperature)
1108
1119
  .updateCharacteristic(Characteristic.LockPhysicalControls, obj.lockPhysicalControl)
1109
1120
  .updateCharacteristic(Characteristic.TemperatureDisplayUnits, obj.useFahrenheit)
1110
- .updateCharacteristic(Characteristic.CoolingThresholdTemperature, defaultCoolingSetTemperature);
1111
- const updateDefHeat = modelSupportsHeat ? this.melCloudService?.updateCharacteristic(Characteristic.HeatingThresholdTemperature, defaultHeatingSetTemperature) : false;
1112
- const updateRS = modelSupportsFanSpeed ? this.melCloudService?.updateCharacteristic(Characteristic.RotationSpeed, obj.fanSpeed) : false;
1113
- const updateSM = swingFunction ? this.melCloudService?.updateCharacteristic(Characteristic.SwingMode, obj.swingMode) : false;
1121
+ .updateCharacteristic(Characteristic.CoolingThresholdTemperature, operationMode === 8 ? defaultCoolingSetTemperature : setTemperature);
1122
+ if (supportsHeat) this.melCloudService?.updateCharacteristic(Characteristic.HeatingThresholdTemperature, operationMode === 8 ? defaultHeatingSetTemperature : setTemperature);
1123
+ if (supportsFanSpeed) this.melCloudService?.updateCharacteristic(Characteristic.RotationSpeed, obj.currentFanSpeed);
1124
+ if (supportsSwingFunction) this.melCloudService?.updateCharacteristic(Characteristic.SwingMode, obj.currentSwingMode);
1114
1125
  break;
1115
1126
  case 2: //Thermostat
1116
1127
  switch (operationMode) {
@@ -1154,8 +1165,8 @@ class DeviceAta extends EventEmitter {
1154
1165
  obj.currentOperationMode = !power ? 0 : obj.currentOperationMode;
1155
1166
  obj.targetOperationMode = !power ? 0 : obj.targetOperationMode;
1156
1167
  obj.operationModeSetPropsMinValue = 0
1157
- obj.operationModeSetPropsMaxValue = modelSupportsAuto && modelSupportsHeat ? 3 : !modelSupportsAuto && modelSupportsHeat ? 2 : modelSupportsAuto && !modelSupportsHeat ? 3 : 2;
1158
- obj.operationModeSetPropsValidValues = modelSupportsAuto && modelSupportsHeat ? [0, 1, 2, 3] : !modelSupportsAuto && modelSupportsHeat ? [0, 1, 2] : modelSupportsAuto && !modelSupportsHeat ? [0, 2, 3] : [0, 2];
1168
+ obj.operationModeSetPropsMaxValue = supportsAuto && supportsHeat ? 3 : !supportsAuto && supportsHeat ? 2 : supportsAuto && !supportsHeat ? 3 : 2;
1169
+ obj.operationModeSetPropsValidValues = supportsAuto && supportsHeat ? [0, 1, 2, 3] : !supportsAuto && supportsHeat ? [0, 1, 2] : supportsAuto && !supportsHeat ? [0, 2, 3] : [0, 2];
1159
1170
 
1160
1171
  //update characteristics
1161
1172
  this.melCloudService
@@ -1179,9 +1190,9 @@ class DeviceAta extends EventEmitter {
1179
1190
  preset.state = presetData ? (presetData.Power === power
1180
1191
  && presetData.SetTemperature === setTemperature
1181
1192
  && presetData.OperationMode === operationMode
1182
- && presetData.VaneHorizontal === vaneHorizontalDirection
1183
- && presetData.VaneVertical === vaneVerticalDirection
1184
- && presetData.FanSpeed === fanSpeed) : false;
1193
+ && presetData.VaneHorizontalDirection === vaneHorizontalDirection
1194
+ && presetData.VaneVerticalDirection === vaneVerticalDirection
1195
+ && presetData[fanKey] === setFanSpeed) : false;
1185
1196
 
1186
1197
  const characteristicType = preset.characteristicType;
1187
1198
  this.presetsServices?.[i]?.updateCharacteristic(characteristicType, preset.state);
@@ -1266,25 +1277,25 @@ class DeviceAta extends EventEmitter {
1266
1277
  button.state = power ? (hideVaneControls === true) : false;
1267
1278
  break;
1268
1279
  case 30: //FAN SPEED MODE AUTO
1269
- button.state = power ? (fanSpeed === 0) : false;
1280
+ button.state = power ? (setFanSpeed === 0) : false;
1270
1281
  break;
1271
1282
  case 31: //FAN SPEED MODE 1
1272
- button.state = power ? (fanSpeed === 1) : false;
1283
+ button.state = power ? (setFanSpeed === 1) : false;
1273
1284
  break;
1274
1285
  case 32: //FAN SPEED MODE 2
1275
- button.state = power ? (fanSpeed === 2) : false;
1286
+ button.state = power ? (setFanSpeed === 2) : false;
1276
1287
  break;
1277
1288
  case 33: //FAN SPEED MODE 3
1278
- button.state = power ? (fanSpeed === 3) : false;
1289
+ button.state = power ? (setFanSpeed === 3) : false;
1279
1290
  break;
1280
1291
  case 34: //FAN SPEED MODE 4
1281
- button.state = power ? (fanSpeed === 4) : false;
1292
+ button.state = power ? (setFanSpeed === 4) : false;
1282
1293
  break;
1283
1294
  case 35: //FAN SPEED MODE 5
1284
- button.state = power ? (fanSpeed === 5) : false;
1295
+ button.state = power ? (setFanSpeed === 5) : false;
1285
1296
  break;
1286
1297
  case 36: //FAN SPEED MODE 6
1287
- button.state = power ? (fanSpeed === 6) : false;
1298
+ button.state = power ? (setFanSpeed === 6) : false;
1288
1299
  break;
1289
1300
  case 37: //PHYSICAL LOCK CONTROLS ALL
1290
1301
  button.state = (obj.lockPhysicalControl === 1);
@@ -1312,18 +1323,18 @@ class DeviceAta extends EventEmitter {
1312
1323
  //log current state
1313
1324
  if (this.logInfo) {
1314
1325
  this.emit('info', `Power: ${power ? 'ON' : 'OFF'}`);
1315
- this.emit('info', `Target operation mode: ${AirConditioner.DriveMode[operationMode]}`);
1316
- this.emit('info', `Current operation mode: ${this.displayMode === 1 ? AirConditioner.CurrentOperationModeHeatherCooler[obj.currentOperationMode] : AirConditioner.CurrentOperationModeThermostat[obj.currentOperationMode]}`);
1326
+ this.emit('info', `Target operation mode: ${AirConditioner.OperationModeMapEnumToString[operationMode]}`);
1327
+ this.emit('info', `Current operation mode: ${this.displayType === 1 ? AirConditioner.CurrentOperationModeHeatherCoolerMapEnumToString[obj.currentOperationMode] : AirConditioner.CurrentOperationModeThermostatMapEnumToString[obj.currentOperationMode]}`);
1317
1328
  this.emit('info', `Target temperature: ${setTemperature}${obj.temperatureUnit}`);
1318
1329
  this.emit('info', `Current temperature: ${roomTemperature}${obj.temperatureUnit}`);
1319
- const info = hasOutdoorTemperature && outdoorTemperature !== null ? this.emit('info', `Outdoor temperature: ${outdoorTemperature}${obj.temperatureUnit}`) : false;
1320
- const info3 = modelSupportsFanSpeed ? this.emit('info', `Target fan speed: ${AirConditioner.FanSpeed[fanSpeed]}`) : false;
1321
- const info4 = modelSupportsFanSpeed ? this.emit('info', `Current fan speed: ${AirConditioner.FanSpeed[actualFanSpeed]}`) : false;
1322
- const info5 = vaneHorizontalDirection !== null ? this.emit('info', `Vane horizontal: ${AirConditioner.HorizontalVane[vaneHorizontalDirection] ?? vaneHorizontalDirection}`) : false;
1323
- const info6 = vaneVerticalDirection !== null ? this.emit('info', `Vane vertical: ${AirConditioner.VerticalVane[vaneVerticalDirection] ?? vaneVerticalDirection}`) : false;
1324
- const info7 = swingFunction ? this.emit('info', `Air direction: ${AirConditioner.AirDirection[obj.swingMode]}`) : false;
1330
+ if (supportsOutdoorTemperature && outdoorTemperature !== null) this.emit('info', `Outdoor temperature: ${outdoorTemperature}${obj.temperatureUnit}`);
1331
+ if (supportsFanSpeed) this.emit('info', `Target fan speed: ${AirConditioner.FanSpeedMapEnumToString[setFanSpeed]}`);
1332
+ if (supportsFanSpeed) this.emit('info', `Current fan speed: ${AirConditioner.FanSpeedCurrentMapEnumToString[actualFanSpeed]}`);
1333
+ if (vaneHorizontalDirection !== null) this.emit('info', `Vane horizontal: ${AirConditioner.VaneHorizontalDirectionMapEnumToString[vaneHorizontalDirection]}`);
1334
+ if (vaneVerticalDirection !== null) this.emit('info', `Vane vertical: ${AirConditioner.VaneVerticalDirectionMapEnumToString[vaneVerticalDirection]}`);
1335
+ if (supportsSwingFunction) this.emit('info', `Air direction: ${AirConditioner.AirDirectionMapEnumToString[obj.currentSwingMode]}`);
1325
1336
  this.emit('info', `Temperature display unit: ${obj.temperatureUnit}`);
1326
- this.emit('info', `Lock physical controls: ${obj.lockPhysicalControl ? 'LOCKED' : 'UNLOCKED'}`);
1337
+ this.emit('info', `Lock physical controls: ${obj.lockPhysicalControl ? 'Locked' : 'Unlocked'}`);
1327
1338
  };
1328
1339
  })
1329
1340
  .on('success', (success) => this.emit('success', success))