tsvesync 1.0.73 → 1.0.75

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.
@@ -40,50 +40,6 @@ export class VeSyncAirBypass extends VeSyncFan {
40
40
  async getDetails(): Promise<Boolean> {
41
41
  logger.debug(`Getting details for device: ${this.deviceName}`);
42
42
 
43
- // Special handling for LV series
44
- if (this.deviceType.startsWith('LV-')) {
45
- const [response, status] = await this.callApi(
46
- '/131airPurifier/v1/device/devicedetail',
47
- 'post',
48
- {
49
- acceptLanguage: 'en',
50
- accountID: this.manager.accountId!,
51
- appVersion: '2.8.6',
52
- method: 'devicedetail',
53
- mobileId: '1234567890123456',
54
- phoneBrand: 'SM N9005',
55
- phoneOS: 'Android',
56
- timeZone: this.manager.timeZone!,
57
- token: this.manager.token!,
58
- uuid: this.uuid
59
- },
60
- {
61
- 'accept-language': 'en',
62
- 'accountId': this.manager.accountId!,
63
- 'appVersion': '2.8.6',
64
- 'content-type': 'application/json',
65
- 'tk': this.manager.token!,
66
- 'tz': this.manager.timeZone!
67
- }
68
- );
69
-
70
- const success = this.checkResponse([response, status], 'getDetails');
71
- if (success && response) {
72
- this.deviceStatus = response.result?.result?.deviceStatus === 'on' ? 'on' : 'off';
73
- this.details = {
74
- mode: response.result?.result?.mode || '',
75
- speed: response.result?.result?.level || 0,
76
- filterLife: response.result?.result?.filterLife || 0,
77
- screenStatus: response.result?.result?.display ? 'on' : 'off',
78
- childLock: response.result?.result?.childLock || false,
79
- airQuality: response.result?.result?.airQuality || 0
80
- };
81
- return true;
82
- }
83
- return false;
84
- }
85
-
86
- // Original implementation for other devices
87
43
  const [response, status] = await this.callApi(
88
44
  '/cloud/v2/deviceManaged/bypassV2',
89
45
  'post',
@@ -130,37 +86,6 @@ export class VeSyncAirBypass extends VeSyncFan {
130
86
  async turnOn(): Promise<boolean> {
131
87
  logger.info(`Turning on device: ${this.deviceName}`);
132
88
 
133
- // Special handling for LV series
134
- if (this.deviceType.startsWith('LV-')) {
135
- const [response, status] = await this.callApi(
136
- '/131airPurifier/v1/device/deviceStatus',
137
- 'put',
138
- {
139
- acceptLanguage: 'en',
140
- accountID: this.manager.accountId!,
141
- status: 'on',
142
- timeZone: this.manager.timeZone!,
143
- token: this.manager.token!,
144
- uuid: this.uuid
145
- },
146
- {
147
- 'accept-language': 'en',
148
- 'accountId': this.manager.accountId!,
149
- 'appVersion': '2.8.6',
150
- 'content-type': 'application/json',
151
- 'tk': this.manager.token!,
152
- 'tz': this.manager.timeZone!
153
- }
154
- );
155
-
156
- const success = this.checkResponse([response, status], 'turnOn');
157
- if (!success) {
158
- logger.error(`Failed to turn on device: ${this.deviceName}`);
159
- }
160
- return success;
161
- }
162
-
163
- // Original implementation for other devices
164
89
  const [response, status] = await this.callApi(
165
90
  '/cloud/v2/deviceManaged/bypassV2',
166
91
  'post',
@@ -193,37 +118,6 @@ export class VeSyncAirBypass extends VeSyncFan {
193
118
  async turnOff(): Promise<boolean> {
194
119
  logger.info(`Turning off device: ${this.deviceName}`);
195
120
 
196
- // Special handling for LV series
197
- if (this.deviceType.startsWith('LV-')) {
198
- const [response, status] = await this.callApi(
199
- '/131airPurifier/v1/device/deviceStatus',
200
- 'put',
201
- {
202
- acceptLanguage: 'en',
203
- accountID: this.manager.accountId!,
204
- status: 'off',
205
- timeZone: this.manager.timeZone!,
206
- token: this.manager.token!,
207
- uuid: this.uuid
208
- },
209
- {
210
- 'accept-language': 'en',
211
- 'accountId': this.manager.accountId!,
212
- 'appVersion': '2.8.6',
213
- 'content-type': 'application/json',
214
- 'tk': this.manager.token!,
215
- 'tz': this.manager.timeZone!
216
- }
217
- );
218
-
219
- const success = this.checkResponse([response, status], 'turnOff');
220
- if (!success) {
221
- logger.error(`Failed to turn off device: ${this.deviceName}`);
222
- }
223
- return success;
224
- }
225
-
226
- // Original implementation for other devices
227
121
  const [response, status] = await this.callApi(
228
122
  '/cloud/v2/deviceManaged/bypassV2',
229
123
  'post',
@@ -254,60 +148,14 @@ export class VeSyncAirBypass extends VeSyncFan {
254
148
  * Change fan speed
255
149
  */
256
150
  async changeFanSpeed(speed: number): Promise<boolean> {
257
- // const speeds = this.config.levels ?? [];
258
- // if (!speeds.includes(speed)) {
259
- // logger.error(`Invalid speed: ${speed}. Must be one of: ${speeds.join(', ')} for device: ${this.deviceName}`);
260
- // return false;
261
- // }
151
+ const speeds = this.config.levels ?? [];
152
+ if (!speeds.includes(speed)) {
153
+ logger.error(`Invalid speed: ${speed}. Must be one of: ${speeds.join(', ')} for device: ${this.deviceName}`);
154
+ return false;
155
+ }
262
156
 
263
157
  logger.info(`Changing fan speed to ${speed} for device: ${this.deviceName}`);
264
158
 
265
- // Special handling for LV series
266
- if (this.deviceType.startsWith('LV-')) {
267
- // Check if device is in manual mode
268
- if (this.details.mode !== 'manual') {
269
- logger.debug(`${this.deviceName} not in manual mode, cannot change speed`);
270
- return false;
271
- }
272
-
273
- // Validate speed for LV series (1-3)
274
- if (speed < 1 || speed > 3) {
275
- logger.error(`Invalid fan speed: ${speed}. Must be between 1 and 3 for device: ${this.deviceName}`);
276
- return false;
277
- }
278
-
279
- const [response, status] = await this.callApi(
280
- '/131airPurifier/v1/device/updateSpeed',
281
- 'put',
282
- {
283
- acceptLanguage: 'en',
284
- accountID: this.manager.accountId!,
285
- level: speed,
286
- timeZone: this.manager.timeZone!,
287
- token: this.manager.token!,
288
- uuid: this.uuid
289
- },
290
- {
291
- 'accept-language': 'en',
292
- 'accountId': this.manager.accountId!,
293
- 'appVersion': '2.8.6',
294
- 'content-type': 'application/json',
295
- 'tk': this.manager.token!,
296
- 'tz': this.manager.timeZone!
297
- }
298
- );
299
-
300
- const success = this.checkResponse([response, status], 'changeFanSpeed');
301
- if (success) {
302
- this.details.speed = speed;
303
- return true;
304
- } else {
305
- logger.error(`Failed to change fan speed to ${speed} for device: ${this.deviceName}`);
306
- return false;
307
- }
308
- }
309
-
310
- // Standard implementation for other devices
311
159
  const [response, status] = await this.callApi(
312
160
  '/cloud/v2/deviceManaged/bypassV2',
313
161
  'post',
@@ -348,46 +196,6 @@ export class VeSyncAirBypass extends VeSyncFan {
348
196
 
349
197
  logger.debug(`Setting mode to ${mode} for device: ${this.deviceName}`);
350
198
 
351
- // Special handling for LV series
352
- if (this.deviceType.startsWith('LV-')) {
353
- const payload: Record<string, any> = {
354
- acceptLanguage: 'en',
355
- accountID: this.manager.accountId!,
356
- mode: mode,
357
- timeZone: this.manager.timeZone!,
358
- token: this.manager.token!,
359
- uuid: this.uuid
360
- };
361
-
362
- // For manual mode, we need to set the level
363
- if (mode === 'manual') {
364
- payload.level = this.details.speed || 1;
365
- }
366
-
367
- const [response, status] = await this.callApi(
368
- '/131airPurifier/v1/device/updateMode',
369
- 'put',
370
- payload,
371
- {
372
- 'accept-language': 'en',
373
- 'accountId': this.manager.accountId!,
374
- 'appVersion': '2.8.6',
375
- 'content-type': 'application/json',
376
- 'tk': this.manager.token!,
377
- 'tz': this.manager.timeZone!
378
- }
379
- );
380
-
381
- const success = this.checkResponse([response, status], 'setMode');
382
- if (success) {
383
- this.details.mode = mode;
384
- return true;
385
- } else {
386
- logger.error(`Failed to set mode to ${mode} for device: ${this.deviceName}`);
387
- return false;
388
- }
389
- }
390
-
391
199
  // Special handling for Core200S auto mode
392
200
  if (this.deviceType.includes('Core200S') && mode === 'auto') {
393
201
  // Core200S doesn't support auto mode, so we'll set it to manual mode
@@ -441,40 +249,6 @@ export class VeSyncAirBypass extends VeSyncFan {
441
249
 
442
250
  logger.debug(`Setting display to ${enabled ? 'on' : 'off'} for device: ${this.deviceName}`);
443
251
 
444
- // Special handling for LV series
445
- if (this.deviceType.startsWith('LV-')) {
446
- const [response, status] = await this.callApi(
447
- '/131airPurifier/v1/device/updateScreen',
448
- 'put',
449
- {
450
- acceptLanguage: 'en',
451
- accountID: this.manager.accountId!,
452
- status: enabled ? 'on' : 'off',
453
- timeZone: this.manager.timeZone!,
454
- token: this.manager.token!,
455
- uuid: this.uuid
456
- },
457
- {
458
- 'accept-language': 'en',
459
- 'accountId': this.manager.accountId!,
460
- 'appVersion': '2.8.6',
461
- 'content-type': 'application/json',
462
- 'tk': this.manager.token!,
463
- 'tz': this.manager.timeZone!
464
- }
465
- );
466
-
467
- const success = this.checkResponse([response, status], 'setDisplay');
468
- if (success) {
469
- this.details.screenStatus = enabled ? 'on' : 'off';
470
- return true;
471
- } else {
472
- logger.error(`Failed to set display to ${enabled ? 'on' : 'off'} for device: ${this.deviceName}`);
473
- return false;
474
- }
475
- }
476
-
477
- // Standard implementation for other devices
478
252
  const [response, status] = await this.callApi(
479
253
  '/cloud/v2/deviceManaged/bypassV2',
480
254
  'post',
@@ -527,45 +301,6 @@ export class VeSyncAirBypass extends VeSyncFan {
527
301
 
528
302
  logger.debug(`Setting child lock to ${enabled ? 'on' : 'off'} for device: ${this.deviceName}`);
529
303
 
530
- // Special handling for LV series
531
- if (this.deviceType.startsWith('LV-')) {
532
- const [response, status] = await this.callApi(
533
- '/131airPurifier/v1/device/updateChildLock',
534
- 'put',
535
- {
536
- acceptLanguage: 'en',
537
- accountID: this.manager.accountId!,
538
- status: enabled ? 'on' : 'off',
539
- timeZone: this.manager.timeZone!,
540
- token: this.manager.token!,
541
- uuid: this.uuid
542
- },
543
- {
544
- 'accept-language': 'en',
545
- 'accountId': this.manager.accountId!,
546
- 'appVersion': '2.8.6',
547
- 'content-type': 'application/json',
548
- 'tk': this.manager.token!,
549
- 'tz': this.manager.timeZone!
550
- }
551
- );
552
-
553
- const success = this.checkResponse([response, status], 'setChildLock');
554
- if (success) {
555
- this.details.childLock = enabled;
556
- return true;
557
- } else {
558
- // Check for error code 11000000 (feature not supported)
559
- if (response?.code === 11000000) {
560
- logger.warn(`Child lock control not supported via API for device: ${this.deviceName}`);
561
- return false;
562
- }
563
- logger.error(`Failed to set child lock to ${enabled ? 'on' : 'off'} for device: ${this.deviceName}`);
564
- return false;
565
- }
566
- }
567
-
568
- // Standard implementation for other devices
569
304
  const [response, status] = await this.callApi(
570
305
  '/cloud/v2/deviceManaged/bypassV2',
571
306
  'post',
@@ -611,43 +346,14 @@ export class VeSyncAirBypass extends VeSyncFan {
611
346
  throw new Error(error);
612
347
  }
613
348
 
614
- logger.debug(`Setting timer to ${hours} hours for device: ${this.deviceName}`);
615
-
616
- // Special handling for LV series
617
- if (this.deviceType.startsWith('LV-')) {
618
- const [response, status] = await this.callApi(
619
- '/131airPurifier/v1/device/updateTimer',
620
- 'put',
621
- {
622
- acceptLanguage: 'en',
623
- accountID: this.manager.accountId!,
624
- action: 'off',
625
- duration: hours,
626
- timeZone: this.manager.timeZone!,
627
- token: this.manager.token!,
628
- uuid: this.uuid
629
- },
630
- {
631
- 'accept-language': 'en',
632
- 'accountId': this.manager.accountId!,
633
- 'appVersion': '2.8.6',
634
- 'content-type': 'application/json',
635
- 'tk': this.manager.token!,
636
- 'tz': this.manager.timeZone!
637
- }
638
- );
639
-
640
- const success = this.checkResponse([response, status], 'setTimer');
641
- if (success) {
642
- this.timer = { duration: hours * 3600, action: 'off' };
643
- return true;
644
- } else {
645
- logger.error(`Failed to set timer to ${hours} hours for device: ${this.deviceName}`);
646
- return false;
647
- }
349
+ // Check if device is on - timer can only be set when device is on
350
+ if (this.deviceStatus !== 'on') {
351
+ logger.debug(`Cannot set timer when device is off: ${this.deviceName}`);
352
+ return false;
648
353
  }
649
354
 
650
- // Standard implementation for other devices
355
+ logger.debug(`Setting timer to ${hours} hours for device: ${this.deviceName}`);
356
+
651
357
  const [response, status] = await this.callApi(
652
358
  '/cloud/v2/deviceManaged/bypassV2',
653
359
  'post',
@@ -702,39 +408,6 @@ export class VeSyncAirBypass extends VeSyncFan {
702
408
 
703
409
  logger.debug(`Clearing timer for device: ${this.deviceName}`);
704
410
 
705
- // Special handling for LV series
706
- if (this.deviceType.startsWith('LV-')) {
707
- const [response, status] = await this.callApi(
708
- '/131airPurifier/v1/device/cancelTimer',
709
- 'put',
710
- {
711
- acceptLanguage: 'en',
712
- accountID: this.manager.accountId!,
713
- timeZone: this.manager.timeZone!,
714
- token: this.manager.token!,
715
- uuid: this.uuid
716
- },
717
- {
718
- 'accept-language': 'en',
719
- 'accountId': this.manager.accountId!,
720
- 'appVersion': '2.8.6',
721
- 'content-type': 'application/json',
722
- 'tk': this.manager.token!,
723
- 'tz': this.manager.timeZone!
724
- }
725
- );
726
-
727
- const success = this.checkResponse([response, status], 'clearTimer');
728
- if (success) {
729
- this.timer = null;
730
- return true;
731
- } else {
732
- logger.error(`Failed to clear timer for device: ${this.deviceName}`);
733
- return false;
734
- }
735
- }
736
-
737
- // Standard implementation for other devices
738
411
  const [response, status] = await this.callApi(
739
412
  '/cloud/v2/deviceManaged/bypassV2',
740
413
  'post',
@@ -833,6 +506,12 @@ export class VeSyncAirBypass extends VeSyncFan {
833
506
  * Set auto mode
834
507
  */
835
508
  async autoMode(): Promise<boolean> {
509
+ // Check if auto mode is supported
510
+ if (!this.hasFeature('auto_mode')) {
511
+ logger.debug(`Auto mode not supported for device: ${this.deviceName}`);
512
+ return false;
513
+ }
514
+
836
515
  logger.debug(`Setting auto mode for device: ${this.deviceName}`);
837
516
  const success = await this.setMode('auto');
838
517
  if (!success) {
@@ -888,4 +567,11 @@ export class VeSyncAirBypass extends VeSyncFan {
888
567
  }
889
568
  return success;
890
569
  }
570
+
571
+ /**
572
+ * Get night light state
573
+ */
574
+ get nightLight(): string {
575
+ return this.details.night_light || 'off';
576
+ }
891
577
  }
@@ -1,5 +1,6 @@
1
1
  import { VeSyncAirBypass } from './airBypass';
2
2
  import { VeSyncAirBaseV2 } from './airBaseV2';
3
+ import { VeSyncAir131 } from './air131';
3
4
  import { VeSyncTowerFan } from './towerFan';
4
5
  import { VeSyncHumidifier } from './humidifier';
5
6
  import { VeSyncWarmHumidifier } from './warmHumidifier';
@@ -13,6 +14,7 @@ import { VeSync } from '../vesync';
13
14
  // Re-export all classes
14
15
  export { VeSyncAirBypass } from './airBypass';
15
16
  export { VeSyncAirBaseV2 } from './airBaseV2';
17
+ export { VeSyncAir131 } from './air131';
16
18
  export { VeSyncTowerFan } from './towerFan';
17
19
  export { VeSyncHumidifier } from './humidifier';
18
20
  export { VeSyncWarmHumidifier } from './warmHumidifier';
@@ -71,11 +73,11 @@ export const fanModules: Record<string, new (details: Record<string, any>, manag
71
73
  'LTF-F422S-WUS': VeSyncTowerFan,
72
74
 
73
75
  // Classic Series
74
- 'Classic300S': VeSyncHumidifier,
76
+ 'Classic300S': VeSyncHumid200300S,
75
77
  'Classic200S': VeSyncHumid200S,
76
78
 
77
79
  // Dual Series
78
- 'Dual200S': VeSyncHumidifier,
80
+ 'Dual200S': VeSyncHumid200300S,
79
81
 
80
82
  // LUH Series
81
83
  'LUH-A601S-WUSB': VeSyncHumid200300S,
@@ -102,6 +104,6 @@ export const fanModules: Record<string, new (details: Record<string, any>, manag
102
104
  'LEH-S601S-WUSR': VeSyncSuperior6000S,
103
105
 
104
106
  // LV Series
105
- 'LV-PUR131S': VeSyncAirBypass,
106
- 'LV-RH131S': VeSyncAirBypass
107
+ 'LV-PUR131S': VeSyncAir131,
108
+ 'LV-RH131S': VeSyncAir131
107
109
  };