tsvesync 1.0.73 → 1.0.74

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',
@@ -262,52 +156,6 @@ export class VeSyncAirBypass extends VeSyncFan {
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',
@@ -613,41 +348,6 @@ export class VeSyncAirBypass extends VeSyncFan {
613
348
 
614
349
  logger.debug(`Setting timer to ${hours} hours for device: ${this.deviceName}`);
615
350
 
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
- }
648
- }
649
-
650
- // Standard implementation for other devices
651
351
  const [response, status] = await this.callApi(
652
352
  '/cloud/v2/deviceManaged/bypassV2',
653
353
  'post',
@@ -702,39 +402,6 @@ export class VeSyncAirBypass extends VeSyncFan {
702
402
 
703
403
  logger.debug(`Clearing timer for device: ${this.deviceName}`);
704
404
 
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
405
  const [response, status] = await this.callApi(
739
406
  '/cloud/v2/deviceManaged/bypassV2',
740
407
  'post',
@@ -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';
@@ -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
  };
@@ -8,7 +8,7 @@ import { logger } from './logger';
8
8
 
9
9
  interface FanConfig {
10
10
  [key: string]: {
11
- module: 'VeSyncAirBypass' | 'VeSyncHumidifier' | 'VeSyncWarmHumidifier' | 'VeSyncTowerFan' | 'VeSyncAirBaseV2' | 'VeSyncSuperior6000S' | 'VeSyncHumid1000S' | 'VeSyncHumid200S';
11
+ module: 'VeSyncAirBypass' | 'VeSyncHumidifier' | 'VeSyncWarmHumidifier' | 'VeSyncTowerFan' | 'VeSyncAirBaseV2' | 'VeSyncSuperior6000S' | 'VeSyncHumid1000S' | 'VeSyncHumid200S' | 'VeSyncAir131';
12
12
  features: string[];
13
13
  levels?: number[];
14
14
  };
@@ -24,154 +24,154 @@ export const fanConfig: FanConfig = {
24
24
  },
25
25
  'Core300S': {
26
26
  module: 'VeSyncAirBypass',
27
- features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer'],
27
+ features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_speed'],
28
28
  levels: [1, 2, 3, 4]
29
29
  },
30
30
  'Core400S': {
31
31
  module: 'VeSyncAirBypass',
32
- features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer'],
32
+ features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_speed'],
33
33
  levels: [1, 2, 3, 4]
34
34
  },
35
35
  'Core600S': {
36
36
  module: 'VeSyncAirBypass',
37
- features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer'],
37
+ features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_speed'],
38
38
  levels: [1, 2, 3, 4]
39
39
  },
40
40
 
41
41
  // LAP Series
42
42
  'LAP-C201S-AUSR': {
43
43
  module: 'VeSyncAirBypass',
44
- features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer'],
44
+ features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_speed'],
45
45
  levels: [1, 2, 3]
46
46
  },
47
47
  'LAP-C202S-WUSR': {
48
48
  module: 'VeSyncAirBypass',
49
- features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer'],
49
+ features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_speed'],
50
50
  levels: [1, 2, 3]
51
51
  },
52
52
  'LAP-C301S-WJP': {
53
53
  module: 'VeSyncAirBypass',
54
- features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer'],
54
+ features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_speed'],
55
55
  levels: [1, 2, 3, 4]
56
56
  },
57
57
  'LAP-C302S-WUSB': {
58
58
  module: 'VeSyncAirBypass',
59
- features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer'],
59
+ features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_speed'],
60
60
  levels: [1, 2, 3, 4]
61
61
  },
62
62
  'LAP-C301S-WAAA': {
63
63
  module: 'VeSyncAirBypass',
64
- features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer'],
64
+ features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_speed'],
65
65
  levels: [1, 2, 3, 4]
66
66
  },
67
67
  'LAP-C401S-WJP': {
68
68
  module: 'VeSyncAirBypass',
69
- features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer'],
69
+ features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_speed'],
70
70
  levels: [1, 2, 3, 4]
71
71
  },
72
72
  'LAP-C401S-WUSR': {
73
73
  module: 'VeSyncAirBypass',
74
- features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer'],
74
+ features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_speed'],
75
75
  levels: [1, 2, 3, 4]
76
76
  },
77
77
  'LAP-C401S-WAAA': {
78
78
  module: 'VeSyncAirBypass',
79
- features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer'],
79
+ features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_speed'],
80
80
  levels: [1, 2, 3, 4]
81
81
  },
82
82
  'LAP-C601S-WUS': {
83
83
  module: 'VeSyncAirBypass',
84
- features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer'],
84
+ features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_speed'],
85
85
  levels: [1, 2, 3, 4]
86
86
  },
87
87
  'LAP-C601S-WUSR': {
88
88
  module: 'VeSyncAirBypass',
89
- features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer'],
89
+ features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_speed'],
90
90
  levels: [1, 2, 3, 4]
91
91
  },
92
92
  'LAP-C601S-WEU': {
93
93
  module: 'VeSyncAirBypass',
94
- features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer'],
94
+ features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_speed'],
95
95
  levels: [1, 2, 3, 4]
96
96
  },
97
97
  'LAP-V102S-AASR': {
98
98
  module: 'VeSyncAirBaseV2',
99
- features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer'],
99
+ features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_speed'],
100
100
  levels: [1, 2, 3, 4]
101
101
  },
102
102
  'LAP-V102S-WUS': {
103
103
  module: 'VeSyncAirBaseV2',
104
- features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer'],
104
+ features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_speed'],
105
105
  levels: [1, 2, 3, 4]
106
106
  },
107
107
  'LAP-V102S-WEU': {
108
108
  module: 'VeSyncAirBaseV2',
109
- features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer'],
109
+ features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_speed'],
110
110
  levels: [1, 2, 3, 4]
111
111
  },
112
112
  'LAP-V102S-AUSR': {
113
113
  module: 'VeSyncAirBaseV2',
114
- features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer'],
114
+ features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_speed'],
115
115
  levels: [1, 2, 3, 4]
116
116
  },
117
117
  'LAP-V102S-WJP': {
118
118
  module: 'VeSyncAirBaseV2',
119
- features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer'],
119
+ features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_speed'],
120
120
  levels: [1, 2, 3, 4]
121
121
  },
122
122
  'LAP-V201S-AASR': {
123
123
  module: 'VeSyncAirBaseV2',
124
- features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'light_detection'],
124
+ features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'light_detection', 'fan_speed'],
125
125
  levels: [1, 2, 3, 4]
126
126
  },
127
127
  'LAP-V201S-WJP': {
128
128
  module: 'VeSyncAirBaseV2',
129
- features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'light_detection'],
129
+ features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'light_detection', 'fan_speed'],
130
130
  levels: [1, 2, 3, 4]
