tsvesync 1.0.11 → 1.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +7 -0
- package/dist/index.js +25 -0
- package/dist/lib/helpers.d.ts +52 -51
- package/dist/lib/helpers.js +135 -112
- package/dist/lib/logger.d.ts +23 -0
- package/dist/lib/logger.js +54 -0
- package/dist/lib/vesync.d.ts +57 -15
- package/dist/lib/vesync.js +341 -217
- package/dist/lib/vesyncBaseDevice.d.ts +25 -50
- package/dist/lib/vesyncBaseDevice.js +63 -90
- package/dist/lib/vesyncBulb.d.ts +88 -0
- package/dist/lib/vesyncBulb.js +295 -1
- package/dist/lib/vesyncBulbImpl.d.ts +38 -0
- package/dist/lib/vesyncBulbImpl.js +230 -0
- package/dist/lib/vesyncFan.d.ts +55 -67
- package/dist/lib/vesyncFan.js +366 -213
- package/dist/lib/vesyncFanImpl.d.ts +173 -0
- package/dist/lib/vesyncFanImpl.js +909 -0
- package/dist/lib/vesyncOutlet.d.ts +70 -0
- package/dist/lib/vesyncOutlet.js +213 -1
- package/dist/lib/vesyncOutletImpl.d.ts +70 -0
- package/dist/lib/vesyncOutletImpl.js +245 -0
- package/dist/lib/vesyncSwitch.d.ts +45 -0
- package/dist/lib/vesyncSwitch.js +77 -1
- package/dist/lib/vesyncSwitchImpl.d.ts +82 -0
- package/dist/lib/vesyncSwitchImpl.js +344 -0
- package/package.json +1 -1
- package/src/index.ts +14 -0
- package/src/lib/helpers.ts +3 -2
- package/src/lib/logger.ts +60 -0
- package/src/lib/vesync.ts +42 -43
- package/src/lib/vesyncBaseDevice.ts +8 -7
- package/src/lib/vesyncBulb.ts +138 -30
- package/src/lib/vesyncBulbImpl.ts +113 -44
- package/src/lib/vesyncFan.ts +2 -4
- package/src/lib/vesyncFanImpl.ts +314 -42
- package/src/lib/vesyncOutlet.ts +140 -13
- package/src/lib/vesyncOutletImpl.ts +41 -0
- package/src/lib/vesyncSwitch.ts +3 -454
- package/src/lib/vesyncSwitchImpl.ts +66 -16
package/src/lib/vesyncFanImpl.ts
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import { VeSyncFan } from './vesyncFan';
|
|
6
6
|
import { VeSync } from './vesync';
|
|
7
7
|
import { Helpers } from './helpers';
|
|
8
|
+
import { logger } from './logger';
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* VeSync Air Purifier with Bypass
|
|
@@ -17,12 +18,14 @@ export class VeSyncAirBypass extends VeSyncFan {
|
|
|
17
18
|
|
|
18
19
|
constructor(details: Record<string, any>, manager: VeSync) {
|
|
19
20
|
super(details, manager);
|
|
21
|
+
logger.debug(`Initialized VeSyncAirBypass device: ${this.deviceName}`);
|
|
20
22
|
}
|
|
21
23
|
|
|
22
24
|
/**
|
|
23
25
|
* Get device details
|
|
24
26
|
*/
|
|
25
27
|
async getDetails(): Promise<void> {
|
|
28
|
+
logger.debug(`Getting details for device: ${this.deviceName}`);
|
|
26
29
|
const [response, status] = await Helpers.callApi(
|
|
27
30
|
'/cloud/v2/deviceManaged/bypassV2',
|
|
28
31
|
'post',
|
|
@@ -59,7 +62,10 @@ export class VeSyncAirBypass extends VeSyncFan {
|
|
|
59
62
|
if (result.configuration) {
|
|
60
63
|
this.config = result.configuration;
|
|
61
64
|
}
|
|
65
|
+
logger.debug(`Successfully got details for device: ${this.deviceName}`);
|
|
62
66
|
}
|
|
67
|
+
} else {
|
|
68
|
+
logger.error(`Failed to get details for device: ${this.deviceName}`);
|
|
63
69
|
}
|
|
64
70
|
}
|
|
65
71
|
|
|
@@ -67,6 +73,7 @@ export class VeSyncAirBypass extends VeSyncFan {
|
|
|
67
73
|
* Turn device on
|
|
68
74
|
*/
|
|
69
75
|
async turnOn(): Promise<boolean> {
|
|
76
|
+
logger.debug(`Turning on device: ${this.deviceName}`);
|
|
70
77
|
const [response, status] = await Helpers.callApi(
|
|
71
78
|
'/cloud/v2/deviceManaged/bypassV2',
|
|
72
79
|
'post',
|
|
@@ -86,13 +93,18 @@ export class VeSyncAirBypass extends VeSyncFan {
|
|
|
86
93
|
Helpers.reqHeaderBypass()
|
|
87
94
|
);
|
|
88
95
|
|
|
89
|
-
|
|
96
|
+
const success = this.checkResponse([response, status], 'turnOn');
|
|
97
|
+
if (!success) {
|
|
98
|
+
logger.error(`Failed to turn on device: ${this.deviceName}`);
|
|
99
|
+
}
|
|
100
|
+
return success;
|
|
90
101
|
}
|
|
91
102
|
|
|
92
103
|
/**
|
|
93
104
|
* Turn device off
|
|
94
105
|
*/
|
|
95
106
|
async turnOff(): Promise<boolean> {
|
|
107
|
+
logger.debug(`Turning off device: ${this.deviceName}`);
|
|
96
108
|
const [response, status] = await Helpers.callApi(
|
|
97
109
|
'/cloud/v2/deviceManaged/bypassV2',
|
|
98
110
|
'post',
|
|
@@ -112,7 +124,11 @@ export class VeSyncAirBypass extends VeSyncFan {
|
|
|
112
124
|
Helpers.reqHeaderBypass()
|
|
113
125
|
);
|
|
114
126
|
|
|
115
|
-
|
|
127
|
+
const success = this.checkResponse([response, status], 'turnOff');
|
|
128
|
+
if (!success) {
|
|
129
|
+
logger.error(`Failed to turn off device: ${this.deviceName}`);
|
|
130
|
+
}
|
|
131
|
+
return success;
|
|
116
132
|
}
|
|
117
133
|
|
|
118
134
|
/**
|
|
@@ -120,9 +136,12 @@ export class VeSyncAirBypass extends VeSyncFan {
|
|
|
120
136
|
*/
|
|
121
137
|
async changeFanSpeed(speed: number): Promise<boolean> {
|
|
122
138
|
if (!this.speeds.includes(speed)) {
|
|
123
|
-
|
|
139
|
+
const error = `Invalid speed: ${speed}. Must be one of: ${this.speeds.join(', ')}`;
|
|
140
|
+
logger.error(`${error} for device: ${this.deviceName}`);
|
|
141
|
+
throw new Error(error);
|
|
124
142
|
}
|
|
125
143
|
|
|
144
|
+
logger.debug(`Changing fan speed to ${speed} for device: ${this.deviceName}`);
|
|
126
145
|
const [response, status] = await Helpers.callApi(
|
|
127
146
|
'/cloud/v2/deviceManaged/bypassV2',
|
|
128
147
|
'post',
|
|
@@ -144,7 +163,11 @@ export class VeSyncAirBypass extends VeSyncFan {
|
|
|
144
163
|
Helpers.reqHeaderBypass()
|
|
145
164
|
);
|
|
146
165
|
|
|
147
|
-
|
|
166
|
+
const success = this.checkResponse([response, status], 'changeFanSpeed');
|
|
167
|
+
if (!success) {
|
|
168
|
+
logger.error(`Failed to change fan speed to ${speed} for device: ${this.deviceName}`);
|
|
169
|
+
}
|
|
170
|
+
return success;
|
|
148
171
|
}
|
|
149
172
|
|
|
150
173
|
/**
|
|
@@ -152,9 +175,12 @@ export class VeSyncAirBypass extends VeSyncFan {
|
|
|
152
175
|
*/
|
|
153
176
|
async setMode(mode: string): Promise<boolean> {
|
|
154
177
|
if (!this.modes.includes(mode as any)) {
|
|
155
|
-
|
|
178
|
+
const error = `Invalid mode: ${mode}. Must be one of: ${this.modes.join(', ')}`;
|
|
179
|
+
logger.error(`${error} for device: ${this.deviceName}`);
|
|
180
|
+
throw new Error(error);
|
|
156
181
|
}
|
|
157
182
|
|
|
183
|
+
logger.debug(`Setting mode to ${mode} for device: ${this.deviceName}`);
|
|
158
184
|
const [response, status] = await Helpers.callApi(
|
|
159
185
|
'/cloud/v2/deviceManaged/bypassV2',
|
|
160
186
|
'post',
|
|
@@ -173,7 +199,11 @@ export class VeSyncAirBypass extends VeSyncFan {
|
|
|
173
199
|
Helpers.reqHeaderBypass()
|
|
174
200
|
);
|
|
175
201
|
|
|
176
|
-
|
|
202
|
+
const success = this.checkResponse([response, status], 'setMode');
|
|
203
|
+
if (!success) {
|
|
204
|
+
logger.error(`Failed to set mode to ${mode} for device: ${this.deviceName}`);
|
|
205
|
+
}
|
|
206
|
+
return success;
|
|
177
207
|
}
|
|
178
208
|
|
|
179
209
|
/**
|
|
@@ -181,9 +211,12 @@ export class VeSyncAirBypass extends VeSyncFan {
|
|
|
181
211
|
*/
|
|
182
212
|
async setDisplay(enabled: boolean): Promise<boolean> {
|
|
183
213
|
if (!this.hasFeature('display')) {
|
|
184
|
-
|
|
214
|
+
const error = 'Display control not supported';
|
|
215
|
+
logger.error(`${error} for device: ${this.deviceName}`);
|
|
216
|
+
throw new Error(error);
|
|
185
217
|
}
|
|
186
218
|
|
|
219
|
+
logger.debug(`Setting display to ${enabled ? 'on' : 'off'} for device: ${this.deviceName}`);
|
|
187
220
|
const [response, status] = await Helpers.callApi(
|
|
188
221
|
'/cloud/v2/deviceManaged/bypassV2',
|
|
189
222
|
'post',
|
|
@@ -202,7 +235,11 @@ export class VeSyncAirBypass extends VeSyncFan {
|
|
|
202
235
|
Helpers.reqHeaderBypass()
|
|
203
236
|
);
|
|
204
237
|
|
|
205
|
-
|
|
238
|
+
const success = this.checkResponse([response, status], 'setDisplay');
|
|
239
|
+
if (!success) {
|
|
240
|
+
logger.error(`Failed to set display to ${enabled ? 'on' : 'off'} for device: ${this.deviceName}`);
|
|
241
|
+
}
|
|
242
|
+
return success;
|
|
206
243
|
}
|
|
207
244
|
|
|
208
245
|
/**
|
|
@@ -210,9 +247,12 @@ export class VeSyncAirBypass extends VeSyncFan {
|
|
|
210
247
|
*/
|
|
211
248
|
async setChildLock(enabled: boolean): Promise<boolean> {
|
|
212
249
|
if (!this.hasFeature('child_lock')) {
|
|
213
|
-
|
|
250
|
+
const error = 'Child lock not supported';
|
|
251
|
+
logger.error(`${error} for device: ${this.deviceName}`);
|
|
252
|
+
throw new Error(error);
|
|
214
253
|
}
|
|
215
254
|
|
|
255
|
+
logger.debug(`Setting child lock to ${enabled ? 'on' : 'off'} for device: ${this.deviceName}`);
|
|
216
256
|
const [response, status] = await Helpers.callApi(
|
|
217
257
|
'/cloud/v2/deviceManaged/bypassV2',
|
|
218
258
|
'post',
|
|
@@ -231,7 +271,11 @@ export class VeSyncAirBypass extends VeSyncFan {
|
|
|
231
271
|
Helpers.reqHeaderBypass()
|
|
232
272
|
);
|
|
233
273
|
|
|
234
|
-
|
|
274
|
+
const success = this.checkResponse([response, status], 'setChildLock');
|
|
275
|
+
if (!success) {
|
|
276
|
+
logger.error(`Failed to set child lock to ${enabled ? 'on' : 'off'} for device: ${this.deviceName}`);
|
|
277
|
+
}
|
|
278
|
+
return success;
|
|
235
279
|
}
|
|
236
280
|
|
|
237
281
|
/**
|
|
@@ -239,9 +283,12 @@ export class VeSyncAirBypass extends VeSyncFan {
|
|
|
239
283
|
*/
|
|
240
284
|
async setTimer(hours: number): Promise<boolean> {
|
|
241
285
|
if (!this.hasFeature('timer')) {
|
|
242
|
-
|
|
286
|
+
const error = 'Timer not supported';
|
|
287
|
+
logger.error(`${error} for device: ${this.deviceName}`);
|
|
288
|
+
throw new Error(error);
|
|
243
289
|
}
|
|
244
290
|
|
|
291
|
+
logger.debug(`Setting timer to ${hours} hours for device: ${this.deviceName}`);
|
|
245
292
|
const [response, status] = await Helpers.callApi(
|
|
246
293
|
'/cloud/v2/deviceManaged/bypassV2',
|
|
247
294
|
'post',
|
|
@@ -261,7 +308,11 @@ export class VeSyncAirBypass extends VeSyncFan {
|
|
|
261
308
|
Helpers.reqHeaderBypass()
|
|
262
309
|
);
|
|
263
310
|
|
|
264
|
-
|
|
311
|
+
const success = this.checkResponse([response, status], 'setTimer');
|
|
312
|
+
if (!success) {
|
|
313
|
+
logger.error(`Failed to set timer to ${hours} hours for device: ${this.deviceName}`);
|
|
314
|
+
}
|
|
315
|
+
return success;
|
|
265
316
|
}
|
|
266
317
|
|
|
267
318
|
/**
|
|
@@ -269,9 +320,12 @@ export class VeSyncAirBypass extends VeSyncFan {
|
|
|
269
320
|
*/
|
|
270
321
|
async clearTimer(): Promise<boolean> {
|
|
271
322
|
if (!this.hasFeature('timer')) {
|
|
272
|
-
|
|
323
|
+
const error = 'Timer not supported';
|
|
324
|
+
logger.error(`${error} for device: ${this.deviceName}`);
|
|
325
|
+
throw new Error(error);
|
|
273
326
|
}
|
|
274
327
|
|
|
328
|
+
logger.debug(`Clearing timer for device: ${this.deviceName}`);
|
|
275
329
|
const [response, status] = await Helpers.callApi(
|
|
276
330
|
'/cloud/v2/deviceManaged/bypassV2',
|
|
277
331
|
'post',
|
|
@@ -288,13 +342,18 @@ export class VeSyncAirBypass extends VeSyncFan {
|
|
|
288
342
|
Helpers.reqHeaderBypass()
|
|
289
343
|
);
|
|
290
344
|
|
|
291
|
-
|
|
345
|
+
const success = this.checkResponse([response, status], 'clearTimer');
|
|
346
|
+
if (!success) {
|
|
347
|
+
logger.error(`Failed to clear timer for device: ${this.deviceName}`);
|
|
348
|
+
}
|
|
349
|
+
return success;
|
|
292
350
|
}
|
|
293
351
|
|
|
294
352
|
/**
|
|
295
353
|
* Turn automatic stop on
|
|
296
354
|
*/
|
|
297
355
|
async automaticStopOn(): Promise<boolean> {
|
|
356
|
+
logger.debug(`Setting automatic stop on for device: ${this.deviceName}`);
|
|
298
357
|
const [response, status] = await Helpers.callApi(
|
|
299
358
|
'/cloud/v2/deviceManaged/bypassV2',
|
|
300
359
|
'post',
|
|
@@ -313,13 +372,18 @@ export class VeSyncAirBypass extends VeSyncFan {
|
|
|
313
372
|
Helpers.reqHeaderBypass()
|
|
314
373
|
);
|
|
315
374
|
|
|
316
|
-
|
|
375
|
+
const success = this.checkResponse([response, status], 'automaticStopOn');
|
|
376
|
+
if (!success) {
|
|
377
|
+
logger.error(`Failed to set automatic stop on for device: ${this.deviceName}`);
|
|
378
|
+
}
|
|
379
|
+
return success;
|
|
317
380
|
}
|
|
318
381
|
|
|
319
382
|
/**
|
|
320
383
|
* Turn automatic stop off
|
|
321
384
|
*/
|
|
322
385
|
async automaticStopOff(): Promise<boolean> {
|
|
386
|
+
logger.debug(`Setting automatic stop off for device: ${this.deviceName}`);
|
|
323
387
|
const [response, status] = await Helpers.callApi(
|
|
324
388
|
'/cloud/v2/deviceManaged/bypassV2',
|
|
325
389
|
'post',
|
|
@@ -338,7 +402,71 @@ export class VeSyncAirBypass extends VeSyncFan {
|
|
|
338
402
|
Helpers.reqHeaderBypass()
|
|
339
403
|
);
|
|
340
404
|
|
|
341
|
-
|
|
405
|
+
const success = this.checkResponse([response, status], 'automaticStopOff');
|
|
406
|
+
if (!success) {
|
|
407
|
+
logger.error(`Failed to set automatic stop off for device: ${this.deviceName}`);
|
|
408
|
+
}
|
|
409
|
+
return success;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
/**
|
|
413
|
+
* Set auto mode
|
|
414
|
+
*/
|
|
415
|
+
async autoMode(): Promise<boolean> {
|
|
416
|
+
logger.debug(`Setting auto mode for device: ${this.deviceName}`);
|
|
417
|
+
const success = await this.setMode('auto');
|
|
418
|
+
if (!success) {
|
|
419
|
+
logger.error(`Failed to set auto mode for device: ${this.deviceName}`);
|
|
420
|
+
}
|
|
421
|
+
return success;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
/**
|
|
425
|
+
* Set manual mode
|
|
426
|
+
*/
|
|
427
|
+
async manualMode(): Promise<boolean> {
|
|
428
|
+
logger.debug(`Setting manual mode for device: ${this.deviceName}`);
|
|
429
|
+
const success = await this.setMode('manual');
|
|
430
|
+
if (!success) {
|
|
431
|
+
logger.error(`Failed to set manual mode for device: ${this.deviceName}`);
|
|
432
|
+
}
|
|
433
|
+
return success;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
/**
|
|
437
|
+
* Set sleep mode
|
|
438
|
+
*/
|
|
439
|
+
async sleepMode(): Promise<boolean> {
|
|
440
|
+
logger.debug(`Setting sleep mode for device: ${this.deviceName}`);
|
|
441
|
+
const success = await this.setMode('sleep');
|
|
442
|
+
if (!success) {
|
|
443
|
+
logger.error(`Failed to set sleep mode for device: ${this.deviceName}`);
|
|
444
|
+
}
|
|
445
|
+
return success;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
/**
|
|
449
|
+
* Turn off display
|
|
450
|
+
*/
|
|
451
|
+
async turnOffDisplay(): Promise<boolean> {
|
|
452
|
+
logger.debug(`Turning off display for device: ${this.deviceName}`);
|
|
453
|
+
const success = await this.setDisplay(false);
|
|
454
|
+
if (!success) {
|
|
455
|
+
logger.error(`Failed to turn off display for device: ${this.deviceName}`);
|
|
456
|
+
}
|
|
457
|
+
return success;
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
/**
|
|
461
|
+
* Turn on display
|
|
462
|
+
*/
|
|
463
|
+
async turnOnDisplay(): Promise<boolean> {
|
|
464
|
+
logger.debug(`Turning on display for device: ${this.deviceName}`);
|
|
465
|
+
const success = await this.setDisplay(true);
|
|
466
|
+
if (!success) {
|
|
467
|
+
logger.error(`Failed to turn on display for device: ${this.deviceName}`);
|
|
468
|
+
}
|
|
469
|
+
return success;
|
|
342
470
|
}
|
|
343
471
|
}
|
|
344
472
|
|
|
@@ -354,12 +482,14 @@ export class VeSyncHumidifier extends VeSyncFan {
|
|
|
354
482
|
|
|
355
483
|
constructor(details: Record<string, any>, manager: VeSync) {
|
|
356
484
|
super(details, manager);
|
|
485
|
+
logger.debug(`Initialized VeSyncHumidifier device: ${this.deviceName}`);
|
|
357
486
|
}
|
|
358
487
|
|
|
359
488
|
/**
|
|
360
489
|
* Get device details
|
|
361
490
|
*/
|
|
362
491
|
async getDetails(): Promise<void> {
|
|
492
|
+
logger.debug(`Getting details for device: ${this.deviceName}`);
|
|
363
493
|
const [response, status] = await Helpers.callApi(
|
|
364
494
|
'/cloud/v2/deviceManaged/bypassV2',
|
|
365
495
|
'post',
|
|
@@ -376,8 +506,12 @@ export class VeSyncHumidifier extends VeSyncFan {
|
|
|
376
506
|
Helpers.reqHeaderBypass()
|
|
377
507
|
);
|
|
378
508
|
|
|
379
|
-
|
|
509
|
+
const success = this.checkResponse([response, status], 'getDetails');
|
|
510
|
+
if (success) {
|
|
380
511
|
this.details = response.result.result;
|
|
512
|
+
logger.debug(`Successfully got details for device: ${this.deviceName}`);
|
|
513
|
+
} else {
|
|
514
|
+
logger.error(`Failed to get details for device: ${this.deviceName}`);
|
|
381
515
|
}
|
|
382
516
|
}
|
|
383
517
|
|
|
@@ -385,6 +519,7 @@ export class VeSyncHumidifier extends VeSyncFan {
|
|
|
385
519
|
* Turn device on
|
|
386
520
|
*/
|
|
387
521
|
async turnOn(): Promise<boolean> {
|
|
522
|
+
logger.debug(`Turning on device: ${this.deviceName}`);
|
|
388
523
|
const [response, status] = await Helpers.callApi(
|
|
389
524
|
'/cloud/v2/deviceManaged/bypassV2',
|
|
390
525
|
'post',
|
|
@@ -404,13 +539,18 @@ export class VeSyncHumidifier extends VeSyncFan {
|
|
|
404
539
|
Helpers.reqHeaderBypass()
|
|
405
540
|
);
|
|
406
541
|
|
|
407
|
-
|
|
542
|
+
const success = this.checkResponse([response, status], 'turnOn');
|
|
543
|
+
if (!success) {
|
|
544
|
+
logger.error(`Failed to turn on device: ${this.deviceName}`);
|
|
545
|
+
}
|
|
546
|
+
return success;
|
|
408
547
|
}
|
|
409
548
|
|
|
410
549
|
/**
|
|
411
550
|
* Turn device off
|
|
412
551
|
*/
|
|
413
552
|
async turnOff(): Promise<boolean> {
|
|
553
|
+
logger.debug(`Turning off device: ${this.deviceName}`);
|
|
414
554
|
const [response, status] = await Helpers.callApi(
|
|
415
555
|
'/cloud/v2/deviceManaged/bypassV2',
|
|
416
556
|
'post',
|
|
@@ -430,7 +570,11 @@ export class VeSyncHumidifier extends VeSyncFan {
|
|
|
430
570
|
Helpers.reqHeaderBypass()
|
|
431
571
|
);
|
|
432
572
|
|
|
433
|
-
|
|
573
|
+
const success = this.checkResponse([response, status], 'turnOff');
|
|
574
|
+
if (!success) {
|
|
575
|
+
logger.error(`Failed to turn off device: ${this.deviceName}`);
|
|
576
|
+
}
|
|
577
|
+
return success;
|
|
434
578
|
}
|
|
435
579
|
|
|
436
580
|
/**
|
|
@@ -438,9 +582,12 @@ export class VeSyncHumidifier extends VeSyncFan {
|
|
|
438
582
|
*/
|
|
439
583
|
async changeFanSpeed(speed: number): Promise<boolean> {
|
|
440
584
|
if (!this.speeds.includes(speed)) {
|
|
441
|
-
|
|
585
|
+
const error = `Invalid speed: ${speed}. Must be one of: ${this.speeds.join(', ')}`;
|
|
586
|
+
logger.error(`${error} for device: ${this.deviceName}`);
|
|
587
|
+
throw new Error(error);
|
|
442
588
|
}
|
|
443
589
|
|
|
590
|
+
logger.debug(`Changing fan speed to ${speed} for device: ${this.deviceName}`);
|
|
444
591
|
const [response, status] = await Helpers.callApi(
|
|
445
592
|
'/cloud/v2/deviceManaged/bypassV2',
|
|
446
593
|
'post',
|
|
@@ -461,7 +608,11 @@ export class VeSyncHumidifier extends VeSyncFan {
|
|
|
461
608
|
Helpers.reqHeaderBypass()
|
|
462
609
|
);
|
|
463
610
|
|
|
464
|
-
|
|
611
|
+
const success = this.checkResponse([response, status], 'changeFanSpeed');
|
|
612
|
+
if (!success) {
|
|
613
|
+
logger.error(`Failed to change fan speed to ${speed} for device: ${this.deviceName}`);
|
|
614
|
+
}
|
|
615
|
+
return success;
|
|
465
616
|
}
|
|
466
617
|
|
|
467
618
|
/**
|
|
@@ -469,9 +620,12 @@ export class VeSyncHumidifier extends VeSyncFan {
|
|
|
469
620
|
*/
|
|
470
621
|
async setMode(mode: string): Promise<boolean> {
|
|
471
622
|
if (!this.modes.includes(mode as any)) {
|
|
472
|
-
|
|
623
|
+
const error = `Invalid mode: ${mode}. Must be one of: ${this.modes.join(', ')}`;
|
|
624
|
+
logger.error(`${error} for device: ${this.deviceName}`);
|
|
625
|
+
throw new Error(error);
|
|
473
626
|
}
|
|
474
627
|
|
|
628
|
+
logger.debug(`Setting mode to ${mode} for device: ${this.deviceName}`);
|
|
475
629
|
const [response, status] = await Helpers.callApi(
|
|
476
630
|
'/cloud/v2/deviceManaged/bypassV2',
|
|
477
631
|
'post',
|
|
@@ -490,7 +644,11 @@ export class VeSyncHumidifier extends VeSyncFan {
|
|
|
490
644
|
Helpers.reqHeaderBypass()
|
|
491
645
|
);
|
|
492
646
|
|
|
493
|
-
|
|
647
|
+
const success = this.checkResponse([response, status], 'setMode');
|
|
648
|
+
if (!success) {
|
|
649
|
+
logger.error(`Failed to set mode to ${mode} for device: ${this.deviceName}`);
|
|
650
|
+
}
|
|
651
|
+
return success;
|
|
494
652
|
}
|
|
495
653
|
|
|
496
654
|
/**
|
|
@@ -498,13 +656,18 @@ export class VeSyncHumidifier extends VeSyncFan {
|
|
|
498
656
|
*/
|
|
499
657
|
async setMistLevel(level: number): Promise<boolean> {
|
|
500
658
|
if (!this.hasFeature('mist')) {
|
|
501
|
-
|
|
659
|
+
const error = 'Mist control not supported';
|
|
660
|
+
logger.error(`${error} for device: ${this.deviceName}`);
|
|
661
|
+
throw new Error(error);
|
|
502
662
|
}
|
|
503
663
|
|
|
504
664
|
if (!this.mistLevels.includes(level)) {
|
|
505
|
-
|
|
665
|
+
const error = `Invalid mist level: ${level}. Must be one of: ${this.mistLevels.join(', ')}`;
|
|
666
|
+
logger.error(`${error} for device: ${this.deviceName}`);
|
|
667
|
+
throw new Error(error);
|
|
506
668
|
}
|
|
507
669
|
|
|
670
|
+
logger.debug(`Setting mist level to ${level} for device: ${this.deviceName}`);
|
|
508
671
|
const [response, status] = await Helpers.callApi(
|
|
509
672
|
'/cloud/v2/deviceManaged/bypassV2',
|
|
510
673
|
'post',
|
|
@@ -523,7 +686,11 @@ export class VeSyncHumidifier extends VeSyncFan {
|
|
|
523
686
|
Helpers.reqHeaderBypass()
|
|
524
687
|
);
|
|
525
688
|
|
|
526
|
-
|
|
689
|
+
const success = this.checkResponse([response, status], 'setMistLevel');
|
|
690
|
+
if (!success) {
|
|
691
|
+
logger.error(`Failed to set mist level to ${level} for device: ${this.deviceName}`);
|
|
692
|
+
}
|
|
693
|
+
return success;
|
|
527
694
|
}
|
|
528
695
|
|
|
529
696
|
/**
|
|
@@ -531,13 +698,18 @@ export class VeSyncHumidifier extends VeSyncFan {
|
|
|
531
698
|
*/
|
|
532
699
|
async setHumidity(humidity: number): Promise<boolean> {
|
|
533
700
|
if (!this.hasFeature('humidity')) {
|
|
534
|
-
|
|
701
|
+
const error = 'Humidity control not supported';
|
|
702
|
+
logger.error(`${error} for device: ${this.deviceName}`);
|
|
703
|
+
throw new Error(error);
|
|
535
704
|
}
|
|
536
705
|
|
|
537
706
|
if (humidity < this.humidityRange.min || humidity > this.humidityRange.max) {
|
|
538
|
-
|
|
707
|
+
const error = `Invalid humidity: ${humidity}. Must be between ${this.humidityRange.min} and ${this.humidityRange.max}`;
|
|
708
|
+
logger.error(`${error} for device: ${this.deviceName}`);
|
|
709
|
+
throw new Error(error);
|
|
539
710
|
}
|
|
540
711
|
|
|
712
|
+
logger.debug(`Setting target humidity to ${humidity}% for device: ${this.deviceName}`);
|
|
541
713
|
const [response, status] = await Helpers.callApi(
|
|
542
714
|
'/cloud/v2/deviceManaged/bypassV2',
|
|
543
715
|
'post',
|
|
@@ -556,7 +728,11 @@ export class VeSyncHumidifier extends VeSyncFan {
|
|
|
556
728
|
Helpers.reqHeaderBypass()
|
|
557
729
|
);
|
|
558
730
|
|
|
559
|
-
|
|
731
|
+
const success = this.checkResponse([response, status], 'setHumidity');
|
|
732
|
+
if (!success) {
|
|
733
|
+
logger.error(`Failed to set target humidity to ${humidity}% for device: ${this.deviceName}`);
|
|
734
|
+
}
|
|
735
|
+
return success;
|
|
560
736
|
}
|
|
561
737
|
|
|
562
738
|
/**
|
|
@@ -564,9 +740,12 @@ export class VeSyncHumidifier extends VeSyncFan {
|
|
|
564
740
|
*/
|
|
565
741
|
async setDisplay(enabled: boolean): Promise<boolean> {
|
|
566
742
|
if (!this.hasFeature('display')) {
|
|
567
|
-
|
|
743
|
+
const error = 'Display control not supported';
|
|
744
|
+
logger.error(`${error} for device: ${this.deviceName}`);
|
|
745
|
+
throw new Error(error);
|
|
568
746
|
}
|
|
569
747
|
|
|
748
|
+
logger.debug(`Setting display to ${enabled ? 'on' : 'off'} for device: ${this.deviceName}`);
|
|
570
749
|
const [response, status] = await Helpers.callApi(
|
|
571
750
|
'/cloud/v2/deviceManaged/bypassV2',
|
|
572
751
|
'post',
|
|
@@ -585,7 +764,11 @@ export class VeSyncHumidifier extends VeSyncFan {
|
|
|
585
764
|
Helpers.reqHeaderBypass()
|
|
586
765
|
);
|
|
587
766
|
|
|
588
|
-
|
|
767
|
+
const success = this.checkResponse([response, status], 'setDisplay');
|
|
768
|
+
if (!success) {
|
|
769
|
+
logger.error(`Failed to set display to ${enabled ? 'on' : 'off'} for device: ${this.deviceName}`);
|
|
770
|
+
}
|
|
771
|
+
return success;
|
|
589
772
|
}
|
|
590
773
|
|
|
591
774
|
/**
|
|
@@ -593,9 +776,12 @@ export class VeSyncHumidifier extends VeSyncFan {
|
|
|
593
776
|
*/
|
|
594
777
|
async setTimer(hours: number): Promise<boolean> {
|
|
595
778
|
if (!this.hasFeature('timer')) {
|
|
596
|
-
|
|
779
|
+
const error = 'Timer not supported';
|
|
780
|
+
logger.error(`${error} for device: ${this.deviceName}`);
|
|
781
|
+
throw new Error(error);
|
|
597
782
|
}
|
|
598
783
|
|
|
784
|
+
logger.debug(`Setting timer to ${hours} hours for device: ${this.deviceName}`);
|
|
599
785
|
const [response, status] = await Helpers.callApi(
|
|
600
786
|
'/cloud/v2/deviceManaged/bypassV2',
|
|
601
787
|
'post',
|
|
@@ -615,7 +801,11 @@ export class VeSyncHumidifier extends VeSyncFan {
|
|
|
615
801
|
Helpers.reqHeaderBypass()
|
|
616
802
|
);
|
|
617
803
|
|
|
618
|
-
|
|
804
|
+
const success = this.checkResponse([response, status], 'setTimer');
|
|
805
|
+
if (!success) {
|
|
806
|
+
logger.error(`Failed to set timer to ${hours} hours for device: ${this.deviceName}`);
|
|
807
|
+
}
|
|
808
|
+
return success;
|
|
619
809
|
}
|
|
620
810
|
|
|
621
811
|
/**
|
|
@@ -623,9 +813,12 @@ export class VeSyncHumidifier extends VeSyncFan {
|
|
|
623
813
|
*/
|
|
624
814
|
async clearTimer(): Promise<boolean> {
|
|
625
815
|
if (!this.hasFeature('timer')) {
|
|
626
|
-
|
|
816
|
+
const error = 'Timer not supported';
|
|
817
|
+
logger.error(`${error} for device: ${this.deviceName}`);
|
|
818
|
+
throw new Error(error);
|
|
627
819
|
}
|
|
628
820
|
|
|
821
|
+
logger.debug(`Clearing timer for device: ${this.deviceName}`);
|
|
629
822
|
const [response, status] = await Helpers.callApi(
|
|
630
823
|
'/cloud/v2/deviceManaged/bypassV2',
|
|
631
824
|
'post',
|
|
@@ -642,13 +835,18 @@ export class VeSyncHumidifier extends VeSyncFan {
|
|
|
642
835
|
Helpers.reqHeaderBypass()
|
|
643
836
|
);
|
|
644
837
|
|
|
645
|
-
|
|
838
|
+
const success = this.checkResponse([response, status], 'clearTimer');
|
|
839
|
+
if (!success) {
|
|
840
|
+
logger.error(`Failed to clear timer for device: ${this.deviceName}`);
|
|
841
|
+
}
|
|
842
|
+
return success;
|
|
646
843
|
}
|
|
647
844
|
|
|
648
845
|
/**
|
|
649
846
|
* Turn automatic stop on
|
|
650
847
|
*/
|
|
651
848
|
async automaticStopOn(): Promise<boolean> {
|
|
849
|
+
logger.debug(`Setting automatic stop on for device: ${this.deviceName}`);
|
|
652
850
|
const [response, status] = await Helpers.callApi(
|
|
653
851
|
'/cloud/v2/deviceManaged/bypassV2',
|
|
654
852
|
'post',
|
|
@@ -667,13 +865,18 @@ export class VeSyncHumidifier extends VeSyncFan {
|
|
|
667
865
|
Helpers.reqHeaderBypass()
|
|
668
866
|
);
|
|
669
867
|
|
|
670
|
-
|
|
868
|
+
const success = this.checkResponse([response, status], 'automaticStopOn');
|
|
869
|
+
if (!success) {
|
|
870
|
+
logger.error(`Failed to set automatic stop on for device: ${this.deviceName}`);
|
|
871
|
+
}
|
|
872
|
+
return success;
|
|
671
873
|
}
|
|
672
874
|
|
|
673
875
|
/**
|
|
674
876
|
* Turn automatic stop off
|
|
675
877
|
*/
|
|
676
878
|
async automaticStopOff(): Promise<boolean> {
|
|
879
|
+
logger.debug(`Setting automatic stop off for device: ${this.deviceName}`);
|
|
677
880
|
const [response, status] = await Helpers.callApi(
|
|
678
881
|
'/cloud/v2/deviceManaged/bypassV2',
|
|
679
882
|
'post',
|
|
@@ -692,7 +895,59 @@ export class VeSyncHumidifier extends VeSyncFan {
|
|
|
692
895
|
Helpers.reqHeaderBypass()
|
|
693
896
|
);
|
|
694
897
|
|
|
695
|
-
|
|
898
|
+
const success = this.checkResponse([response, status], 'automaticStopOff');
|
|
899
|
+
if (!success) {
|
|
900
|
+
logger.error(`Failed to set automatic stop off for device: ${this.deviceName}`);
|
|
901
|
+
}
|
|
902
|
+
return success;
|
|
903
|
+
}
|
|
904
|
+
|
|
905
|
+
/**
|
|
906
|
+
* Set auto mode
|
|
907
|
+
*/
|
|
908
|
+
async setAutoMode(): Promise<boolean> {
|
|
909
|
+
logger.debug(`Setting auto mode for device: ${this.deviceName}`);
|
|
910
|
+
const success = await this.setMode('auto');
|
|
911
|
+
if (!success) {
|
|
912
|
+
logger.error(`Failed to set auto mode for device: ${this.deviceName}`);
|
|
913
|
+
}
|
|
914
|
+
return success;
|
|
915
|
+
}
|
|
916
|
+
|
|
917
|
+
/**
|
|
918
|
+
* Set manual mode
|
|
919
|
+
*/
|
|
920
|
+
async setManualMode(): Promise<boolean> {
|
|
921
|
+
logger.debug(`Setting manual mode for device: ${this.deviceName}`);
|
|
922
|
+
const success = await this.setMode('manual');
|
|
923
|
+
if (!success) {
|
|
924
|
+
logger.error(`Failed to set manual mode for device: ${this.deviceName}`);
|
|
925
|
+
}
|
|
926
|
+
return success;
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
/**
|
|
930
|
+
* Turn off display
|
|
931
|
+
*/
|
|
932
|
+
async turnOffDisplay(): Promise<boolean> {
|
|
933
|
+
logger.debug(`Turning off display for device: ${this.deviceName}`);
|
|
934
|
+
const success = await this.setDisplay(false);
|
|
935
|
+
if (!success) {
|
|
936
|
+
logger.error(`Failed to turn off display for device: ${this.deviceName}`);
|
|
937
|
+
}
|
|
938
|
+
return success;
|
|
939
|
+
}
|
|
940
|
+
|
|
941
|
+
/**
|
|
942
|
+
* Turn on display
|
|
943
|
+
*/
|
|
944
|
+
async turnOnDisplay(): Promise<boolean> {
|
|
945
|
+
logger.debug(`Turning on display for device: ${this.deviceName}`);
|
|
946
|
+
const success = await this.setDisplay(true);
|
|
947
|
+
if (!success) {
|
|
948
|
+
logger.error(`Failed to turn on display for device: ${this.deviceName}`);
|
|
949
|
+
}
|
|
950
|
+
return success;
|
|
696
951
|
}
|
|
697
952
|
}
|
|
698
953
|
|
|
@@ -704,6 +959,7 @@ export class VeSyncWarmHumidifier extends VeSyncHumidifier {
|
|
|
704
959
|
|
|
705
960
|
constructor(details: Record<string, any>, manager: VeSync) {
|
|
706
961
|
super(details, manager);
|
|
962
|
+
logger.debug(`Initialized VeSyncWarmHumidifier device: ${this.deviceName}`);
|
|
707
963
|
}
|
|
708
964
|
|
|
709
965
|
/**
|
|
@@ -711,13 +967,18 @@ export class VeSyncWarmHumidifier extends VeSyncHumidifier {
|
|
|
711
967
|
*/
|
|
712
968
|
async setWarmLevel(level: number): Promise<boolean> {
|
|
713
969
|
if (!this.hasFeature('warm')) {
|
|
714
|
-
|
|
970
|
+
const error = 'Warm mist control not supported';
|
|
971
|
+
logger.error(`${error} for device: ${this.deviceName}`);
|
|
972
|
+
throw new Error(error);
|
|
715
973
|
}
|
|
716
974
|
|
|
717
975
|
if (!this.warmLevels.includes(level)) {
|
|
718
|
-
|
|
976
|
+
const error = `Invalid warm level: ${level}. Must be one of: ${this.warmLevels.join(', ')}`;
|
|
977
|
+
logger.error(`${error} for device: ${this.deviceName}`);
|
|
978
|
+
throw new Error(error);
|
|
719
979
|
}
|
|
720
980
|
|
|
981
|
+
logger.debug(`Setting warm level to ${level} for device: ${this.deviceName}`);
|
|
721
982
|
const [response, status] = await Helpers.callApi(
|
|
722
983
|
'/cloud/v2/deviceManaged/bypassV2',
|
|
723
984
|
'post',
|
|
@@ -736,7 +997,11 @@ export class VeSyncWarmHumidifier extends VeSyncHumidifier {
|
|
|
736
997
|
Helpers.reqHeaderBypass()
|
|
737
998
|
);
|
|
738
999
|
|
|
739
|
-
|
|
1000
|
+
const success = this.checkResponse([response, status], 'setWarmLevel');
|
|
1001
|
+
if (!success) {
|
|
1002
|
+
logger.error(`Failed to set warm level to ${level} for device: ${this.deviceName}`);
|
|
1003
|
+
}
|
|
1004
|
+
return success;
|
|
740
1005
|
}
|
|
741
1006
|
|
|
742
1007
|
/**
|
|
@@ -744,9 +1009,12 @@ export class VeSyncWarmHumidifier extends VeSyncHumidifier {
|
|
|
744
1009
|
*/
|
|
745
1010
|
async setDryingModeEnabled(enabled: boolean): Promise<boolean> {
|
|
746
1011
|
if (!this.hasFeature('drying')) {
|
|
747
|
-
|
|
1012
|
+
const error = 'Drying mode not supported';
|
|
1013
|
+
logger.error(`${error} for device: ${this.deviceName}`);
|
|
1014
|
+
throw new Error(error);
|
|
748
1015
|
}
|
|
749
1016
|
|
|
1017
|
+
logger.debug(`Setting drying mode to ${enabled} for device: ${this.deviceName}`);
|
|
750
1018
|
const [response, status] = await Helpers.callApi(
|
|
751
1019
|
'/cloud/v2/deviceManaged/bypassV2',
|
|
752
1020
|
'post',
|
|
@@ -765,7 +1033,11 @@ export class VeSyncWarmHumidifier extends VeSyncHumidifier {
|
|
|
765
1033
|
Helpers.reqHeaderBypass()
|
|
766
1034
|
);
|
|
767
1035
|
|
|
768
|
-
|
|
1036
|
+
const success = this.checkResponse([response, status], 'setDryingModeEnabled');
|
|
1037
|
+
if (!success) {
|
|
1038
|
+
logger.error(`Failed to set drying mode to ${enabled} for device: ${this.deviceName}`);
|
|
1039
|
+
}
|
|
1040
|
+
return success;
|
|
769
1041
|
}
|
|
770
1042
|
}
|
|
771
1043
|
|