homebridge-gree-ac 1.0.1 → 2.0.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.
@@ -0,0 +1,867 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.GreeAirConditioner = void 0;
7
+ const dgram_1 = __importDefault(require("dgram"));
8
+ const settings_1 = require("./settings");
9
+ const crypto_1 = __importDefault(require("./crypto"));
10
+ const commands_1 = __importDefault(require("./commands"));
11
+ /**
12
+ * Platform Accessory
13
+ * An instance of this class is created for each accessory your platform registers
14
+ * Each accessory may expose multiple services of different service types.
15
+ */
16
+ class GreeAirConditioner {
17
+ constructor(platform, accessory, deviceConfig, port, platform_ts) {
18
+ var _a, _b, _c;
19
+ this.platform = platform;
20
+ this.accessory = accessory;
21
+ this.deviceConfig = deviceConfig;
22
+ this.port = port;
23
+ this.platform_ts = platform_ts;
24
+ // device communication functions
25
+ this.handleMessage = (msg, rinfo) => {
26
+ if (this.accessory.context.device.address === rinfo.address) {
27
+ const message = JSON.parse(msg.toString());
28
+ this.platform.log.debug(`[${this.getDeviceLabel()}] handleMessage -> %j`, message);
29
+ const pack = crypto_1.default.decrypt(message.pack, message.i === 1 ? undefined : this.key);
30
+ switch (pack.t) {
31
+ case 'bindok': // package type is binding confirmation
32
+ this.key = pack.key;
33
+ this.bound = true;
34
+ this.platform.log.debug(`[${this.getDeviceLabel()}] Package (Device binding) -> %j`, pack);
35
+ this.platform.log.info(`[${this.getDeviceLabel()}] Device is bound -> ${this.key}`);
36
+ if (this.updateTimer) {
37
+ clearInterval(this.updateTimer);
38
+ }
39
+ this.requestDeviceStatus();
40
+ this.updateTimer = setInterval(this.requestDeviceStatus.bind(this), this.deviceConfig.statusUpdateInterval * 1000); // statusUpdateInterval in seconds
41
+ break;
42
+ case 'dat': // package type is device status
43
+ if (this.bound) {
44
+ pack.cols.forEach((col, i) => {
45
+ this.status[col] = pack.dat[i];
46
+ });
47
+ this.platform.log.debug(`[${this.getDeviceLabel()}] Package (Device status) -> %j`, pack);
48
+ if (!pack.cols.includes(commands_1.default.temperature.code) &&
49
+ pack.cols.includes(commands_1.default.targetTemperature.code)) {
50
+ // temperature is not accessible -> use targetTemperature
51
+ this.status[commands_1.default.temperature.code] = this.status[commands_1.default.targetTemperature.code] + this.deviceConfig.sensorOffset;
52
+ if (this.TemperatureSensor !== undefined) {
53
+ this.accessory.removeService(this.TemperatureSensor);
54
+ this.TemperatureSensor = undefined;
55
+ this.platform.log.debug(`[${this.getDeviceLabel()}] temperature is not accessible -> Temperature Sensor removed`);
56
+ }
57
+ }
58
+ this.updateStatus(pack.cols);
59
+ }
60
+ break;
61
+ case 'res': // package type is response
62
+ if (this.bound) {
63
+ this.platform.log.debug(`[${this.getDeviceLabel()}] Package (Device response) -> %j`, pack);
64
+ const updatedParams = [];
65
+ pack.opt.forEach((opt, i) => {
66
+ const value = pack.p !== undefined ? pack.p[i] : pack.val[i];
67
+ if (this.status[opt] !== value) {
68
+ updatedParams.push(`${this.getKeyName(commands_1.default, opt, 'code')}: ${this.status[opt]} -> ${value}`);
69
+ }
70
+ this.status[opt] = value;
71
+ });
72
+ if (updatedParams.length > 0) {
73
+ this.platform.log.info(`[${this.getDeviceLabel()}] Device updated (%j)`, updatedParams);
74
+ }
75
+ }
76
+ break;
77
+ }
78
+ }
79
+ };
80
+ this.platform.log.debug(`[${this.getDeviceLabel()}] deviceConfig -> %j`, deviceConfig);
81
+ // set accessory information
82
+ this.accessory.getService(this.platform.Service.AccessoryInformation)
83
+ .setCharacteristic(this.platform.Characteristic.Manufacturer, this.accessory.context.device.brand || 'Gree')
84
+ .setCharacteristic(this.platform.Characteristic.Model, ((_a = this.deviceConfig) === null || _a === void 0 ? void 0 : _a.model) || this.accessory.context.device.model || this.accessory.context.device.name || 'Air Conditioner')
85
+ .setCharacteristic(this.platform.Characteristic.SerialNumber, this.accessory.context.device.mac)
86
+ .setCharacteristic(this.platform.Characteristic.FirmwareRevision, this.accessory.context.device.hid && this.accessory.context.device.hid.lastIndexOf('V') >= 0 &&
87
+ this.accessory.context.device.hid.lastIndexOf('V') < this.accessory.context.device.hid.lastIndexOf('.') ?
88
+ this.accessory.context.device.hid.substring(this.accessory.context.device.hid.lastIndexOf('V') + 1, this.accessory.context.device.hid.lastIndexOf('.')) : '1.0.0')
89
+ .setCharacteristic(this.platform.Characteristic.HardwareRevision, this.accessory.context.device.ver ?
90
+ this.accessory.context.device.ver.substring(this.accessory.context.device.ver.lastIndexOf('V') + 1) : '1.0.0');
91
+ // get the HeaterCooler service if it exists, otherwise create a new HeaterCooler service
92
+ // we don't use subtype because we add only one service with this type
93
+ this.HeaterCooler = this.accessory.getService(this.platform.Service.HeaterCooler) ||
94
+ this.accessory.addService(this.platform.Service.HeaterCooler, this.accessory.displayName, undefined);
95
+ this.HeaterCooler.displayName = this.accessory.displayName;
96
+ if (deviceConfig.temperatureSensor === 'child') {
97
+ this.platform.log.debug(`[${this.getDeviceLabel()}] Add Temperature Sensor child service`);
98
+ this.TemperatureSensor = this.accessory.getService(this.platform.Service.TemperatureSensor) ||
99
+ this.accessory.addService(this.platform.Service.TemperatureSensor, 'Temperature Sensor - ' + this.accessory.displayName, undefined);
100
+ this.TemperatureSensor.displayName = 'Temperature Sensor - ' + this.accessory.displayName;
101
+ }
102
+ else {
103
+ const ts = this.accessory.getService(this.platform.Service.TemperatureSensor);
104
+ this.platform.log.debug(`[${this.getDeviceLabel()}] Temperature Sensor child service not allowed (%s)`, ts === null || ts === void 0 ? void 0 : ts.displayName);
105
+ if (ts !== undefined) {
106
+ this.platform.log.debug(`[${this.getDeviceLabel()}] Remove Temperature Sensor child service (%s)`, ts.displayName);
107
+ this.accessory.removeService(ts);
108
+ }
109
+ }
110
+ this.HeaterCooler.setPrimaryService(true);
111
+ (_b = this.TemperatureSensor) === null || _b === void 0 ? void 0 : _b.setPrimaryService(false);
112
+ // each service must implement at-minimum the "required characteristics" for the given service type
113
+ // see https://developers.homebridge.io/#/service/HeaterCooler
114
+ // register handlers for the Active Characteristic
115
+ this.HeaterCooler.getCharacteristic(this.platform.Characteristic.Active)
116
+ .onSet(this.setActive.bind(this))
117
+ .onGet(this.getActive.bind(this));
118
+ // register handlers for the Current Heater-Cooler State Characteristic
119
+ this.HeaterCooler.getCharacteristic(this.platform.Characteristic.CurrentHeaterCoolerState)
120
+ .onGet(this.getCurrentHeaterCoolerState.bind(this));
121
+ // register handlers for the Target Heater-Cooler State Characteristic
122
+ this.HeaterCooler.getCharacteristic(this.platform.Characteristic.TargetHeaterCoolerState)
123
+ .onGet(this.getTargetHeaterCoolerState.bind(this))
124
+ .onSet(this.setTargetHeaterCoolerState.bind(this));
125
+ // register handlers for the Current Temperature Characteristic
126
+ this.HeaterCooler.getCharacteristic(this.platform.Characteristic.CurrentTemperature)
127
+ .onGet(this.getCurrentTemperature.bind(this, 'Heater Cooler'));
128
+ (_c = this.TemperatureSensor) === null || _c === void 0 ? void 0 : _c.getCharacteristic(this.platform.Characteristic.CurrentTemperature).onGet(this.getCurrentTemperature.bind(this, 'Temperature Sensor'));
129
+ // register handlers for the Cooling Threshold Temperature Characteristic
130
+ this.HeaterCooler.getCharacteristic(this.platform.Characteristic.CoolingThresholdTemperature)
131
+ .setProps({
132
+ minValue: this.deviceConfig.minimumTargetTemperature,
133
+ maxValue: this.deviceConfig.maximumTargetTemperature,
134
+ minStep: 0.5
135
+ })
136
+ .onGet(this.getTargetTemperature.bind(this, 'CoolingThresholdTemperature'))
137
+ .onSet(this.setTargetTemperature.bind(this));
138
+ // register handlers for the Heating Threshold Temperature Characteristic
139
+ this.HeaterCooler.getCharacteristic(this.platform.Characteristic.HeatingThresholdTemperature)
140
+ .setProps({
141
+ minValue: this.deviceConfig.minimumTargetTemperature,
142
+ maxValue: this.deviceConfig.maximumTargetTemperature,
143
+ minStep: 0.5
144
+ })
145
+ .onGet(this.getTargetTemperature.bind(this, 'HeatingThresholdTemperature'))
146
+ .onSet(this.setTargetTemperature.bind(this));
147
+ // register handlers for the Temperature Display Units Characteristic
148
+ this.HeaterCooler.getCharacteristic(this.platform.Characteristic.TemperatureDisplayUnits)
149
+ .onGet(this.getTemperatureDisplayUnits.bind(this))
150
+ .onSet(this.setTemperatureDisplayUnits.bind(this));
151
+ // register handlers for the Swing Mode Characteristic
152
+ this.HeaterCooler.getCharacteristic(this.platform.Characteristic.SwingMode)
153
+ .onGet(this.getSwingMode.bind(this))
154
+ .onSet(this.setSwingMode.bind(this));
155
+ // register handlers for the Rotation Speed Characteristic
156
+ this.HeaterCooler.getCharacteristic(this.platform.Characteristic.RotationSpeed)
157
+ .setProps({
158
+ minValue: 0,
159
+ maxValue: this.deviceConfig.speedSteps + 3,
160
+ minStep: 1
161
+ })
162
+ .onGet(this.getRotationSpeed.bind(this))
163
+ .onSet(this.setRotationSpeed.bind(this));
164
+ // initialize communication with device
165
+ this.status = {};
166
+ this.bound = false;
167
+ this.socket = dgram_1.default.createSocket({ type: 'udp4', reuseAddr: true });
168
+ this.socket.on('error', (err) => {
169
+ this.platform.log.error(`[${this.getDeviceLabel()}] Network error:`, err.message);
170
+ });
171
+ this.socket.on('message', this.handleMessage);
172
+ this.socket.bind(this.port + parseInt(this.accessory.context.device.address.split('.')[3]) + 1, '0.0.0.0', () => {
173
+ this.socket.setBroadcast(false);
174
+ this.sendBindRequest();
175
+ });
176
+ }
177
+ /**
178
+ * Handle "SET" requests from HomeKit
179
+ * These are sent when the user changes the state of an accessory
180
+ */
181
+ async setActive(value) {
182
+ const powerValue = (value === this.platform.Characteristic.Active.ACTIVE);
183
+ this.platform.log.debug(`[${this.getDeviceLabel()}] Set Active ->`, powerValue ? 'ACTIVE' : 'INACTIVE');
184
+ this.power = powerValue;
185
+ }
186
+ async setTargetHeaterCoolerState(value) {
187
+ let modeValue = commands_1.default.mode.value.auto;
188
+ let logValue = 'AUTO';
189
+ switch (value) {
190
+ case this.platform.Characteristic.TargetHeaterCoolerState.COOL:
191
+ modeValue = commands_1.default.mode.value.cool;
192
+ logValue = 'COOL';
193
+ break;
194
+ case this.platform.Characteristic.TargetHeaterCoolerState.HEAT:
195
+ modeValue = commands_1.default.mode.value.heat;
196
+ logValue = 'HEAT';
197
+ break;
198
+ }
199
+ this.platform.log.debug(`[${this.getDeviceLabel()}] Set TargetHeaterCoolerState ->`, logValue);
200
+ this.mode = modeValue;
201
+ }
202
+ async setTargetTemperature(value) {
203
+ this.platform.log.debug(`[${this.getDeviceLabel()}] Set ThresholdTemperature ->`, value);
204
+ this.targetTemperature = value;
205
+ }
206
+ async setTemperatureDisplayUnits(value) {
207
+ const logValue = (value === this.platform.Characteristic.TemperatureDisplayUnits.CELSIUS) ? 'CELSIUS' : 'FAHRENHEIT';
208
+ this.platform.log.debug(`[${this.getDeviceLabel()}] Set TemperatureDisplayUnits ->`, logValue);
209
+ this.units = (value === this.platform.Characteristic.TemperatureDisplayUnits.CELSIUS) ?
210
+ commands_1.default.units.value.celsius : commands_1.default.units.value.fahrenheit;
211
+ }
212
+ async setSwingMode(value) {
213
+ const logValue = (value === this.platform.Characteristic.SwingMode.SWING_ENABLED) ? 'ENABLED' : 'DISABLED';
214
+ this.platform.log.debug(`[${this.getDeviceLabel()}] Set SwingMode ->`, logValue);
215
+ this.swingMode = (value === this.platform.Characteristic.SwingMode.SWING_ENABLED) ?
216
+ commands_1.default.swingVertical.value.full : commands_1.default.swingVertical.value.default;
217
+ }
218
+ async setRotationSpeed(value) {
219
+ switch (value) {
220
+ case 1: // quiet
221
+ this.platform.log.debug(`[${this.getDeviceLabel()}] Set RotationSpeed ->`, value + ' (quiet)');
222
+ this.quietMode = commands_1.default.quietMode.value.on;
223
+ break;
224
+ case 2: // auto
225
+ this.platform.log.debug(`[${this.getDeviceLabel()}] Set RotationSpeed ->`, value +
226
+ ' (' + this.getKeyName(commands_1.default.speed.value, commands_1.default.speed.value.auto) + ')');
227
+ this.speed = commands_1.default.speed.value.auto;
228
+ break;
229
+ case 3: // low
230
+ this.platform.log.debug(`[${this.getDeviceLabel()}] Set RotationSpeed ->`, value +
231
+ ' (' + this.getKeyName(commands_1.default.speed.value, commands_1.default.speed.value.low) + ')');
232
+ this.speed = commands_1.default.speed.value.low;
233
+ break;
234
+ case 4: // mediumLow / medium
235
+ this.platform.log.debug(`[${this.getDeviceLabel()}] Set RotationSpeed ->`, value + ' (' +
236
+ this.getKeyName(commands_1.default.speed.value, (this.deviceConfig.speedSteps === 5) ? commands_1.default.speed.value.mediumLow : commands_1.default.speed.value.medium) + ')');
237
+ this.speed = (this.deviceConfig.speedSteps === 5) ? commands_1.default.speed.value.mediumLow : commands_1.default.speed.value.medium;
238
+ break;
239
+ case 5: // medium / high
240
+ this.platform.log.debug(`[${this.getDeviceLabel()}] Set RotationSpeed ->`, value + ' (' +
241
+ this.getKeyName(commands_1.default.speed.value, (this.deviceConfig.speedSteps === 5) ? commands_1.default.speed.value.medium : commands_1.default.speed.value.high) + ')');
242
+ this.speed = (this.deviceConfig.speedSteps === 5) ? commands_1.default.speed.value.medium : commands_1.default.speed.value.high;
243
+ break;
244
+ case 6: // mediumHigh / powerful
245
+ if (this.deviceConfig.speedSteps === 5) {
246
+ // mediumHigh
247
+ this.platform.log.debug(`[${this.getDeviceLabel()}] Set RotationSpeed ->`, value +
248
+ ' (' + this.getKeyName(commands_1.default.speed.value, commands_1.default.speed.value.mediumHigh) + ')');
249
+ this.speed = commands_1.default.speed.value.mediumHigh;
250
+ }
251
+ else {
252
+ // powerful
253
+ this.platform.log.debug(`[${this.getDeviceLabel()}] Set RotationSpeed ->`, value + ' (powerful)');
254
+ this.powerfulMode = commands_1.default.powerfulMode.value.on;
255
+ }
256
+ break;
257
+ case 7: // high
258
+ this.platform.log.debug(`[${this.getDeviceLabel()}] Set RotationSpeed ->`, value +
259
+ ' (' + this.getKeyName(commands_1.default.speed.value, commands_1.default.speed.value.high) + ')');
260
+ this.speed = commands_1.default.speed.value.high;
261
+ break;
262
+ case 8: // powerful
263
+ this.platform.log.debug(`[${this.getDeviceLabel()}] Set RotationSpeed ->`, value + ' (powerful)');
264
+ this.powerfulMode = commands_1.default.powerfulMode.value.on;
265
+ break;
266
+ default: // auto
267
+ this.platform.log.debug(`[${this.getDeviceLabel()}] Set RotationSpeed ->`, value +
268
+ ' (' + this.getKeyName(commands_1.default.speed.value, commands_1.default.speed.value.auto) + ')');
269
+ this.speed = commands_1.default.speed.value.auto;
270
+ break;
271
+ }
272
+ }
273
+ /**
274
+ * Handle the "GET" requests from HomeKit
275
+ * These are sent when HomeKit wants to know the current state of the accessory
276
+ *
277
+ * GET requests should return as fast as possbile. A long delay here will result in
278
+ * HomeKit being unresponsive and a bad user experience in general.
279
+ *
280
+ * If your device takes time to respond you should update the status of your device
281
+ * asynchronously instead using the `updateCharacteristic` method instead.
282
+
283
+ * @example
284
+ * this.service.updateCharacteristic(this.platform.Characteristic.On, true)
285
+
286
+ * if you need to return an error to show the device as "Not Responding" in the Home app:
287
+ * throw new this.platform.api.hap.HapStatusError(this.platform.api.hap.HAPStatus.SERVICE_COMMUNICATION_FAILURE);
288
+ */
289
+ async getActive() {
290
+ const currentPower = this.power;
291
+ this.platform.log.debug(`[${this.getDeviceLabel()}] Get Active ->`, currentPower ? 'ACTIVE' : 'INACTIVE');
292
+ return currentPower ?
293
+ this.platform.Characteristic.Active.ACTIVE : this.platform.Characteristic.Active.INACTIVE;
294
+ }
295
+ async getCurrentHeaterCoolerState() {
296
+ if (this.power) {
297
+ switch (this.mode) {
298
+ case commands_1.default.mode.value.cool:
299
+ this.platform.log.debug(`[${this.getDeviceLabel()}] Get CurrentHeaterCoolerState ->`, 'COOLING');
300
+ return this.platform.Characteristic.CurrentHeaterCoolerState.COOLING;
301
+ case commands_1.default.mode.value.heat:
302
+ this.platform.log.debug(`[${this.getDeviceLabel()}] Get CurrentHeaterCoolerState ->`, 'HEATING');
303
+ return this.platform.Characteristic.CurrentHeaterCoolerState.HEATING;
304
+ case commands_1.default.mode.value.fan:
305
+ case commands_1.default.mode.value.dry:
306
+ this.platform.log.debug(`[${this.getDeviceLabel()}] Get CurrentHeaterCoolerState ->`, 'IDLE');
307
+ return this.platform.Characteristic.CurrentHeaterCoolerState.IDLE;
308
+ case commands_1.default.mode.value.auto:
309
+ if (this.currentTemperature > this.status[commands_1.default.targetTemperature.code]) {
310
+ this.platform.log.debug(`[${this.getDeviceLabel()}] Get CurrentHeaterCoolerState ->`, 'COOLING');
311
+ return this.platform.Characteristic.CurrentHeaterCoolerState.COOLING;
312
+ }
313
+ if (this.currentTemperature < this.status[commands_1.default.targetTemperature.code]) {
314
+ this.platform.log.debug(`[${this.getDeviceLabel()}] Get CurrentHeaterCoolerState ->`, 'HEATING');
315
+ return this.platform.Characteristic.CurrentHeaterCoolerState.HEATING;
316
+ }
317
+ this.platform.log.debug(`[${this.getDeviceLabel()}] Get CurrentHeaterCoolerState ->`, 'IDLE');
318
+ return this.platform.Characteristic.CurrentHeaterCoolerState.IDLE;
319
+ }
320
+ }
321
+ this.platform.log.debug(`[${this.getDeviceLabel()}] Get CurrentHeaterCoolerState ->`, 'INACTIVE');
322
+ return this.platform.Characteristic.CurrentHeaterCoolerState.INACTIVE;
323
+ }
324
+ async getTargetHeaterCoolerState() {
325
+ switch (this.mode) {
326
+ case commands_1.default.mode.value.cool:
327
+ this.platform.log.debug(`[${this.getDeviceLabel()}] Get TargetHeaterCoolerState ->`, 'COOL');
328
+ return this.platform.Characteristic.TargetHeaterCoolerState.COOL;
329
+ case commands_1.default.mode.value.heat:
330
+ this.platform.log.debug(`[${this.getDeviceLabel()}] Get TargetHeaterCoolerState ->`, 'HEAT');
331
+ return this.platform.Characteristic.TargetHeaterCoolerState.HEAT;
332
+ }
333
+ this.platform.log.debug(`[${this.getDeviceLabel()}] Get TargetHeaterCoolerState ->`, 'AUTO');
334
+ return this.platform.Characteristic.TargetHeaterCoolerState.AUTO;
335
+ }
336
+ async getCurrentTemperature(service) {
337
+ const currentValue = this.currentTemperature;
338
+ this.platform.log.debug(`[${this.getDeviceLabel()}] Get ${service} CurrentTemperature ->`, currentValue);
339
+ return currentValue;
340
+ }
341
+ async getTargetTemperature(target) {
342
+ const currentValue = this.targetTemperature;
343
+ this.platform.log.debug(`[${this.getDeviceLabel()}] Get ${target} ->`, currentValue);
344
+ return currentValue;
345
+ }
346
+ async getTemperatureDisplayUnits() {
347
+ const currentValue = (this.units === commands_1.default.units.value.celsius) ?
348
+ this.platform.Characteristic.TemperatureDisplayUnits.CELSIUS : this.platform.Characteristic.TemperatureDisplayUnits.FAHRENHEIT;
349
+ this.platform.log.debug(`[${this.getDeviceLabel()}] Get TemperatureDisplayUnits ->`, (currentValue === this.platform.Characteristic.TemperatureDisplayUnits.CELSIUS) ? 'CELSIUS' : 'FAHRENHEIT');
350
+ return currentValue;
351
+ }
352
+ async getSwingMode() {
353
+ switch (this.swingMode || commands_1.default.swingVertical.value.default) {
354
+ case commands_1.default.swingVertical.value.default:
355
+ case commands_1.default.swingVertical.value.fixedHighest:
356
+ case commands_1.default.swingVertical.value.fixedHigher:
357
+ case commands_1.default.swingVertical.value.fixedMiddle:
358
+ case commands_1.default.swingVertical.value.fixedLower:
359
+ case commands_1.default.swingVertical.value.fixedLowest:
360
+ this.platform.log.debug(`[${this.getDeviceLabel()}] Get SwingMode ->`, 'DISABLED');
361
+ return this.platform.Characteristic.SwingMode.SWING_DISABLED;
362
+ }
363
+ this.platform.log.debug(`[${this.getDeviceLabel()}] Get SwingMode ->`, 'ENABLED');
364
+ return this.platform.Characteristic.SwingMode.SWING_ENABLED;
365
+ }
366
+ async getRotationSpeed() {
367
+ if (this.quietMode === commands_1.default.quietMode.value.on) {
368
+ this.platform.log.debug(`[${this.getDeviceLabel()}] Get RotationSpeed -> 1 (quiet)`);
369
+ return 1;
370
+ }
371
+ if (this.powerfulMode === commands_1.default.powerfulMode.value.on) {
372
+ this.platform.log.debug(`[${this.getDeviceLabel()}] Get RotationSpeed ->`, (this.deviceConfig.speedSteps + 3) + ' (powerful)');
373
+ return this.deviceConfig.speedSteps + 3;
374
+ }
375
+ let value = 2; // default to auto
376
+ let logValue = this.getKeyName(commands_1.default.speed.value, commands_1.default.speed.value.auto);
377
+ switch (this.speed) {
378
+ case commands_1.default.speed.value.low:
379
+ value = 3;
380
+ logValue = this.getKeyName(commands_1.default.speed.value, commands_1.default.speed.value.low);
381
+ break;
382
+ case commands_1.default.speed.value.mediumLow:
383
+ value = 4;
384
+ logValue = this.getKeyName(commands_1.default.speed.value, (this.deviceConfig.speedSteps === 5) ? commands_1.default.speed.value.mediumLow : commands_1.default.speed.value.medium);
385
+ break;
386
+ case commands_1.default.speed.value.medium:
387
+ value = (this.deviceConfig.speedSteps === 5) ? 5 : 4;
388
+ logValue = this.getKeyName(commands_1.default.speed.value, commands_1.default.speed.value.medium);
389
+ break;
390
+ case commands_1.default.speed.value.mediumHigh:
391
+ value = (this.deviceConfig.speedSteps === 5) ? 6 : 4;
392
+ logValue = this.getKeyName(commands_1.default.speed.value, (this.deviceConfig.speedSteps === 5) ? commands_1.default.speed.value.mediumHigh : commands_1.default.speed.value.medium);
393
+ break;
394
+ case commands_1.default.speed.value.high:
395
+ value = (this.deviceConfig.speedSteps === 5) ? 7 : 5;
396
+ logValue = this.getKeyName(commands_1.default.speed.value, commands_1.default.speed.value.high);
397
+ break;
398
+ }
399
+ this.platform.log.debug(`[${this.getDeviceLabel()}] Get RotationSpeed ->`, value + ' (' + logValue + ')');
400
+ return value;
401
+ }
402
+ // helper functions
403
+ getDeviceLabel() {
404
+ return `${this.accessory.displayName} -- ${this.accessory.context.device.address}:${this.accessory.context.device.port}`;
405
+ }
406
+ getCols() {
407
+ if (!this.cols) {
408
+ this.cols = Object.keys(commands_1.default).map((k) => commands_1.default[k].code);
409
+ }
410
+ return this.cols;
411
+ }
412
+ getKeyName(obj, value, subkey) {
413
+ let name = '';
414
+ if (subkey === undefined) {
415
+ Object.entries(obj).find(([key, val]) => {
416
+ if (val === value) {
417
+ name = key;
418
+ return true;
419
+ }
420
+ return false;
421
+ });
422
+ }
423
+ else {
424
+ Object.entries(obj).find(([key, val]) => {
425
+ const v = val;
426
+ if (v[subkey] === value) {
427
+ name = key;
428
+ return true;
429
+ }
430
+ return false;
431
+ });
432
+ }
433
+ return name;
434
+ }
435
+ calcDeviceTargetTemp(temp) {
436
+ const baseTemp = Math.round(temp);
437
+ const baseFahrenheit = temp * 9 / 5 + 32;
438
+ const baseFahrenheitDecimalPart = baseFahrenheit - Math.floor(baseFahrenheit);
439
+ const correction = (baseFahrenheitDecimalPart >= 0.05 && baseFahrenheitDecimalPart < 0.15) ||
440
+ (baseFahrenheitDecimalPart >= 0.25 && baseFahrenheitDecimalPart < 0.35) ? 1 : 0;
441
+ return baseTemp - correction;
442
+ }
443
+ calcDeviceTargetOffset(temp) {
444
+ if (temp === 16) {
445
+ return 0;
446
+ }
447
+ const baseFahrenheit = temp * 9 / 5 + 32;
448
+ const baseFahrenheitDecimalPart = baseFahrenheit - Math.floor(baseFahrenheit);
449
+ return (((baseFahrenheitDecimalPart >= 0.05 && baseFahrenheitDecimalPart < 0.15) ||
450
+ (baseFahrenheitDecimalPart >= 0.25 && baseFahrenheitDecimalPart < 0.35) ||
451
+ (baseFahrenheitDecimalPart >= 0.55 && baseFahrenheitDecimalPart < 0.65) ||
452
+ (baseFahrenheitDecimalPart >= 0.75 && baseFahrenheitDecimalPart < 0.85)) ? 1 : 0);
453
+ }
454
+ getTargetTempFromDevice(temp, offset) {
455
+ const key = temp.toString() + ',' + offset.toString();
456
+ const value = settings_1.TEMPERATURE_TABLE[key];
457
+ if (value === undefined) {
458
+ return 25; // default value if invalid data received from device
459
+ }
460
+ // some temperature values are the same on the physical AC unit -> fix this issue:
461
+ const targetValue = this.HeaterCooler.getCharacteristic(this.platform.Characteristic.CoolingThresholdTemperature).value ||
462
+ this.HeaterCooler.getCharacteristic(this.platform.Characteristic.HeatingThresholdTemperature).value;
463
+ if ((targetValue === 17.5 && value === 18) ||
464
+ (targetValue === 22.5 && value === 23) ||
465
+ (targetValue === 27.5 && value === 28)) {
466
+ this.platform.log.debug(`[${this.getDeviceLabel()}] TargetTemperature FIX: %d -> %d`, value, targetValue);
467
+ return targetValue;
468
+ }
469
+ // no fix needed, return original value
470
+ return value;
471
+ }
472
+ // device functions
473
+ get power() {
474
+ return (this.status[commands_1.default.power.code] === commands_1.default.power.value.on);
475
+ }
476
+ set power(value) {
477
+ if (value === this.power) {
478
+ return;
479
+ }
480
+ const powerValue = value ? commands_1.default.power.value.on : commands_1.default.power.value.off;
481
+ const command = { [commands_1.default.power.code]: powerValue };
482
+ let logValue = 'power -> ' + this.getKeyName(commands_1.default.power.value, powerValue);
483
+ if (powerValue === commands_1.default.power.value.on) {
484
+ switch (this.HeaterCooler.getCharacteristic(this.platform.Characteristic.TargetHeaterCoolerState).value) {
485
+ case this.platform.Characteristic.TargetHeaterCoolerState.COOL:
486
+ if (this.status[commands_1.default.mode.code] !== commands_1.default.mode.value.cool) {
487
+ command[commands_1.default.mode.code] = commands_1.default.mode.value.cool;
488
+ logValue += ', mode -> ' + this.getKeyName(commands_1.default.mode.value, commands_1.default.mode.value.cool);
489
+ if (this.deviceConfig.xFanEnabled && (this.status[commands_1.default.xFan.code] || commands_1.default.xFan.value.off) !== commands_1.default.xFan.value.on) {
490
+ // turn on xFan in Cool mode if xFan is enabled for this device
491
+ logValue += ', xFan -> ' + this.getKeyName(commands_1.default.xFan.value, commands_1.default.xFan.value.on);
492
+ command[commands_1.default.xFan.code] = commands_1.default.xFan.value.on;
493
+ }
494
+ }
495
+ break;
496
+ case this.platform.Characteristic.TargetHeaterCoolerState.HEAT:
497
+ if (this.status[commands_1.default.mode.code] !== commands_1.default.mode.value.heat) {
498
+ command[commands_1.default.mode.code] = commands_1.default.mode.value.heat;
499
+ logValue += ', mode -> ' + this.getKeyName(commands_1.default.mode.value, commands_1.default.mode.value.heat);
500
+ }
501
+ break;
502
+ case this.platform.Characteristic.TargetHeaterCoolerState.AUTO:
503
+ if (this.status[commands_1.default.mode.code] !== commands_1.default.mode.value.auto) {
504
+ command[commands_1.default.mode.code] = commands_1.default.mode.value.auto;
505
+ logValue += ', mode -> ' + this.getKeyName(commands_1.default.mode.value, commands_1.default.mode.value.auto);
506
+ }
507
+ break;
508
+ }
509
+ }
510
+ this.platform.log.info(`[${this.getDeviceLabel()}]`, logValue);
511
+ this.sendCommand(command);
512
+ }
513
+ get mode() {
514
+ return this.status[commands_1.default.mode.code] || commands_1.default.mode.value.auto;
515
+ }
516
+ set mode(value) {
517
+ if (value === this.mode) {
518
+ return;
519
+ }
520
+ let logValue = 'mode -> ' + this.getKeyName(commands_1.default.mode.value, value);
521
+ const command = { [commands_1.default.mode.code]: value };
522
+ if (this.deviceConfig.xFanEnabled && (this.status[commands_1.default.xFan.code] || commands_1.default.xFan.value.off) !== commands_1.default.xFan.value.on &&
523
+ (value === commands_1.default.mode.value.cool || value === commands_1.default.mode.value.dry)) {
524
+ // turn on xFan in Cool and Dry mode if xFan is enabled for this device
525
+ logValue += ', xFan -> ' + this.getKeyName(commands_1.default.xFan.value, commands_1.default.xFan.value.on);
526
+ command[commands_1.default.xFan.code] = commands_1.default.xFan.value.on;
527
+ }
528
+ this.platform.log.info(`[${this.getDeviceLabel()}]`, logValue);
529
+ this.sendCommand(command);
530
+ }
531
+ get currentTemperature() {
532
+ return this.status[commands_1.default.temperature.code] - (this.deviceConfig.sensorOffset) || 25;
533
+ }
534
+ get targetTemperature() {
535
+ return Math.max(Math.min(this.getTargetTempFromDevice(this.status[commands_1.default.targetTemperature.code] || 25, this.status[commands_1.default.temperatureOffset.code] || 0), (this.deviceConfig.maximumTargetTemperature)), (this.deviceConfig.minimumTargetTemperature));
536
+ }
537
+ set targetTemperature(value) {
538
+ if (value === this.targetTemperature) {
539
+ return;
540
+ }
541
+ const tempValue = this.calcDeviceTargetTemp(value);
542
+ const command = { [commands_1.default.targetTemperature.code]: tempValue };
543
+ let logValue = 'targetTemperature -> ' + tempValue.toString();
544
+ const tempOffset = this.calcDeviceTargetOffset(value);
545
+ command[commands_1.default.temperatureOffset.code] = tempOffset;
546
+ logValue += ', temperatureOffset -> ' + tempOffset.toString();
547
+ const displayUnits = this.HeaterCooler.getCharacteristic(this.platform.Characteristic.TemperatureDisplayUnits).value;
548
+ const deviceDisplayUnits = (displayUnits === this.platform.Characteristic.TemperatureDisplayUnits.CELSIUS) ?
549
+ commands_1.default.units.value.celsius : commands_1.default.units.value.fahrenheit;
550
+ if (deviceDisplayUnits === commands_1.default.units.value.fahrenheit) {
551
+ logValue += ' (-> ' + Math.round(value * 9 / 5 + 32).toString() + ' °F)';
552
+ }
553
+ else {
554
+ logValue += ' (-> ' + value.toString() + ' °C)';
555
+ }
556
+ if (deviceDisplayUnits !== this.units) {
557
+ command[commands_1.default.units.code] = deviceDisplayUnits;
558
+ logValue += ', units -> ' + this.getKeyName(commands_1.default.units.value, deviceDisplayUnits);
559
+ }
560
+ this.platform.log.info(`[${this.getDeviceLabel()}]`, logValue);
561
+ this.sendCommand(command);
562
+ }
563
+ get units() {
564
+ return this.status[commands_1.default.units.code] || commands_1.default.units.value.celsius;
565
+ }
566
+ set units(value) {
567
+ if (value === this.units) {
568
+ return;
569
+ }
570
+ const command = { [commands_1.default.units.code]: value };
571
+ this.platform.log.info(`[${this.getDeviceLabel()}] units ->`, this.getKeyName(commands_1.default.units.value, value));
572
+ this.sendCommand(command);
573
+ }
574
+ get swingMode() {
575
+ return this.status[commands_1.default.swingVertical.code] || commands_1.default.swingVertical.value.default;
576
+ }
577
+ set swingMode(value) {
578
+ if (value === this.swingMode) {
579
+ return;
580
+ }
581
+ const command = { [commands_1.default.swingVertical.code]: value };
582
+ this.platform.log.info(`[${this.getDeviceLabel()}] swingVertical ->`, this.getKeyName(commands_1.default.swingVertical.value, value));
583
+ this.sendCommand(command);
584
+ }
585
+ get speed() {
586
+ return this.status[commands_1.default.speed.code] || commands_1.default.speed.value.auto;
587
+ }
588
+ set speed(value) {
589
+ if (value === this.speed) {
590
+ return;
591
+ }
592
+ const command = { [commands_1.default.speed.code]: value };
593
+ command[commands_1.default.quietMode.code] = commands_1.default.quietMode.value.off;
594
+ command[commands_1.default.powerfulMode.code] = commands_1.default.powerfulMode.value.off;
595
+ this.platform.log.info(`[${this.getDeviceLabel()}] speed ->`, this.getKeyName(commands_1.default.speed.value, value) +
596
+ ', quietMode -> ' + this.getKeyName(commands_1.default.quietMode.value, commands_1.default.quietMode.value.off) +
597
+ ', powerfulMode -> ' + this.getKeyName(commands_1.default.powerfulMode.value, commands_1.default.powerfulMode.value.off));
598
+ this.sendCommand(command);
599
+ }
600
+ get quietMode() {
601
+ return this.status[commands_1.default.quietMode.code] || commands_1.default.quietMode.value.off;
602
+ }
603
+ set quietMode(value) {
604
+ if (value === this.quietMode) {
605
+ return;
606
+ }
607
+ const command = { [commands_1.default.quietMode.code]: value };
608
+ let logValue = 'quietMode -> ' + this.getKeyName(commands_1.default.quietMode.value, value);
609
+ if (value === commands_1.default.quietMode.value.on) {
610
+ command[commands_1.default.powerfulMode.code] = commands_1.default.powerfulMode.value.off;
611
+ logValue += ', powerfulMode -> ' + this.getKeyName(commands_1.default.powerfulMode.value, commands_1.default.powerfulMode.value.off);
612
+ command[commands_1.default.speed.code] = commands_1.default.speed.value.low;
613
+ logValue += ', speed -> ' + this.getKeyName(commands_1.default.speed.value, commands_1.default.speed.value.low);
614
+ }
615
+ else {
616
+ command[commands_1.default.speed.code] = commands_1.default.speed.value.auto;
617
+ logValue += ', speed -> ' + this.getKeyName(commands_1.default.speed.value, commands_1.default.speed.value.auto);
618
+ }
619
+ this.platform.log.info(`[${this.getDeviceLabel()}]`, logValue);
620
+ this.sendCommand(command);
621
+ }
622
+ get powerfulMode() {
623
+ return this.status[commands_1.default.powerfulMode.code] || commands_1.default.powerfulMode.value.off;
624
+ }
625
+ set powerfulMode(value) {
626
+ if (value === this.powerfulMode) {
627
+ return;
628
+ }
629
+ let logValue = 'powerfulMode -> ' + this.getKeyName(commands_1.default.powerfulMode.value, value);
630
+ const command = { [commands_1.default.powerfulMode.code]: value };
631
+ if (value === commands_1.default.powerfulMode.value.on) {
632
+ command[commands_1.default.quietMode.code] = commands_1.default.quietMode.value.off;
633
+ logValue += ', quietMode -> ' + this.getKeyName(commands_1.default.quietMode.value, commands_1.default.quietMode.value.off);
634
+ command[commands_1.default.speed.code] = commands_1.default.speed.value.high;
635
+ logValue += ', speed -> ' + this.getKeyName(commands_1.default.speed.value, commands_1.default.speed.value.high);
636
+ }
637
+ else {
638
+ command[commands_1.default.speed.code] = commands_1.default.speed.value.auto;
639
+ logValue += ', speed -> ' + this.getKeyName(commands_1.default.speed.value, commands_1.default.speed.value.auto);
640
+ }
641
+ this.platform.log.info(`[${this.getDeviceLabel()}]`, logValue);
642
+ this.sendCommand(command);
643
+ }
644
+ updateStatus(props) {
645
+ var _a, _b, _c;
646
+ this.platform.log.debug(`[${this.getDeviceLabel()}] updateStatus -> %j`, props);
647
+ // Active
648
+ if (props.includes(commands_1.default.power.code)) {
649
+ this.platform.log.debug(`[${this.getDeviceLabel()}] updateStatus (Active) ->`, this.power ? 'ACTIVE' : 'INACTIVE');
650
+ this.HeaterCooler.getCharacteristic(this.platform.Characteristic.Active)
651
+ .updateValue(this.power ?
652
+ this.platform.Characteristic.Active.ACTIVE : this.platform.Characteristic.Active.INACTIVE);
653
+ }
654
+ // Current Heater-Cooler State
655
+ if (props.includes(commands_1.default.mode.code)) {
656
+ if (this.power) {
657
+ switch (this.mode) {
658
+ case commands_1.default.mode.value.cool:
659
+ this.platform.log.debug(`[${this.getDeviceLabel()}] updateStatus (Current Heater-Cooler State) -> COOLING`);
660
+ this.HeaterCooler.getCharacteristic(this.platform.Characteristic.CurrentHeaterCoolerState)
661
+ .updateValue(this.platform.Characteristic.CurrentHeaterCoolerState.COOLING);
662
+ break;
663
+ case commands_1.default.mode.value.heat:
664
+ this.platform.log.debug(`[${this.getDeviceLabel()}] updateStatus (Current Heater-Cooler State) -> HEATING`);
665
+ this.HeaterCooler.getCharacteristic(this.platform.Characteristic.CurrentHeaterCoolerState)
666
+ .updateValue(this.platform.Characteristic.CurrentHeaterCoolerState.HEATING);
667
+ break;
668
+ case commands_1.default.mode.value.fan:
669
+ case commands_1.default.mode.value.dry:
670
+ this.platform.log.debug(`[${this.getDeviceLabel()}] updateStatus (Current Heater-Cooler State) -> IDLE`);
671
+ this.HeaterCooler.getCharacteristic(this.platform.Characteristic.CurrentHeaterCoolerState)
672
+ .updateValue(this.platform.Characteristic.CurrentHeaterCoolerState.IDLE);
673
+ break;
674
+ case commands_1.default.mode.value.auto:
675
+ if (this.currentTemperature > this.targetTemperature + 1.5) {
676
+ this.platform.log.debug(`[${this.getDeviceLabel()}] updateStatus (Current Heater-Cooler State) -> COOLING`);
677
+ this.HeaterCooler.getCharacteristic(this.platform.Characteristic.CurrentHeaterCoolerState)
678
+ .updateValue(this.platform.Characteristic.CurrentHeaterCoolerState.COOLING);
679
+ }
680
+ else if (this.currentTemperature < this.targetTemperature - 1.5) {
681
+ this.platform.log.debug(`[${this.getDeviceLabel()}] updateStatus (Current Heater-Cooler State) -> HEATING`);
682
+ this.HeaterCooler.getCharacteristic(this.platform.Characteristic.CurrentHeaterCoolerState)
683
+ .updateValue(this.platform.Characteristic.CurrentHeaterCoolerState.HEATING);
684
+ }
685
+ else {
686
+ this.platform.log.debug(`[${this.getDeviceLabel()}] updateStatus (Current Heater-Cooler State) -> IDLE`);
687
+ this.HeaterCooler.getCharacteristic(this.platform.Characteristic.CurrentHeaterCoolerState)
688
+ .updateValue(this.platform.Characteristic.CurrentHeaterCoolerState.IDLE);
689
+ }
690
+ break;
691
+ }
692
+ }
693
+ else {
694
+ this.platform.log.debug(`[${this.getDeviceLabel()}] updateStatus (Current Heater-Cooler State) -> INACTIVE`);
695
+ this.HeaterCooler.getCharacteristic(this.platform.Characteristic.CurrentHeaterCoolerState)
696
+ .updateValue(this.platform.Characteristic.CurrentHeaterCoolerState.INACTIVE);
697
+ }
698
+ }
699
+ // Target Heater-Cooler State
700
+ if (props.includes(commands_1.default.mode.code) && this.power) {
701
+ switch (this.mode) {
702
+ case commands_1.default.mode.value.cool:
703
+ this.platform.log.debug(`[${this.getDeviceLabel()}] updateStatus (Target Heater-Cooler State) -> COOL`);
704
+ this.HeaterCooler.getCharacteristic(this.platform.Characteristic.TargetHeaterCoolerState)
705
+ .updateValue(this.platform.Characteristic.TargetHeaterCoolerState.COOL);
706
+ break;
707
+ case commands_1.default.mode.value.heat:
708
+ this.platform.log.debug(`[${this.getDeviceLabel()}] updateStatus (Target Heater-Cooler State) -> HEAT`);
709
+ this.HeaterCooler.getCharacteristic(this.platform.Characteristic.TargetHeaterCoolerState)
710
+ .updateValue(this.platform.Characteristic.TargetHeaterCoolerState.HEAT);
711
+ break;
712
+ default:
713
+ this.platform.log.debug(`[${this.getDeviceLabel()}] updateStatus (Target Heater-Cooler State) -> AUTO`);
714
+ this.HeaterCooler.getCharacteristic(this.platform.Characteristic.TargetHeaterCoolerState)
715
+ .updateValue(this.platform.Characteristic.TargetHeaterCoolerState.AUTO);
716
+ }
717
+ }
718
+ // Current Temperature
719
+ if (props.includes(commands_1.default.temperature.code)) {
720
+ this.platform.log.debug(`[${this.getDeviceLabel()}] updateStatus (Current Temperature) ->`, this.currentTemperature);
721
+ this.HeaterCooler.getCharacteristic(this.platform.Characteristic.CurrentTemperature)
722
+ .updateValue(this.currentTemperature);
723
+ (_a = this.TemperatureSensor) === null || _a === void 0 ? void 0 : _a.getCharacteristic(this.platform.Characteristic.CurrentTemperature).updateValue(this.currentTemperature);
724
+ (_b = this.platform_ts) === null || _b === void 0 ? void 0 : _b.setCurrentTemperature(this.currentTemperature);
725
+ (_c = this.platform_ts) === null || _c === void 0 ? void 0 : _c.TemperatureSensor.getCharacteristic(this.platform.Characteristic.CurrentTemperature).updateValue(this.currentTemperature);
726
+ }
727
+ else if (props.includes(commands_1.default.targetTemperature.code) && this.TemperatureSensor === undefined) {
728
+ // temperature is not accessible -> targetTemperature is saved as currentTemperature
729
+ this.platform.log.debug(`[${this.getDeviceLabel()}] updateStatus (Current Temperature) ->`, this.currentTemperature);
730
+ this.HeaterCooler.getCharacteristic(this.platform.Characteristic.CurrentTemperature)
731
+ .updateValue(this.currentTemperature);
732
+ }
733
+ // Cooling Threshold Temperature
734
+ if (props.includes(commands_1.default.targetTemperature.code) && this.power &&
735
+ (this.mode === commands_1.default.mode.value.cool || this.mode === commands_1.default.mode.value.auto)) {
736
+ this.platform.log.debug(`[${this.getDeviceLabel()}] updateStatus (Cooling Threshold Temperature) ->`, this.targetTemperature);
737
+ this.HeaterCooler.getCharacteristic(this.platform.Characteristic.CoolingThresholdTemperature)
738
+ .updateValue(this.targetTemperature);
739
+ }
740
+ // Heating Threshold Temperature
741
+ if (props.includes(commands_1.default.targetTemperature.code) && this.power &&
742
+ (this.mode === commands_1.default.mode.value.heat || this.mode === commands_1.default.mode.value.auto)) {
743
+ this.platform.log.debug(`[${this.getDeviceLabel()}] updateStatus (Heating Threshold Temperature) ->`, this.targetTemperature);
744
+ this.HeaterCooler.getCharacteristic(this.platform.Characteristic.HeatingThresholdTemperature)
745
+ .updateValue(this.targetTemperature);
746
+ }
747
+ // Temperature Display Units
748
+ if (props.includes(commands_1.default.units.code)) {
749
+ this.platform.log.debug(`[${this.getDeviceLabel()}] updateStatus (Temperature Display Units) ->`, this.units === commands_1.default.units.value.celsius ? 'CELSIUS' : 'FAHRENHEIT');
750
+ this.HeaterCooler.getCharacteristic(this.platform.Characteristic.TemperatureDisplayUnits)
751
+ .updateValue(this.units === commands_1.default.units.value.celsius ?
752
+ this.platform.Characteristic.TemperatureDisplayUnits.CELSIUS : this.platform.Characteristic.TemperatureDisplayUnits.FAHRENHEIT);
753
+ }
754
+ // Swing Mode
755
+ if (props.includes(commands_1.default.swingVertical.code) && this.power) {
756
+ let swing = this.platform.Characteristic.SwingMode.SWING_ENABLED;
757
+ let logValue = 'ENABLED';
758
+ switch (this.swingMode) {
759
+ case commands_1.default.swingVertical.value.default:
760
+ case commands_1.default.swingVertical.value.fixedHighest:
761
+ case commands_1.default.swingVertical.value.fixedHigher:
762
+ case commands_1.default.swingVertical.value.fixedMiddle:
763
+ case commands_1.default.swingVertical.value.fixedLower:
764
+ case commands_1.default.swingVertical.value.fixedLowest:
765
+ swing = this.platform.Characteristic.SwingMode.SWING_DISABLED;
766
+ logValue = 'DISABLED';
767
+ break;
768
+ }
769
+ this.platform.log.debug(`[${this.getDeviceLabel()}] updateStatus (Swing Mode) ->`, logValue);
770
+ this.HeaterCooler.getCharacteristic(this.platform.Characteristic.SwingMode)
771
+ .updateValue(swing);
772
+ }
773
+ // Rotation Speed
774
+ if (this.power) {
775
+ let logValue = '2 (auto)';
776
+ if (props.includes(commands_1.default.quietMode.code) && this.quietMode === commands_1.default.quietMode.value.on) {
777
+ // quietMode -> on
778
+ this.platform.log.debug(`[${this.getDeviceLabel()}] updateStatus (Rotation Speed) -> 1 (quiet)`);
779
+ this.HeaterCooler.getCharacteristic(this.platform.Characteristic.RotationSpeed)
780
+ .updateValue(1);
781
+ }
782
+ else if (props.includes(commands_1.default.powerfulMode.code) && this.powerfulMode === commands_1.default.powerfulMode.value.on) {
783
+ // powerfulMode -> on
784
+ logValue = `${this.deviceConfig.speedSteps + 3} (powerful)`;
785
+ this.platform.log.debug(`[${this.getDeviceLabel()}] updateStatus (Rotation Speed) ->`, logValue);
786
+ this.HeaterCooler.getCharacteristic(this.platform.Characteristic.RotationSpeed)
787
+ .updateValue(this.deviceConfig.speedSteps + 3);
788
+ }
789
+ else if (props.includes(commands_1.default.speed.code)) {
790
+ // speed
791
+ let speedValue = 2; // default: auto
792
+ switch (this.speed) {
793
+ case commands_1.default.speed.value.low:
794
+ logValue = '3 (low)';
795
+ speedValue = 3;
796
+ break;
797
+ case commands_1.default.speed.value.mediumLow:
798
+ logValue = '4 (mediumLow)';
799
+ speedValue = 4;
800
+ break;
801
+ case commands_1.default.speed.value.medium:
802
+ logValue = ((this.deviceConfig.speedSteps === 5) ? '5' : '4') + ' (medium)';
803
+ speedValue = (this.deviceConfig.speedSteps === 5) ? 5 : 4;
804
+ break;
805
+ case commands_1.default.speed.value.mediumHigh:
806
+ logValue = ((this.deviceConfig.speedSteps === 5) ? '6' : '4') + ' (mediumHigh)';
807
+ speedValue = (this.deviceConfig.speedSteps === 5) ? 6 : 4;
808
+ break;
809
+ case commands_1.default.speed.value.high:
810
+ logValue = ((this.deviceConfig.speedSteps === 5) ? '7' : '5') + ' (high)';
811
+ speedValue = (this.deviceConfig.speedSteps === 5) ? 7 : 5;
812
+ break;
813
+ }
814
+ this.platform.log.debug(`[${this.getDeviceLabel()}] updateStatus (Rotation Speed) ->`, logValue);
815
+ this.HeaterCooler.getCharacteristic(this.platform.Characteristic.RotationSpeed)
816
+ .updateValue(speedValue);
817
+ }
818
+ }
819
+ }
820
+ sendMessage(message) {
821
+ const pack = crypto_1.default.encrypt(message, this.key);
822
+ const payload = {
823
+ cid: 'app',
824
+ i: this.key === undefined ? 1 : 0,
825
+ t: 'pack',
826
+ uid: 0,
827
+ tcid: this.accessory.context.device.mac,
828
+ pack,
829
+ };
830
+ try {
831
+ this.socket.send(JSON.stringify(payload), this.accessory.context.device.port, this.accessory.context.device.address);
832
+ }
833
+ catch (err) {
834
+ this.platform.log.error('Error:', err.message);
835
+ }
836
+ }
837
+ sendBindRequest() {
838
+ const message = {
839
+ mac: this.accessory.context.device.mac,
840
+ t: 'bind',
841
+ uid: 0,
842
+ };
843
+ this.platform.log.debug(`[${this.getDeviceLabel()}] Bind to device -> ${this.accessory.context.device.mac}`);
844
+ this.sendMessage(message);
845
+ }
846
+ sendCommand(cmd) {
847
+ this.platform.log.debug(`[${this.getDeviceLabel()}] Send commands -> %j`, cmd);
848
+ const keys = Object.keys(cmd);
849
+ const values = keys.map((k) => cmd[k]);
850
+ const message = {
851
+ t: 'cmd',
852
+ opt: keys,
853
+ p: values,
854
+ };
855
+ this.sendMessage(message);
856
+ }
857
+ requestDeviceStatus() {
858
+ const message = {
859
+ mac: this.accessory.context.device.mac,
860
+ t: 'status',
861
+ cols: this.getCols(),
862
+ };
863
+ this.sendMessage(message);
864
+ }
865
+ }
866
+ exports.GreeAirConditioner = GreeAirConditioner;
867
+ //# sourceMappingURL=platformAccessory.js.map