homebridge-melcloud-control 3.5.1 → 3.5.3-beta.0

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
@@ -96,691 +96,330 @@ class DeviceAta extends EventEmitter {
96
96
  this.accessory.temperatureUnit = TemperatureDisplayUnits[this.accessory.useFahrenheit];
97
97
  };
98
98
 
99
- async start() {
99
+ async setOverExternalIntegration(integration, deviceData, key, value) {
100
100
  try {
101
- //melcloud device
102
- this.melCloudAta = new MelCloudAta({
103
- contextKey: this.contextKey,
104
- devicesFile: this.devicesFile,
105
- deviceId: this.deviceId,
106
- debugLog: this.enableDebugMode
107
- });
108
-
109
- this.melCloudAta.on('externalIntegrations', (deviceData) => {
110
- try {
111
- //RESTFul server
112
- const restFulEnabled = this.restFul.enable || false;
113
- if (restFulEnabled) {
114
- if (!this.restFulConnected) {
115
- this.restFul1 = new RestFul({
116
- port: this.deviceId.slice(-4),
117
- debug: this.restFul.debug || false
118
- });
119
-
120
- this.restFul1.on('connected', (message) => {
121
- this.restFulConnected = true;
122
- this.emit('success', message);
123
- })
124
- .on('set', async (key, value) => {
125
- try {
126
- await this.setOverExternalIntegration('RESTFul', deviceData, key, value);
127
- } catch (error) {
128
- this.emit('warn', error);
129
- };
130
- })
131
- .on('debug', (debug) => {
132
- this.emit('debug', debug);
133
- })
134
- .on('error', (error) => {
135
- this.emit('warn', error);
136
- });
137
- }
138
- const restFul0 = this.restFulConnected ? this.restFul1.update('info', deviceData) : false;
139
- const restFul1 = this.restFulConnected ? this.restFul1.update('state', deviceData.Device) : false;
140
- }
101
+ let set = false
102
+ switch (key) {
103
+ case 'Power':
104
+ deviceData.Device[key] = value;
105
+ deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.Power;
106
+ set = await this.melCloudAta.send(deviceData, this.displayMode);
107
+ break;
108
+ case 'OperationMode':
109
+ deviceData.Device[key] = value;
110
+ deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.OperationModeSetTemperature;
111
+ set = await this.melCloudAta.send(deviceData, this.displayMode);
112
+ break;
113
+ case 'SetTemperature':
114
+ deviceData.Device[key] = value;
115
+ deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.SetTemperature;
116
+ set = await this.melCloudAta.send(deviceData, this.displayMode);
117
+ break;
118
+ case 'DefaultCoolingSetTemperature':
119
+ deviceData.Device[key] = value;
120
+ deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.SetTemperature;
121
+ set = await this.melCloudAta.send(deviceData, this.displayMode);
122
+ break;
123
+ case 'DefaultHeatingSetTemperature':
124
+ deviceData.Device[key] = value;
125
+ deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.SetTemperature;
126
+ set = await this.melCloudAta.send(deviceData, this.displayMode);
127
+ break;
128
+ case 'FanSpeed':
129
+ deviceData.Device[key] = value;
130
+ deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.SetFanSpeed;
131
+ set = await this.melCloudAta.send(deviceData, this.displayMode);
132
+ break;
133
+ case 'VaneHorizontalDirection':
134
+ deviceData.Device[key] = value;
135
+ deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.VaneHorizontal;
136
+ set = await this.melCloudAta.send(deviceData, this.displayMode);
137
+ break;
138
+ case 'VaneVerticalDirection':
139
+ deviceData.Device[key] = value;
140
+ deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.VaneVertical;
141
+ set = await this.melCloudAta.send(deviceData, this.displayMode);
142
+ break;
143
+ case 'HideVaneControls':
144
+ deviceData[key] = value;
145
+ deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.Prohibit;
146
+ set = await this.melCloudAta.send(deviceData, this.displayMode);
147
+ break;
148
+ case 'HideDryModeControl':
149
+ deviceData[key] = value;
150
+ deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.Prohibit;
151
+ await this.melCloudAta.send(deviceData, this.displayMode);
152
+ break;
153
+ case 'ProhibitSetTemperature':
154
+ deviceData.Device[key] = value;
155
+ deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.Prohibit;
156
+ set = await this.melCloudAta.send(deviceData, this.displayMode);
157
+ break;
158
+ case 'ProhibitOperationMode':
159
+ deviceData.Device[key] = value;
160
+ deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.Prohibit;
161
+ await this.melCloudAta.send(deviceData, this.displayMode);
162
+ break;
163
+ case 'ProhibitPower':
164
+ deviceData.Device[key] = value;
165
+ deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.Prohibit;
166
+ set = await this.melCloudAta.send(deviceData, this.displayMode);
167
+ break;
168
+ default:
169
+ this.emit('warn', `${integration}, received key: ${key}, value: ${value}`);
170
+ break;
171
+ };
172
+ return set;
173
+ } catch (error) {
174
+ throw new Error(`${integration} set key: ${key}, value: ${value}, error: ${error.message ?? error}`);
175
+ };
176
+ }
141
177
 
142
- //MQTT client
143
- const mqttEnabled = this.mqtt.enable || false;
144
- if (mqttEnabled) {
145
- if (!this.mqttConnected) {
146
- this.mqtt1 = new Mqtt({
147
- host: this.mqtt.host,
148
- port: this.mqtt.port || 1883,
149
- clientId: `${this.mqtt.clientId}_${this.deviceId}` || `${this.deviceTypeText}_${this.deviceName}_${this.deviceId}`,
150
- prefix: `${this.mqtt.prefix}/${this.deviceTypeText}/${this.deviceName}`,
151
- user: this.mqtt.user,
152
- passwd: this.mqtt.pass,
153
- debug: this.mqtt.debug || false
154
- });
178
+ //prepare accessory
179
+ async prepareAccessory(accountInfo, deviceData, deviceId, deviceTypeText, deviceName, accountName) {
180
+ try {
181
+ const presetsOnServer = this.accessory.presets;
182
+ const modelSupportsHeat = this.accessory.modelSupportsHeat;
183
+ const modelSupportsDry = this.accessory.modelSupportsDry;
184
+ const modelSupportsCool = this.accessory.modelSupportsCool;
185
+ const modelSupportsAuto = this.accessory.modelSupportsAuto;
186
+ const modelSupportsFanSpeed = this.accessory.modelSupportsFanSpeed;
187
+ const hasAutomaticFanSpeed = this.accessory.hasAutomaticFanSpeed;
188
+ const hasOutdoorTemperature = this.accessory.hasOutdoorTemperature;
189
+ const numberOfFanSpeeds = this.accessory.numberOfFanSpeeds;
190
+ const swingFunction = this.accessory.swingFunction;
191
+ const autoDryFanMode = [this.accessory.operationMode, 8, modelSupportsDry ? 2 : 8, 7][this.autoDryFanMode]; //NONE, AUTO - 8, DRY - 2, FAN - 7
192
+ const heatDryFanMode = [this.accessory.operationMode, 1, modelSupportsDry ? 2 : 1, 7][this.heatDryFanMode]; //NONE, HEAT - 1, DRY - 2, FAN - 7
193
+ const coolDryFanMode = [this.accessory.operationMode, 3, modelSupportsDry ? 2 : 3, 7][this.coolDryFanMode]; //NONE, COOL - 3, DRY - 2, FAN - 7
155
194
 
156
- this.mqtt1.on('connected', (message) => {
157
- this.mqttConnected = true;
158
- this.emit('success', message);
159
- })
160
- .on('subscribed', (message) => {
161
- this.emit('success', message);
162
- })
163
- .on('set', async (key, value) => {
164
- try {
165
- await this.setOverExternalIntegration('MQTT', deviceData, key, value);
166
- } catch (error) {
167
- this.emit('warn', error);
168
- };
169
- })
170
- .on('debug', (debug) => {
171
- this.emit('debug', debug);
172
- })
173
- .on('error', (error) => {
174
- this.emit('warn', error);
175
- });
176
- }
177
- const mqtt0 = this.mqttConnected ? this.mqtt1.emit('publish', `Info`, deviceData) : false;
178
- const mqtt1 = this.mqttConnected ? this.mqtt1.emit('publish', `State`, deviceData.Device) : false;
179
- }
195
+ //accessory
196
+ const debug = this.enableDebugMode ? this.emit('debug', `Prepare accessory`) : false;
197
+ const accessoryName = deviceName;
198
+ const accessoryUUID = AccessoryUUID.generate(accountName + deviceId.toString());
199
+ const accessoryCategory = Categories.AIR_CONDITIONER;
200
+ const accessory = new Accessory(accessoryName, accessoryUUID, accessoryCategory);
180
201
 
181
- } catch (error) {
182
- this.emit('warn', `External integration start error: ${error}.`);
183
- };
184
- })
185
- .on('deviceInfo', (manufacturer, modelIndoor, modelOutdoor, serialNumber, firmwareAppVersion) => {
186
- if (!this.displayDeviceInfo) {
187
- return;
188
- }
202
+ //information service
203
+ const debug1 = this.enableDebugMode ? this.emit('debug', `Prepare information service`) : false;
204
+ accessory.getService(Service.AccessoryInformation)
205
+ .setCharacteristic(Characteristic.Manufacturer, this.manufacturer)
206
+ .setCharacteristic(Characteristic.Model, this.model)
207
+ .setCharacteristic(Characteristic.SerialNumber, this.serialNumber)
208
+ .setCharacteristic(Characteristic.FirmwareRevision, this.firmwareRevision)
209
+ .setCharacteristic(Characteristic.ConfiguredName, accessoryName);
189
210
 
190
- if (!this.disableLogDeviceInfo) {
191
- this.emit('devInfo', `---- ${this.deviceTypeText}: ${this.deviceName} ----`);
192
- this.emit('devInfo', `Account: ${this.accountName}`);
193
- const indoor = modelIndoor ? this.emit('devInfo', `Indoor: ${modelIndoor}`) : false;
194
- const outdoor = modelOutdoor ? this.emit('devInfo', `Outdoor: ${modelOutdoor}`) : false
195
- this.emit('devInfo', `Serial: ${serialNumber}`);
196
- this.emit('devInfo', `Firmware: ${firmwareAppVersion}`);
197
- this.emit('devInfo', `Manufacturer: ${manufacturer}`);
198
- this.emit('devInfo', '----------------------------------');
199
- };
211
+ //melcloud services
212
+ const serviceName = `${deviceTypeText} ${accessoryName}`;
213
+ switch (this.displayMode) {
214
+ case 1: //Heater Cooler
215
+ const debug = this.enableDebugMode ? this.emit('debug', `Prepare heater/cooler service`) : false;
216
+ this.melCloudService = new Service.HeaterCooler(serviceName, `HeaterCooler ${deviceId}`);
217
+ this.melCloudService.getCharacteristic(Characteristic.Active)
218
+ .onGet(async () => {
219
+ const state = this.accessory.power;
220
+ return state;
221
+ })
222
+ .onSet(async (state) => {
223
+ try {
224
+ deviceData.Device.Power = [false, true][state];
225
+ deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.Power;
226
+ await this.melCloudAta.send(deviceData, this.displayMode);
227
+ const info = this.disableLogInfo ? false : this.emit('message', `Set power: ${state ? 'ON' : 'OFF'}`);
228
+ } catch (error) {
229
+ this.emit('warn', `Set power error: ${error}`);
230
+ };
231
+ });
232
+ this.melCloudService.getCharacteristic(Characteristic.CurrentHeaterCoolerState)
233
+ .onGet(async () => {
234
+ const value = this.accessory.currentOperationMode;
235
+ return value;
236
+ });
237
+ this.melCloudService.getCharacteristic(Characteristic.TargetHeaterCoolerState)
238
+ .setProps({
239
+ minValue: this.accessory.operationModeSetPropsMinValue,
240
+ maxValue: this.accessory.operationModeSetPropsMaxValue,
241
+ validValues: this.accessory.operationModeSetPropsValidValues
242
+ })
243
+ .onGet(async () => {
244
+ const value = this.accessory.targetOperationMode; //1 = HEAT, 2 = DRY 3 = COOL, 7 = FAN, 8 = AUTO
245
+ return value;
246
+ })
247
+ .onSet(async (value) => {
248
+ try {
249
+ switch (value) {
250
+ case 0: //AUTO - AUTO
251
+ deviceData.Device.OperationMode = autoDryFanMode;
252
+ break;
253
+ case 1: //HEAT - HEAT
254
+ deviceData.Device.OperationMode = heatDryFanMode;
255
+ break;
256
+ case 2: //COOL - COOL
257
+ deviceData.Device.OperationMode = coolDryFanMode;
258
+ break;
259
+ };
200
260
 
201
- //accessory info
202
- this.manufacturer = manufacturer;
203
- this.model = modelIndoor ? modelIndoor : modelOutdoor ? modelOutdoor : `${this.deviceTypeText} ${this.deviceId}`;
204
- this.serialNumber = serialNumber;
205
- this.firmwareRevision = firmwareAppVersion;
206
- this.displayDeviceInfo = false;
207
- })
208
- .on('deviceState', async (deviceData) => {
209
- //presets
210
- const presetsOnServer = deviceData.Presets ?? [];
211
-
212
- //device control
213
- const hideVaneControls = deviceData.HideVaneControls ?? false;
214
- const hideDryModeControl = deviceData.HideDryModeControl ?? false;
215
-
216
- //device info
217
- const hasAutomaticFanSpeed = deviceData.Device.HasAutomaticFanSpeed ?? false;
218
- const airDirectionFunction = deviceData.Device.AirDirectionFunction ?? false;
219
- const swingFunction = deviceData.Device.SwingFunction ?? false;
220
- const hasOutdoorTemperature = deviceData.Device.HasOutdoorTemperature ?? false;
221
- const numberOfFanSpeeds = deviceData.Device.NumberOfFanSpeeds ?? 0;
222
- const modelSupportsFanSpeed = deviceData.Device.ModelSupportsFanSpeed ?? false;
223
- const modelSupportsAuto1 = deviceData.Device.ModelSupportsAuto ?? false;
224
- const modelSupportsAuto = this.autoDryFanMode >= 1 && modelSupportsAuto1
225
- const modelSupportsHeat1 = deviceData.Device.ModelSupportsHeat ?? false;
226
- const modelSupportsHeat = this.heatDryFanMode >= 1 && modelSupportsHeat1;
227
- const modelSupportsDry = deviceData.Device.ModelSupportsDry ?? false;
228
- const modelSupportsCool = this.coolDryFanMode >= 1;
229
- const minTempHeat = 10;
230
- const maxTempHeat = 31;
231
- const minTempCoolDry = 16;
232
- const maxTempCoolDry = 31;
233
-
234
- //device state
235
- const power = deviceData.Device.Power ?? false;
236
- const inStandbyMode = deviceData.Device.InStandbyMode ?? false;
237
- const roomTemperature = deviceData.Device.RoomTemperature;
238
- const setTemperature = deviceData.Device.SetTemperature ?? 20;
239
- const defaultHeatingSetTemperature = deviceData.Device.DefaultHeatingSetTemperature ?? 20;
240
- const defaultCoolingSetTemperature = deviceData.Device.DefaultCoolingSetTemperature ?? 23;
241
- const actualFanSpeed = deviceData.Device.ActualFanSpeed;
242
- const automaticFanSpeed = deviceData.Device.AutomaticFanSpeed;
243
- const fanSpeed = deviceData.Device.FanSpeed ?? 0;
244
- const operationMode = deviceData.Device.OperationMode;
245
- const vaneVerticalDirection = deviceData.Device.VaneVerticalDirection;
246
- const vaneVerticalSwing = deviceData.Device.VaneVerticalSwing;
247
- const vaneHorizontalDirection = deviceData.Device.VaneHorizontalDirection;
248
- const vaneHorizontalSwing = deviceData.Device.VaneHorizontalSwing;
249
- const prohibitSetTemperature = deviceData.Device.ProhibitSetTemperature ?? false;
250
- const prohibitOperationMode = deviceData.Device.ProhibitOperationMode ?? false;
251
- const prohibitPower = deviceData.Device.ProhibitPower ?? false;
252
- const temperatureIncrement = deviceData.Device.TemperatureIncrement ?? 1;
253
- const outdoorTemperature = deviceData.Device.OutdoorTemperature;
254
-
255
- //accessory
256
- this.accessory.presets = presetsOnServer;
257
- this.accessory.hasAutomaticFanSpeed = hasAutomaticFanSpeed;
258
- this.accessory.airDirectionFunction = airDirectionFunction;
259
- this.accessory.swingFunction = swingFunction;
260
- this.accessory.hasOutdoorTemperature = hasOutdoorTemperature;
261
- this.accessory.numberOfFanSpeeds = numberOfFanSpeeds;
262
- this.accessory.modelSupportsFanSpeed = modelSupportsFanSpeed;
263
- this.accessory.modelSupportsAuto = modelSupportsAuto;
264
- this.accessory.modelSupportsHeat = modelSupportsHeat;
265
- this.accessory.modelSupportsDry = modelSupportsDry;
266
- this.accessory.modelSupportsCool = modelSupportsCool;
267
- this.accessory.minTempHeat = minTempHeat;
268
- this.accessory.maxTempHeat = maxTempHeat;
269
- this.accessory.minTempCoolDry = minTempCoolDry;
270
- this.accessory.maxTempCoolDry = maxTempCoolDry;
271
-
272
- this.accessory.power = power ? 1 : 0;
273
- this.accessory.inStandbyMode = inStandbyMode;
274
- this.accessory.operationMode = operationMode;
275
- this.accessory.roomTemperature = roomTemperature;
276
- this.accessory.outdoorTemperature = outdoorTemperature;
277
- this.accessory.setTemperature = setTemperature;
278
- this.accessory.defaultHeatingSetTemperature = defaultHeatingSetTemperature;
279
- this.accessory.defaultCoolingSetTemperature = defaultCoolingSetTemperature;
280
- this.accessory.actualFanSpeed = actualFanSpeed;
281
- this.accessory.automaticFanSpeed = automaticFanSpeed;
282
- this.accessory.vaneVerticalSwing = vaneVerticalSwing;
283
- this.accessory.vaneHorizontalSwing = vaneHorizontalSwing;
284
- this.accessory.swingMode = swingFunction && vaneHorizontalDirection === 12 && vaneVerticalDirection === 7 ? 1 : 0;
285
- this.accessory.lockPhysicalControl = prohibitSetTemperature && prohibitOperationMode && prohibitPower ? 1 : 0;
286
- this.accessory.temperatureIncrement = temperatureIncrement;
287
-
288
- //operating mode 0, HEAT, DRY, COOL, 4, 5, 6, FAN, AUTO, ISEE HEAT, ISEE DRY, ISEE COOL
289
- switch (this.displayMode) {
290
- case 1: //Heater Cooler
291
- switch (operationMode) {
292
- case 1: //HEAT
293
- this.accessory.currentOperationMode = roomTemperature > setTemperature ? 1 : 2; //INACTIVE, IDLE, HEATING, COOLING
294
- this.accessory.targetOperationMode = 1; //AUTO, HEAT, COOL
295
- break;
296
- case 2: //DRY
297
- this.accessory.currentOperationMode = 1;
298
- this.accessory.targetOperationMode = this.autoDryFanMode === 2 ? 0 : this.heatDryFanMode === 2 ? 1 : this.coolDryFanMode === 2 ? 2 : this.accessory.targetOperationMode ?? 0;
299
- break;
300
- case 3: //COOL
301
- this.accessory.currentOperationMode = roomTemperature < setTemperature ? 1 : 3;
302
- this.accessory.targetOperationMode = 2;
303
- break;
304
- case 7: //FAN
305
- this.accessory.currentOperationMode = 1;
306
- this.accessory.targetOperationMode = this.autoDryFanMode === 3 ? 0 : this.heatDryFanMode === 3 ? 1 : this.coolDryFanMode === 3 ? 2 : this.accessory.targetOperationMode ?? 0;
307
- break;
308
- case 8: //AUTO
309
- this.accessory.currentOperationMode = roomTemperature > setTemperature ? 3 : roomTemperature < setTemperature ? 2 : 1;
310
- this.accessory.targetOperationMode = 0;
311
- break;
312
- case 9: //ISEE HEAT
313
- this.accessory.currentOperationMode = roomTemperature > setTemperature ? 1 : 2
314
- this.accessory.targetOperationMode = 1;
315
- break;
316
- case 10: //ISEE DRY
317
- this.accessory.currentOperationMode = 1;
318
- this.accessory.targetOperationMode = this.autoDryFanMode === 2 ? 0 : this.heatDryFanMode === 2 ? 1 : this.coolDryFanMode === 2 ? 2 : this.accessory.targetOperationMode ?? 0;
319
- break;
320
- case 11: //ISEE COOL;
321
- this.accessory.currentOperationMode = roomTemperature < setTemperature ? 1 : 3;
322
- this.accessory.targetOperationMode = 2;
323
- break;
324
- default:
325
- this.emit('warn', `Unknown operating mode: ${operationMode}`);
326
- return
261
+ deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.OperationModeSetTemperature;
262
+ await this.melCloudAta.send(deviceData, this.displayMode);
263
+ const operationModeText = AirConditioner.DriveMode[deviceData.Device.OperationMode];
264
+ const info = this.disableLogInfo ? false : this.emit('message', `Set operation mode: ${operationModeText}`);
265
+ } catch (error) {
266
+ this.emit('warn', `Set operation mode error: ${error}`);
327
267
  };
328
-
329
- this.accessory.currentOperationMode = !power ? 0 : inStandbyMode ? 1 : this.accessory.currentOperationMode;
330
- this.accessory.operationModeSetPropsMinValue = modelSupportsAuto && modelSupportsHeat ? 0 : !modelSupportsAuto && modelSupportsHeat ? 1 : modelSupportsAuto && !modelSupportsHeat ? 0 : 2;
331
- this.accessory.operationModeSetPropsMaxValue = 2
332
- this.accessory.operationModeSetPropsValidValues = modelSupportsAuto && modelSupportsHeat ? [0, 1, 2] : !modelSupportsAuto && modelSupportsHeat ? [1, 2] : modelSupportsAuto && !modelSupportsHeat ? [0, 2] : [2];
333
-
334
- //fan speed mode
335
- if (modelSupportsFanSpeed) {
336
- switch (numberOfFanSpeeds) {
337
- case 2: //Fan speed mode 2
338
- this.accessory.fanSpeed = hasAutomaticFanSpeed ? [3, 1, 2][fanSpeed] : [0, 1, 2][fanSpeed];
339
- this.accessory.fanSpeedSetPropsMaxValue = hasAutomaticFanSpeed ? 3 : 2;
340
- break;
341
- case 3: //Fan speed mode 3
342
- this.accessory.fanSpeed = hasAutomaticFanSpeed ? [4, 1, 2, 3][fanSpeed] : [0, 1, 2, 3][fanSpeed];
343
- this.accessory.fanSpeedSetPropsMaxValue = hasAutomaticFanSpeed ? 4 : 3;
344
- break;
345
- case 4: //Fan speed mode 4
346
- this.accessory.fanSpeed = hasAutomaticFanSpeed ? [5, 1, 2, 3, 4][fanSpeed] : [0, 1, 2, 3, 4][fanSpeed];
347
- this.accessory.fanSpeedSetPropsMaxValue = hasAutomaticFanSpeed ? 5 : 4;
348
- break;
349
- case 5: //Fan speed mode 5
350
- this.accessory.fanSpeed = hasAutomaticFanSpeed ? [6, 1, 2, 3, 4, 5][fanSpeed] : [0, 1, 2, 3, 4, 5][fanSpeed];
351
- this.accessory.fanSpeedSetPropsMaxValue = hasAutomaticFanSpeed ? 6 : 5;
352
- break;
353
- case 6: //Fan speed mode 6
354
- this.accessory.fanSpeed = hasAutomaticFanSpeed ? [7, 1, 2, 3, 4, 5, 6][fanSpeed] : [0, 1, 2, 3, 4, 5, 6][fanSpeed];
355
- this.accessory.fanSpeedSetPropsMaxValue = hasAutomaticFanSpeed ? 7 : 6;
356
- break;
268
+ });
269
+ this.melCloudService.getCharacteristic(Characteristic.CurrentTemperature)
270
+ .onGet(async () => {
271
+ const value = this.accessory.roomTemperature;
272
+ return value;
273
+ });
274
+ if (modelSupportsFanSpeed) {
275
+ this.melCloudService.getCharacteristic(Characteristic.RotationSpeed)
276
+ .setProps({
277
+ minValue: 0,
278
+ maxValue: this.accessory.fanSpeedSetPropsMaxValue,
279
+ minStep: 1
280
+ })
281
+ .onGet(async () => {
282
+ const value = this.accessory.fanSpeed; //AUTO, 1, 2, 3, 4, 5, 6, OFF
283
+ return value;
284
+ })
285
+ .onSet(async (value) => {
286
+ try {
287
+ let fanSpeedModeText = '';
288
+ switch (numberOfFanSpeeds) {
289
+ case 2: //Fan speed mode 2
290
+ fanSpeedModeText = hasAutomaticFanSpeed ? [7, 1, 2, 0][value] : [7, 1, 2][value];
291
+ deviceData.Device.FanSpeed = hasAutomaticFanSpeed ? [0, 1, 2, 0][value] : [1, 1, 2][value];
292
+ break;
293
+ case 3: //Fan speed mode 3
294
+ fanSpeedModeText = hasAutomaticFanSpeed ? [7, 1, 2, 3, 0][value] : [7, 1, 2, 3][value];
295
+ deviceData.Device.FanSpeed = hasAutomaticFanSpeed ? [0, 1, 2, 3, 0][value] : [1, 1, 2, 3][value];
296
+ break;
297
+ case 4: //Fan speed mode 4
298
+ fanSpeedModeText = hasAutomaticFanSpeed ? [7, 1, 2, 3, 4, 0][value] : [7, 1, 2, 3, 4][value];
299
+ deviceData.Device.FanSpeed = hasAutomaticFanSpeed ? [0, 1, 2, 3, 4, 0][value] : [1, 1, 2, 3, 4][value];
300
+ break;
301
+ case 5: //Fan speed mode 5
302
+ 5; fanSpeedModeText = hasAutomaticFanSpeed ? [7, 1, 2, 3, 4, 5, 0][value] : [7, 1, 2, 3, 4, 5][value];
303
+ deviceData.Device.FanSpeed = hasAutomaticFanSpeed ? [0, 1, 2, 3, 4, 5, 0][value] : [1, 1, 2, 3, 4, 5][value];
304
+ break;
305
+ case 6: //Fan speed mode 6
306
+ fanSpeedModeText = hasAutomaticFanSpeed ? [7, 1, 2, 3, 4, 5, 6, 0][value] : [7, 1, 2, 3, 4, 5, 6][value];
307
+ deviceData.Device.FanSpeed = hasAutomaticFanSpeed ? [0, 1, 2, 3, 4, 5, 6, 0][value] : [1, 1, 2, 3, 4, 5, 6][value];
308
+ break;
309
+ };
310
+ deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.SetFanSpeed;
311
+ await this.melCloudAta.send(deviceData, this.displayMode);
312
+ const info = this.disableLogInfo ? false : this.emit('message', `Set fan speed mode: ${AirConditioner.FanSpeed[fanSpeedModeText]}`);
313
+ } catch (error) {
314
+ this.emit('warn', `Set fan speed mode error: ${error}`);
315
+ };
316
+ });
317
+ };
318
+ if (swingFunction) {
319
+ this.melCloudService.getCharacteristic(Characteristic.SwingMode)
320
+ .onGet(async () => {
321
+ //Vane Horizontal: Auto, 1, 2, 3, 4, 5, 6, 12 = Swing //Vertical: Auto, 1, 2, 3, 4, 5, 7 = Swing
322
+ const value = this.accessory.swingMode;
323
+ return value;
324
+ })
325
+ .onSet(async (value) => {
326
+ try {
327
+ deviceData.Device.VaneHorizontal = value ? 12 : 0;
328
+ deviceData.Device.VaneVertical = value ? 7 : 0;
329
+ deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.VaneVerticalVaneHorizontal;
330
+ await this.melCloudAta.send(deviceData, this.displayMode);
331
+ const info = this.disableLogInfo ? false : this.emit('message', `Set air direction mode: ${AirConditioner.AirDirection[value]}`);
332
+ } catch (error) {
333
+ this.emit('warn', `Set vane swing mode error: ${error}`);
357
334
  };
335
+ });
336
+ };
337
+ this.melCloudService.getCharacteristic(Characteristic.CoolingThresholdTemperature)
338
+ .setProps({
339
+ minValue: this.accessory.minTempCoolDry,
340
+ maxValue: this.accessory.maxTempCoolDry,
341
+ minStep: this.accessory.temperatureIncrement
342
+ })
343
+ .onGet(async () => {
344
+ const value = this.accessory.operationMode === 8 ? this.accessory.defaultCoolingSetTemperature : this.accessory.setTemperature;
345
+ return value;
346
+ })
347
+ .onSet(async (value) => {
348
+ try {
349
+ deviceData.Device.DefaultCoolingSetTemperature = value;
350
+ deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.SetTemperature;
351
+ await this.melCloudAta.send(deviceData, this.displayMode);
352
+ const info = this.disableLogInfo ? false : this.emit('message', `Set cooling threshold temperature: ${value}${this.accessory.temperatureUnit}`);
353
+ } catch (error) {
354
+ this.emit('warn', `Set cooling threshold temperature error: ${error}`);
358
355
  };
359
-
360
- //update characteristics
361
- if (this.melCloudService) {
362
- this.melCloudService
363
- .updateCharacteristic(Characteristic.Active, power ? 1 : 0)
364
- .updateCharacteristic(Characteristic.CurrentHeaterCoolerState, this.accessory.currentOperationMode)
365
- .updateCharacteristic(Characteristic.TargetHeaterCoolerState, this.accessory.targetOperationMode)
366
- .updateCharacteristic(Characteristic.CurrentTemperature, roomTemperature)
367
- .updateCharacteristic(Characteristic.LockPhysicalControls, this.accessory.lockPhysicalControl)
368
- .updateCharacteristic(Characteristic.TemperatureDisplayUnits, this.accessory.useFahrenheit)
369
- .updateCharacteristic(Characteristic.CoolingThresholdTemperature, defaultCoolingSetTemperature);
370
- const updateDefHeat = modelSupportsHeat ? this.melCloudService.updateCharacteristic(Characteristic.HeatingThresholdTemperature, defaultHeatingSetTemperature) : false;
371
- const updateRS = modelSupportsFanSpeed ? this.melCloudService.updateCharacteristic(Characteristic.RotationSpeed, this.accessory.fanSpeed) : false;
372
- const updateSM = swingFunction ? this.melCloudService.updateCharacteristic(Characteristic.SwingMode, this.accessory.swingMode) : false;
373
- };
374
- break;
375
- case 2: //Thermostat
376
- switch (operationMode) {
377
- case 1: //HEAT
378
- this.accessory.currentOperationMode = roomTemperature > setTemperature ? 0 : 1; //OFF, HEATING, COOLING
379
- this.accessory.targetOperationMode = 1; //OFF, HEAT, COOL, AUTO
380
- break;
381
- case 2: //DRY
382
- this.accessory.currentOperationMode = 0;
383
- this.accessory.targetOperationMode = this.autoDryFanMode === 2 ? 3 : this.heatDryFanMode === 2 ? 1 : this.coolDryFanMode === 2 ? 2 : this.accessory.targetOperationMode ?? 0;
384
- break;
385
- case 3: //COOL
386
- this.accessory.currentOperationMode = roomTemperature < setTemperature ? 0 : 2;
387
- this.accessory.targetOperationMode = 2;
388
- break;
389
- case 7: //FAN
390
- this.accessory.currentOperationMode = 0;
391
- this.accessory.targetOperationMode = this.autoDryFanMode === 3 ? 3 : this.heatDryFanMode === 3 ? 1 : this.coolDryFanMode === 3 ? 2 : this.accessory.targetOperationMode ?? 0;
392
- break;
393
- case 8: //AUTO
394
- this.accessory.currentOperationMode = roomTemperature < setTemperature ? 1 : roomTemperature > setTemperature ? 2 : 0;
395
- this.accessory.targetOperationMode = 3;
396
- break;
397
- case 9: //ISEE HEAT
398
- this.accessory.currentOperationMode = roomTemperature > setTemperature ? 0 : 1;
399
- this.accessory.targetOperationMode = 1;
400
- break;
401
- case 10: //ISEE DRY
402
- this.accessory.currentOperationMode = 0;
403
- this.accessory.targetOperationMode = this.autoDryFanMode === 2 ? 3 : this.heatDryFanMode === 2 ? 1 : this.coolDryFanMode === 2 ? 2 : this.accessory.targetOperationMode ?? 0;
404
- break;
405
- case 11: //ISEE COOL;
406
- this.accessory.currentOperationMode = roomTemperature < setTemperature ? 0 : 2;
407
- this.accessory.targetOperationMode = 2;
408
- break;
409
- default:
410
- this.emit('warn', `Unknown operating mode: ${operationMode}`);
411
- break;
412
- };
413
-
414
- this.accessory.currentOperationMode = !power ? 0 : this.accessory.currentOperationMode;
415
- this.accessory.targetOperationMode = !power ? 0 : this.accessory.targetOperationMode;
416
- this.accessory.operationModeSetPropsMinValue = 0
417
- this.accessory.operationModeSetPropsMaxValue = modelSupportsAuto && modelSupportsHeat ? 3 : !modelSupportsAuto && modelSupportsHeat ? 2 : modelSupportsAuto && !modelSupportsHeat ? 3 : 2;
418
- this.accessory.operationModeSetPropsValidValues = modelSupportsAuto && modelSupportsHeat ? [0, 1, 2, 3] : !modelSupportsAuto && modelSupportsHeat ? [0, 1, 2] : modelSupportsAuto && !modelSupportsHeat ? [0, 2, 3] : [0, 2];
419
-
420
- //update characteristics
421
- if (this.melCloudService) {
422
- this.melCloudService
423
- .updateCharacteristic(Characteristic.CurrentHeatingCoolingState, this.accessory.currentOperationMode)
424
- .updateCharacteristic(Characteristic.TargetHeatingCoolingState, this.accessory.targetOperationMode)
425
- .updateCharacteristic(Characteristic.CurrentTemperature, roomTemperature)
426
- .updateCharacteristic(Characteristic.TargetTemperature, setTemperature)
427
- .updateCharacteristic(Characteristic.TemperatureDisplayUnits, this.accessory.useFahrenheit);
428
- };
429
- break;
430
- };
431
-
432
- if (this.roomTemperatureSensorService) {
433
- this.roomTemperatureSensorService
434
- .updateCharacteristic(Characteristic.CurrentTemperature, roomTemperature)
435
- };
436
-
437
- if (this.outdoorTemperatureSensorService) {
438
- this.outdoorTemperatureSensorService
439
- .updateCharacteristic(Characteristic.CurrentTemperature, outdoorTemperature)
440
- };
441
-
442
- //update presets state
443
- if (this.presetsConfigured.length > 0) {
444
- for (let i = 0; i < this.presetsConfigured.length; i++) {
445
- const preset = this.presetsConfigured[i];
446
- const presetData = presetsOnServer.find(p => p.ID === preset.Id);
447
-
448
- preset.state = presetData ? (presetData.Power === power
449
- && presetData.SetTemperature === setTemperature
450
- && presetData.OperationMode === operationMode
451
- && presetData.VaneHorizontal === vaneHorizontalDirection
452
- && presetData.VaneVertical === vaneVerticalDirection
453
- && presetData.FanSpeed === fanSpeed) : false;
454
-
455
- if (this.presetsServices) {
456
- const characteristicType = preset.characteristicType;
457
- this.presetsServices[i]
458
- .updateCharacteristic(characteristicType, preset.state)
459
- };
460
- };
461
- };
462
-
463
- //update buttons state
464
- if (this.buttonsConfiguredCount > 0) {
465
- for (let i = 0; i < this.buttonsConfiguredCount; i++) {
466
- const button = this.buttonsConfigured[i];
467
- const mode = button.mode;
468
- switch (mode) {
469
- case 0: //POWER ON,OFF
470
- button.state = (power === true);
471
- break;
472
- case 1: //OPERATING MODE HEAT
473
- button.state = power ? (operationMode === 1 || operationMode === 9) : false;
474
- break;
475
- case 2: //OPERATING MODE DRY
476
- button.state = power ? (operationMode === 2 || operationMode === 10) : false;
477
- break
478
- case 3: //OPERATING MODE COOL
479
- button.state = power ? (operationMode === 3 || operationMode === 11) : false;
480
- break;
481
- case 4: //OPERATING MODE FAN
482
- button.state = power ? (operationMode === 7) : false;
483
- break;
484
- case 5: //OPERATING MODE AUTO
485
- button.state = power ? (operationMode === 8) : false;
486
- break;
487
- case 6: //OPERATING MODE PURIFY
488
- button.state = power ? (operationMode === 12) : false;
489
- break;
490
- case 7: //OPERATING MODE DRY CONTROL HIDE
491
- button.state = power ? (hideDryModeControl === true) : false;
492
- break;
493
- case 10: //VANE H SWING MODE AUTO
494
- button.state = power ? (vaneHorizontalDirection === 0) : false;
495
- break;
496
- case 11: //VANE H SWING MODE 1
497
- button.state = power ? (vaneHorizontalDirection === 1) : false;
498
- break;
499
- case 12: //VANE H SWING MODE 2
500
- button.state = power ? (vaneHorizontalDirection === 2) : false;
501
- break;
502
- case 13: //VANE H SWING MODE 3
503
- button.state = power ? (vaneHorizontalDirection === 3) : false;
504
- break;
505
- case 14: //VANE H SWING MODE 4
506
- button.state = power ? (vaneHorizontalDirection === 4) : false;
507
- break;
508
- case 15: //VANE H SWING MODE 5
509
- button.state = power ? (vaneHorizontalDirection === 5) : false;
510
- break;
511
- case 16: //VANE H SWING MODE SPLIT
512
- button.state = power ? (vaneHorizontalDirection === 8) : false;
513
- break;
514
- case 17: //VANE H SWING MODE SWING
515
- button.state = power ? (vaneHorizontalDirection === 12) : false;
516
- break;
517
- case 20: //VANE V SWING MODE AUTO
518
- button.state = power ? (vaneVerticalDirection === 0) : false;
519
- break;
520
- case 21: //VANE V SWING MODE 1
521
- button.state = power ? (vaneVerticalDirection === 1) : false;
522
- break;
523
- case 22: //VANE V SWING MODE 2
524
- button.state = power ? (vaneVerticalDirection === 2) : false;
525
- break;
526
- case 23: //VANE V SWING MODE 3
527
- button.state = power ? (vaneVerticalDirection === 3) : false;
528
- break;
529
- case 24: //VANE V SWING MODE 4
530
- button.state = power ? (vaneVerticalDirection === 4) : false;
531
- break;
532
- case 25: //VANE V SWING MODE 5
533
- button.state = power ? (vaneVerticalDirection === 5) : false;
534
- break;
535
- case 26: //VANE V SWING MODE SWING
536
- button.state = power ? (vaneVerticalDirection === 7) : false;
537
- break;
538
- case 27: //VANE H/V CONTROLS HIDE
539
- button.state = power ? (hideVaneControls === true) : false;
540
- break;
541
- case 30: //FAN SPEED MODE AUTO
542
- button.state = power ? (fanSpeed === 0) : false;
543
- break;
544
- case 31: //FAN SPEED MODE 1
545
- button.state = power ? (fanSpeed === 1) : false;
546
- break;
547
- case 32: //FAN SPEED MODE 2
548
- button.state = power ? (fanSpeed === 2) : false;
549
- break;
550
- case 33: //FAN SPEED MODE 3
551
- button.state = power ? (fanSpeed === 3) : false;
552
- break;
553
- case 34: //FAN SPEED MODE 4
554
- button.state = power ? (fanSpeed === 4) : false;
555
- break;
556
- case 35: //FAN SPEED MODE 5
557
- button.state = power ? (fanSpeed === 5) : false;
558
- break;
559
- case 36: //FAN SPEED MODE 6
560
- button.state = power ? (fanSpeed === 6) : false;
561
- break;
562
- case 37: //PHYSICAL LOCK CONTROLS ALL
563
- button.state = (this.accessory.lockPhysicalControl === 1);
564
- break;
565
- case 38: //PHYSICAL LOCK CONTROLS POWER
566
- button.state = (prohibitPower === true);
567
- break;
568
- case 39: //PHYSICAL LOCK CONTROLS MODE
569
- button.state = (prohibitOperationMode === true);
570
- break;
571
- case 40: //PHYSICAL LOCK CONTROLS TEMP
572
- button.state = (prohibitSetTemperature === true);
573
- break;
574
- default: //Unknown button
575
- this.emit('message', `Unknown button mode: ${mode} detected.`);
576
- break;
577
- };
578
-
579
- //update services
580
- if (this.buttonsServices) {
581
- const characteristicType = button.characteristicType;
582
- this.buttonsServices[i]
583
- .updateCharacteristic(characteristicType, button.state)
584
- };
585
- };
586
- };
587
-
588
- //log current state
589
- if (!this.disableLogInfo) {
590
- this.emit('message', `Power: ${power ? 'ON' : 'OFF'}`);
591
- this.emit('message', `Target operation mode: ${AirConditioner.DriveMode[operationMode]}`);
592
- this.emit('message', `Current operation mode: ${this.displayMode === 1 ? AirConditioner.CurrentOperationModeHeatherCooler[this.accessory.currentOperationMode] : AirConditioner.CurrentOperationModeThermostat[this.accessory.currentOperationMode]}`);
593
- this.emit('message', `Target temperature: ${setTemperature}${this.accessory.temperatureUnit}`);
594
- this.emit('message', `Current temperature: ${roomTemperature}${this.accessory.temperatureUnit}`);
595
- const info = hasOutdoorTemperature && outdoorTemperature !== null ? this.emit('message', `Outdoor temperature: ${outdoorTemperature}${this.accessory.temperatureUnit}`) : false;
596
- const info3 = modelSupportsFanSpeed ? this.emit('message', `Target fan speed: ${AirConditioner.FanSpeed[fanSpeed]}`) : false;
597
- const info4 = modelSupportsFanSpeed ? this.emit('message', `Current fan speed: ${AirConditioner.FanSpeed[actualFanSpeed]}`) : false;
598
- const info5 = vaneHorizontalDirection !== null ? this.emit('message', `Vane horizontal: ${AirConditioner.HorizontalVane[vaneHorizontalDirection] ?? vaneHorizontalDirection}`) : false;
599
- const info6 = vaneVerticalDirection !== null ? this.emit('message', `Vane vertical: ${AirConditioner.VerticalVane[vaneVerticalDirection] ?? vaneVerticalDirection}`) : false;
600
- const info7 = swingFunction ? this.emit('message', `Air direction: ${AirConditioner.AirDirection[this.accessory.swingMode]}`) : false;
601
- this.emit('message', `Temperature display unit: ${this.accessory.temperatureUnit}`);
602
- this.emit('message', `Lock physical controls: ${this.accessory.lockPhysicalControl ? 'LOCKED' : 'UNLOCKED'}`);
603
- };
604
-
605
- //start prepare accessory
606
- if (!this.startPrepareAccessory) {
607
- return;
608
- }
609
- try {
610
- const accessory = await this.prepareAccessory(this.accountInfo, deviceData, this.deviceId, this.deviceTypeText, this.deviceName, this.accountName);
611
- this.emit('publishAccessory', accessory);
612
- this.startPrepareAccessory = false;
613
- } catch (error) {
614
- this.emit('error', error);
615
- };
616
- })
617
- .on('success', (message) => {
618
- this.emit('success', message);
619
- })
620
- .on('message', (message) => {
621
- this.emit('message', message);
622
- })
623
- .on('debug', (debug) => {
624
- this.emit('debug', debug);
625
- })
626
- .on('warn', async (warn) => {
627
- this.emit('warn', warn);
628
- })
629
- .on('error', async (error) => {
630
- this.emit('error', error);
631
- });
632
-
633
- //check state
634
- await this.melCloudAta.checkState();
635
-
636
- //start impule generator
637
- await this.melCloudAta.impulseGenerator.start([{ name: 'checkState', sampling: this.refreshInterval }]);
638
-
639
- return true;
640
- } catch (error) {
641
- throw new Error(`Start error: ${error}`);
642
- };
643
- };
644
-
645
- async setOverExternalIntegration(integration, deviceData, key, value) {
646
- try {
647
- let set = false
648
- switch (key) {
649
- case 'Power':
650
- deviceData.Device[key] = value;
651
- deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.Power;
652
- set = await this.melCloudAta.send(deviceData, this.displayMode);
653
- break;
654
- case 'OperationMode':
655
- deviceData.Device[key] = value;
656
- deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.OperationModeSetTemperature;
657
- set = await this.melCloudAta.send(deviceData, this.displayMode);
658
- break;
659
- case 'SetTemperature':
660
- deviceData.Device[key] = value;
661
- deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.SetTemperature;
662
- set = await this.melCloudAta.send(deviceData, this.displayMode);
663
- break;
664
- case 'DefaultCoolingSetTemperature':
665
- deviceData.Device[key] = value;
666
- deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.SetTemperature;
667
- set = await this.melCloudAta.send(deviceData, this.displayMode);
668
- break;
669
- case 'DefaultHeatingSetTemperature':
670
- deviceData.Device[key] = value;
671
- deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.SetTemperature;
672
- set = await this.melCloudAta.send(deviceData, this.displayMode);
673
- break;
674
- case 'FanSpeed':
675
- deviceData.Device[key] = value;
676
- deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.SetFanSpeed;
677
- set = await this.melCloudAta.send(deviceData, this.displayMode);
678
- break;
679
- case 'VaneHorizontalDirection':
680
- deviceData.Device[key] = value;
681
- deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.VaneHorizontal;
682
- set = await this.melCloudAta.send(deviceData, this.displayMode);
683
- break;
684
- case 'VaneVerticalDirection':
685
- deviceData.Device[key] = value;
686
- deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.VaneVertical;
687
- set = await this.melCloudAta.send(deviceData, this.displayMode);
688
- break;
689
- case 'HideVaneControls':
690
- deviceData[key] = value;
691
- deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.Prohibit;
692
- set = await this.melCloudAta.send(deviceData, this.displayMode);
693
- break;
694
- case 'HideDryModeControl':
695
- deviceData[key] = value;
696
- deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.Prohibit;
697
- await this.melCloudAta.send(deviceData, this.displayMode);
698
- break;
699
- case 'ProhibitSetTemperature':
700
- deviceData.Device[key] = value;
701
- deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.Prohibit;
702
- set = await this.melCloudAta.send(deviceData, this.displayMode);
703
- break;
704
- case 'ProhibitOperationMode':
705
- deviceData.Device[key] = value;
706
- deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.Prohibit;
707
- await this.melCloudAta.send(deviceData, this.displayMode);
708
- break;
709
- case 'ProhibitPower':
710
- deviceData.Device[key] = value;
711
- deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.Prohibit;
712
- set = await this.melCloudAta.send(deviceData, this.displayMode);
713
- break;
714
- default:
715
- this.emit('warn', `${integration}, received key: ${key}, value: ${value}`);
716
- break;
717
- };
718
- return set;
719
- } catch (error) {
720
- throw new Error(`${integration} set key: ${key}, value: ${value}, error: ${error.message ?? error}`);
721
- };
722
- }
723
-
724
- //prepare accessory
725
- async prepareAccessory(accountInfo, deviceData, deviceId, deviceTypeText, deviceName, accountName) {
726
- try {
727
- const presetsOnServer = this.accessory.presets;
728
- const modelSupportsHeat = this.accessory.modelSupportsHeat;
729
- const modelSupportsDry = this.accessory.modelSupportsDry;
730
- const modelSupportsCool = this.accessory.modelSupportsCool;
731
- const modelSupportsAuto = this.accessory.modelSupportsAuto;
732
- const modelSupportsFanSpeed = this.accessory.modelSupportsFanSpeed;
733
- const hasAutomaticFanSpeed = this.accessory.hasAutomaticFanSpeed;
734
- const hasOutdoorTemperature = this.accessory.hasOutdoorTemperature;
735
- const numberOfFanSpeeds = this.accessory.numberOfFanSpeeds;
736
- const swingFunction = this.accessory.swingFunction;
737
- const autoDryFanMode = [this.accessory.operationMode, 8, modelSupportsDry ? 2 : 8, 7][this.autoDryFanMode]; //NONE, AUTO - 8, DRY - 2, FAN - 7
738
- const heatDryFanMode = [this.accessory.operationMode, 1, modelSupportsDry ? 2 : 1, 7][this.heatDryFanMode]; //NONE, HEAT - 1, DRY - 2, FAN - 7
739
- const coolDryFanMode = [this.accessory.operationMode, 3, modelSupportsDry ? 2 : 3, 7][this.coolDryFanMode]; //NONE, COOL - 3, DRY - 2, FAN - 7
740
-
741
- //accessory
742
- const debug = this.enableDebugMode ? this.emit('debug', `Prepare accessory`) : false;
743
- const accessoryName = deviceName;
744
- const accessoryUUID = AccessoryUUID.generate(accountName + deviceId.toString());
745
- const accessoryCategory = Categories.AIR_CONDITIONER;
746
- const accessory = new Accessory(accessoryName, accessoryUUID, accessoryCategory);
747
-
748
- //information service
749
- const debug1 = this.enableDebugMode ? this.emit('debug', `Prepare information service`) : false;
750
- accessory.getService(Service.AccessoryInformation)
751
- .setCharacteristic(Characteristic.Manufacturer, this.manufacturer)
752
- .setCharacteristic(Characteristic.Model, this.model)
753
- .setCharacteristic(Characteristic.SerialNumber, this.serialNumber)
754
- .setCharacteristic(Characteristic.FirmwareRevision, this.firmwareRevision)
755
- .setCharacteristic(Characteristic.ConfiguredName, accessoryName);
756
-
757
- //melcloud services
758
- const serviceName = `${deviceTypeText} ${accessoryName}`;
759
- switch (this.displayMode) {
760
- case 1: //Heater Cooler
761
- const debug = this.enableDebugMode ? this.emit('debug', `Prepare heater/cooler service`) : false;
762
- this.melCloudService = new Service.HeaterCooler(serviceName, `HeaterCooler ${deviceId}`);
763
- this.melCloudService.getCharacteristic(Characteristic.Active)
356
+ });
357
+ if (modelSupportsHeat) {
358
+ this.melCloudService.getCharacteristic(Characteristic.HeatingThresholdTemperature)
359
+ .setProps({
360
+ minValue: this.accessory.minTempHeat,
361
+ maxValue: this.accessory.maxTempHeat,
362
+ minStep: this.accessory.temperatureIncrement
363
+ })
364
+ .onGet(async () => {
365
+ const value = this.accessory.operationMode === 8 ? this.accessory.defaultHeatingSetTemperature : this.accessory.setTemperature;
366
+ return value;
367
+ })
368
+ .onSet(async (value) => {
369
+ try {
370
+ deviceData.Device.DefaultHeatingSetTemperature = value;
371
+ deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.SetTemperature;
372
+ await this.melCloudAta.send(deviceData, this.displayMode);
373
+ const info = this.disableLogInfo ? false : this.emit('message', `Set heating threshold temperature: ${value}${this.accessory.temperatureUnit}`);
374
+ } catch (error) {
375
+ this.emit('warn', `Set heating threshold temperature error: ${error}`);
376
+ };
377
+ });
378
+ };
379
+ this.melCloudService.getCharacteristic(Characteristic.LockPhysicalControls)
764
380
  .onGet(async () => {
765
- const state = this.accessory.power;
766
- return state;
381
+ const value = this.accessory.lockPhysicalControl;
382
+ return value;
767
383
  })
768
- .onSet(async (state) => {
384
+ .onSet(async (value) => {
769
385
  try {
770
- deviceData.Device.Power = [false, true][state];
771
- deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.Power;
386
+ value = value ? true : false;
387
+ deviceData.Device.ProhibitSetTemperature = value;
388
+ deviceData.Device.ProhibitOperationMode = value;
389
+ deviceData.Device.ProhibitPower = value;
390
+ deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.Prohibit;
772
391
  await this.melCloudAta.send(deviceData, this.displayMode);
773
- const info = this.disableLogInfo ? false : this.emit('message', `Set power: ${state ? 'ON' : 'OFF'}`);
392
+ const info = this.disableLogInfo ? false : this.emit('message', `Set local physical controls: ${value ? 'LOCK' : 'UNLOCK'}`);
774
393
  } catch (error) {
775
- this.emit('warn', `Set power error: ${error}`);
394
+ this.emit('warn', `Set lock physical controls error: ${error}`);
776
395
  };
777
396
  });
778
- this.melCloudService.getCharacteristic(Characteristic.CurrentHeaterCoolerState)
397
+ this.melCloudService.getCharacteristic(Characteristic.TemperatureDisplayUnits)
398
+ .onGet(async () => {
399
+ const value = this.accessory.useFahrenheit;
400
+ return value;
401
+ })
402
+ .onSet(async (value) => {
403
+ try {
404
+ accountInfo.UseFahrenheit = [false, true][value];
405
+ await this.melCloud.send(accountInfo);
406
+ this.accessory.useFahrenheit = value;
407
+ const info = this.disableLogInfo ? false : this.emit('message', `Set temperature display unit: ${TemperatureDisplayUnits[value]}`);
408
+ } catch (error) {
409
+ this.emit('warn', `Set temperature display unit error: ${error}`);
410
+ };
411
+ });
412
+ accessory.addService(this.melCloudService);
413
+ break;
414
+ case 2: //Thermostat
415
+ const debug1 = this.enableDebugMode ? this.emit('debug', `Prepare thermostat service`) : false;
416
+ this.melCloudService = new Service.Thermostat(serviceName, `Thermostat ${deviceId}`);
417
+ this.melCloudService.getCharacteristic(Characteristic.CurrentHeatingCoolingState)
779
418
  .onGet(async () => {
780
419
  const value = this.accessory.currentOperationMode;
781
420
  return value;
782
421
  });
783
- this.melCloudService.getCharacteristic(Characteristic.TargetHeaterCoolerState)
422
+ this.melCloudService.getCharacteristic(Characteristic.TargetHeatingCoolingState)
784
423
  .setProps({
785
424
  minValue: this.accessory.operationModeSetPropsMinValue,
786
425
  maxValue: this.accessory.operationModeSetPropsMaxValue,
@@ -793,607 +432,969 @@ class DeviceAta extends EventEmitter {
793
432
  .onSet(async (value) => {
794
433
  try {
795
434
  switch (value) {
796
- case 0: //AUTO - AUTO
435
+ case 0: //OFF - POWER OFF
436
+ deviceData.Device.Power = false;
437
+ deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.Power;
438
+ break;
439
+ case 1: //HEAT - HEAT
440
+ deviceData.Device.Power = true;
441
+ deviceData.Device.OperationMode = heatDryFanMode;
442
+ deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerOperationModeSetTemperature;
443
+ break;
444
+ case 2: //COOL - COOL
445
+ deviceData.Device.Power = true;
446
+ deviceData.Device.OperationMode = coolDryFanMode;
447
+ deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerOperationModeSetTemperature
448
+ break;
449
+ case 3: //AUTO - AUTO
450
+ deviceData.Device.Power = true;
797
451
  deviceData.Device.OperationMode = autoDryFanMode;
452
+ deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerOperationModeSetTemperature;
453
+ break;
454
+ };
455
+
456
+ await this.melCloudAta.send(deviceData, this.displayMode);
457
+ const operationModeText = AirConditioner.DriveMode[deviceData.Device.OperationMode];
458
+ const info = this.disableLogInfo ? false : this.emit('message', `Set operation mode: ${operationModeText}`);
459
+ } catch (error) {
460
+ this.emit('warn', `Set operation mode error: ${error}`);
461
+ };
462
+ });
463
+ this.melCloudService.getCharacteristic(Characteristic.CurrentTemperature)
464
+ .onGet(async () => {
465
+ const value = this.accessory.roomTemperature;
466
+ return value;
467
+ });
468
+ this.melCloudService.getCharacteristic(Characteristic.TargetTemperature)
469
+ .setProps({
470
+ minValue: this.accessory.minTempHeat,
471
+ maxValue: this.accessory.maxTempHeat,
472
+ minStep: this.accessory.temperatureIncrement
473
+ })
474
+ .onGet(async () => {
475
+ const value = this.accessory.setTemperature;
476
+ return value;
477
+ })
478
+ .onSet(async (value) => {
479
+ try {
480
+ deviceData.Device.SetTemperature = value;
481
+ deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.SetTemperature;
482
+ await this.melCloudAta.send(deviceData, this.displayMode);
483
+ const info = this.disableLogInfo ? false : this.emit('message', `Set temperature: ${value}${this.accessory.temperatureUnit}`);
484
+ } catch (error) {
485
+ this.emit('warn', `Set temperature error: ${error}`);
486
+ };
487
+ });
488
+ this.melCloudService.getCharacteristic(Characteristic.TemperatureDisplayUnits)
489
+ .onGet(async () => {
490
+ const value = this.accessory.useFahrenheit;
491
+ return value;
492
+ })
493
+ .onSet(async (value) => {
494
+ try {
495
+ accountInfo.UseFahrenheit = [false, true][value];
496
+ await this.melCloud.send(accountInfo);
497
+ this.accessory.useFahrenheit = value;
498
+ const info = this.disableLogInfo ? false : this.emit('message', `Set temperature display unit: ${TemperatureDisplayUnits[value]}`);
499
+ } catch (error) {
500
+ this.emit('warn', `Set temperature display unit error: ${error}`);
501
+ };
502
+ });
503
+ accessory.addService(this.melCloudService);
504
+ break;
505
+ };
506
+
507
+ //temperature sensor services
508
+ if (this.temperatureSensor && this.accessory.roomTemperature !== null) {
509
+ const debug = this.enableDebugMode ? this.emit('debug', `Prepare room temperature sensor service`) : false;
510
+ this.roomTemperatureSensorService = new Service.TemperatureSensor(`${serviceName} Room`, `Room Temperature Sensor ${deviceId}`);
511
+ this.roomTemperatureSensorService.addOptionalCharacteristic(Characteristic.ConfiguredName);
512
+ this.roomTemperatureSensorService.setCharacteristic(Characteristic.ConfiguredName, `${accessoryName} Room`);
513
+ this.roomTemperatureSensorService.getCharacteristic(Characteristic.CurrentTemperature)
514
+ .setProps({
515
+ minValue: -35,
516
+ maxValue: 150,
517
+ minStep: 0.5
518
+ })
519
+ .onGet(async () => {
520
+ const state = this.accessory.roomTemperature;
521
+ return state;
522
+ })
523
+ accessory.addService(this.roomTemperatureSensorService);
524
+ };
525
+
526
+ if (this.temperatureSensorOutdoor && hasOutdoorTemperature && this.accessory.outdoorTemperature !== null) {
527
+ const debug = this.enableDebugMode ? this.emit('debug', `Prepare outdoor temperature sensor service`) : false;
528
+ this.outdoorTemperatureSensorService = new Service.TemperatureSensor(`${serviceName} Outdoor`, `Outdoor Temperature Sensor ${deviceId}`);
529
+ this.outdoorTemperatureSensorService.addOptionalCharacteristic(Characteristic.ConfiguredName);
530
+ this.outdoorTemperatureSensorService.setCharacteristic(Characteristic.ConfiguredName, `${accessoryName} Outdoor`);
531
+ this.outdoorTemperatureSensorService.getCharacteristic(Characteristic.CurrentTemperature)
532
+ .setProps({
533
+ minValue: -35,
534
+ maxValue: 150,
535
+ minStep: 0.5
536
+ })
537
+ .onGet(async () => {
538
+ const state = this.accessory.outdoorTemperature;
539
+ return state;
540
+ })
541
+ accessory.addService(this.outdoorTemperatureSensorService);
542
+ };
543
+
544
+ //presets services
545
+ if (this.presetsConfiguredCount > 0) {
546
+ const debug = this.enableDebugMode ? this.emit('debug', `Prepare presets services`) : false;
547
+ this.presetsServices = [];
548
+
549
+ for (let i = 0; i < this.presetsConfiguredCount; i++) {
550
+ const preset = this.presetsConfigured[i];
551
+ const presetData = presetsOnServer.find(p => p.ID === preset.Id);
552
+
553
+ //get preset name
554
+ const presetName = preset.name;
555
+
556
+ //get preset name prefix
557
+ const presetNamePrefix = preset.namePrefix;
558
+
559
+ const serviceName = presetNamePrefix ? `${accessoryName} ${presetName}` : presetName;
560
+ const serviceType = preset.serviceType;
561
+ const characteristicType = preset.characteristicType;
562
+ const presetService = new serviceType(serviceName, `Preset ${deviceId} ${i}`);
563
+ presetService.addOptionalCharacteristic(Characteristic.ConfiguredName);
564
+ presetService.setCharacteristic(Characteristic.ConfiguredName, serviceName);
565
+ presetService.getCharacteristic(characteristicType)
566
+ .onGet(async () => {
567
+ const state = preset.state;
568
+ return state;
569
+ })
570
+ .onSet(async (state) => {
571
+ try {
572
+ switch (state) {
573
+ case true:
574
+ preset.previousSettings = deviceData.Device;
575
+ deviceData.Device.Power = presetData.Power;
576
+ deviceData.Device.OperationMode = presetData.OperationMode;
577
+ deviceData.Device.SetTemperature = presetData.SetTemperature;
578
+ deviceData.Device.VaneHorizontalDirection = presetData.VaneHorizontal;
579
+ deviceData.Device.VaneVerticalDirection = presetData.VaneVertical;
580
+ deviceData.Device.FanSpeed = presetData.FanSpeed;
581
+ deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.Presets;
582
+ break;
583
+ case false:
584
+ deviceData.Device.Power = preset.previousSettings.Power;
585
+ deviceData.Device.OperationMode = preset.previousSettings.OperationMode;
586
+ deviceData.Device.SetTemperature = preset.previousSettings.SetTemperature;
587
+ deviceData.Device.VaneHorizontalDirection = preset.previousSettings.VaneHorizontalDirection;
588
+ deviceData.Device.VaneVerticalDirection = preset.previousSettings.VaneVerticalDirection;
589
+ deviceData.Device.FanSpeed = preset.previousSettings.FanSpeed;
590
+ deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.Presets;
591
+ break;
592
+ };
593
+
594
+ await this.melCloudAta.send(deviceData, this.displayMode);
595
+ const info = this.disableLogInfo ? false : this.emit('message', `${state ? 'Set:' : 'Unset:'} ${presetName}`);
596
+ } catch (error) {
597
+ this.emit('warn', `Set preset error: ${error}`);
598
+ };
599
+ });
600
+ this.presetsServices.push(presetService);
601
+ accessory.addService(presetService);
602
+ };
603
+ };
604
+
605
+ //buttons services
606
+ if (this.buttonsConfiguredCount > 0) {
607
+ const debug = this.enableDebugMode ? this.emit('debug', `Prepare buttons/sensors services`) : false;
608
+ this.buttonsServices = [];
609
+
610
+ for (let i = 0; i < this.buttonsConfiguredCount; i++) {
611
+ const button = this.buttonsConfigured[i];
612
+
613
+ //get button mode
614
+ const mode = button.mode;
615
+
616
+ //get button name
617
+ const buttonName = button.name;
618
+
619
+ //get button name prefix
620
+ const buttonNamePrefix = button.namePrefix;
621
+
622
+ const serviceName = buttonNamePrefix ? `${accessoryName} ${buttonName}` : buttonName;
623
+ const serviceType = button.serviceType;
624
+ const characteristicType = button.characteristicType;
625
+ const buttonService = new serviceType(serviceName, `Button ${deviceId} ${i}`);
626
+ buttonService.addOptionalCharacteristic(Characteristic.ConfiguredName);
627
+ buttonService.setCharacteristic(Characteristic.ConfiguredName, serviceName);
628
+ buttonService.getCharacteristic(characteristicType)
629
+ .onGet(async () => {
630
+ const state = button.state;
631
+ return state;
632
+ })
633
+ .onSet(async (state) => {
634
+ try {
635
+ switch (mode) {
636
+ case 0: //POWER ON,OFF
637
+ deviceData.Device.Power = state;
638
+ deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.Power;
639
+ break;
640
+ case 1: //OPERATING MODE HEAT
641
+ button.previousValue = state ? deviceData.Device.OperationMode : button.previousValue ?? deviceData.Device.OperationMode;
642
+ deviceData.Device.Power = true;
643
+ deviceData.Device.OperationMode = state ? 1 : button.previousValue === 9 ? 1 : button.previousValue;
644
+ deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerOperationModeSetTemperature;
798
645
  break;
799
- case 1: //HEAT - HEAT
800
- deviceData.Device.OperationMode = heatDryFanMode;
646
+ case 2: //OPERATING MODE DRY
647
+ button.previousValue = state ? deviceData.Device.OperationMode : button.previousValue ?? deviceData.Device.OperationMode;
648
+ deviceData.Device.Power = true;
649
+ deviceData.Device.OperationMode = state ? 2 : button.previousValue === 10 ? 2 : button.previousValue;
650
+ deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerOperationModeSetTemperature;
651
+ break
652
+ case 3: //OPERATING MODE COOL
653
+ button.previousValue = state ? deviceData.Device.OperationMode : button.previousValue ?? deviceData.Device.OperationMode;
654
+ deviceData.Device.Power = true;
655
+ deviceData.Device.OperationMode = state ? 3 : button.previousValue === 11 ? 3 : button.previousValue;
656
+ deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerOperationModeSetTemperature;
801
657
  break;
802
- case 2: //COOL - COOL
803
- deviceData.Device.OperationMode = coolDryFanMode;
658
+ case 4: //OPERATING MODE FAN
659
+ button.previousValue = state ? deviceData.Device.OperationMode : button.previousValue ?? deviceData.Device.OperationMode;
660
+ deviceData.Device.Power = true;
661
+ deviceData.Device.OperationMode = state ? 7 : button.previousValue;
662
+ deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerOperationModeSetTemperature;
663
+ break;
664
+ case 5: //OPERATING MODE AUTO
665
+ button.previousValue = state ? deviceData.Device.OperationMode : button.previousValue ?? deviceData.Device.OperationMode;
666
+ deviceData.Device.Power = true;
667
+ deviceData.Device.OperationMode = state ? 8 : button.previousValue;
668
+ deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerOperationModeSetTemperature;
669
+ break;
670
+ case 6: //OPERATING MODE PURIFY
671
+ button.previousValue = state ? deviceData.Device.OperationMode : button.previousValue ?? deviceData.Device.OperationMode;
672
+ deviceData.Device.Power = true;
673
+ deviceData.Device.OperationMode = state ? 12 : button.previousValue;
674
+ deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerOperationModeSetTemperature;
675
+ break;
676
+ case 7: //OPERATING MODE DRY CONTROL HIDE
677
+ deviceData.HideDryModeControl = state;
678
+ break;
679
+ case 10: //VANE H SWING MODE AUTO
680
+ button.previousValue = state ? deviceData.Device.VaneHorizontalDirection : button.previousValue ?? deviceData.Device.VaneHorizontalDirection;
681
+ deviceData.Device.Power = true;
682
+ deviceData.Device.VaneHorizontalDirection = state ? 0 : button.previousValue;
683
+ deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerVaneHorizontal;
684
+ break;
685
+ case 11: //VANE H SWING MODE 1
686
+ button.previousValue = state ? deviceData.Device.VaneHorizontalDirection : button.previousValue ?? deviceData.Device.VaneHorizontalDirection;
687
+ deviceData.Device.Power = true;
688
+ deviceData.Device.VaneHorizontalDirection = state ? 1 : button.previousValue;
689
+ deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerVaneHorizontal;
690
+ break;
691
+ case 12: //VANE H SWING MODE 2
692
+ button.previousValue = state ? deviceData.Device.VaneHorizontalDirection : button.previousValue ?? deviceData.Device.VaneHorizontalDirection;
693
+ deviceData.Device.Power = true;
694
+ deviceData.Device.VaneHorizontalDirection = state ? 2 : button.previousValue;
695
+ deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerVaneHorizontal;
696
+ break;
697
+ case 13: //VANE H SWING MODE 3
698
+ button.previousValue = state ? deviceData.Device.VaneHorizontalDirection : button.previousValue ?? deviceData.Device.VaneHorizontalDirection;
699
+ deviceData.Device.Power = true;
700
+ deviceData.Device.VaneHorizontalDirection = state ? 3 : button.previousValue;
701
+ deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerVaneHorizontal;
702
+ break;
703
+ case 14: //VANE H SWING MODE 4
704
+ button.previousValue = state ? deviceData.Device.VaneHorizontalDirection : button.previousValue ?? deviceData.Device.VaneHorizontalDirection;
705
+ deviceData.Device.Power = true;
706
+ deviceData.Device.VaneHorizontalDirection = state ? 4 : button.previousValue;
707
+ deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerVaneHorizontal;
708
+ break;
709
+ case 15: //VANE H SWING MODE 5
710
+ button.previousValue = state ? deviceData.Device.VaneHorizontalDirection : button.previousValue ?? deviceData.Device.VaneHorizontalDirection;
711
+ deviceData.Device.Power = true;
712
+ deviceData.Device.VaneHorizontalDirection = state ? 5 : button.previousValue;
713
+ deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerVaneHorizontal;
714
+ break;
715
+ case 16: //VANE H SWING MODE SPLIT
716
+ button.previousValue = state ? deviceData.Device.VaneHorizontalDirection : button.previousValue ?? deviceData.Device.VaneHorizontalDirection;
717
+ deviceData.Device.Power = true;
718
+ deviceData.Device.VaneHorizontalDirection = state ? 8 : button.previousValue;
719
+ deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerVaneHorizontal;
720
+ break;
721
+ case 17: //VANE H SWING MODE SWING
722
+ button.previousValue = state ? deviceData.Device.VaneHorizontalDirection : button.previousValue ?? deviceData.Device.VaneHorizontalDirection;
723
+ deviceData.Device.Power = true;
724
+ deviceData.Device.VaneHorizontalDirection = state ? 12 : button.previousValue;
725
+ deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerVaneHorizontal;
726
+ break;
727
+ case 20: //VANE V SWING MODE AUTO
728
+ button.previousValue = state ? deviceData.Device.VaneVerticalDirection : button.previousValue ?? deviceData.Device.VaneVerticalDirection;
729
+ deviceData.Device.Power = true;
730
+ deviceData.Device.VaneVerticalDirection = state ? 0 : button.previousValue;
731
+ deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerVaneVertical;
732
+ break;
733
+ case 21: //VANE V SWING MODE 1
734
+ button.previousValue = state ? deviceData.Device.VaneVerticalDirection : button.previousValue ?? deviceData.Device.VaneVerticalDirection;
735
+ deviceData.Device.Power = true;
736
+ deviceData.Device.VaneVerticalDirection = state ? 1 : button.previousValue;
737
+ deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerVaneVertical;
738
+ break;
739
+ case 22: //VANE V SWING MODE 2
740
+ button.previousValue = state ? deviceData.Device.VaneVerticalDirection : button.previousValue ?? deviceData.Device.VaneVerticalDirection;
741
+ deviceData.Device.Power = true;
742
+ deviceData.Device.VaneVerticalDirection = state ? 2 : button.previousValue;
743
+ deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerVaneVertical;
744
+ break;
745
+ case 23: //VANE V SWING MODE 3
746
+ button.previousValue = state ? deviceData.Device.VaneVerticalDirection : button.previousValue ?? deviceData.Device.VaneVerticalDirection;
747
+ deviceData.Device.Power = true;
748
+ deviceData.Device.VaneVerticalDirection = state ? 3 : button.previousValue;
749
+ deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerVaneVertical;
750
+ break;
751
+ case 24: //VANE V SWING MODE 4
752
+ button.previousValue = state ? deviceData.Device.VaneVerticalDirection : button.previousValue ?? deviceData.Device.VaneVerticalDirection;
753
+ deviceData.Device.Power = true;
754
+ deviceData.Device.VaneVerticalDirection = state ? 4 : button.previousValue;
755
+ deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerVaneVertical;
756
+ break;
757
+ case 25: //VANE V SWING MODE 5
758
+ button.previousValue = state ? deviceData.Device.VaneVerticalDirection : button.previousValue ?? deviceData.Device.VaneVerticalDirection;
759
+ deviceData.Device.Power = true;
760
+ deviceData.Device.VaneVerticalDirection = state ? 5 : button.previousValue;
761
+ deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerVaneVertical;
762
+ break;
763
+ case 26: //VANE V SWING MODE SWING
764
+ button.previousValue = state ? deviceData.Device.VaneVerticalDirection : button.previousValue ?? deviceData.Device.VaneVerticalDirection;
765
+ deviceData.Device.Power = true;
766
+ deviceData.Device.VaneVerticalDirection = state ? 7 : button.previousValue;
767
+ deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerVaneVertical;
768
+ break;
769
+ case 27: //VANE H/V CONTROLS HIDE
770
+ deviceData.HideVaneControls = state;
771
+ break;
772
+ case 30: //FAN SPEED MODE AUTO
773
+ button.previousValue = state ? deviceData.Device.FanSpeed : button.previousValue ?? deviceData.Device.FanSpeed;
774
+ deviceData.Device.Power = true;
775
+ deviceData.Device.FanSpeed = state ? 0 : button.previousValue;
776
+ deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerSetFanSpeed;
777
+ break;
778
+ case 31: //FAN SPEED MODE 1
779
+ button.previousValue = state ? deviceData.Device.FanSpeed : button.previousValue ?? deviceData.Device.FanSpeed;
780
+ deviceData.Device.Power = true;
781
+ deviceData.Device.FanSpeed = state ? 1 : button.previousValue;
782
+ deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerSetFanSpeed;
783
+ break;
784
+ case 32: //FAN SPEED MODE 2
785
+ button.previousValue = state ? deviceData.Device.FanSpeed : button.previousValue ?? deviceData.Device.FanSpeed;
786
+ deviceData.Device.Power = true;
787
+ deviceData.Device.FanSpeed = state ? 2 : button.previousValue;
788
+ deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerSetFanSpeed;
789
+ break;
790
+ case 33: //FAN SPEED MODE 3
791
+ button.previousValue = state ? deviceData.Device.FanSpeed : button.previousValue ?? deviceData.Device.FanSpeed;
792
+ deviceData.Device.Power = true;
793
+ deviceData.Device.FanSpeed = state ? 3 : button.previousValue;
794
+ deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerSetFanSpeed;
795
+ break;
796
+ case 34: //FAN MODE 4
797
+ button.previousValue = state ? deviceData.Device.FanSpeed : button.previousValue ?? deviceData.Device.FanSpeed;
798
+ deviceData.Device.Power = true;
799
+ deviceData.Device.FanSpeed = state ? 4 : button.previousValue;
800
+ deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerSetFanSpeed;
801
+ break;
802
+ case 35: //FAN SPEED MODE 5
803
+ button.previousValue = state ? deviceData.Device.FanSpeed : button.previousValue ?? deviceData.Device.FanSpeed;
804
+ deviceData.Device.Power = true;
805
+ deviceData.Device.FanSpeed = state ? 5 : button.previousValue;
806
+ deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerSetFanSpeed;
807
+ break;
808
+ case 36: //FAN SPEED MODE 6
809
+ button.previousValue = state ? deviceData.Device.FanSpeed : button.previousValue ?? deviceData.Device.FanSpeed;
810
+ deviceData.Device.Power = true;
811
+ deviceData.Device.FanSpeed = state ? 6 : button.previousValue;
812
+ deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerSetFanSpeed;
813
+ break;
814
+ case 37: //PHYSICAL LOCK CONTROLS
815
+ deviceData.Device.ProhibitSetTemperature = state;
816
+ deviceData.Device.ProhibitOperationMode = state;
817
+ deviceData.Device.ProhibitPower = state;
818
+ deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.Prohibit;
819
+ break;
820
+ case 38: //PHYSICAL LOCK CONTROLS POWER
821
+ deviceData.Device.ProhibitPower = state;
822
+ deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.Prohibit;
823
+ break;
824
+ case 39: //PHYSICAL LOCK CONTROLS MODE
825
+ deviceData.Device.ProhibitOperationMode = state;
826
+ deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.Prohibit;
827
+ break;
828
+ case 40: //PHYSICAL LOCK CONTROLS TEMP
829
+ deviceData.Device.ProhibitSetTemperature = state;
830
+ deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.Prohibit;
831
+ break;
832
+ default:
833
+ this.emit('message', `Unknown button mode: ${mode}`);
804
834
  break;
805
835
  };
806
-
807
- deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.OperationModeSetTemperature;
808
- await this.melCloudAta.send(deviceData, this.displayMode);
809
- const operationModeText = AirConditioner.DriveMode[deviceData.Device.OperationMode];
810
- const info = this.disableLogInfo ? false : this.emit('message', `Set operation mode: ${operationModeText}`);
811
- } catch (error) {
812
- this.emit('warn', `Set operation mode error: ${error}`);
813
- };
814
- });
815
- this.melCloudService.getCharacteristic(Characteristic.CurrentTemperature)
816
- .onGet(async () => {
817
- const value = this.accessory.roomTemperature;
818
- return value;
819
- });
820
- if (modelSupportsFanSpeed) {
821
- this.melCloudService.getCharacteristic(Characteristic.RotationSpeed)
822
- .setProps({
823
- minValue: 0,
824
- maxValue: this.accessory.fanSpeedSetPropsMaxValue,
825
- minStep: 1
826
- })
827
- .onGet(async () => {
828
- const value = this.accessory.fanSpeed; //AUTO, 1, 2, 3, 4, 5, 6, OFF
829
- return value;
830
- })
831
- .onSet(async (value) => {
832
- try {
833
- let fanSpeedModeText = '';
834
- switch (numberOfFanSpeeds) {
835
- case 2: //Fan speed mode 2
836
- fanSpeedModeText = hasAutomaticFanSpeed ? [7, 1, 2, 0][value] : [7, 1, 2][value];
837
- deviceData.Device.FanSpeed = hasAutomaticFanSpeed ? [0, 1, 2, 0][value] : [1, 1, 2][value];
838
- break;
839
- case 3: //Fan speed mode 3
840
- fanSpeedModeText = hasAutomaticFanSpeed ? [7, 1, 2, 3, 0][value] : [7, 1, 2, 3][value];
841
- deviceData.Device.FanSpeed = hasAutomaticFanSpeed ? [0, 1, 2, 3, 0][value] : [1, 1, 2, 3][value];
842
- break;
843
- case 4: //Fan speed mode 4
844
- fanSpeedModeText = hasAutomaticFanSpeed ? [7, 1, 2, 3, 4, 0][value] : [7, 1, 2, 3, 4][value];
845
- deviceData.Device.FanSpeed = hasAutomaticFanSpeed ? [0, 1, 2, 3, 4, 0][value] : [1, 1, 2, 3, 4][value];
846
- break;
847
- case 5: //Fan speed mode 5
848
- 5; fanSpeedModeText = hasAutomaticFanSpeed ? [7, 1, 2, 3, 4, 5, 0][value] : [7, 1, 2, 3, 4, 5][value];
849
- deviceData.Device.FanSpeed = hasAutomaticFanSpeed ? [0, 1, 2, 3, 4, 5, 0][value] : [1, 1, 2, 3, 4, 5][value];
850
- break;
851
- case 6: //Fan speed mode 6
852
- fanSpeedModeText = hasAutomaticFanSpeed ? [7, 1, 2, 3, 4, 5, 6, 0][value] : [7, 1, 2, 3, 4, 5, 6][value];
853
- deviceData.Device.FanSpeed = hasAutomaticFanSpeed ? [0, 1, 2, 3, 4, 5, 6, 0][value] : [1, 1, 2, 3, 4, 5, 6][value];
854
- break;
855
- };
856
- deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.SetFanSpeed;
857
- await this.melCloudAta.send(deviceData, this.displayMode);
858
- const info = this.disableLogInfo ? false : this.emit('message', `Set fan speed mode: ${AirConditioner.FanSpeed[fanSpeedModeText]}`);
859
- } catch (error) {
860
- this.emit('warn', `Set fan speed mode error: ${error}`);
861
- };
862
- });
863
- };
864
- if (swingFunction) {
865
- this.melCloudService.getCharacteristic(Characteristic.SwingMode)
866
- .onGet(async () => {
867
- //Vane Horizontal: Auto, 1, 2, 3, 4, 5, 6, 12 = Swing //Vertical: Auto, 1, 2, 3, 4, 5, 7 = Swing
868
- const value = this.accessory.swingMode;
869
- return value;
870
- })
871
- .onSet(async (value) => {
872
- try {
873
- deviceData.Device.VaneHorizontal = value ? 12 : 0;
874
- deviceData.Device.VaneVertical = value ? 7 : 0;
875
- deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.VaneVerticalVaneHorizontal;
876
- await this.melCloudAta.send(deviceData, this.displayMode);
877
- const info = this.disableLogInfo ? false : this.emit('message', `Set air direction mode: ${AirConditioner.AirDirection[value]}`);
878
- } catch (error) {
879
- this.emit('warn', `Set vane swing mode error: ${error}`);
880
- };
881
- });
882
- };
883
- this.melCloudService.getCharacteristic(Characteristic.CoolingThresholdTemperature)
884
- .setProps({
885
- minValue: this.accessory.minTempCoolDry,
886
- maxValue: this.accessory.maxTempCoolDry,
887
- minStep: this.accessory.temperatureIncrement
888
- })
889
- .onGet(async () => {
890
- const value = this.accessory.operationMode === 8 ? this.accessory.defaultCoolingSetTemperature : this.accessory.setTemperature;
891
- return value;
892
- })
893
- .onSet(async (value) => {
894
- try {
895
- deviceData.Device.DefaultCoolingSetTemperature = value;
896
- deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.SetTemperature;
836
+
897
837
  await this.melCloudAta.send(deviceData, this.displayMode);
898
- const info = this.disableLogInfo ? false : this.emit('message', `Set cooling threshold temperature: ${value}${this.accessory.temperatureUnit}`);
838
+ const info = this.disableLogInfo ? false : this.emit('message', `${state ? `Set: ${buttonName}` : `Unset: ${buttonName}, Set: ${button.previousValue}`}`);
899
839
  } catch (error) {
900
- this.emit('warn', `Set cooling threshold temperature error: ${error}`);
840
+ this.emit('warn', `Set button error: ${error}`);
901
841
  };
902
842
  });
903
- if (modelSupportsHeat) {
904
- this.melCloudService.getCharacteristic(Characteristic.HeatingThresholdTemperature)
905
- .setProps({
906
- minValue: this.accessory.minTempHeat,
907
- maxValue: this.accessory.maxTempHeat,
908
- minStep: this.accessory.temperatureIncrement
909
- })
910
- .onGet(async () => {
911
- const value = this.accessory.operationMode === 8 ? this.accessory.defaultHeatingSetTemperature : this.accessory.setTemperature;
912
- return value;
843
+ this.buttonsServices.push(buttonService);
844
+ accessory.addService(buttonService);
845
+ };
846
+ };
847
+
848
+ return accessory;
849
+ } catch (error) {
850
+ throw new Error(`Prepare accessory error: ${error.message || error}`);
851
+ };
852
+ };
853
+
854
+ //start
855
+ async start() {
856
+ try {
857
+ //melcloud device
858
+ this.melCloudAta = new MelCloudAta({
859
+ contextKey: this.contextKey,
860
+ devicesFile: this.devicesFile,
861
+ deviceId: this.deviceId,
862
+ debugLog: this.enableDebugMode
863
+ });
864
+
865
+ this.melCloudAta.on('externalIntegrations', (deviceData) => {
866
+ try {
867
+ //RESTFul server
868
+ const restFulEnabled = this.restFul.enable || false;
869
+ if (restFulEnabled) {
870
+ if (!this.restFulConnected) {
871
+ this.restFul1 = new RestFul({
872
+ port: this.deviceId.slice(-4),
873
+ debug: this.restFul.debug || false
874
+ });
875
+
876
+ this.restFul1.on('connected', (message) => {
877
+ this.restFulConnected = true;
878
+ this.emit('success', message);
913
879
  })
914
- .onSet(async (value) => {
915
- try {
916
- deviceData.Device.DefaultHeatingSetTemperature = value;
917
- deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.SetTemperature;
918
- await this.melCloudAta.send(deviceData, this.displayMode);
919
- const info = this.disableLogInfo ? false : this.emit('message', `Set heating threshold temperature: ${value}${this.accessory.temperatureUnit}`);
920
- } catch (error) {
921
- this.emit('warn', `Set heating threshold temperature error: ${error}`);
922
- };
880
+ .on('set', async (key, value) => {
881
+ try {
882
+ await this.setOverExternalIntegration('RESTFul', deviceData, key, value);
883
+ } catch (error) {
884
+ this.emit('warn', error);
885
+ };
886
+ })
887
+ .on('debug', (debug) => {
888
+ this.emit('debug', debug);
889
+ })
890
+ .on('error', (error) => {
891
+ this.emit('warn', error);
892
+ });
893
+ }
894
+ const restFul0 = this.restFulConnected ? this.restFul1.update('info', deviceData) : false;
895
+ const restFul1 = this.restFulConnected ? this.restFul1.update('state', deviceData.Device) : false;
896
+ }
897
+
898
+ //MQTT client
899
+ const mqttEnabled = this.mqtt.enable || false;
900
+ if (mqttEnabled) {
901
+ if (!this.mqttConnected) {
902
+ this.mqtt1 = new Mqtt({
903
+ host: this.mqtt.host,
904
+ port: this.mqtt.port || 1883,
905
+ clientId: `${this.mqtt.clientId}_${this.deviceId}` || `${this.deviceTypeText}_${this.deviceName}_${this.deviceId}`,
906
+ prefix: `${this.mqtt.prefix}/${this.deviceTypeText}/${this.deviceName}`,
907
+ user: this.mqtt.user,
908
+ passwd: this.mqtt.pass,
909
+ debug: this.mqtt.debug || false
923
910
  });
911
+
912
+ this.mqtt1.on('connected', (message) => {
913
+ this.mqttConnected = true;
914
+ this.emit('success', message);
915
+ })
916
+ .on('subscribed', (message) => {
917
+ this.emit('success', message);
918
+ })
919
+ .on('set', async (key, value) => {
920
+ try {
921
+ await this.setOverExternalIntegration('MQTT', deviceData, key, value);
922
+ } catch (error) {
923
+ this.emit('warn', error);
924
+ };
925
+ })
926
+ .on('debug', (debug) => {
927
+ this.emit('debug', debug);
928
+ })
929
+ .on('error', (error) => {
930
+ this.emit('warn', error);
931
+ });
932
+ }
933
+ const mqtt0 = this.mqttConnected ? this.mqtt1.emit('publish', `Info`, deviceData) : false;
934
+ const mqtt1 = this.mqttConnected ? this.mqtt1.emit('publish', `State`, deviceData.Device) : false;
935
+ }
936
+
937
+ } catch (error) {
938
+ this.emit('warn', `External integration start error: ${error}.`);
939
+ };
940
+ })
941
+ .on('deviceInfo', (manufacturer, modelIndoor, modelOutdoor, serialNumber, firmwareAppVersion) => {
942
+ if (!this.displayDeviceInfo) {
943
+ return;
944
+ }
945
+
946
+ if (!this.disableLogDeviceInfo) {
947
+ this.emit('devInfo', `---- ${this.deviceTypeText}: ${this.deviceName} ----`);
948
+ this.emit('devInfo', `Account: ${this.accountName}`);
949
+ const indoor = modelIndoor ? this.emit('devInfo', `Indoor: ${modelIndoor}`) : false;
950
+ const outdoor = modelOutdoor ? this.emit('devInfo', `Outdoor: ${modelOutdoor}`) : false
951
+ this.emit('devInfo', `Serial: ${serialNumber}`);
952
+ this.emit('devInfo', `Firmware: ${firmwareAppVersion}`);
953
+ this.emit('devInfo', `Manufacturer: ${manufacturer}`);
954
+ this.emit('devInfo', '----------------------------------');
924
955
  };
925
- this.melCloudService.getCharacteristic(Characteristic.LockPhysicalControls)
926
- .onGet(async () => {
927
- const value = this.accessory.lockPhysicalControl;
928
- return value;
929
- })
930
- .onSet(async (value) => {
931
- try {
932
- value = value ? true : false;
933
- deviceData.Device.ProhibitSetTemperature = value;
934
- deviceData.Device.ProhibitOperationMode = value;
935
- deviceData.Device.ProhibitPower = value;
936
- deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.Prohibit;
937
- await this.melCloudAta.send(deviceData, this.displayMode);
938
- const info = this.disableLogInfo ? false : this.emit('message', `Set local physical controls: ${value ? 'LOCK' : 'UNLOCK'}`);
939
- } catch (error) {
940
- this.emit('warn', `Set lock physical controls error: ${error}`);
941
- };
942
- });
943
- this.melCloudService.getCharacteristic(Characteristic.TemperatureDisplayUnits)
944
- .onGet(async () => {
945
- const value = this.accessory.useFahrenheit;
946
- return value;
947
- })
948
- .onSet(async (value) => {
949
- try {
950
- accountInfo.UseFahrenheit = [false, true][value];
951
- await this.melCloud.send(accountInfo);
952
- this.accessory.useFahrenheit = value;
953
- const info = this.disableLogInfo ? false : this.emit('message', `Set temperature display unit: ${TemperatureDisplayUnits[value]}`);
954
- } catch (error) {
955
- this.emit('warn', `Set temperature display unit error: ${error}`);
956
+
957
+ //accessory info
958
+ this.manufacturer = manufacturer;
959
+ this.model = modelIndoor ? modelIndoor : modelOutdoor ? modelOutdoor : `${this.deviceTypeText} ${this.deviceId}`;
960
+ this.serialNumber = serialNumber;
961
+ this.firmwareRevision = firmwareAppVersion;
962
+ this.displayDeviceInfo = false;
963
+ })
964
+ .on('deviceState', async (deviceData) => {
965
+ //presets
966
+ const presetsOnServer = deviceData.Presets ?? [];
967
+
968
+ //device control
969
+ const hideVaneControls = deviceData.HideVaneControls ?? false;
970
+ const hideDryModeControl = deviceData.HideDryModeControl ?? false;
971
+
972
+ //device info
973
+ const hasAutomaticFanSpeed = deviceData.Device.HasAutomaticFanSpeed ?? false;
974
+ const airDirectionFunction = deviceData.Device.AirDirectionFunction ?? false;
975
+ const swingFunction = deviceData.Device.SwingFunction ?? false;
976
+ const hasOutdoorTemperature = deviceData.Device.HasOutdoorTemperature ?? false;
977
+ const numberOfFanSpeeds = deviceData.Device.NumberOfFanSpeeds ?? 0;
978
+ const modelSupportsFanSpeed = deviceData.Device.ModelSupportsFanSpeed ?? false;
979
+ const modelSupportsAuto1 = deviceData.Device.ModelSupportsAuto ?? false;
980
+ const modelSupportsAuto = this.autoDryFanMode >= 1 && modelSupportsAuto1
981
+ const modelSupportsHeat1 = deviceData.Device.ModelSupportsHeat ?? false;
982
+ const modelSupportsHeat = this.heatDryFanMode >= 1 && modelSupportsHeat1;
983
+ const modelSupportsDry = deviceData.Device.ModelSupportsDry ?? false;
984
+ const modelSupportsCool = this.coolDryFanMode >= 1;
985
+ const minTempHeat = 10;
986
+ const maxTempHeat = 31;
987
+ const minTempCoolDry = 16;
988
+ const maxTempCoolDry = 31;
989
+
990
+ //device state
991
+ const power = deviceData.Device.Power ?? false;
992
+ const inStandbyMode = deviceData.Device.InStandbyMode ?? false;
993
+ const roomTemperature = deviceData.Device.RoomTemperature;
994
+ const setTemperature = deviceData.Device.SetTemperature ?? 20;
995
+ const defaultHeatingSetTemperature = deviceData.Device.DefaultHeatingSetTemperature ?? 20;
996
+ const defaultCoolingSetTemperature = deviceData.Device.DefaultCoolingSetTemperature ?? 23;
997
+ const actualFanSpeed = deviceData.Device.ActualFanSpeed;
998
+ const automaticFanSpeed = deviceData.Device.AutomaticFanSpeed;
999
+ const fanSpeed = deviceData.Device.FanSpeed ?? 0;
1000
+ const operationMode = deviceData.Device.OperationMode;
1001
+ const vaneVerticalDirection = deviceData.Device.VaneVerticalDirection;
1002
+ const vaneVerticalSwing = deviceData.Device.VaneVerticalSwing;
1003
+ const vaneHorizontalDirection = deviceData.Device.VaneHorizontalDirection;
1004
+ const vaneHorizontalSwing = deviceData.Device.VaneHorizontalSwing;
1005
+ const prohibitSetTemperature = deviceData.Device.ProhibitSetTemperature ?? false;
1006
+ const prohibitOperationMode = deviceData.Device.ProhibitOperationMode ?? false;
1007
+ const prohibitPower = deviceData.Device.ProhibitPower ?? false;
1008
+ const temperatureIncrement = deviceData.Device.TemperatureIncrement ?? 1;
1009
+ const outdoorTemperature = deviceData.Device.OutdoorTemperature;
1010
+
1011
+ //accessory
1012
+ this.accessory.presets = presetsOnServer;
1013
+ this.accessory.hasAutomaticFanSpeed = hasAutomaticFanSpeed;
1014
+ this.accessory.airDirectionFunction = airDirectionFunction;
1015
+ this.accessory.swingFunction = swingFunction;
1016
+ this.accessory.hasOutdoorTemperature = hasOutdoorTemperature;
1017
+ this.accessory.numberOfFanSpeeds = numberOfFanSpeeds;
1018
+ this.accessory.modelSupportsFanSpeed = modelSupportsFanSpeed;
1019
+ this.accessory.modelSupportsAuto = modelSupportsAuto;
1020
+ this.accessory.modelSupportsHeat = modelSupportsHeat;
1021
+ this.accessory.modelSupportsDry = modelSupportsDry;
1022
+ this.accessory.modelSupportsCool = modelSupportsCool;
1023
+ this.accessory.minTempHeat = minTempHeat;
1024
+ this.accessory.maxTempHeat = maxTempHeat;
1025
+ this.accessory.minTempCoolDry = minTempCoolDry;
1026
+ this.accessory.maxTempCoolDry = maxTempCoolDry;
1027
+
1028
+ this.accessory.power = power ? 1 : 0;
1029
+ this.accessory.inStandbyMode = inStandbyMode;
1030
+ this.accessory.operationMode = operationMode;
1031
+ this.accessory.roomTemperature = roomTemperature;
1032
+ this.accessory.outdoorTemperature = outdoorTemperature;
1033
+ this.accessory.setTemperature = setTemperature;
1034
+ this.accessory.defaultHeatingSetTemperature = defaultHeatingSetTemperature;
1035
+ this.accessory.defaultCoolingSetTemperature = defaultCoolingSetTemperature;
1036
+ this.accessory.actualFanSpeed = actualFanSpeed;
1037
+ this.accessory.automaticFanSpeed = automaticFanSpeed;
1038
+ this.accessory.vaneVerticalSwing = vaneVerticalSwing;
1039
+ this.accessory.vaneHorizontalSwing = vaneHorizontalSwing;
1040
+ this.accessory.swingMode = swingFunction && vaneHorizontalDirection === 12 && vaneVerticalDirection === 7 ? 1 : 0;
1041
+ this.accessory.lockPhysicalControl = prohibitSetTemperature && prohibitOperationMode && prohibitPower ? 1 : 0;
1042
+ this.accessory.temperatureIncrement = temperatureIncrement;
1043
+
1044
+ //operating mode 0, HEAT, DRY, COOL, 4, 5, 6, FAN, AUTO, ISEE HEAT, ISEE DRY, ISEE COOL
1045
+ switch (this.displayMode) {
1046
+ case 1: //Heater Cooler
1047
+ switch (operationMode) {
1048
+ case 1: //HEAT
1049
+ this.accessory.currentOperationMode = roomTemperature > setTemperature ? 1 : 2; //INACTIVE, IDLE, HEATING, COOLING
1050
+ this.accessory.targetOperationMode = 1; //AUTO, HEAT, COOL
1051
+ break;
1052
+ case 2: //DRY
1053
+ this.accessory.currentOperationMode = 1;
1054
+ this.accessory.targetOperationMode = this.autoDryFanMode === 2 ? 0 : this.heatDryFanMode === 2 ? 1 : this.coolDryFanMode === 2 ? 2 : this.accessory.targetOperationMode ?? 0;
1055
+ break;
1056
+ case 3: //COOL
1057
+ this.accessory.currentOperationMode = roomTemperature < setTemperature ? 1 : 3;
1058
+ this.accessory.targetOperationMode = 2;
1059
+ break;
1060
+ case 7: //FAN
1061
+ this.accessory.currentOperationMode = 1;
1062
+ this.accessory.targetOperationMode = this.autoDryFanMode === 3 ? 0 : this.heatDryFanMode === 3 ? 1 : this.coolDryFanMode === 3 ? 2 : this.accessory.targetOperationMode ?? 0;
1063
+ break;
1064
+ case 8: //AUTO
1065
+ this.accessory.currentOperationMode = roomTemperature > setTemperature ? 3 : roomTemperature < setTemperature ? 2 : 1;
1066
+ this.accessory.targetOperationMode = 0;
1067
+ break;
1068
+ case 9: //ISEE HEAT
1069
+ this.accessory.currentOperationMode = roomTemperature > setTemperature ? 1 : 2
1070
+ this.accessory.targetOperationMode = 1;
1071
+ break;
1072
+ case 10: //ISEE DRY
1073
+ this.accessory.currentOperationMode = 1;
1074
+ this.accessory.targetOperationMode = this.autoDryFanMode === 2 ? 0 : this.heatDryFanMode === 2 ? 1 : this.coolDryFanMode === 2 ? 2 : this.accessory.targetOperationMode ?? 0;
1075
+ break;
1076
+ case 11: //ISEE COOL;
1077
+ this.accessory.currentOperationMode = roomTemperature < setTemperature ? 1 : 3;
1078
+ this.accessory.targetOperationMode = 2;
1079
+ break;
1080
+ default:
1081
+ this.emit('warn', `Unknown operating mode: ${operationMode}`);
1082
+ return
956
1083
  };
957
- });
958
- accessory.addService(this.melCloudService);
959
- break;
960
- case 2: //Thermostat
961
- const debug1 = this.enableDebugMode ? this.emit('debug', `Prepare thermostat service`) : false;
962
- this.melCloudService = new Service.Thermostat(serviceName, `Thermostat ${deviceId}`);
963
- this.melCloudService.getCharacteristic(Characteristic.CurrentHeatingCoolingState)
964
- .onGet(async () => {
965
- const value = this.accessory.currentOperationMode;
966
- return value;
967
- });
968
- this.melCloudService.getCharacteristic(Characteristic.TargetHeatingCoolingState)
969
- .setProps({
970
- minValue: this.accessory.operationModeSetPropsMinValue,
971
- maxValue: this.accessory.operationModeSetPropsMaxValue,
972
- validValues: this.accessory.operationModeSetPropsValidValues
973
- })
974
- .onGet(async () => {
975
- const value = this.accessory.targetOperationMode; //1 = HEAT, 2 = DRY 3 = COOL, 7 = FAN, 8 = AUTO
976
- return value;
977
- })
978
- .onSet(async (value) => {
979
- try {
980
- switch (value) {
981
- case 0: //OFF - POWER OFF
982
- deviceData.Device.Power = false;
983
- deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.Power;
1084
+
1085
+ this.accessory.currentOperationMode = !power ? 0 : inStandbyMode ? 1 : this.accessory.currentOperationMode;
1086
+ this.accessory.operationModeSetPropsMinValue = modelSupportsAuto && modelSupportsHeat ? 0 : !modelSupportsAuto && modelSupportsHeat ? 1 : modelSupportsAuto && !modelSupportsHeat ? 0 : 2;
1087
+ this.accessory.operationModeSetPropsMaxValue = 2
1088
+ this.accessory.operationModeSetPropsValidValues = modelSupportsAuto && modelSupportsHeat ? [0, 1, 2] : !modelSupportsAuto && modelSupportsHeat ? [1, 2] : modelSupportsAuto && !modelSupportsHeat ? [0, 2] : [2];
1089
+
1090
+ //fan speed mode
1091
+ if (modelSupportsFanSpeed) {
1092
+ switch (numberOfFanSpeeds) {
1093
+ case 2: //Fan speed mode 2
1094
+ this.accessory.fanSpeed = hasAutomaticFanSpeed ? [3, 1, 2][fanSpeed] : [0, 1, 2][fanSpeed];
1095
+ this.accessory.fanSpeedSetPropsMaxValue = hasAutomaticFanSpeed ? 3 : 2;
984
1096
  break;
985
- case 1: //HEAT - HEAT
986
- deviceData.Device.Power = true;
987
- deviceData.Device.OperationMode = heatDryFanMode;
988
- deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerOperationModeSetTemperature;
1097
+ case 3: //Fan speed mode 3
1098
+ this.accessory.fanSpeed = hasAutomaticFanSpeed ? [4, 1, 2, 3][fanSpeed] : [0, 1, 2, 3][fanSpeed];
1099
+ this.accessory.fanSpeedSetPropsMaxValue = hasAutomaticFanSpeed ? 4 : 3;
989
1100
  break;
990
- case 2: //COOL - COOL
991
- deviceData.Device.Power = true;
992
- deviceData.Device.OperationMode = coolDryFanMode;
993
- deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerOperationModeSetTemperature
1101
+ case 4: //Fan speed mode 4
1102
+ this.accessory.fanSpeed = hasAutomaticFanSpeed ? [5, 1, 2, 3, 4][fanSpeed] : [0, 1, 2, 3, 4][fanSpeed];
1103
+ this.accessory.fanSpeedSetPropsMaxValue = hasAutomaticFanSpeed ? 5 : 4;
994
1104
  break;
995
- case 3: //AUTO - AUTO
996
- deviceData.Device.Power = true;
997
- deviceData.Device.OperationMode = autoDryFanMode;
998
- deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerOperationModeSetTemperature;
1105
+ case 5: //Fan speed mode 5
1106
+ this.accessory.fanSpeed = hasAutomaticFanSpeed ? [6, 1, 2, 3, 4, 5][fanSpeed] : [0, 1, 2, 3, 4, 5][fanSpeed];
1107
+ this.accessory.fanSpeedSetPropsMaxValue = hasAutomaticFanSpeed ? 6 : 5;
1108
+ break;
1109
+ case 6: //Fan speed mode 6
1110
+ this.accessory.fanSpeed = hasAutomaticFanSpeed ? [7, 1, 2, 3, 4, 5, 6][fanSpeed] : [0, 1, 2, 3, 4, 5, 6][fanSpeed];
1111
+ this.accessory.fanSpeedSetPropsMaxValue = hasAutomaticFanSpeed ? 7 : 6;
999
1112
  break;
1000
1113
  };
1001
-
1002
- await this.melCloudAta.send(deviceData, this.displayMode);
1003
- const operationModeText = AirConditioner.DriveMode[deviceData.Device.OperationMode];
1004
- const info = this.disableLogInfo ? false : this.emit('message', `Set operation mode: ${operationModeText}`);
1005
- } catch (error) {
1006
- this.emit('warn', `Set operation mode error: ${error}`);
1007
- };
1008
- });
1009
- this.melCloudService.getCharacteristic(Characteristic.CurrentTemperature)
1010
- .onGet(async () => {
1011
- const value = this.accessory.roomTemperature;
1012
- return value;
1013
- });
1014
- this.melCloudService.getCharacteristic(Characteristic.TargetTemperature)
1015
- .setProps({
1016
- minValue: this.accessory.minTempHeat,
1017
- maxValue: this.accessory.maxTempHeat,
1018
- minStep: this.accessory.temperatureIncrement
1019
- })
1020
- .onGet(async () => {
1021
- const value = this.accessory.setTemperature;
1022
- return value;
1023
- })
1024
- .onSet(async (value) => {
1025
- try {
1026
- deviceData.Device.SetTemperature = value;
1027
- deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.SetTemperature;
1028
- await this.melCloudAta.send(deviceData, this.displayMode);
1029
- const info = this.disableLogInfo ? false : this.emit('message', `Set temperature: ${value}${this.accessory.temperatureUnit}`);
1030
- } catch (error) {
1031
- this.emit('warn', `Set temperature error: ${error}`);
1032
- };
1033
- });
1034
- this.melCloudService.getCharacteristic(Characteristic.TemperatureDisplayUnits)
1035
- .onGet(async () => {
1036
- const value = this.accessory.useFahrenheit;
1037
- return value;
1038
- })
1039
- .onSet(async (value) => {
1040
- try {
1041
- accountInfo.UseFahrenheit = [false, true][value];
1042
- await this.melCloud.send(accountInfo);
1043
- this.accessory.useFahrenheit = value;
1044
- const info = this.disableLogInfo ? false : this.emit('message', `Set temperature display unit: ${TemperatureDisplayUnits[value]}`);
1045
- } catch (error) {
1046
- this.emit('warn', `Set temperature display unit error: ${error}`);
1047
1114
  };
1048
- });
1049
- accessory.addService(this.melCloudService);
1050
- break;
1051
- };
1052
-
1053
- //temperature sensor services
1054
- if (this.temperatureSensor && this.accessory.roomTemperature !== null) {
1055
- const debug = this.enableDebugMode ? this.emit('debug', `Prepare room temperature sensor service`) : false;
1056
- this.roomTemperatureSensorService = new Service.TemperatureSensor(`${serviceName} Room`, `Room Temperature Sensor ${deviceId}`);
1057
- this.roomTemperatureSensorService.addOptionalCharacteristic(Characteristic.ConfiguredName);
1058
- this.roomTemperatureSensorService.setCharacteristic(Characteristic.ConfiguredName, `${accessoryName} Room`);
1059
- this.roomTemperatureSensorService.getCharacteristic(Characteristic.CurrentTemperature)
1060
- .setProps({
1061
- minValue: -35,
1062
- maxValue: 150,
1063
- minStep: 0.5
1064
- })
1065
- .onGet(async () => {
1066
- const state = this.accessory.roomTemperature;
1067
- return state;
1068
- })
1069
- accessory.addService(this.roomTemperatureSensorService);
1070
- };
1071
1115
 
1072
- if (this.temperatureSensorOutdoor && hasOutdoorTemperature && this.accessory.outdoorTemperature !== null) {
1073
- const debug = this.enableDebugMode ? this.emit('debug', `Prepare outdoor temperature sensor service`) : false;
1074
- this.outdoorTemperatureSensorService = new Service.TemperatureSensor(`${serviceName} Outdoor`, `Outdoor Temperature Sensor ${deviceId}`);
1075
- this.outdoorTemperatureSensorService.addOptionalCharacteristic(Characteristic.ConfiguredName);
1076
- this.outdoorTemperatureSensorService.setCharacteristic(Characteristic.ConfiguredName, `${accessoryName} Outdoor`);
1077
- this.outdoorTemperatureSensorService.getCharacteristic(Characteristic.CurrentTemperature)
1078
- .setProps({
1079
- minValue: -35,
1080
- maxValue: 150,
1081
- minStep: 0.5
1082
- })
1083
- .onGet(async () => {
1084
- const state = this.accessory.outdoorTemperature;
1085
- return state;
1086
- })
1087
- accessory.addService(this.outdoorTemperatureSensorService);
1088
- };
1116
+ //update characteristics
1117
+ if (this.melCloudService) {
1118
+ this.melCloudService
1119
+ .updateCharacteristic(Characteristic.Active, power ? 1 : 0)
1120
+ .updateCharacteristic(Characteristic.CurrentHeaterCoolerState, this.accessory.currentOperationMode)
1121
+ .updateCharacteristic(Characteristic.TargetHeaterCoolerState, this.accessory.targetOperationMode)
1122
+ .updateCharacteristic(Characteristic.CurrentTemperature, roomTemperature)
1123
+ .updateCharacteristic(Characteristic.LockPhysicalControls, this.accessory.lockPhysicalControl)
1124
+ .updateCharacteristic(Characteristic.TemperatureDisplayUnits, this.accessory.useFahrenheit)
1125
+ .updateCharacteristic(Characteristic.CoolingThresholdTemperature, defaultCoolingSetTemperature);
1126
+ const updateDefHeat = modelSupportsHeat ? this.melCloudService.updateCharacteristic(Characteristic.HeatingThresholdTemperature, defaultHeatingSetTemperature) : false;
1127
+ const updateRS = modelSupportsFanSpeed ? this.melCloudService.updateCharacteristic(Characteristic.RotationSpeed, this.accessory.fanSpeed) : false;
1128
+ const updateSM = swingFunction ? this.melCloudService.updateCharacteristic(Characteristic.SwingMode, this.accessory.swingMode) : false;
1129
+ };
1130
+ break;
1131
+ case 2: //Thermostat
1132
+ switch (operationMode) {
1133
+ case 1: //HEAT
1134
+ this.accessory.currentOperationMode = roomTemperature > setTemperature ? 0 : 1; //OFF, HEATING, COOLING
1135
+ this.accessory.targetOperationMode = 1; //OFF, HEAT, COOL, AUTO
1136
+ break;
1137
+ case 2: //DRY
1138
+ this.accessory.currentOperationMode = 0;
1139
+ this.accessory.targetOperationMode = this.autoDryFanMode === 2 ? 3 : this.heatDryFanMode === 2 ? 1 : this.coolDryFanMode === 2 ? 2 : this.accessory.targetOperationMode ?? 0;
1140
+ break;
1141
+ case 3: //COOL
1142
+ this.accessory.currentOperationMode = roomTemperature < setTemperature ? 0 : 2;
1143
+ this.accessory.targetOperationMode = 2;
1144
+ break;
1145
+ case 7: //FAN
1146
+ this.accessory.currentOperationMode = 0;
1147
+ this.accessory.targetOperationMode = this.autoDryFanMode === 3 ? 3 : this.heatDryFanMode === 3 ? 1 : this.coolDryFanMode === 3 ? 2 : this.accessory.targetOperationMode ?? 0;
1148
+ break;
1149
+ case 8: //AUTO
1150
+ this.accessory.currentOperationMode = roomTemperature < setTemperature ? 1 : roomTemperature > setTemperature ? 2 : 0;
1151
+ this.accessory.targetOperationMode = 3;
1152
+ break;
1153
+ case 9: //ISEE HEAT
1154
+ this.accessory.currentOperationMode = roomTemperature > setTemperature ? 0 : 1;
1155
+ this.accessory.targetOperationMode = 1;
1156
+ break;
1157
+ case 10: //ISEE DRY
1158
+ this.accessory.currentOperationMode = 0;
1159
+ this.accessory.targetOperationMode = this.autoDryFanMode === 2 ? 3 : this.heatDryFanMode === 2 ? 1 : this.coolDryFanMode === 2 ? 2 : this.accessory.targetOperationMode ?? 0;
1160
+ break;
1161
+ case 11: //ISEE COOL;
1162
+ this.accessory.currentOperationMode = roomTemperature < setTemperature ? 0 : 2;
1163
+ this.accessory.targetOperationMode = 2;
1164
+ break;
1165
+ default:
1166
+ this.emit('warn', `Unknown operating mode: ${operationMode}`);
1167
+ break;
1168
+ };
1089
1169
 
1090
- //presets services
1091
- if (this.presetsConfiguredCount > 0) {
1092
- const debug = this.enableDebugMode ? this.emit('debug', `Prepare presets services`) : false;
1093
- this.presetsServices = [];
1170
+ this.accessory.currentOperationMode = !power ? 0 : this.accessory.currentOperationMode;
1171
+ this.accessory.targetOperationMode = !power ? 0 : this.accessory.targetOperationMode;
1172
+ this.accessory.operationModeSetPropsMinValue = 0
1173
+ this.accessory.operationModeSetPropsMaxValue = modelSupportsAuto && modelSupportsHeat ? 3 : !modelSupportsAuto && modelSupportsHeat ? 2 : modelSupportsAuto && !modelSupportsHeat ? 3 : 2;
1174
+ this.accessory.operationModeSetPropsValidValues = modelSupportsAuto && modelSupportsHeat ? [0, 1, 2, 3] : !modelSupportsAuto && modelSupportsHeat ? [0, 1, 2] : modelSupportsAuto && !modelSupportsHeat ? [0, 2, 3] : [0, 2];
1094
1175
 
1095
- for (let i = 0; i < this.presetsConfiguredCount; i++) {
1096
- const preset = this.presetsConfigured[i];
1097
- const presetData = presetsOnServer.find(p => p.ID === preset.Id);
1176
+ //update characteristics
1177
+ if (this.melCloudService) {
1178
+ this.melCloudService
1179
+ .updateCharacteristic(Characteristic.CurrentHeatingCoolingState, this.accessory.currentOperationMode)
1180
+ .updateCharacteristic(Characteristic.TargetHeatingCoolingState, this.accessory.targetOperationMode)
1181
+ .updateCharacteristic(Characteristic.CurrentTemperature, roomTemperature)
1182
+ .updateCharacteristic(Characteristic.TargetTemperature, setTemperature)
1183
+ .updateCharacteristic(Characteristic.TemperatureDisplayUnits, this.accessory.useFahrenheit);
1184
+ };
1185
+ break;
1186
+ };
1098
1187
 
1099
- //get preset name
1100
- const presetName = preset.name;
1188
+ if (this.roomTemperatureSensorService) {
1189
+ this.roomTemperatureSensorService
1190
+ .updateCharacteristic(Characteristic.CurrentTemperature, roomTemperature)
1191
+ };
1101
1192
 
1102
- //get preset name prefix
1103
- const presetNamePrefix = preset.namePrefix;
1193
+ if (this.outdoorTemperatureSensorService) {
1194
+ this.outdoorTemperatureSensorService
1195
+ .updateCharacteristic(Characteristic.CurrentTemperature, outdoorTemperature)
1196
+ };
1104
1197
 
1105
- const serviceName = presetNamePrefix ? `${accessoryName} ${presetName}` : presetName;
1106
- const serviceType = preset.serviceType;
1107
- const characteristicType = preset.characteristicType;
1108
- const presetService = new serviceType(serviceName, `Preset ${deviceId} ${i}`);
1109
- presetService.addOptionalCharacteristic(Characteristic.ConfiguredName);
1110
- presetService.setCharacteristic(Characteristic.ConfiguredName, serviceName);
1111
- presetService.getCharacteristic(characteristicType)
1112
- .onGet(async () => {
1113
- const state = preset.state;
1114
- return state;
1115
- })
1116
- .onSet(async (state) => {
1117
- try {
1118
- switch (state) {
1119
- case true:
1120
- preset.previousSettings = deviceData.Device;
1121
- deviceData.Device.Power = presetData.Power;
1122
- deviceData.Device.OperationMode = presetData.OperationMode;
1123
- deviceData.Device.SetTemperature = presetData.SetTemperature;
1124
- deviceData.Device.VaneHorizontalDirection = presetData.VaneHorizontal;
1125
- deviceData.Device.VaneVerticalDirection = presetData.VaneVertical;
1126
- deviceData.Device.FanSpeed = presetData.FanSpeed;
1127
- deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.Presets;
1128
- break;
1129
- case false:
1130
- deviceData.Device.Power = preset.previousSettings.Power;
1131
- deviceData.Device.OperationMode = preset.previousSettings.OperationMode;
1132
- deviceData.Device.SetTemperature = preset.previousSettings.SetTemperature;
1133
- deviceData.Device.VaneHorizontalDirection = preset.previousSettings.VaneHorizontalDirection;
1134
- deviceData.Device.VaneVerticalDirection = preset.previousSettings.VaneVerticalDirection;
1135
- deviceData.Device.FanSpeed = preset.previousSettings.FanSpeed;
1136
- deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.Presets;
1137
- break;
1138
- };
1198
+ //update presets state
1199
+ if (this.presetsConfigured.length > 0) {
1200
+ for (let i = 0; i < this.presetsConfigured.length; i++) {
1201
+ const preset = this.presetsConfigured[i];
1202
+ const presetData = presetsOnServer.find(p => p.ID === preset.Id);
1139
1203
 
1140
- await this.melCloudAta.send(deviceData, this.displayMode);
1141
- const info = this.disableLogInfo ? false : this.emit('message', `${state ? 'Set:' : 'Unset:'} ${presetName}`);
1142
- } catch (error) {
1143
- this.emit('warn', `Set preset error: ${error}`);
1144
- };
1145
- });
1146
- this.presetsServices.push(presetService);
1147
- accessory.addService(presetService);
1148
- };
1149
- };
1204
+ preset.state = presetData ? (presetData.Power === power
1205
+ && presetData.SetTemperature === setTemperature
1206
+ && presetData.OperationMode === operationMode
1207
+ && presetData.VaneHorizontal === vaneHorizontalDirection
1208
+ && presetData.VaneVertical === vaneVerticalDirection
1209
+ && presetData.FanSpeed === fanSpeed) : false;
1150
1210
 
1151
- //buttons services
1152
- if (this.buttonsConfiguredCount > 0) {
1153
- const debug = this.enableDebugMode ? this.emit('debug', `Prepare buttons/sensors services`) : false;
1154
- this.buttonsServices = [];
1211
+ if (this.presetsServices) {
1212
+ const characteristicType = preset.characteristicType;
1213
+ this.presetsServices[i]
1214
+ .updateCharacteristic(characteristicType, preset.state)
1215
+ };
1216
+ };
1217
+ };
1155
1218
 
1156
- for (let i = 0; i < this.buttonsConfiguredCount; i++) {
1157
- const button = this.buttonsConfigured[i];
1219
+ //update buttons state
1220
+ if (this.buttonsConfiguredCount > 0) {
1221
+ for (let i = 0; i < this.buttonsConfiguredCount; i++) {
1222
+ const button = this.buttonsConfigured[i];
1223
+ const mode = button.mode;
1224
+ switch (mode) {
1225
+ case 0: //POWER ON,OFF
1226
+ button.state = (power === true);
1227
+ break;
1228
+ case 1: //OPERATING MODE HEAT
1229
+ button.state = power ? (operationMode === 1 || operationMode === 9) : false;
1230
+ break;
1231
+ case 2: //OPERATING MODE DRY
1232
+ button.state = power ? (operationMode === 2 || operationMode === 10) : false;
1233
+ break
1234
+ case 3: //OPERATING MODE COOL
1235
+ button.state = power ? (operationMode === 3 || operationMode === 11) : false;
1236
+ break;
1237
+ case 4: //OPERATING MODE FAN
1238
+ button.state = power ? (operationMode === 7) : false;
1239
+ break;
1240
+ case 5: //OPERATING MODE AUTO
1241
+ button.state = power ? (operationMode === 8) : false;
1242
+ break;
1243
+ case 6: //OPERATING MODE PURIFY
1244
+ button.state = power ? (operationMode === 12) : false;
1245
+ break;
1246
+ case 7: //OPERATING MODE DRY CONTROL HIDE
1247
+ button.state = power ? (hideDryModeControl === true) : false;
1248
+ break;
1249
+ case 10: //VANE H SWING MODE AUTO
1250
+ button.state = power ? (vaneHorizontalDirection === 0) : false;
1251
+ break;
1252
+ case 11: //VANE H SWING MODE 1
1253
+ button.state = power ? (vaneHorizontalDirection === 1) : false;
1254
+ break;
1255
+ case 12: //VANE H SWING MODE 2
1256
+ button.state = power ? (vaneHorizontalDirection === 2) : false;
1257
+ break;
1258
+ case 13: //VANE H SWING MODE 3
1259
+ button.state = power ? (vaneHorizontalDirection === 3) : false;
1260
+ break;
1261
+ case 14: //VANE H SWING MODE 4
1262
+ button.state = power ? (vaneHorizontalDirection === 4) : false;
1263
+ break;
1264
+ case 15: //VANE H SWING MODE 5
1265
+ button.state = power ? (vaneHorizontalDirection === 5) : false;
1266
+ break;
1267
+ case 16: //VANE H SWING MODE SPLIT
1268
+ button.state = power ? (vaneHorizontalDirection === 8) : false;
1269
+ break;
1270
+ case 17: //VANE H SWING MODE SWING
1271
+ button.state = power ? (vaneHorizontalDirection === 12) : false;
1272
+ break;
1273
+ case 20: //VANE V SWING MODE AUTO
1274
+ button.state = power ? (vaneVerticalDirection === 0) : false;
1275
+ break;
1276
+ case 21: //VANE V SWING MODE 1
1277
+ button.state = power ? (vaneVerticalDirection === 1) : false;
1278
+ break;
1279
+ case 22: //VANE V SWING MODE 2
1280
+ button.state = power ? (vaneVerticalDirection === 2) : false;
1281
+ break;
1282
+ case 23: //VANE V SWING MODE 3
1283
+ button.state = power ? (vaneVerticalDirection === 3) : false;
1284
+ break;
1285
+ case 24: //VANE V SWING MODE 4
1286
+ button.state = power ? (vaneVerticalDirection === 4) : false;
1287
+ break;
1288
+ case 25: //VANE V SWING MODE 5
1289
+ button.state = power ? (vaneVerticalDirection === 5) : false;
1290
+ break;
1291
+ case 26: //VANE V SWING MODE SWING
1292
+ button.state = power ? (vaneVerticalDirection === 7) : false;
1293
+ break;
1294
+ case 27: //VANE H/V CONTROLS HIDE
1295
+ button.state = power ? (hideVaneControls === true) : false;
1296
+ break;
1297
+ case 30: //FAN SPEED MODE AUTO
1298
+ button.state = power ? (fanSpeed === 0) : false;
1299
+ break;
1300
+ case 31: //FAN SPEED MODE 1
1301
+ button.state = power ? (fanSpeed === 1) : false;
1302
+ break;
1303
+ case 32: //FAN SPEED MODE 2
1304
+ button.state = power ? (fanSpeed === 2) : false;
1305
+ break;
1306
+ case 33: //FAN SPEED MODE 3
1307
+ button.state = power ? (fanSpeed === 3) : false;
1308
+ break;
1309
+ case 34: //FAN SPEED MODE 4
1310
+ button.state = power ? (fanSpeed === 4) : false;
1311
+ break;
1312
+ case 35: //FAN SPEED MODE 5
1313
+ button.state = power ? (fanSpeed === 5) : false;
1314
+ break;
1315
+ case 36: //FAN SPEED MODE 6
1316
+ button.state = power ? (fanSpeed === 6) : false;
1317
+ break;
1318
+ case 37: //PHYSICAL LOCK CONTROLS ALL
1319
+ button.state = (this.accessory.lockPhysicalControl === 1);
1320
+ break;
1321
+ case 38: //PHYSICAL LOCK CONTROLS POWER
1322
+ button.state = (prohibitPower === true);
1323
+ break;
1324
+ case 39: //PHYSICAL LOCK CONTROLS MODE
1325
+ button.state = (prohibitOperationMode === true);
1326
+ break;
1327
+ case 40: //PHYSICAL LOCK CONTROLS TEMP
1328
+ button.state = (prohibitSetTemperature === true);
1329
+ break;
1330
+ default: //Unknown button
1331
+ this.emit('message', `Unknown button mode: ${mode} detected.`);
1332
+ break;
1333
+ };
1158
1334
 
1159
- //get button mode
1160
- const mode = button.mode;
1335
+ //update services
1336
+ if (this.buttonsServices) {
1337
+ const characteristicType = button.characteristicType;
1338
+ this.buttonsServices[i]
1339
+ .updateCharacteristic(characteristicType, button.state)
1340
+ };
1341
+ };
1342
+ };
1161
1343
 
1162
- //get button name
1163
- const buttonName = button.name;
1344
+ //log current state
1345
+ if (!this.disableLogInfo) {
1346
+ this.emit('message', `Power: ${power ? 'ON' : 'OFF'}`);
1347
+ this.emit('message', `Target operation mode: ${AirConditioner.DriveMode[operationMode]}`);
1348
+ this.emit('message', `Current operation mode: ${this.displayMode === 1 ? AirConditioner.CurrentOperationModeHeatherCooler[this.accessory.currentOperationMode] : AirConditioner.CurrentOperationModeThermostat[this.accessory.currentOperationMode]}`);
1349
+ this.emit('message', `Target temperature: ${setTemperature}${this.accessory.temperatureUnit}`);
1350
+ this.emit('message', `Current temperature: ${roomTemperature}${this.accessory.temperatureUnit}`);
1351
+ const info = hasOutdoorTemperature && outdoorTemperature !== null ? this.emit('message', `Outdoor temperature: ${outdoorTemperature}${this.accessory.temperatureUnit}`) : false;
1352
+ const info3 = modelSupportsFanSpeed ? this.emit('message', `Target fan speed: ${AirConditioner.FanSpeed[fanSpeed]}`) : false;
1353
+ const info4 = modelSupportsFanSpeed ? this.emit('message', `Current fan speed: ${AirConditioner.FanSpeed[actualFanSpeed]}`) : false;
1354
+ const info5 = vaneHorizontalDirection !== null ? this.emit('message', `Vane horizontal: ${AirConditioner.HorizontalVane[vaneHorizontalDirection] ?? vaneHorizontalDirection}`) : false;
1355
+ const info6 = vaneVerticalDirection !== null ? this.emit('message', `Vane vertical: ${AirConditioner.VerticalVane[vaneVerticalDirection] ?? vaneVerticalDirection}`) : false;
1356
+ const info7 = swingFunction ? this.emit('message', `Air direction: ${AirConditioner.AirDirection[this.accessory.swingMode]}`) : false;
1357
+ this.emit('message', `Temperature display unit: ${this.accessory.temperatureUnit}`);
1358
+ this.emit('message', `Lock physical controls: ${this.accessory.lockPhysicalControl ? 'LOCKED' : 'UNLOCKED'}`);
1359
+ };
1164
1360
 
1165
- //get button name prefix
1166
- const buttonNamePrefix = button.namePrefix;
1361
+ //start prepare accessory
1362
+ if (!this.startPrepareAccessory) {
1363
+ return;
1364
+ }
1365
+ try {
1366
+ const accessory = await this.prepareAccessory(this.accountInfo, deviceData, this.deviceId, this.deviceTypeText, this.deviceName, this.accountName);
1367
+ this.emit('publishAccessory', accessory);
1368
+ this.startPrepareAccessory = false;
1369
+ } catch (error) {
1370
+ this.emit('error', error);
1371
+ };
1372
+ })
1373
+ .on('success', (success) => {
1374
+ this.emit('success', success);
1375
+ })
1376
+ .on('info', (info) => {
1377
+ this.emit('info', info);
1378
+ })
1379
+ .on('debug', (debug) => {
1380
+ this.emit('debug', debug);
1381
+ })
1382
+ .on('warn', (warn) => {
1383
+ this.emit('warn', warn);
1384
+ })
1385
+ .on('error', (error) => {
1386
+ this.emit('error', error);
1387
+ });
1167
1388
 
1168
- const serviceName = buttonNamePrefix ? `${accessoryName} ${buttonName}` : buttonName;
1169
- const serviceType = button.serviceType;
1170
- const characteristicType = button.characteristicType;
1171
- const buttonService = new serviceType(serviceName, `Button ${deviceId} ${i}`);
1172
- buttonService.addOptionalCharacteristic(Characteristic.ConfiguredName);
1173
- buttonService.setCharacteristic(Characteristic.ConfiguredName, serviceName);
1174
- buttonService.getCharacteristic(characteristicType)
1175
- .onGet(async () => {
1176
- const state = button.state;
1177
- return state;
1178
- })
1179
- .onSet(async (state) => {
1180
- try {
1181
- switch (mode) {
1182
- case 0: //POWER ON,OFF
1183
- deviceData.Device.Power = state;
1184
- deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.Power;
1185
- break;
1186
- case 1: //OPERATING MODE HEAT
1187
- button.previousValue = state ? deviceData.Device.OperationMode : button.previousValue ?? deviceData.Device.OperationMode;
1188
- deviceData.Device.Power = true;
1189
- deviceData.Device.OperationMode = state ? 1 : button.previousValue === 9 ? 1 : button.previousValue;
1190
- deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerOperationModeSetTemperature;
1191
- break;
1192
- case 2: //OPERATING MODE DRY
1193
- button.previousValue = state ? deviceData.Device.OperationMode : button.previousValue ?? deviceData.Device.OperationMode;
1194
- deviceData.Device.Power = true;
1195
- deviceData.Device.OperationMode = state ? 2 : button.previousValue === 10 ? 2 : button.previousValue;
1196
- deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerOperationModeSetTemperature;
1197
- break
1198
- case 3: //OPERATING MODE COOL
1199
- button.previousValue = state ? deviceData.Device.OperationMode : button.previousValue ?? deviceData.Device.OperationMode;
1200
- deviceData.Device.Power = true;
1201
- deviceData.Device.OperationMode = state ? 3 : button.previousValue === 11 ? 3 : button.previousValue;
1202
- deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerOperationModeSetTemperature;
1203
- break;
1204
- case 4: //OPERATING MODE FAN
1205
- button.previousValue = state ? deviceData.Device.OperationMode : button.previousValue ?? deviceData.Device.OperationMode;
1206
- deviceData.Device.Power = true;
1207
- deviceData.Device.OperationMode = state ? 7 : button.previousValue;
1208
- deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerOperationModeSetTemperature;
1209
- break;
1210
- case 5: //OPERATING MODE AUTO
1211
- button.previousValue = state ? deviceData.Device.OperationMode : button.previousValue ?? deviceData.Device.OperationMode;
1212
- deviceData.Device.Power = true;
1213
- deviceData.Device.OperationMode = state ? 8 : button.previousValue;
1214
- deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerOperationModeSetTemperature;
1215
- break;
1216
- case 6: //OPERATING MODE PURIFY
1217
- button.previousValue = state ? deviceData.Device.OperationMode : button.previousValue ?? deviceData.Device.OperationMode;
1218
- deviceData.Device.Power = true;
1219
- deviceData.Device.OperationMode = state ? 12 : button.previousValue;
1220
- deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerOperationModeSetTemperature;
1221
- break;
1222
- case 7: //OPERATING MODE DRY CONTROL HIDE
1223
- deviceData.HideDryModeControl = state;
1224
- break;
1225
- case 10: //VANE H SWING MODE AUTO
1226
- button.previousValue = state ? deviceData.Device.VaneHorizontalDirection : button.previousValue ?? deviceData.Device.VaneHorizontalDirection;
1227
- deviceData.Device.Power = true;
1228
- deviceData.Device.VaneHorizontalDirection = state ? 0 : button.previousValue;
1229
- deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerVaneHorizontal;
1230
- break;
1231
- case 11: //VANE H SWING MODE 1
1232
- button.previousValue = state ? deviceData.Device.VaneHorizontalDirection : button.previousValue ?? deviceData.Device.VaneHorizontalDirection;
1233
- deviceData.Device.Power = true;
1234
- deviceData.Device.VaneHorizontalDirection = state ? 1 : button.previousValue;
1235
- deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerVaneHorizontal;
1236
- break;
1237
- case 12: //VANE H SWING MODE 2
1238
- button.previousValue = state ? deviceData.Device.VaneHorizontalDirection : button.previousValue ?? deviceData.Device.VaneHorizontalDirection;
1239
- deviceData.Device.Power = true;
1240
- deviceData.Device.VaneHorizontalDirection = state ? 2 : button.previousValue;
1241
- deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerVaneHorizontal;
1242
- break;
1243
- case 13: //VANE H SWING MODE 3
1244
- button.previousValue = state ? deviceData.Device.VaneHorizontalDirection : button.previousValue ?? deviceData.Device.VaneHorizontalDirection;
1245
- deviceData.Device.Power = true;
1246
- deviceData.Device.VaneHorizontalDirection = state ? 3 : button.previousValue;
1247
- deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerVaneHorizontal;
1248
- break;
1249
- case 14: //VANE H SWING MODE 4
1250
- button.previousValue = state ? deviceData.Device.VaneHorizontalDirection : button.previousValue ?? deviceData.Device.VaneHorizontalDirection;
1251
- deviceData.Device.Power = true;
1252
- deviceData.Device.VaneHorizontalDirection = state ? 4 : button.previousValue;
1253
- deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerVaneHorizontal;
1254
- break;
1255
- case 15: //VANE H SWING MODE 5
1256
- button.previousValue = state ? deviceData.Device.VaneHorizontalDirection : button.previousValue ?? deviceData.Device.VaneHorizontalDirection;
1257
- deviceData.Device.Power = true;
1258
- deviceData.Device.VaneHorizontalDirection = state ? 5 : button.previousValue;
1259
- deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerVaneHorizontal;
1260
- break;
1261
- case 16: //VANE H SWING MODE SPLIT
1262
- button.previousValue = state ? deviceData.Device.VaneHorizontalDirection : button.previousValue ?? deviceData.Device.VaneHorizontalDirection;
1263
- deviceData.Device.Power = true;
1264
- deviceData.Device.VaneHorizontalDirection = state ? 8 : button.previousValue;
1265
- deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerVaneHorizontal;
1266
- break;
1267
- case 17: //VANE H SWING MODE SWING
1268
- button.previousValue = state ? deviceData.Device.VaneHorizontalDirection : button.previousValue ?? deviceData.Device.VaneHorizontalDirection;
1269
- deviceData.Device.Power = true;
1270
- deviceData.Device.VaneHorizontalDirection = state ? 12 : button.previousValue;
1271
- deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerVaneHorizontal;
1272
- break;
1273
- case 20: //VANE V SWING MODE AUTO
1274
- button.previousValue = state ? deviceData.Device.VaneVerticalDirection : button.previousValue ?? deviceData.Device.VaneVerticalDirection;
1275
- deviceData.Device.Power = true;
1276
- deviceData.Device.VaneVerticalDirection = state ? 0 : button.previousValue;
1277
- deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerVaneVertical;
1278
- break;
1279
- case 21: //VANE V SWING MODE 1
1280
- button.previousValue = state ? deviceData.Device.VaneVerticalDirection : button.previousValue ?? deviceData.Device.VaneVerticalDirection;
1281
- deviceData.Device.Power = true;
1282
- deviceData.Device.VaneVerticalDirection = state ? 1 : button.previousValue;
1283
- deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerVaneVertical;
1284
- break;
1285
- case 22: //VANE V SWING MODE 2
1286
- button.previousValue = state ? deviceData.Device.VaneVerticalDirection : button.previousValue ?? deviceData.Device.VaneVerticalDirection;
1287
- deviceData.Device.Power = true;
1288
- deviceData.Device.VaneVerticalDirection = state ? 2 : button.previousValue;
1289
- deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerVaneVertical;
1290
- break;
1291
- case 23: //VANE V SWING MODE 3
1292
- button.previousValue = state ? deviceData.Device.VaneVerticalDirection : button.previousValue ?? deviceData.Device.VaneVerticalDirection;
1293
- deviceData.Device.Power = true;
1294
- deviceData.Device.VaneVerticalDirection = state ? 3 : button.previousValue;
1295
- deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerVaneVertical;
1296
- break;
1297
- case 24: //VANE V SWING MODE 4
1298
- button.previousValue = state ? deviceData.Device.VaneVerticalDirection : button.previousValue ?? deviceData.Device.VaneVerticalDirection;
1299
- deviceData.Device.Power = true;
1300
- deviceData.Device.VaneVerticalDirection = state ? 4 : button.previousValue;
1301
- deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerVaneVertical;
1302
- break;
1303
- case 25: //VANE V SWING MODE 5
1304
- button.previousValue = state ? deviceData.Device.VaneVerticalDirection : button.previousValue ?? deviceData.Device.VaneVerticalDirection;
1305
- deviceData.Device.Power = true;
1306
- deviceData.Device.VaneVerticalDirection = state ? 5 : button.previousValue;
1307
- deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerVaneVertical;
1308
- break;
1309
- case 26: //VANE V SWING MODE SWING
1310
- button.previousValue = state ? deviceData.Device.VaneVerticalDirection : button.previousValue ?? deviceData.Device.VaneVerticalDirection;
1311
- deviceData.Device.Power = true;
1312
- deviceData.Device.VaneVerticalDirection = state ? 7 : button.previousValue;
1313
- deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerVaneVertical;
1314
- break;
1315
- case 27: //VANE H/V CONTROLS HIDE
1316
- deviceData.HideVaneControls = state;
1317
- break;
1318
- case 30: //FAN SPEED MODE AUTO
1319
- button.previousValue = state ? deviceData.Device.FanSpeed : button.previousValue ?? deviceData.Device.FanSpeed;
1320
- deviceData.Device.Power = true;
1321
- deviceData.Device.FanSpeed = state ? 0 : button.previousValue;
1322
- deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerSetFanSpeed;
1323
- break;
1324
- case 31: //FAN SPEED MODE 1
1325
- button.previousValue = state ? deviceData.Device.FanSpeed : button.previousValue ?? deviceData.Device.FanSpeed;
1326
- deviceData.Device.Power = true;
1327
- deviceData.Device.FanSpeed = state ? 1 : button.previousValue;
1328
- deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerSetFanSpeed;
1329
- break;
1330
- case 32: //FAN SPEED MODE 2
1331
- button.previousValue = state ? deviceData.Device.FanSpeed : button.previousValue ?? deviceData.Device.FanSpeed;
1332
- deviceData.Device.Power = true;
1333
- deviceData.Device.FanSpeed = state ? 2 : button.previousValue;
1334
- deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerSetFanSpeed;
1335
- break;
1336
- case 33: //FAN SPEED MODE 3
1337
- button.previousValue = state ? deviceData.Device.FanSpeed : button.previousValue ?? deviceData.Device.FanSpeed;
1338
- deviceData.Device.Power = true;
1339
- deviceData.Device.FanSpeed = state ? 3 : button.previousValue;
1340
- deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerSetFanSpeed;
1341
- break;
1342
- case 34: //FAN MODE 4
1343
- button.previousValue = state ? deviceData.Device.FanSpeed : button.previousValue ?? deviceData.Device.FanSpeed;
1344
- deviceData.Device.Power = true;
1345
- deviceData.Device.FanSpeed = state ? 4 : button.previousValue;
1346
- deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerSetFanSpeed;
1347
- break;
1348
- case 35: //FAN SPEED MODE 5
1349
- button.previousValue = state ? deviceData.Device.FanSpeed : button.previousValue ?? deviceData.Device.FanSpeed;
1350
- deviceData.Device.Power = true;
1351
- deviceData.Device.FanSpeed = state ? 5 : button.previousValue;
1352
- deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerSetFanSpeed;
1353
- break;
1354
- case 36: //FAN SPEED MODE 6
1355
- button.previousValue = state ? deviceData.Device.FanSpeed : button.previousValue ?? deviceData.Device.FanSpeed;
1356
- deviceData.Device.Power = true;
1357
- deviceData.Device.FanSpeed = state ? 6 : button.previousValue;
1358
- deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.PowerSetFanSpeed;
1359
- break;
1360
- case 37: //PHYSICAL LOCK CONTROLS
1361
- deviceData.Device.ProhibitSetTemperature = state;
1362
- deviceData.Device.ProhibitOperationMode = state;
1363
- deviceData.Device.ProhibitPower = state;
1364
- deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.Prohibit;
1365
- break;
1366
- case 38: //PHYSICAL LOCK CONTROLS POWER
1367
- deviceData.Device.ProhibitPower = state;
1368
- deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.Prohibit;
1369
- break;
1370
- case 39: //PHYSICAL LOCK CONTROLS MODE
1371
- deviceData.Device.ProhibitOperationMode = state;
1372
- deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.Prohibit;
1373
- break;
1374
- case 40: //PHYSICAL LOCK CONTROLS TEMP
1375
- deviceData.Device.ProhibitSetTemperature = state;
1376
- deviceData.Device.EffectiveFlags = AirConditioner.EffectiveFlags.Prohibit;
1377
- break;
1378
- default:
1379
- this.emit('message', `Unknown button mode: ${mode}`);
1380
- break;
1381
- };
1389
+ //check state
1390
+ await this.melCloudAta.checkState();
1382
1391
 
1383
- await this.melCloudAta.send(deviceData, this.displayMode);
1384
- const info = this.disableLogInfo ? false : this.emit('message', `${state ? `Set: ${buttonName}` : `Unset: ${buttonName}, Set: ${button.previousValue}`}`);
1385
- } catch (error) {
1386
- this.emit('warn', `Set button error: ${error}`);
1387
- };
1388
- });
1389
- this.buttonsServices.push(buttonService);
1390
- accessory.addService(buttonService);
1391
- };
1392
- };
1392
+ //start impule generator
1393
+ await this.melCloudAta.impulseGenerator.start([{ name: 'checkState', sampling: this.refreshInterval }]);
1393
1394
 
1394
- return accessory;
1395
+ return true;
1395
1396
  } catch (error) {
1396
- throw new Error(`Prepare accessory error: ${error.message || error}`);
1397
+ throw new Error(`Start error: ${error}`);
1397
1398
  };
1398
1399
  };
1399
1400
  };