131
131
  },
132
132
  'LAP-V201S-WEU': {
133
133
  module: 'VeSyncAirBaseV2',
134
- features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'light_detection'],
134
+ features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'light_detection', 'fan_speed'],
135
135
  levels: [1, 2, 3, 4]
136
136
  },
137
137
  'LAP-V201S-WUS': {
138
138
  module: 'VeSyncAirBaseV2',
139
- features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'light_detection'],
139
+ features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'light_detection', 'fan_speed'],
140
140
  levels: [1, 2, 3, 4]
141
141
  },
142
142
  'LAP-V201-AUSR': {
143
143
  module: 'VeSyncAirBaseV2',
144
- features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'light_detection'],
144
+ features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'light_detection', 'fan_speed'],
145
145
  levels: [1, 2, 3, 4]
146
146
  },
147
147
  'LAP-V201S-AUSR': {
148
148
  module: 'VeSyncAirBaseV2',
149
- features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'light_detection'],
149
+ features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'light_detection', 'fan_speed'],
150
150
  levels: [1, 2, 3, 4]
151
151
  },
152
152
  'LAP-V201S-AEUR': {
153
153
  module: 'VeSyncAirBaseV2',
154
- features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'light_detection'],
154
+ features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'light_detection', 'fan_speed'],
155
155
  levels: [1, 2, 3, 4]
156
156
  },
157
157
  'LAP-EL551S-AUS': {
158
158
  module: 'VeSyncAirBaseV2',
159
- features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_rotate'],
159
+ features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_rotate', 'fan_speed'],
160
160
  levels: [1, 2, 3]
161
161
  },
162
162
  'LAP-EL551S-AEUR': {
163
163
  module: 'VeSyncAirBaseV2',
164
- features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_rotate'],
164
+ features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_rotate', 'fan_speed'],
165
165
  levels: [1, 2, 3]
166
166
  },
167
167
  'LAP-EL551S-WEU': {
168
168
  module: 'VeSyncAirBaseV2',
169
- features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_rotate'],
169
+ features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_rotate', 'fan_speed'],
170
170
  levels: [1, 2, 3]
171
171
  },
172
172
  'LAP-EL551S-WUS': {
173
173
  module: 'VeSyncAirBaseV2',
174
- features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_rotate'],
174
+ features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_rotate', 'fan_speed'],
175
175
  levels: [1, 2, 3]
176
176
  },
177
177
 
@@ -304,13 +304,13 @@ export const fanConfig: FanConfig = {
304
304
 
305
305
  // LV Series
306
306
  'LV-PUR131S': {
307
- module: 'VeSyncAirBypass',
308
- features: ['air_quality', 'display', 'child_lock', 'night_light', 'timer'],
307
+ module: 'VeSyncAir131',
308
+ features: ['air_quality', 'display', 'child_lock', 'night_light', 'timer', 'fan_speed'],
309
309
  levels: [1, 2, 3]
310
310
  },
311
311
  'LV-RH131S': {
312
- module: 'VeSyncAirBypass',
313
- features: ['display', 'child_lock', 'night_light', 'timer'],
312
+ module: 'VeSyncAir131',
313
+ features: ['display', 'child_lock', 'night_light', 'timer', 'fan_speed'],
314
314
  levels: [1, 2, 3]
315
315
  }
316
316
  };
@@ -336,7 +336,7 @@ export abstract class VeSyncFan extends VeSyncBaseDevice {
336
336
  protected speed_dict: Record<string, any> = {};
337
337
  protected _timer: number | { duration: number; action: string } | null = null;
338
338
  protected config: {
339
- module: 'VeSyncAirBypass' | 'VeSyncHumidifier' | 'VeSyncWarmHumidifier' | 'VeSyncTowerFan' | 'VeSyncAirBaseV2' | 'VeSyncSuperior6000S' | 'VeSyncHumid1000S' | 'VeSyncHumid200S';
339
+ module: 'VeSyncAirBypass' | 'VeSyncHumidifier' | 'VeSyncWarmHumidifier' | 'VeSyncTowerFan' | 'VeSyncAirBaseV2' | 'VeSyncSuperior6000S' | 'VeSyncHumid1000S' | 'VeSyncHumid200S' | 'VeSyncAir131';
340
340
  features: string[];
341
341
  levels?: number[];
342
342
  };