tsvesync 1.0.64 → 1.0.65

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.
@@ -2,1852 +2,20 @@
2
2
  /**
3
3
  * VeSync Fan Implementations
4
4
  */
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.fanModules = exports.VeSyncTowerFan = exports.VeSyncAirBaseV2 = exports.VeSyncWarmHumidifier = exports.VeSyncHumidifier = exports.VeSyncAirBypass = void 0;
7
- const vesyncFan_1 = require("./vesyncFan");
8
- const helpers_1 = require("./helpers");
9
- const logger_1 = require("./logger");
10
- /**
11
- * VeSync Air Purifier with Bypass
12
- */
13
- class VeSyncAirBypass extends vesyncFan_1.VeSyncFan {
14
- constructor(details, manager) {
15
- super(details, manager);
16
- this.modes = ['auto', 'manual', 'sleep'];
17
- this.displayModes = ['on', 'off'];
18
- this.childLockModes = ['on', 'off'];
19
- logger_1.logger.debug(`Initialized VeSyncAirBypass device: ${this.deviceName}`);
20
- }
21
- /**
22
- * Build API dictionary
23
- */
24
- buildApiDict(method) {
25
- const head = helpers_1.Helpers.reqHeaderBypass();
26
- const body = {
27
- ...helpers_1.Helpers.reqBody(this.manager, 'bypassV2'),
28
- cid: this.cid,
29
- configModule: this.configModule,
30
- payload: {
31
- method,
32
- source: 'APP',
33
- data: {}
34
- }
35
- };
36
- return [head, body];
37
- }
38
- /**
39
- * Get device details
40
- */
41
- async getDetails() {
42
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
43
- logger_1.logger.debug(`Getting details for device: ${this.deviceName}`);
44
- // Special handling for LV series
45
- if (this.deviceType.startsWith('LV-')) {
46
- const [response, status] = await this.callApi('/131airPurifier/v1/device/devicedetail', 'post', {
47
- acceptLanguage: 'en',
48
- accountID: this.manager.accountId,
49
- appVersion: '2.8.6',
50
- method: 'devicedetail',
51
- mobileId: '1234567890123456',
52
- phoneBrand: 'SM N9005',
53
- phoneOS: 'Android',
54
- timeZone: this.manager.timeZone,
55
- token: this.manager.token,
56
- uuid: this.uuid
57
- }, {
58
- 'accept-language': 'en',
59
- 'accountId': this.manager.accountId,
60
- 'appVersion': '2.8.6',
61
- 'content-type': 'application/json',
62
- 'tk': this.manager.token,
63
- 'tz': this.manager.timeZone
64
- });
65
- const success = this.checkResponse([response, status], 'getDetails');
66
- if (success && response) {
67
- this.deviceStatus = ((_b = (_a = response.result) === null || _a === void 0 ? void 0 : _a.result) === null || _b === void 0 ? void 0 : _b.deviceStatus) === 'on' ? 'on' : 'off';
68
- this.details = {
69
- mode: ((_d = (_c = response.result) === null || _c === void 0 ? void 0 : _c.result) === null || _d === void 0 ? void 0 : _d.mode) || '',
70
- speed: ((_f = (_e = response.result) === null || _e === void 0 ? void 0 : _e.result) === null || _f === void 0 ? void 0 : _f.level) || 0,
71
- filterLife: ((_h = (_g = response.result) === null || _g === void 0 ? void 0 : _g.result) === null || _h === void 0 ? void 0 : _h.filterLife) || 0,
72
- screenStatus: ((_k = (_j = response.result) === null || _j === void 0 ? void 0 : _j.result) === null || _k === void 0 ? void 0 : _k.display) || false,
73
- childLock: ((_m = (_l = response.result) === null || _l === void 0 ? void 0 : _l.result) === null || _m === void 0 ? void 0 : _m.childLock) || false,
74
- airQuality: ((_p = (_o = response.result) === null || _o === void 0 ? void 0 : _o.result) === null || _p === void 0 ? void 0 : _p.airQuality) || 0
75
- };
76
- return true;
77
- }
78
- return false;
79
- }
80
- // Original implementation for other devices
81
- const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', {
82
- ...helpers_1.Helpers.reqBody(this.manager, 'bypassV2'),
83
- cid: this.cid,
84
- configModule: this.configModule,
85
- payload: {
86
- data: {},
87
- method: 'getPurifierStatus',
88
- source: 'APP'
89
- }
90
- }, helpers_1.Helpers.reqHeaderBypass());
91
- const success = this.checkResponse([response, status], 'getDetails');
92
- if (success) {
93
- const result = (_q = response === null || response === void 0 ? void 0 : response.result) === null || _q === void 0 ? void 0 : _q.result;
94
- if (result) {
95
- this.deviceStatus = result.enabled ? 'on' : 'off';
96
- this.details = {
97
- mode: result.mode || '',
98
- speed: result.level || 0,
99
- filterLife: result.filter_life || 0,
100
- screenStatus: result.display || false,
101
- childLock: result.child_lock || false,
102
- airQuality: result.air_quality || 0
103
- };
104
- if (result.configuration) {
105
- this.config = result.configuration;
106
- }
107
- logger_1.logger.debug(`Successfully got details for device: ${this.deviceName}`);
108
- }
109
- }
110
- return success;
111
- }
112
- /**
113
- * Turn device on
114
- */
115
- async turnOn() {
116
- logger_1.logger.info(`Turning on device: ${this.deviceName}`);
117
- // Special handling for LV series
118
- if (this.deviceType.startsWith('LV-')) {
119
- const [response, status] = await this.callApi('/131airPurifier/v1/device/deviceStatus', 'put', {
120
- acceptLanguage: 'en',
121
- accountID: this.manager.accountId,
122
- status: 'on',
123
- timeZone: this.manager.timeZone,
124
- token: this.manager.token,
125
- uuid: this.uuid
126
- }, {
127
- 'accept-language': 'en',
128
- 'accountId': this.manager.accountId,
129
- 'appVersion': '2.8.6',
130
- 'content-type': 'application/json',
131
- 'tk': this.manager.token,
132
- 'tz': this.manager.timeZone
133
- });
134
- const success = this.checkResponse([response, status], 'turnOn');
135
- if (!success) {
136
- logger_1.logger.error(`Failed to turn on device: ${this.deviceName}`);
137
- }
138
- return success;
139
- }
140
- // Original implementation for other devices
141
- const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', {
142
- ...helpers_1.Helpers.reqBody(this.manager, 'bypassV2'),
143
- cid: this.cid,
144
- configModule: this.configModule,
145
- payload: {
146
- data: {
147
- enabled: true,
148
- id: 0
149
- },
150
- method: 'setSwitch',
151
- source: 'APP'
152
- }
153
- }, helpers_1.Helpers.reqHeaderBypass());
154
- const success = this.checkResponse([response, status], 'turnOn');
155
- if (!success) {
156
- logger_1.logger.error(`Failed to turn on device: ${this.deviceName}`);
157
- }
158
- return success;
159
- }
160
- /**
161
- * Turn device off
162
- */
163
- async turnOff() {
164
- logger_1.logger.info(`Turning off device: ${this.deviceName}`);
165
- // Special handling for LV series
166
- if (this.deviceType.startsWith('LV-')) {
167
- const [response, status] = await this.callApi('/131airPurifier/v1/device/deviceStatus', 'put', {
168
- acceptLanguage: 'en',
169
- accountID: this.manager.accountId,
170
- status: 'off',
171
- timeZone: this.manager.timeZone,
172
- token: this.manager.token,
173
- uuid: this.uuid
174
- }, {
175
- 'accept-language': 'en',
176
- 'accountId': this.manager.accountId,
177
- 'appVersion': '2.8.6',
178
- 'content-type': 'application/json',
179
- 'tk': this.manager.token,
180
- 'tz': this.manager.timeZone
181
- });
182
- const success = this.checkResponse([response, status], 'turnOff');
183
- if (!success) {
184
- logger_1.logger.error(`Failed to turn off device: ${this.deviceName}`);
185
- }
186
- return success;
187
- }
188
- // Original implementation for other devices
189
- const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', {
190
- ...helpers_1.Helpers.reqBody(this.manager, 'bypassV2'),
191
- cid: this.cid,
192
- configModule: this.configModule,
193
- payload: {
194
- data: {
195
- enabled: false,
196
- id: 0
197
- },
198
- method: 'setSwitch',
199
- source: 'APP'
200
- }
201
- }, helpers_1.Helpers.reqHeaderBypass());
202
- const success = this.checkResponse([response, status], 'turnOff');
203
- if (!success) {
204
- logger_1.logger.error(`Failed to turn off device: ${this.deviceName}`);
205
- }
206
- return success;
207
- }
208
- /**
209
- * Change fan speed
210
- */
211
- async changeFanSpeed(speed) {
212
- // const speeds = this.config.levels ?? [];
213
- // if (!speeds.includes(speed)) {
214
- // logger.error(`Invalid speed: ${speed}. Must be one of: ${speeds.join(', ')} for device: ${this.deviceName}`);
215
- // return false;
216
- // }
217
- logger_1.logger.info(`Changing fan speed to ${speed} for device: ${this.deviceName}`);
218
- const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', {
219
- ...helpers_1.Helpers.reqBody(this.manager, 'bypassV2'),
220
- cid: this.cid,
221
- configModule: this.configModule,
222
- payload: {
223
- data: {
224
- id: 0,
225
- level: speed,
226
- mode: 'manual',
227
- type: 'wind'
228
- },
229
- method: 'setLevel',
230
- source: 'APP'
231
- }
232
- }, helpers_1.Helpers.reqHeaderBypass());
233
- const success = this.checkResponse([response, status], 'changeFanSpeed');
234
- if (!success) {
235
- logger_1.logger.error(`Failed to change fan speed to ${speed} for device: ${this.deviceName}`);
236
- }
237
- return success;
238
- }
239
- /**
240
- * Set device mode
241
- */
242
- async setMode(mode) {
243
- if (!this.modes.includes(mode)) {
244
- const error = `Invalid mode: ${mode}. Must be one of: ${this.modes.join(', ')}`;
245
- logger_1.logger.error(`${error} for device: ${this.deviceName}`);
246
- throw new Error(error);
247
- }
248
- logger_1.logger.debug(`Setting mode to ${mode} for device: ${this.deviceName}`);
249
- const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', {
250
- ...helpers_1.Helpers.reqBody(this.manager, 'bypassV2'),
251
- cid: this.cid,
252
- configModule: this.configModule,
253
- payload: {
254
- data: {
255
- mode
256
- },
257
- method: 'setPurifierMode',
258
- source: 'APP'
259
- }
260
- }, helpers_1.Helpers.reqHeaderBypass());
261
- const success = this.checkResponse([response, status], 'setMode');
262
- if (!success) {
263
- logger_1.logger.error(`Failed to set mode to ${mode} for device: ${this.deviceName}`);
264
- }
265
- return success;
266
- }
267
- /**
268
- * Set display status
269
- */
270
- async setDisplay(enabled) {
271
- if (!this.hasFeature('display')) {
272
- const error = 'Display control not supported';
273
- logger_1.logger.error(`${error} for device: ${this.deviceName}`);
274
- throw new Error(error);
275
- }
276
- logger_1.logger.debug(`Setting display to ${enabled ? 'on' : 'off'} for device: ${this.deviceName}`);
277
- const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', {
278
- ...helpers_1.Helpers.reqBody(this.manager, 'bypassV2'),
279
- cid: this.cid,
280
- configModule: this.configModule,
281
- payload: {
282
- data: {
283
- state: enabled
284
- },
285
- method: 'setDisplay',
286
- source: 'APP'
287
- }
288
- }, helpers_1.Helpers.reqHeaderBypass());
289
- const success = this.checkResponse([response, status], 'setDisplay');
290
- if (!success) {
291
- logger_1.logger.error(`Failed to set display to ${enabled ? 'on' : 'off'} for device: ${this.deviceName}`);
292
- }
293
- return success;
294
- }
295
- /**
296
- * Set child lock
297
- */
298
- async setChildLock(enabled) {
299
- if (!this.hasFeature('child_lock')) {
300
- const error = 'Child lock not supported';
301
- logger_1.logger.error(`${error} for device: ${this.deviceName}`);
302
- throw new Error(error);
303
- }
304
- logger_1.logger.debug(`Setting child lock to ${enabled ? 'on' : 'off'} for device: ${this.deviceName}`);
305
- const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', {
306
- ...helpers_1.Helpers.reqBody(this.manager, 'bypassV2'),
307
- cid: this.cid,
308
- configModule: this.configModule,
309
- payload: {
310
- data: {
311
- state: enabled
312
- },
313
- method: 'setChildLock',
314
- source: 'APP'
315
- }
316
- }, helpers_1.Helpers.reqHeaderBypass());
317
- const success = this.checkResponse([response, status], 'setChildLock');
318
- if (!success) {
319
- logger_1.logger.error(`Failed to set child lock to ${enabled ? 'on' : 'off'} for device: ${this.deviceName}`);
320
- }
321
- return success;
322
- }
323
- /**
324
- * Set timer
325
- */
326
- async setTimer(hours) {
327
- if (!this.hasFeature('timer')) {
328
- const error = 'Timer not supported';
329
- logger_1.logger.error(`${error} for device: ${this.deviceName}`);
330
- throw new Error(error);
331
- }
332
- logger_1.logger.debug(`Setting timer to ${hours} hours for device: ${this.deviceName}`);
333
- const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', {
334
- ...helpers_1.Helpers.reqBody(this.manager, 'bypassV2'),
335
- cid: this.cid,
336
- configModule: this.configModule,
337
- payload: {
338
- data: {
339
- action: 'off',
340
- total: hours * 3600
341
- },
342
- method: 'addTimer',
343
- source: 'APP'
344
- }
345
- }, helpers_1.Helpers.reqHeaderBypass());
346
- const success = this.checkResponse([response, status], 'setTimer');
347
- if (!success) {
348
- logger_1.logger.error(`Failed to set timer to ${hours} hours for device: ${this.deviceName}`);
349
- }
350
- return success;
351
- }
352
- /**
353
- * Clear timer
354
- */
355
- async clearTimer() {
356
- if (!this.hasFeature('timer')) {
357
- const error = 'Timer not supported';
358
- logger_1.logger.error(`${error} for device: ${this.deviceName}`);
359
- throw new Error(error);
360
- }
361
- logger_1.logger.debug(`Clearing timer for device: ${this.deviceName}`);
362
- const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', {
363
- ...helpers_1.Helpers.reqBody(this.manager, 'bypassV2'),
364
- cid: this.cid,
365
- configModule: this.configModule,
366
- payload: {
367
- data: {},
368
- method: 'deleteTimer',
369
- source: 'APP'
370
- }
371
- }, helpers_1.Helpers.reqHeaderBypass());
372
- const success = this.checkResponse([response, status], 'clearTimer');
373
- if (!success) {
374
- logger_1.logger.error(`Failed to clear timer for device: ${this.deviceName}`);
375
- }
376
- return success;
377
- }
378
- /**
379
- * Turn automatic stop on
380
- */
381
- async automaticStopOn() {
382
- logger_1.logger.debug(`Setting automatic stop on for device: ${this.deviceName}`);
383
- const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', {
384
- ...helpers_1.Helpers.reqBody(this.manager, 'bypassV2'),
385
- cid: this.cid,
386
- configModule: this.configModule,
387
- payload: {
388
- data: {
389
- enabled: true
390
- },
391
- method: 'setAutomaticStop',
392
- source: 'APP'
393
- }
394
- }, helpers_1.Helpers.reqHeaderBypass());
395
- const success = this.checkResponse([response, status], 'automaticStopOn');
396
- if (!success) {
397
- logger_1.logger.error(`Failed to set automatic stop on for device: ${this.deviceName}`);
398
- }
399
- return success;
400
- }
401
- /**
402
- * Turn automatic stop off
403
- */
404
- async automaticStopOff() {
405
- logger_1.logger.debug(`Setting automatic stop off for device: ${this.deviceName}`);
406
- const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', {
407
- ...helpers_1.Helpers.reqBody(this.manager, 'bypassV2'),
408
- cid: this.cid,
409
- configModule: this.configModule,
410
- payload: {
411
- data: {
412
- enabled: false
413
- },
414
- method: 'setAutomaticStop',
415
- source: 'APP'
416
- }
417
- }, helpers_1.Helpers.reqHeaderBypass());
418
- const success = this.checkResponse([response, status], 'automaticStopOff');
419
- if (!success) {
420
- logger_1.logger.error(`Failed to set automatic stop off for device: ${this.deviceName}`);
421
- }
422
- return success;
423
- }
424
- /**
425
- * Set auto mode
426
- */
427
- async autoMode() {
428
- logger_1.logger.debug(`Setting auto mode for device: ${this.deviceName}`);
429
- const success = await this.setMode('auto');
430
- if (!success) {
431
- logger_1.logger.error(`Failed to set auto mode for device: ${this.deviceName}`);
432
- }
433
- return success;
434
- }
435
- /**
436
- * Set manual mode
437
- */
438
- async manualMode() {
439
- logger_1.logger.debug(`Setting manual mode for device: ${this.deviceName}`);
440
- const success = await this.setMode('manual');
441
- if (!success) {
442
- logger_1.logger.error(`Failed to set manual mode for device: ${this.deviceName}`);
443
- }
444
- return success;
445
- }
446
- /**
447
- * Set sleep mode
448
- */
449
- async sleepMode() {
450
- logger_1.logger.debug(`Setting sleep mode for device: ${this.deviceName}`);
451
- const success = await this.setMode('sleep');
452
- if (!success) {
453
- logger_1.logger.error(`Failed to set sleep mode for device: ${this.deviceName}`);
454
- }
455
- return success;
456
- }
457
- /**
458
- * Turn off display
459
- */
460
- async turnOffDisplay() {
461
- logger_1.logger.debug(`Turning off display for device: ${this.deviceName}`);
462
- const success = await this.setDisplay(false);
463
- if (!success) {
464
- logger_1.logger.error(`Failed to turn off display for device: ${this.deviceName}`);
465
- }
466
- return success;
467
- }
468
- /**
469
- * Turn on display
470
- */
471
- async turnOnDisplay() {
472
- logger_1.logger.debug(`Turning on display for device: ${this.deviceName}`);
473
- const success = await this.setDisplay(true);
474
- if (!success) {
475
- logger_1.logger.error(`Failed to turn on display for device: ${this.deviceName}`);
476
- }
477
- return success;
478
- }
479
- }
480
- exports.VeSyncAirBypass = VeSyncAirBypass;
481
- /**
482
- * VeSync Humidifier Base Class
483
- */
484
- class VeSyncHumidifier extends vesyncFan_1.VeSyncFan {
485
- constructor(details, manager) {
486
- super(details, manager);
487
- this.modes = ['auto', 'manual', 'sleep'];
488
- this.displayModes = ['on', 'off'];
489
- this.humidityRange = { min: 30, max: 80 };
490
- // Set mist levels based on model
491
- switch (this.deviceType) {
492
- case 'Dual200S':
493
- case 'LUH-D301S-WUSR':
494
- case 'LUH-D301S-WJP':
495
- case 'LUH-D301S-WEU':
496
- this.mistLevels = [1, 2];
497
- break;
498
- default:
499
- // All other models support levels 1-9
500
- this.mistLevels = [1, 2, 3, 4, 5, 6, 7, 8, 9];
501
- }
502
- logger_1.logger.debug(`Initialized VeSyncHumidifier device: ${this.deviceName}`);
503
- }
504
- /**
505
- * Get device details
506
- */
507
- async getDetails() {
508
- var _a;
509
- logger_1.logger.debug(`Getting details for device: ${this.deviceName}`);
510
- const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', {
511
- ...helpers_1.Helpers.reqBody(this.manager, 'bypassV2'),
512
- cid: this.cid,
513
- configModule: this.configModule,
514
- payload: {
515
- data: {},
516
- method: 'getHumidifierStatus',
517
- source: 'APP'
518
- }
519
- }, helpers_1.Helpers.reqHeaderBypass());
520
- const success = this.checkResponse([response, status], 'getDetails');
521
- if (success && ((_a = response === null || response === void 0 ? void 0 : response.result) === null || _a === void 0 ? void 0 : _a.result)) {
522
- const result = response.result.result;
523
- // Handle model-specific status fields
524
- if (this.deviceType.startsWith('Classic') || this.deviceType === 'Dual200S') {
525
- this.deviceStatus = result.enabled ? 'on' : 'off';
526
- }
527
- else {
528
- this.deviceStatus = result.powerSwitch === 1 ? 'on' : 'off';
529
- }
530
- this.details = {
531
- mode: result.mode || '',
532
- humidity: result.humidity || 0,
533
- mist_level: result.mistLevel || 0,
534
- mist_virtual_level: result.virtualLevel || 0,
535
- warm_level: result.warmLevel || 0,
536
- water_lacks: result.waterLacks || false,
537
- humidity_high: result.humidityHigh || false,
538
- water_tank_lifted: result.waterTankLifted || false,
539
- display: result.display || false,
540
- automatic_stop: result.automaticStop || false,
541
- configuration: result.configuration || {},
542
- connection_status: result.connectionStatus || null
543
- };
544
- logger_1.logger.debug(`Successfully got details for device: ${this.deviceName}`);
545
- }
546
- return success;
547
- }
548
- /**
549
- * Turn device on
550
- */
551
- async turnOn() {
552
- return this.toggleSwitch(true);
553
- }
554
- /**
555
- * Turn device off
556
- */
557
- async turnOff() {
558
- return this.toggleSwitch(false);
559
- }
560
- /**
561
- * Get model-specific toggle payload
562
- */
563
- getTogglePayload(enabled) {
564
- // Model-specific toggle payload based on PyVeSync implementation
565
- if (this.deviceType.startsWith('Classic') || this.deviceType === 'Dual200S') {
566
- return {
567
- enabled: enabled,
568
- id: 0
569
- };
570
- }
571
- else if (this.deviceType.startsWith('Superior')) {
572
- return {
573
- powerSwitch: enabled ? 1 : 0,
574
- switchIdx: 0
575
- };
576
- }
577
- else {
578
- return {
579
- powerSwitch: enabled ? 1 : 0
580
- };
581
- }
582
- }
583
- /**
584
- * Toggle device power
585
- */
586
- async toggleSwitch(enabled) {
587
- logger_1.logger.info(`Setting device power to ${enabled ? 'on' : 'off'}: ${this.deviceName}`);
588
- const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', {
589
- ...helpers_1.Helpers.reqBody(this.manager, 'bypassV2'),
590
- cid: this.cid,
591
- configModule: this.configModule,
592
- payload: {
593
- data: this.getTogglePayload(enabled),
594
- method: 'setSwitch',
595
- source: 'APP'
596
- }
597
- }, helpers_1.Helpers.reqHeaderBypass());
598
- const success = this.checkResponse([response, status], 'toggleSwitch');
599
- if (success) {
600
- this.deviceStatus = enabled ? 'on' : 'off';
601
- }
602
- else {
603
- logger_1.logger.error(`Failed to set device power to ${enabled ? 'on' : 'off'} for device: ${this.deviceName}`);
604
- }
605
- return success;
606
- }
607
- /**
608
- * Set mist level
609
- */
610
- async setMistLevel(level) {
611
- if (!this.mistLevels.includes(level)) {
612
- const error = `Invalid mist level: ${level}. Must be one of: ${this.mistLevels.join(', ')}`;
613
- logger_1.logger.error(`${error} for device: ${this.deviceName}`);
614
- throw new Error(error);
615
- }
616
- logger_1.logger.info(`Setting mist level to ${level} for device: ${this.deviceName}`);
617
- const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', {
618
- ...helpers_1.Helpers.reqBody(this.manager, 'bypassV2'),
619
- cid: this.cid,
620
- configModule: this.configModule,
621
- payload: {
622
- data: {
623
- id: 0,
624
- level: level,
625
- type: 'mist'
626
- },
627
- method: 'setVirtualLevel',
628
- source: 'APP'
629
- }
630
- }, helpers_1.Helpers.reqHeaderBypass());
631
- const success = this.checkResponse([response, status], 'setMistLevel');
632
- if (!success) {
633
- logger_1.logger.error(`Failed to set mist level to ${level} for device: ${this.deviceName}`);
634
- }
635
- return success;
636
- }
637
- /**
638
- * Change fan speed - Implemented to satisfy interface but redirects to setMistLevel
639
- */
640
- async changeFanSpeed(speed) {
641
- logger_1.logger.debug(`Redirecting fan speed change to mist level for device: ${this.deviceName}`);
642
- return this.setMistLevel(speed);
643
- }
644
- /**
645
- * Set device mode
646
- */
647
- async setMode(mode) {
648
- if (!this.modes.includes(mode)) {
649
- const error = `Invalid mode: ${mode}. Must be one of: ${this.modes.join(', ')}`;
650
- logger_1.logger.error(`${error} for device: ${this.deviceName}`);
651
- throw new Error(error);
652
- }
653
- logger_1.logger.debug(`Setting mode to ${mode} for device: ${this.deviceName}`);
654
- const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', {
655
- ...helpers_1.Helpers.reqBody(this.manager, 'bypassV2'),
656
- cid: this.cid,
657
- configModule: this.configModule,
658
- payload: {
659
- data: {
660
- mode
661
- },
662
- method: 'setHumidityMode',
663
- source: 'APP'
664
- }
665
- }, helpers_1.Helpers.reqHeaderBypass());
666
- const success = this.checkResponse([response, status], 'setMode');
667
- if (success) {
668
- this.details.mode = mode;
669
- }
670
- else {
671
- logger_1.logger.error(`Failed to set mode to ${mode} for device: ${this.deviceName}`);
672
- }
673
- return success;
674
- }
675
- /**
676
- * Set target humidity
677
- */
678
- async setHumidity(humidity) {
679
- if (!this.hasFeature('humidity')) {
680
- const error = 'Humidity control not supported';
681
- logger_1.logger.error(`${error} for device: ${this.deviceName}`);
682
- throw new Error(error);
683
- }
684
- if (humidity < this.humidityRange.min || humidity > this.humidityRange.max) {
685
- const error = `Invalid humidity: ${humidity}. Must be between ${this.humidityRange.min} and ${this.humidityRange.max}`;
686
- logger_1.logger.error(`${error} for device: ${this.deviceName}`);
687
- throw new Error(error);
688
- }
689
- logger_1.logger.debug(`Setting target humidity to ${humidity}% for device: ${this.deviceName}`);
690
- const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', {
691
- ...helpers_1.Helpers.reqBody(this.manager, 'bypassV2'),
692
- cid: this.cid,
693
- configModule: this.configModule,
694
- payload: {
695
- data: {
696
- targetHumidity: humidity
697
- },
698
- method: 'setTargetHumidity',
699
- source: 'APP'
700
- }
701
- }, helpers_1.Helpers.reqHeaderBypass());
702
- const success = this.checkResponse([response, status], 'setHumidity');
703
- if (!success) {
704
- logger_1.logger.error(`Failed to set target humidity to ${humidity}% for device: ${this.deviceName}`);
705
- }
706
- return success;
707
- }
708
- /**
709
- * Set display status
710
- */
711
- async setDisplay(enabled) {
712
- if (!this.hasFeature('display')) {
713
- const error = 'Display control not supported';
714
- logger_1.logger.error(`${error} for device: ${this.deviceName}`);
715
- throw new Error(error);
716
- }
717
- logger_1.logger.debug(`Setting display to ${enabled ? 'on' : 'off'} for device: ${this.deviceName}`);
718
- const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', {
719
- ...helpers_1.Helpers.reqBody(this.manager, 'bypassV2'),
720
- cid: this.cid,
721
- configModule: this.configModule,
722
- payload: {
723
- data: {
724
- state: enabled
725
- },
726
- method: 'setDisplay',
727
- source: 'APP'
728
- }
729
- }, helpers_1.Helpers.reqHeaderBypass());
730
- const success = this.checkResponse([response, status], 'setDisplay');
731
- if (!success) {
732
- logger_1.logger.error(`Failed to set display to ${enabled ? 'on' : 'off'} for device: ${this.deviceName}`);
733
- }
734
- return success;
735
- }
736
- /**
737
- * Set timer
738
- */
739
- async setTimer(hours) {
740
- if (!this.hasFeature('timer')) {
741
- const error = 'Timer not supported';
742
- logger_1.logger.error(`${error} for device: ${this.deviceName}`);
743
- throw new Error(error);
744
- }
745
- logger_1.logger.debug(`Setting timer to ${hours} hours for device: ${this.deviceName}`);
746
- const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', {
747
- ...helpers_1.Helpers.reqBody(this.manager, 'bypassV2'),
748
- cid: this.cid,
749
- configModule: this.configModule,
750
- payload: {
751
- data: {
752
- action: 'off',
753
- total: hours * 3600
754
- },
755
- method: 'addTimer',
756
- source: 'APP'
757
- }
758
- }, helpers_1.Helpers.reqHeaderBypass());
759
- const success = this.checkResponse([response, status], 'setTimer');
760
- if (!success) {
761
- logger_1.logger.error(`Failed to set timer to ${hours} hours for device: ${this.deviceName}`);
762
- }
763
- return success;
764
- }
765
- /**
766
- * Clear timer
767
- */
768
- async clearTimer() {
769
- if (!this.hasFeature('timer')) {
770
- const error = 'Timer not supported';
771
- logger_1.logger.error(`${error} for device: ${this.deviceName}`);
772
- throw new Error(error);
773
- }
774
- logger_1.logger.debug(`Clearing timer for device: ${this.deviceName}`);
775
- const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', {
776
- ...helpers_1.Helpers.reqBody(this.manager, 'bypassV2'),
777
- cid: this.cid,
778
- configModule: this.configModule,
779
- payload: {
780
- data: {},
781
- method: 'deleteTimer',
782
- source: 'APP'
783
- }
784
- }, helpers_1.Helpers.reqHeaderBypass());
785
- const success = this.checkResponse([response, status], 'clearTimer');
786
- if (!success) {
787
- logger_1.logger.error(`Failed to clear timer for device: ${this.deviceName}`);
788
- }
789
- return success;
790
- }
791
- /**
792
- * Turn automatic stop on
793
- */
794
- async automaticStopOn() {
795
- logger_1.logger.debug(`Setting automatic stop on for device: ${this.deviceName}`);
796
- const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', {
797
- ...helpers_1.Helpers.reqBody(this.manager, 'bypassV2'),
798
- cid: this.cid,
799
- configModule: this.configModule,
800
- payload: {
801
- data: {
802
- enabled: true
803
- },
804
- method: 'setAutomaticStop',
805
- source: 'APP'
806
- }
807
- }, helpers_1.Helpers.reqHeaderBypass());
808
- const success = this.checkResponse([response, status], 'automaticStopOn');
809
- if (!success) {
810
- logger_1.logger.error(`Failed to set automatic stop on for device: ${this.deviceName}`);
811
- }
812
- return success;
813
- }
814
- /**
815
- * Turn automatic stop off
816
- */
817
- async automaticStopOff() {
818
- logger_1.logger.debug(`Setting automatic stop off for device: ${this.deviceName}`);
819
- const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', {
820
- ...helpers_1.Helpers.reqBody(this.manager, 'bypassV2'),
821
- cid: this.cid,
822
- configModule: this.configModule,
823
- payload: {
824
- data: {
825
- enabled: false
826
- },
827
- method: 'setAutomaticStop',
828
- source: 'APP'
829
- }
830
- }, helpers_1.Helpers.reqHeaderBypass());
831
- const success = this.checkResponse([response, status], 'automaticStopOff');
832
- if (!success) {
833
- logger_1.logger.error(`Failed to set automatic stop off for device: ${this.deviceName}`);
834
- }
835
- return success;
836
- }
837
- /**
838
- * Set auto mode
839
- */
840
- async setAutoMode() {
841
- logger_1.logger.debug(`Setting auto mode for device: ${this.deviceName}`);
842
- const success = await this.setMode('auto');
843
- if (!success) {
844
- logger_1.logger.error(`Failed to set auto mode for device: ${this.deviceName}`);
845
- }
846
- return success;
847
- }
848
- /**
849
- * Set manual mode
850
- */
851
- async setManualMode() {
852
- logger_1.logger.debug(`Setting manual mode for device: ${this.deviceName}`);
853
- const success = await this.setMode('manual');
854
- if (!success) {
855
- logger_1.logger.error(`Failed to set manual mode for device: ${this.deviceName}`);
856
- }
857
- return success;
858
- }
859
- /**
860
- * Turn off display
861
- */
862
- async turnOffDisplay() {
863
- logger_1.logger.debug(`Turning off display for device: ${this.deviceName}`);
864
- const success = await this.setDisplay(false);
865
- if (!success) {
866
- logger_1.logger.error(`Failed to turn off display for device: ${this.deviceName}`);
867
- }
868
- return success;
869
- }
870
- /**
871
- * Turn on display
872
- */
873
- async turnOnDisplay() {
874
- logger_1.logger.debug(`Turning on display for device: ${this.deviceName}`);
875
- const success = await this.setDisplay(true);
876
- if (!success) {
877
- logger_1.logger.error(`Failed to turn on display for device: ${this.deviceName}`);
878
- }
879
- return success;
880
- }
881
- }
882
- exports.VeSyncHumidifier = VeSyncHumidifier;
883
- /**
884
- * VeSync Warm Humidifier Class
885
- */
886
- class VeSyncWarmHumidifier extends VeSyncHumidifier {
887
- constructor(details, manager) {
888
- super(details, manager);
889
- this.warmLevels = [1, 2, 3];
890
- logger_1.logger.debug(`Initialized VeSyncWarmHumidifier device: ${this.deviceName}`);
891
- }
892
- /**
893
- * Get device details
894
- */
895
- async getDetails() {
896
- const success = await super.getDetails();
897
- if (success && this.details) {
898
- // Add warm humidifier specific fields
899
- this.details = {
900
- ...this.details,
901
- warm_enabled: Boolean(this.details.warm_level && this.details.warm_level > 0),
902
- drying_mode_enabled: this.details.autoDryingSwitch === 1,
903
- drying_mode_state: this.details.dryingMode || '',
904
- drying_mode_level: this.details.dryingLevel || 0,
905
- drying_mode_seconds_remaining: this.details.dryingRemainTime || 0
906
- };
907
- }
908
- return success;
909
- }
910
- /**
911
- * Change fan speed - Implemented to satisfy interface but redirects to setMistLevel
912
- */
913
- async changeFanSpeed(speed) {
914
- logger_1.logger.debug(`Redirecting fan speed change to mist level for device: ${this.deviceName}`);
915
- return this.setMistLevel(speed);
916
- }
917
- /**
918
- * Set device mode
919
- */
920
- async setMode(mode) {
921
- if (!this.modes.includes(mode)) {
922
- const error = `Invalid mode: ${mode}. Must be one of: ${this.modes.join(', ')}`;
923
- logger_1.logger.error(`${error} for device: ${this.deviceName}`);
924
- throw new Error(error);
925
- }
926
- logger_1.logger.debug(`Setting mode to ${mode} for device: ${this.deviceName}`);
927
- const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', {
928
- ...helpers_1.Helpers.reqBody(this.manager, 'bypassV2'),
929
- cid: this.cid,
930
- configModule: this.configModule,
931
- payload: {
932
- data: {
933
- mode
934
- },
935
- method: 'setHumidityMode',
936
- source: 'APP'
937
- }
938
- }, helpers_1.Helpers.reqHeaderBypass());
939
- const success = this.checkResponse([response, status], 'setMode');
940
- if (success) {
941
- this.details.mode = mode;
942
- }
943
- else {
944
- logger_1.logger.error(`Failed to set mode to ${mode} for device: ${this.deviceName}`);
945
- }
946
- return success;
947
- }
948
- /**
949
- * Set warm mist level
950
- */
951
- async setWarmLevel(level) {
952
- if (!this.hasFeature('warm')) {
953
- const error = 'Warm mist control not supported';
954
- logger_1.logger.error(`${error} for device: ${this.deviceName}`);
955
- throw new Error(error);
956
- }
957
- if (!this.warmLevels.includes(level)) {
958
- const error = `Invalid warm level: ${level}. Must be one of: ${this.warmLevels.join(', ')}`;
959
- logger_1.logger.error(`${error} for device: ${this.deviceName}`);
960
- throw new Error(error);
961
- }
962
- logger_1.logger.debug(`Setting warm level to ${level} for device: ${this.deviceName}`);
963
- const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', {
964
- ...helpers_1.Helpers.reqBody(this.manager, 'bypassV2'),
965
- cid: this.cid,
966
- configModule: this.configModule,
967
- payload: {
968
- data: {
969
- warmLevel: level
970
- },
971
- method: 'setWarmLevel',
972
- source: 'APP'
973
- }
974
- }, helpers_1.Helpers.reqHeaderBypass());
975
- const success = this.checkResponse([response, status], 'setWarmLevel');
976
- if (success) {
977
- this.details.warm_level = level;
978
- this.details.warm_enabled = level > 0;
979
- }
980
- else {
981
- logger_1.logger.error(`Failed to set warm level to ${level} for device: ${this.deviceName}`);
982
- }
983
- return success;
984
- }
985
- /**
986
- * Set drying mode enabled
987
- */
988
- async setDryingModeEnabled(enabled) {
989
- if (!this.hasFeature('drying')) {
990
- const error = 'Drying mode not supported';
991
- logger_1.logger.error(`${error} for device: ${this.deviceName}`);
992
- throw new Error(error);
993
- }
994
- logger_1.logger.debug(`Setting drying mode to ${enabled} for device: ${this.deviceName}`);
995
- const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', {
996
- ...helpers_1.Helpers.reqBody(this.manager, 'bypassV2'),
997
- cid: this.cid,
998
- configModule: this.configModule,
999
- payload: {
1000
- data: {
1001
- autoDryingSwitch: enabled ? 1 : 0
1002
- },
1003
- method: 'setDryingMode',
1004
- source: 'APP'
1005
- }
1006
- }, helpers_1.Helpers.reqHeaderBypass());
1007
- const success = this.checkResponse([response, status], 'setDryingModeEnabled');
1008
- if (success) {
1009
- this.details.drying_mode_enabled = enabled;
1010
- this.details.autoDryingSwitch = enabled ? 1 : 0;
1011
- }
1012
- else {
1013
- logger_1.logger.error(`Failed to set drying mode to ${enabled} for device: ${this.deviceName}`);
1014
- }
1015
- return success;
1016
- }
1017
- /**
1018
- * Get warm mist enabled status
1019
- */
1020
- get warmMistEnabled() {
1021
- return this.details.warm_enabled || false;
1022
- }
1023
- /**
1024
- * Get drying mode enabled status
1025
- */
1026
- get dryingModeEnabled() {
1027
- return this.details.drying_mode_enabled || false;
1028
- }
1029
- /**
1030
- * Get drying mode state
1031
- */
1032
- get dryingModeState() {
1033
- return this.details.drying_mode_state || '';
1034
- }
1035
- /**
1036
- * Get drying mode level
1037
- */
1038
- get dryingModeLevel() {
1039
- return this.details.drying_mode_level || 0;
1040
- }
1041
- /**
1042
- * Get drying mode seconds remaining
1043
- */
1044
- get dryingModeSecondsRemaining() {
1045
- return this.details.drying_mode_seconds_remaining || 0;
1046
- }
1047
- }
1048
- exports.VeSyncWarmHumidifier = VeSyncWarmHumidifier;
1049
- /**
1050
- * VeSync Air Purifier with Bypass V2
1051
- */
1052
- class VeSyncAirBaseV2 extends VeSyncAirBypass {
1053
- constructor(details, manager) {
1054
- super(details, manager);
1055
- this._lightDetection = false;
1056
- this._lightDetectionState = false;
1057
- this.setSpeedLevel = null;
1058
- this.autoPreferences = ['default', 'efficient', 'quiet'];
1059
- this.enabled = false;
1060
- this._mode = '';
1061
- this._speed = 0;
1062
- this._timer = null;
1063
- logger_1.logger.debug(`Initialized VeSyncAirBaseV2 device: ${this.deviceName}`);
1064
- }
1065
- buildConfigDict(configDict) {
1066
- if (configDict) {
1067
- this.config = {
1068
- ...this.config, // Preserve existing config
1069
- ...configDict // Merge in new config
1070
- };
1071
- }
1072
- }
1073
- get mode() {
1074
- return this._mode;
1075
- }
1076
- set mode(value) {
1077
- this._mode = value;
1078
- }
1079
- get speed() {
1080
- return this._speed;
1081
- }
1082
- set speed(value) {
1083
- this._speed = value;
1084
- }
1085
- get timer() {
1086
- return this._timer;
1087
- }
1088
- set timer(value) {
1089
- this._timer = value;
1090
- }
1091
- /**
1092
- * Build API dictionary
1093
- */
1094
- buildApiDict(method) {
1095
- const head = helpers_1.Helpers.reqHeaderBypass();
1096
- const body = {
1097
- ...helpers_1.Helpers.reqBody(this.manager, 'bypassV2'),
1098
- cid: this.cid,
1099
- configModule: this.configModule,
1100
- payload: {
1101
- method,
1102
- source: 'APP',
1103
- data: {}
1104
- }
1105
- };
1106
- return [head, body];
1107
- }
1108
- /**
1109
- * Get device details
1110
- */
1111
- async getDetails() {
1112
- logger_1.logger.debug(`Getting details for device: ${this.deviceName}`);
1113
- const [head, body] = this.buildApiDict('getPurifierStatus');
1114
- const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', body, head);
1115
- if (!this.checkResponse([response, status], 'getDetails') || !(response === null || response === void 0 ? void 0 : response.result)) {
1116
- logger_1.logger.debug('Error getting purifier details');
1117
- this.connectionStatus = 'offline';
1118
- return false;
1119
- }
1120
- const innerResponse = response.result;
1121
- if (innerResponse.code !== 0 || !innerResponse.result) {
1122
- logger_1.logger.debug('Error in inner response from purifier');
1123
- this.connectionStatus = 'offline';
1124
- return false;
1125
- }
1126
- const deviceData = innerResponse.result;
1127
- this.buildPurifierDict(deviceData);
1128
- if (deviceData.configuration) {
1129
- this.buildConfigDict(deviceData.configuration);
1130
- }
1131
- return true;
1132
- }
1133
- /**
1134
- * Build purifier dictionary
1135
- */
1136
- buildPurifierDict(devDict) {
1137
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
1138
- this.connectionStatus = 'online';
1139
- const powerSwitch = Boolean((_a = devDict.powerSwitch) !== null && _a !== void 0 ? _a : 0);
1140
- this.enabled = powerSwitch;
1141
- this.deviceStatus = powerSwitch ? 'on' : 'off';
1142
- this.mode = (_b = devDict.workMode) !== null && _b !== void 0 ? _b : 'manual';
1143
- this.speed = (_c = devDict.fanSpeedLevel) !== null && _c !== void 0 ? _c : 0;
1144
- this.setSpeedLevel = (_d = devDict.manualSpeedLevel) !== null && _d !== void 0 ? _d : 1;
1145
- this.details = {
1146
- ...this.details,
1147
- filter_life: (_e = devDict.filterLifePercent) !== null && _e !== void 0 ? _e : 0,
1148
- child_lock: Boolean((_f = devDict.childLockSwitch) !== null && _f !== void 0 ? _f : 0),
1149
- display: Boolean((_g = devDict.screenState) !== null && _g !== void 0 ? _g : 0),
1150
- light_detection_switch: Boolean((_h = devDict.lightDetectionSwitch) !== null && _h !== void 0 ? _h : 0),
1151
- environment_light_state: Boolean((_j = devDict.environmentLightState) !== null && _j !== void 0 ? _j : 0),
1152
- screen_switch: Boolean((_k = devDict.screenSwitch) !== null && _k !== void 0 ? _k : 0)
1153
- };
1154
- if (this.hasFeature('air_quality')) {
1155
- this.details.air_quality_value = (_l = devDict.PM25) !== null && _l !== void 0 ? _l : 0;
1156
- this.details.air_quality = (_m = devDict.AQLevel) !== null && _m !== void 0 ? _m : 0;
1157
- }
1158
- if ('PM1' in devDict)
1159
- this.details.pm1 = devDict.PM1;
1160
- if ('PM10' in devDict)
1161
- this.details.pm10 = devDict.PM10;
1162
- if ('AQPercent' in devDict)
1163
- this.details.aq_percent = devDict.AQPercent;
1164
- if ('fanRotateAngle' in devDict)
1165
- this.details.fan_rotate_angle = devDict.fanRotateAngle;
1166
- if ('filterOpenState' in devDict)
1167
- this.details.filter_open_state = Boolean(devDict.filterOpenState);
1168
- if (((_o = devDict.timerRemain) !== null && _o !== void 0 ? _o : 0) > 0) {
1169
- this.timer = { duration: devDict.timerRemain, action: 'off' };
1170
- }
1171
- if (typeof devDict.autoPreference === 'object' && devDict.autoPreference) {
1172
- this.details.auto_preference_type = (_q = (_p = devDict.autoPreference) === null || _p === void 0 ? void 0 : _p.autoPreferenceType) !== null && _q !== void 0 ? _q : 'default';
1173
- }
1174
- else {
1175
- this.details.auto_preference_type = null;
1176
- }
1177
- }
1178
- /**
1179
- * Toggle device power
1180
- */
1181
- async toggleSwitch(toggle) {
1182
- if (typeof toggle !== 'boolean') {
1183
- logger_1.logger.debug('Invalid toggle value for purifier switch');
1184
- return false;
1185
- }
1186
- const [head, body] = this.buildApiDict('setSwitch');
1187
- body.payload.data = {
1188
- powerSwitch: toggle ? 1 : 0,
1189
- switchIdx: 0
1190
- };
1191
- const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', body, head);
1192
- const success = this.checkResponse([response, status], 'toggleSwitch');
1193
- if (success) {
1194
- this.deviceStatus = toggle ? 'on' : 'off';
1195
- }
1196
- return success;
1197
- }
1198
- /**
1199
- * Turn device on - compatibility method that proxies to toggleSwitch
1200
- */
1201
- async turnOn() {
1202
- logger_1.logger.info(`Turning on device: ${this.deviceName}`);
1203
- return this.toggleSwitch(true);
1204
- }
1205
- /**
1206
- * Turn device off - compatibility method that proxies to toggleSwitch
1207
- */
1208
- async turnOff() {
1209
- logger_1.logger.info(`Turning off device: ${this.deviceName}`);
1210
- return this.toggleSwitch(false);
1211
- }
1212
- /**
1213
- * Change fan speed
1214
- */
1215
- async changeFanSpeed(speed) {
1216
- // const speeds = this.config.levels ?? [];
1217
- // if (!speeds.includes(speed)) {
1218
- // logger.error(`Invalid speed: ${speed}. Must be one of: ${speeds.join(', ')} for device: ${this.deviceName}`);
1219
- // return false;
1220
- // }
1221
- logger_1.logger.info(`Changing fan speed to ${speed} for device: ${this.deviceName}`);
1222
- const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', {
1223
- ...helpers_1.Helpers.reqBody(this.manager, 'bypassV2'),
1224
- cid: this.cid,
1225
- configModule: this.configModule,
1226
- payload: {
1227
- data: {
1228
- id: 0,
1229
- level: speed,
1230
- mode: 'manual',
1231
- type: 'wind'
1232
- },
1233
- method: 'setLevel',
1234
- source: 'APP'
1235
- }
1236
- }, helpers_1.Helpers.reqHeaderBypass());
1237
- const success = this.checkResponse([response, status], 'changeFanSpeed');
1238
- if (success) {
1239
- this.setSpeedLevel = speed;
1240
- this.mode = 'manual';
1241
- }
1242
- return success;
1243
- }
1244
- /**
1245
- * Set mode
1246
- */
1247
- async setMode(mode) {
1248
- if (!this.modes.includes(mode)) {
1249
- logger_1.logger.debug(`Invalid mode: ${mode}. Must be one of: ${this.modes.join(', ')}`);
1250
- return false;
1251
- }
1252
- if (mode === 'manual') {
1253
- if (!this.speed || this.speed === 0) {
1254
- return this.changeFanSpeed(1);
1255
- }
1256
- return this.changeFanSpeed(this.speed);
1257
- }
1258
- if (mode === 'off') {
1259
- return this.turnOff();
1260
- }
1261
- const [head, body] = this.buildApiDict('setPurifierMode');
1262
- body.payload.data = {
1263
- workMode: mode
1264
- };
1265
- const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', body, head);
1266
- const success = this.checkResponse([response, status], 'setMode');
1267
- if (success) {
1268
- this.mode = mode;
1269
- }
1270
- return success;
1271
- }
1272
- /**
1273
- * Set display status
1274
- */
1275
- async setDisplay(enabled) {
1276
- if (!this.hasFeature('display')) {
1277
- const error = 'Display control not supported';
1278
- logger_1.logger.error(`${error} for device: ${this.deviceName}`);
1279
- throw new Error(error);
1280
- }
1281
- const [head, body] = this.buildApiDict('setDisplay');
1282
- body.payload.data = {
1283
- screenSwitch: enabled ? 1 : 0
1284
- };
1285
- const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', body, head);
1286
- const success = this.checkResponse([response, status], 'setDisplay');
1287
- if (success) {
1288
- this.details.screen_switch = enabled;
1289
- }
1290
- return success;
1291
- }
1292
- /**
1293
- * Set child lock
1294
- */
1295
- async setChildLock(enabled) {
1296
- if (!this.hasFeature('child_lock')) {
1297
- const error = 'Child lock not supported';
1298
- logger_1.logger.error(`${error} for device: ${this.deviceName}`);
1299
- throw new Error(error);
1300
- }
1301
- const [head, body] = this.buildApiDict('setChildLock');
1302
- body.payload.data = {
1303
- childLockSwitch: enabled ? 1 : 0
1304
- };
1305
- const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', body, head);
1306
- const success = this.checkResponse([response, status], 'setChildLock');
1307
- if (success) {
1308
- this.details.child_lock = enabled;
1309
- }
1310
- return success;
1311
- }
1312
- /**
1313
- * Set timer
1314
- */
1315
- async setTimer(timerDuration, action = 'off', method = 'powerSwitch') {
1316
- if (!this.hasFeature('timer')) {
1317
- const error = 'Timer not supported';
1318
- logger_1.logger.error(`${error} for device: ${this.deviceName}`);
1319
- throw new Error(error);
1320
- }
1321
- if (!['on', 'off'].includes(action)) {
1322
- logger_1.logger.debug('Invalid action for timer');
1323
- return false;
1324
- }
1325
- if (method !== 'powerSwitch') {
1326
- logger_1.logger.debug('Invalid method for timer');
1327
- return false;
1328
- }
1329
- const [head, body] = this.buildApiDict('addTimerV2');
1330
- body.payload.subDeviceNo = 0;
1331
- body.payload.data = {
1332
- startAct: [{
1333
- type: method,
1334
- num: 0,
1335
- act: action === 'on' ? 1 : 0
1336
- }],
1337
- total: timerDuration,
1338
- subDeviceNo: 0
1339
- };
1340
- const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', body, head);
1341
- const success = this.checkResponse([response, status], 'setTimer');
1342
- if (success) {
1343
- this.timer = { duration: timerDuration, action };
1344
- }
1345
- return success;
1346
- }
1347
- /**
1348
- * Clear timer
1349
- */
1350
- async clearTimer() {
1351
- if (!this.hasFeature('timer')) {
1352
- const error = 'Timer not supported';
1353
- logger_1.logger.error(`${error} for device: ${this.deviceName}`);
1354
- throw new Error(error);
1355
- }
1356
- const [head, body] = this.buildApiDict('delTimerV2');
1357
- body.payload.subDeviceNo = 0;
1358
- body.payload.data = { id: 1, subDeviceNo: 0 };
1359
- const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', body, head);
1360
- const success = this.checkResponse([response, status], 'clearTimer');
1361
- if (success) {
1362
- this.timer = null;
1363
- }
1364
- return success;
1365
- }
1366
- /**
1367
- * Set auto preference
1368
- */
1369
- async setAutoPreference(preference = 'default', roomSize = 600) {
1370
- if (!this.autoPreferences.includes(preference)) {
1371
- logger_1.logger.debug(`Invalid preference: ${preference} - valid preferences are default, efficient, quiet`);
1372
- return false;
1373
- }
1374
- const [head, body] = this.buildApiDict('setAutoPreference');
1375
- body.payload.data = {
1376
- autoPreference: preference,
1377
- roomSize: roomSize
1378
- };
1379
- const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', body, head);
1380
- const success = this.checkResponse([response, status], 'setAutoPreference');
1381
- if (success) {
1382
- this.details.auto_preference = preference;
1383
- }
1384
- return success;
1385
- }
1386
- /**
1387
- * Set light detection
1388
- */
1389
- async setLightDetection(enabled) {
1390
- const [head, body] = this.buildApiDict('setLightDetection');
1391
- body.payload.data = {
1392
- lightDetectionSwitch: enabled ? 1 : 0
1393
- };
1394
- const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', body, head);
1395
- const success = this.checkResponse([response, status], 'setLightDetection');
1396
- if (success) {
1397
- this.details.light_detection_switch = enabled;
1398
- }
1399
- return success;
1400
- }
1401
- /**
1402
- * Get light detection status
1403
- */
1404
- get lightDetection() {
1405
- return Boolean(this.details.light_detection_switch);
1406
- }
1407
- /**
1408
- * Get light detection state
1409
- */
1410
- get lightDetectionState() {
1411
- return Boolean(this.details.environment_light_state);
1412
- }
1413
- /**
1414
- * Get auto preference type
1415
- */
1416
- get autoPreferenceType() {
1417
- return this.details.auto_preference_type;
1418
- }
1419
- /**
1420
- * Display JSON details
1421
- */
1422
- displayJSON() {
1423
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
1424
- const baseInfo = JSON.parse(super.displayJSON());
1425
- const details = {
1426
- ...baseInfo,
1427
- 'Mode': this.mode,
1428
- 'Filter Life': ((_a = this.details.filter_life) !== null && _a !== void 0 ? _a : 0).toString(),
1429
- 'Fan Level': this.speed.toString(),
1430
- 'Display On': (_c = (_b = this.details.display) === null || _b === void 0 ? void 0 : _b.toString()) !== null && _c !== void 0 ? _c : 'false',
1431
- 'Child Lock': ((_d = this.details.child_lock) !== null && _d !== void 0 ? _d : false).toString(),
1432
- 'Night Light': ((_e = this.details.night_light) !== null && _e !== void 0 ? _e : '').toString(),
1433
- 'Display Set On': ((_f = this.details.screen_switch) !== null && _f !== void 0 ? _f : false).toString(),
1434
- 'Light Detection Enabled': ((_g = this.details.light_detection_switch) !== null && _g !== void 0 ? _g : false).toString(),
1435
- 'Environment Light State': ((_h = this.details.environment_light_state) !== null && _h !== void 0 ? _h : false).toString()
1436
- };
1437
- if (this.hasFeature('air_quality')) {
1438
- details['Air Quality Level'] = ((_j = this.details.air_quality) !== null && _j !== void 0 ? _j : '').toString();
1439
- details['Air Quality Value'] = ((_k = this.details.air_quality_value) !== null && _k !== void 0 ? _k : '').toString();
1440
- }
1441
- const everestKeys = {
1442
- 'pm1': 'PM1',
1443
- 'pm10': 'PM10',
1444
- 'fan_rotate_angle': 'Fan Rotate Angle',
1445
- 'filter_open_state': 'Filter Open State'
1446
- };
1447
- for (const [key, value] of Object.entries(everestKeys)) {
1448
- if (key in this.details) {
1449
- details[value] = (_m = (_l = this.details[key]) === null || _l === void 0 ? void 0 : _l.toString()) !== null && _m !== void 0 ? _m : '';
1450
- }
1451
- }
1452
- return JSON.stringify(details, null, 4);
1453
- }
1454
- /**
1455
- * Set oscillation state
1456
- */
1457
- async setOscillation(toggle) {
1458
- logger_1.logger.debug(`Setting oscillation to ${toggle ? 'on' : 'off'} for device: ${this.deviceName}`);
1459
- const [head, body] = this.buildApiDict('setSwitch');
1460
- body.payload.data = {
1461
- oscillationSwitch: toggle ? 1 : 0,
1462
- switchIdx: 0
1463
- };
1464
- const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', body, head);
1465
- const success = this.checkResponse([response, status], 'setOscillation');
1466
- if (success) {
1467
- this.details.oscillationState = toggle;
1468
- this.details.oscillationSwitch = toggle ? 1 : 0;
1469
- }
1470
- return success;
1471
- }
1472
- }
1473
- exports.VeSyncAirBaseV2 = VeSyncAirBaseV2;
1474
- /**
1475
- * VeSync Tower Fan Implementation
1476
- */
1477
- class VeSyncTowerFan extends VeSyncAirBaseV2 {
1478
- constructor(details, manager) {
1479
- super(details, manager);
1480
- this.towerModes = ['normal', 'advancedSleep', 'off'];
1481
- logger_1.logger.debug(`Initialized VeSyncTowerFan device: ${this.deviceName}`);
1482
- }
1483
- /**
1484
- * Get timer status (in seconds)
1485
- */
1486
- get timer() {
1487
- const timerRemain = this.details.timerRemain || 0;
1488
- return timerRemain > 0 ? { duration: timerRemain, action: 'off' } : null;
1489
- }
1490
- set timer(value) {
1491
- if (value) {
1492
- this.details.timerRemain = value.duration;
1493
- }
1494
- else {
1495
- this.details.timerRemain = 0;
1496
- }
1497
- }
1498
- /**
1499
- * Build API dictionary
1500
- */
1501
- buildApiDict(method) {
1502
- const head = helpers_1.Helpers.reqHeaderBypass();
1503
- const body = {
1504
- ...helpers_1.Helpers.reqBody(this.manager, 'bypassV2'),
1505
- cid: this.cid,
1506
- configModule: this.configModule,
1507
- payload: {
1508
- method,
1509
- source: 'APP',
1510
- data: {}
1511
- }
1512
- };
1513
- return [head, body];
1514
- }
1515
- /**
1516
- * Get device details
1517
- */
1518
- async getDetails() {
1519
- logger_1.logger.debug(`Getting details for device: ${this.deviceName}`);
1520
- const [head, body] = this.buildApiDict('getTowerFanStatus');
1521
- const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', body, head);
1522
- if (!this.checkResponse([response, status], 'getDetails') || !(response === null || response === void 0 ? void 0 : response.result)) {
1523
- logger_1.logger.debug('Error getting tower fan details');
1524
- this.connectionStatus = 'offline';
1525
- return false;
1526
- }
1527
- const innerResponse = response.result;
1528
- if (innerResponse.code !== 0 || !innerResponse.result) {
1529
- logger_1.logger.debug('Error in inner response from tower fan');
1530
- this.connectionStatus = 'offline';
1531
- return false;
1532
- }
1533
- const deviceData = innerResponse.result;
1534
- this.deviceStatus = deviceData.powerSwitch === 1 ? 'on' : 'off';
1535
- this.details = {
1536
- powerSwitch: deviceData.powerSwitch,
1537
- workMode: deviceData.workMode,
1538
- manualSpeedLevel: deviceData.manualSpeedLevel,
1539
- fanSpeedLevel: deviceData.fanSpeedLevel,
1540
- screenState: deviceData.screenState,
1541
- screenSwitch: deviceData.screenSwitch,
1542
- oscillationState: deviceData.oscillationState,
1543
- oscillationSwitch: deviceData.oscillationSwitch,
1544
- timerRemain: deviceData.timerRemain,
1545
- temperature: deviceData.temperature || 0,
1546
- humidity: deviceData.humidity || 0,
1547
- thermalComfort: deviceData.thermalComfort,
1548
- sleepPreference: deviceData.sleepPreference || {},
1549
- scheduleCount: deviceData.scheduleCount,
1550
- displayingType: deviceData.displayingType,
1551
- errorCode: deviceData.errorCode
1552
- };
1553
- logger_1.logger.debug(`Successfully got details for device: ${this.deviceName}`);
1554
- return true;
1555
- }
1556
- /**
1557
- * Toggle device power
1558
- */
1559
- async toggleSwitch(toggle) {
1560
- if (typeof toggle !== 'boolean') {
1561
- logger_1.logger.debug('Invalid toggle value for tower fan switch');
1562
- return false;
1563
- }
1564
- const [head, body] = this.buildApiDict('setSwitch');
1565
- body.payload.data = {
1566
- powerSwitch: toggle ? 1 : 0,
1567
- switchIdx: 0
1568
- };
1569
- const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', body, head);
1570
- const success = this.checkResponse([response, status], 'toggleSwitch');
1571
- if (success) {
1572
- this.deviceStatus = toggle ? 'on' : 'off';
1573
- }
1574
- else {
1575
- logger_1.logger.debug('Error toggling tower fan power');
1576
- }
1577
- return success;
1578
- }
1579
- /**
1580
- * Turn device on
1581
- */
1582
- async turnOn() {
1583
- logger_1.logger.debug(`Turning on device: ${this.deviceName}`);
1584
- return this.toggleSwitch(true);
1585
- }
1586
- /**
1587
- * Turn device off
1588
- */
1589
- async turnOff() {
1590
- logger_1.logger.debug(`Turning off device: ${this.deviceName}`);
1591
- return this.toggleSwitch(false);
1592
- }
1593
- /**
1594
- * Set tower fan mode
1595
- */
1596
- async mode_toggle(mode) {
1597
- if (!this.towerModes.includes(mode)) {
1598
- logger_1.logger.debug(`Invalid mode: ${mode}. Must be one of: ${this.towerModes.join(', ')}`);
1599
- return false;
1600
- }
1601
- if (mode === 'off') {
1602
- return this.turnOff();
1603
- }
1604
- const [head, body] = this.buildApiDict('setTowerFanMode');
1605
- body.deviceId = this.cid;
1606
- body.payload.data = {
1607
- workMode: mode
1608
- };
1609
- const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', body, head);
1610
- const success = this.checkResponse([response, status], 'mode_toggle');
1611
- if (success) {
1612
- this.details.workMode = mode;
1613
- }
1614
- else {
1615
- logger_1.logger.error(`Failed to set ${mode} mode for device: ${this.deviceName}`);
1616
- }
1617
- return success;
1618
- }
1619
- /**
1620
- * Change fan speed
1621
- */
1622
- async changeFanSpeed(speed) {
1623
- // const speeds = this.config.levels ?? [];
1624
- // if (!speeds.includes(speed)) {
1625
- // logger.debug(`Invalid speed: ${speed}. Must be one of: ${speeds.join(', ')}`);
1626
- // return false;
1627
- // }
1628
- const [head, body] = this.buildApiDict('setLevel');
1629
- body.payload.data = {
1630
- levelIdx: 0,
1631
- levelType: 'wind',
1632
- manualSpeedLevel: speed
1633
- };
1634
- const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', body, head);
1635
- const success = this.checkResponse([response, status], 'changeFanSpeed');
1636
- if (success) {
1637
- this.details.manualSpeedLevel = speed;
1638
- }
1639
- else {
1640
- logger_1.logger.debug('Error setting fan speed');
1641
- }
1642
- return success;
1643
- }
1644
- /**
1645
- * Set normal mode
1646
- */
1647
- async normal_mode() {
1648
- logger_1.logger.debug(`Setting normal mode for device: ${this.deviceName}`);
1649
- return this.mode_toggle('normal');
1650
- }
1651
- /**
1652
- * Set manual mode - adapter to set mode to normal
1653
- */
1654
- async manual_mode() {
1655
- logger_1.logger.debug(`Setting manual mode for device: ${this.deviceName}`);
1656
- return this.normal_mode();
1657
- }
1658
- /**
1659
- * Set advanced sleep mode
1660
- */
1661
- async advanced_sleep_mode() {
1662
- logger_1.logger.debug(`Setting advanced sleep mode for device: ${this.deviceName}`);
1663
- return this.mode_toggle('advancedSleep');
1664
- }
1665
- /**
1666
- * Set sleep mode - adapter for advanced sleep mode
1667
- */
1668
- async sleep_mode() {
1669
- logger_1.logger.debug(`Setting sleep mode for device: ${this.deviceName}`);
1670
- return this.advanced_sleep_mode();
1671
- }
1672
- /**
1673
- * Override setMode to handle tower fan specific modes
1674
- */
1675
- async setMode(mode) {
1676
- return this.mode_toggle(mode);
1677
- }
1678
- /**
1679
- * Get current speed
1680
- */
1681
- get speed() {
1682
- return this.details.manualSpeedLevel || 0;
1683
- }
1684
- /**
1685
- * Get display status
1686
- */
1687
- get displayState() {
1688
- return Boolean(this.details.screenState);
1689
- }
1690
- /**
1691
- * Get oscillation status
1692
- */
1693
- get oscillationState() {
1694
- return Boolean(this.details.oscillationState);
1695
- }
1696
- /**
1697
- * Get mute status
1698
- */
1699
- get muteState() {
1700
- return Boolean(this.details.muteState);
1701
- }
1702
- /**
1703
- * Get temperature (in tenths of a degree)
1704
- */
1705
- get temperature() {
1706
- return this.details.temperature || 0;
1707
- }
1708
- /**
1709
- * Get humidity percentage
1710
- */
1711
- get humidity() {
1712
- return this.details.humidity || 0;
1713
- }
1714
- /**
1715
- * Get thermal comfort level
1716
- */
1717
- get thermalComfort() {
1718
- return this.details.thermalComfort || 0;
1719
- }
1720
- /**
1721
- * Get sleep preferences
1722
- */
1723
- get sleepPreference() {
1724
- return this.details.sleepPreference || {};
1725
- }
1726
- /**
1727
- * Get schedule count
1728
- */
1729
- get scheduleCount() {
1730
- return this.details.scheduleCount || 0;
1731
- }
1732
- /**
1733
- * Get error code
1734
- */
1735
- get errorCode() {
1736
- return this.details.errorCode || 0;
1737
- }
1738
- /**
1739
- * Turn oscillation on
1740
- */
1741
- async setOscillationOn() {
1742
- return this.setOscillation(true);
1743
- }
1744
- /**
1745
- * Turn oscillation off
1746
- */
1747
- async setOscillationOff() {
1748
- return this.setOscillation(false);
1749
- }
1750
- /**
1751
- * Display device info
1752
- */
1753
- display() {
1754
- super.display();
1755
- const info = [
1756
- ['Mode: ', this.details.workMode || ''],
1757
- ['Speed: ', this.speed],
1758
- ['Fan Speed Level: ', this.details.fanSpeedLevel || 0],
1759
- ['Display: ', this.displayState],
1760
- ['Display Switch: ', this.details.screenSwitch],
1761
- ['Oscillation: ', this.oscillationState],
1762
- ['Oscillation Switch: ', this.details.oscillationSwitch],
1763
- ['Mute: ', this.muteState],
1764
- ['Mute Switch: ', this.details.muteSwitch],
1765
- ['Timer: ', this.timer],
1766
- ['Temperature: ', this.temperature / 10, '°C'],
1767
- ['Humidity: ', this.humidity, '%'],
1768
- ['Thermal Comfort: ', this.thermalComfort],
1769
- ['Sleep Preference: ', JSON.stringify(this.sleepPreference)],
1770
- ['Schedule Count: ', this.scheduleCount],
1771
- ['Displaying Type: ', this.details.displayingType],
1772
- ['Error Code: ', this.errorCode]
1773
- ];
1774
- for (const [key, value, unit = ''] of info) {
1775
- logger_1.logger.info(`${key.toString().padEnd(30, '.')} ${value}${unit}`);
1776
- }
1777
- }
1778
- }
1779
- exports.VeSyncTowerFan = VeSyncTowerFan;
1780
- // Export fan modules dictionary
1781
- exports.fanModules = {
1782
- // Core Series
1783
- 'Core200S': VeSyncAirBypass,
1784
- 'Core300S': VeSyncAirBypass,
1785
- 'Core400S': VeSyncAirBypass,
1786
- 'Core600S': VeSyncAirBypass,
1787
- // LAP Series
1788
- 'LAP-C201S-AUSR': VeSyncAirBypass,
1789
- 'LAP-C202S-WUSR': VeSyncAirBypass,
1790
- 'LAP-C301S-WJP': VeSyncAirBypass,
1791
- 'LAP-C302S-WUSB': VeSyncAirBypass,
1792
- 'LAP-C301S-WAAA': VeSyncAirBypass,
1793
- 'LAP-C401S-WJP': VeSyncAirBypass,
1794
- 'LAP-C401S-WUSR': VeSyncAirBypass,
1795
- 'LAP-C401S-WAAA': VeSyncAirBypass,
1796
- 'LAP-C601S-WUS': VeSyncAirBypass,
1797
- 'LAP-C601S-WUSR': VeSyncAirBypass,
1798
- 'LAP-C601S-WEU': VeSyncAirBypass,
1799
- // Vital100S Series - Using VeSyncAirBaseV2
1800
- 'LAP-V102S-AASR': VeSyncAirBaseV2,
1801
- 'LAP-V102S-WUS': VeSyncAirBaseV2,
1802
- 'LAP-V102S-WEU': VeSyncAirBaseV2,
1803
- 'LAP-V102S-AUSR': VeSyncAirBaseV2,
1804
- 'LAP-V102S-WJP': VeSyncAirBaseV2,
1805
- // Vital200S Series - Using VeSyncAirBaseV2
1806
- 'LAP-V201S-AASR': VeSyncAirBaseV2,
1807
- 'LAP-V201S-WJP': VeSyncAirBaseV2,
1808
- 'LAP-V201S-WEU': VeSyncAirBaseV2,
1809
- 'LAP-V201S-WUS': VeSyncAirBaseV2,
1810
- 'LAP-V201-AUSR': VeSyncAirBaseV2,
1811
- 'LAP-V201S-AUSR': VeSyncAirBaseV2,
1812
- 'LAP-V201S-AEUR': VeSyncAirBaseV2,
1813
- // EverestAir Series - Using VeSyncAirBaseV2
1814
- 'LAP-EL551S-AUS': VeSyncAirBaseV2,
1815
- 'LAP-EL551S-AEUR': VeSyncAirBaseV2,
1816
- 'LAP-EL551S-WEU': VeSyncAirBaseV2,
1817
- 'LAP-EL551S-WUS': VeSyncAirBaseV2,
1818
- // LTF Series
1819
- 'LTF-F422S-KEU': VeSyncTowerFan,
1820
- 'LTF-F422S-WUSR': VeSyncTowerFan,
1821
- 'LTF-F422_WJP': VeSyncTowerFan,
1822
- 'LTF-F422S-WUS': VeSyncTowerFan,
1823
- // Classic Series
1824
- 'Classic300S': VeSyncHumidifier,
1825
- 'Classic200S': VeSyncHumidifier,
1826
- // Dual Series
1827
- 'Dual200S': VeSyncHumidifier,
1828
- // LUH Series
1829
- 'LUH-A601S-WUSB': VeSyncWarmHumidifier,
1830
- 'LUH-A601S-AUSW': VeSyncWarmHumidifier,
1831
- 'LUH-D301S-WUSR': VeSyncWarmHumidifier,
1832
- 'LUH-D301S-WJP': VeSyncWarmHumidifier,
1833
- 'LUH-D301S-WEU': VeSyncWarmHumidifier,
1834
- 'LUH-A602S-WUSR': VeSyncWarmHumidifier,
1835
- 'LUH-A602S-WUS': VeSyncWarmHumidifier,
1836
- 'LUH-A602S-WEUR': VeSyncWarmHumidifier,
1837
- 'LUH-A602S-WEU': VeSyncWarmHumidifier,
1838
- 'LUH-A602S-WJP': VeSyncWarmHumidifier,
1839
- 'LUH-A602S-WUSC': VeSyncWarmHumidifier,
1840
- 'LUH-O451S-WEU': VeSyncWarmHumidifier,
1841
- 'LUH-O451S-WUS': VeSyncWarmHumidifier,
1842
- 'LUH-O451S-WUSR': VeSyncWarmHumidifier,
1843
- 'LUH-O601S-WUS': VeSyncWarmHumidifier,
1844
- 'LUH-O601S-KUS': VeSyncWarmHumidifier,
1845
- 'LUH-M101S-WUS': VeSyncWarmHumidifier,
1846
- 'LUH-M101S-WEUR': VeSyncWarmHumidifier,
1847
- // LEH Series
1848
- 'LEH-S601S-WUS': VeSyncWarmHumidifier,
1849
- 'LEH-S601S-WUSR': VeSyncWarmHumidifier,
1850
- // LV Series
1851
- 'LV-PUR131S': VeSyncAirBypass,
1852
- 'LV-RH131S': VeSyncAirBypass
5
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ var desc = Object.getOwnPropertyDescriptor(m, k);
8
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
9
+ desc = { enumerable: true, get: function() { return m[k]; } };
10
+ }
11
+ Object.defineProperty(o, k2, desc);
12
+ }) : (function(o, m, k, k2) {
13
+ if (k2 === undefined) k2 = k;
14
+ o[k2] = m[k];
15
+ }));
16
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
17
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
1853
18
  };
19
+ Object.defineProperty(exports, "__esModule", { value: true });
20
+ // Re-export all fan implementations from the fans directory
21
+ __exportStar(require("./fans"), exports);