tsvesync 1.3.13 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/fans/airBaseV2.d.ts +8 -0
- package/dist/lib/fans/airBaseV2.js +71 -8
- package/dist/lib/fans/airBypass.d.ts +1 -1
- package/dist/lib/fans/airBypass.js +12 -7
- package/dist/lib/vesyncFan.d.ts +25 -10
- package/dist/lib/vesyncFan.js +161 -55
- package/package.json +2 -1
- package/src/lib/fans/airBaseV2.ts +74 -8
- package/src/lib/fans/airBypass.ts +13 -7
- package/src/lib/vesyncFan.ts +174 -65
|
@@ -57,6 +57,14 @@ export declare class VeSyncAirBaseV2 extends VeSyncAirBypass {
|
|
|
57
57
|
* Override setMode to send workMode payloads for bypassV2 purifiers.
|
|
58
58
|
*/
|
|
59
59
|
setMode(mode: string): Promise<boolean>;
|
|
60
|
+
/**
|
|
61
|
+
* Convenience helper to enter turbo mode when supported.
|
|
62
|
+
*/
|
|
63
|
+
turboMode(): Promise<boolean>;
|
|
64
|
+
/**
|
|
65
|
+
* Convenience helper to enter pet mode when supported.
|
|
66
|
+
*/
|
|
67
|
+
petMode(): Promise<boolean>;
|
|
60
68
|
/**
|
|
61
69
|
* Override changeFanSpeed to use manualSpeedLevel for bypassV2 purifiers.
|
|
62
70
|
*/
|
|
@@ -13,11 +13,11 @@ class VeSyncAirBaseV2 extends airBypass_1.VeSyncAirBypass {
|
|
|
13
13
|
this._lightDetection = false;
|
|
14
14
|
this._lightDetectionState = false;
|
|
15
15
|
this.setSpeedLevel = null;
|
|
16
|
-
this.autoPreferences = ['default', 'efficient', 'quiet'];
|
|
17
16
|
this.enabled = false;
|
|
18
17
|
this._mode = '';
|
|
19
18
|
this._speed = 0;
|
|
20
19
|
this._timer = null;
|
|
20
|
+
this.autoPreferences = [...this.getConfigAutoPreferences(['default', 'efficient', 'quiet'])];
|
|
21
21
|
logger_1.logger.debug(`Initialized VeSyncAirBaseV2 device: ${this.deviceName}`);
|
|
22
22
|
}
|
|
23
23
|
buildConfigDict(configDict) {
|
|
@@ -265,28 +265,63 @@ class VeSyncAirBaseV2 extends airBypass_1.VeSyncAirBypass {
|
|
|
265
265
|
* Override setMode to send workMode payloads for bypassV2 purifiers.
|
|
266
266
|
*/
|
|
267
267
|
async setMode(mode) {
|
|
268
|
-
|
|
268
|
+
var _a, _b;
|
|
269
|
+
const targetMode = mode.toLowerCase();
|
|
270
|
+
const supportedModes = this.modes.map(m => m.toLowerCase());
|
|
271
|
+
if (!supportedModes.includes(targetMode)) {
|
|
269
272
|
const error = `Invalid mode: ${mode}. Must be one of: ${this.modes.join(', ')}`;
|
|
270
273
|
logger_1.logger.error(`${error} for device: ${this.deviceName}`);
|
|
271
274
|
throw new Error(error);
|
|
272
275
|
}
|
|
273
276
|
// Special handling for Core200S stays the same for all models
|
|
274
|
-
if (this.deviceType.includes('Core200S') &&
|
|
277
|
+
if (this.deviceType.includes('Core200S') && targetMode === 'auto') {
|
|
275
278
|
logger_1.logger.warn(`Auto mode not supported for ${this.deviceType}, using manual mode instead`);
|
|
276
279
|
return this.setMode('manual');
|
|
277
280
|
}
|
|
281
|
+
// Manual mode should leverage changeFanSpeed to mirror pyvesync behaviour
|
|
282
|
+
if (targetMode === 'manual') {
|
|
283
|
+
const defaultLevel = this.config.levels && this.config.levels.length > 0
|
|
284
|
+
? this.config.levels[0]
|
|
285
|
+
: 1;
|
|
286
|
+
const desiredLevel = (_b = (_a = this.details.manualSpeedLevel) !== null && _a !== void 0 ? _a : this.speed) !== null && _b !== void 0 ? _b : defaultLevel;
|
|
287
|
+
const success = await this.changeFanSpeed(desiredLevel);
|
|
288
|
+
if (success) {
|
|
289
|
+
this.details.mode = 'manual';
|
|
290
|
+
this.mode = 'manual';
|
|
291
|
+
}
|
|
292
|
+
return success;
|
|
293
|
+
}
|
|
278
294
|
// BypassV2 purifiers need the workMode payload; other models use the base implementation
|
|
279
295
|
if (this.requiresPowerSwitchPayload()) {
|
|
280
296
|
logger_1.logger.debug(`Using bypassV2 mode payload for ${this.deviceName}`);
|
|
281
297
|
const [head, body] = this.buildApiDict('setPurifierMode');
|
|
282
298
|
body.payload.data = {
|
|
283
|
-
workMode:
|
|
299
|
+
workMode: targetMode
|
|
284
300
|
};
|
|
285
301
|
const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', body, head);
|
|
286
302
|
const success = this.checkV2Response(response, status, 'setMode');
|
|
287
303
|
if (success) {
|
|
288
|
-
this.details.mode =
|
|
289
|
-
this.
|
|
304
|
+
this.details.mode = targetMode;
|
|
305
|
+
this.mode = targetMode;
|
|
306
|
+
// Update cached speed snapshot for special modes
|
|
307
|
+
if (targetMode === 'sleep') {
|
|
308
|
+
this.speed = 0;
|
|
309
|
+
this.details.speed = 0;
|
|
310
|
+
}
|
|
311
|
+
else if (targetMode === 'turbo') {
|
|
312
|
+
const maxSpeed = this.config.levels && this.config.levels.length > 0
|
|
313
|
+
? Math.max(...this.config.levels)
|
|
314
|
+
: this.speed;
|
|
315
|
+
if (typeof maxSpeed === 'number' && maxSpeed > 0) {
|
|
316
|
+
this.speed = maxSpeed;
|
|
317
|
+
this.details.speed = maxSpeed;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
else if (targetMode === 'auto') {
|
|
321
|
+
this.speed = 0;
|
|
322
|
+
this.details.speed = 0;
|
|
323
|
+
this.details.isAutoSentinel = true;
|
|
324
|
+
}
|
|
290
325
|
// Force a details update to sync state
|
|
291
326
|
setTimeout(() => {
|
|
292
327
|
this.getDetails().catch(e => {
|
|
@@ -296,7 +331,7 @@ class VeSyncAirBaseV2 extends airBypass_1.VeSyncAirBypass {
|
|
|
296
331
|
return true;
|
|
297
332
|
}
|
|
298
333
|
else {
|
|
299
|
-
logger_1.logger.error(`Failed to set mode to ${
|
|
334
|
+
logger_1.logger.error(`Failed to set mode to ${targetMode} for device: ${this.deviceName}`);
|
|
300
335
|
return false;
|
|
301
336
|
}
|
|
302
337
|
}
|
|
@@ -305,6 +340,26 @@ class VeSyncAirBaseV2 extends airBypass_1.VeSyncAirBypass {
|
|
|
305
340
|
return super.setMode(mode);
|
|
306
341
|
}
|
|
307
342
|
}
|
|
343
|
+
/**
|
|
344
|
+
* Convenience helper to enter turbo mode when supported.
|
|
345
|
+
*/
|
|
346
|
+
async turboMode() {
|
|
347
|
+
if (!this.modes.map(m => m.toLowerCase()).includes('turbo')) {
|
|
348
|
+
logger_1.logger.debug(`Turbo mode not supported for device: ${this.deviceName}`);
|
|
349
|
+
return false;
|
|
350
|
+
}
|
|
351
|
+
return this.setMode('turbo');
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Convenience helper to enter pet mode when supported.
|
|
355
|
+
*/
|
|
356
|
+
async petMode() {
|
|
357
|
+
if (!this.modes.map(m => m.toLowerCase()).includes('pet')) {
|
|
358
|
+
logger_1.logger.debug(`Pet mode not supported for device: ${this.deviceName}`);
|
|
359
|
+
return false;
|
|
360
|
+
}
|
|
361
|
+
return this.setMode('pet');
|
|
362
|
+
}
|
|
308
363
|
/**
|
|
309
364
|
* Override changeFanSpeed to use manualSpeedLevel for bypassV2 purifiers.
|
|
310
365
|
*/
|
|
@@ -331,6 +386,10 @@ class VeSyncAirBaseV2 extends airBypass_1.VeSyncAirBypass {
|
|
|
331
386
|
if (success) {
|
|
332
387
|
this.speed = speed;
|
|
333
388
|
this.details.manualSpeedLevel = speed;
|
|
389
|
+
this.details.speed = speed;
|
|
390
|
+
this.details.mode = 'manual';
|
|
391
|
+
this.mode = 'manual';
|
|
392
|
+
this.details.isAutoSentinel = false;
|
|
334
393
|
// Force a details update to sync state
|
|
335
394
|
setTimeout(() => {
|
|
336
395
|
this.getDetails().catch(e => {
|
|
@@ -357,6 +416,10 @@ class VeSyncAirBaseV2 extends airBypass_1.VeSyncAirBypass {
|
|
|
357
416
|
if (success) {
|
|
358
417
|
this.speed = speed;
|
|
359
418
|
this.details.manualSpeedLevel = speed;
|
|
419
|
+
this.details.speed = speed;
|
|
420
|
+
this.details.mode = 'manual';
|
|
421
|
+
this.mode = 'manual';
|
|
422
|
+
this.details.isAutoSentinel = false;
|
|
360
423
|
return true;
|
|
361
424
|
}
|
|
362
425
|
else {
|
|
@@ -370,7 +433,7 @@ class VeSyncAirBaseV2 extends airBypass_1.VeSyncAirBypass {
|
|
|
370
433
|
*/
|
|
371
434
|
async setAutoPreference(preference = 'default', roomSize = 600) {
|
|
372
435
|
if (!this.autoPreferences.includes(preference)) {
|
|
373
|
-
logger_1.logger.debug(`Invalid preference: ${preference} - valid preferences are
|
|
436
|
+
logger_1.logger.debug(`Invalid preference: ${preference} - valid preferences are ${this.autoPreferences.join(', ')}`);
|
|
374
437
|
return false;
|
|
375
438
|
}
|
|
376
439
|
const [head, body] = this.buildApiDict('setAutoPreference');
|
|
@@ -4,7 +4,7 @@ import { VeSync } from '../vesync';
|
|
|
4
4
|
* VeSync Air Purifier with Bypass
|
|
5
5
|
*/
|
|
6
6
|
export declare class VeSyncAirBypass extends VeSyncFan {
|
|
7
|
-
protected
|
|
7
|
+
protected get modes(): ReadonlyArray<string>;
|
|
8
8
|
protected readonly displayModes: readonly ["on", "off"];
|
|
9
9
|
protected readonly childLockModes: readonly ["on", "off"];
|
|
10
10
|
constructor(details: Record<string, any>, manager: VeSync);
|
|
@@ -8,9 +8,11 @@ const logger_1 = require("../logger");
|
|
|
8
8
|
* VeSync Air Purifier with Bypass
|
|
9
9
|
*/
|
|
10
10
|
class VeSyncAirBypass extends vesyncFan_1.VeSyncFan {
|
|
11
|
+
get modes() {
|
|
12
|
+
return this.getConfigModes(['auto', 'manual', 'sleep']);
|
|
13
|
+
}
|
|
11
14
|
constructor(details, manager) {
|
|
12
15
|
super(details, manager);
|
|
13
|
-
this.modes = ['auto', 'manual', 'sleep'];
|
|
14
16
|
this.displayModes = ['on', 'off'];
|
|
15
17
|
this.childLockModes = ['on', 'off'];
|
|
16
18
|
logger_1.logger.debug(`Initialized VeSyncAirBypass device: ${this.deviceName}`);
|
|
@@ -183,14 +185,17 @@ class VeSyncAirBypass extends vesyncFan_1.VeSyncFan {
|
|
|
183
185
|
* Set device mode
|
|
184
186
|
*/
|
|
185
187
|
async setMode(mode) {
|
|
186
|
-
|
|
188
|
+
const requested = mode.toLowerCase();
|
|
189
|
+
const supported = this.modes.map(m => m.toLowerCase());
|
|
190
|
+
const allowsCore200AutoFallback = this.deviceType.includes('Core200S') && requested === 'auto';
|
|
191
|
+
if (!supported.includes(requested) && !allowsCore200AutoFallback) {
|
|
187
192
|
const error = `Invalid mode: ${mode}. Must be one of: ${this.modes.join(', ')}`;
|
|
188
193
|
logger_1.logger.error(`${error} for device: ${this.deviceName}`);
|
|
189
194
|
throw new Error(error);
|
|
190
195
|
}
|
|
191
|
-
logger_1.logger.debug(`Setting mode to ${
|
|
196
|
+
logger_1.logger.debug(`Setting mode to ${requested} for device: ${this.deviceName}`);
|
|
192
197
|
// Special handling for Core200S auto mode
|
|
193
|
-
if (
|
|
198
|
+
if (allowsCore200AutoFallback) {
|
|
194
199
|
// Core200S doesn't support auto mode, so we'll set it to manual mode
|
|
195
200
|
logger_1.logger.warn(`Auto mode not supported for ${this.deviceType}, using manual mode instead`);
|
|
196
201
|
return this.setMode('manual');
|
|
@@ -202,7 +207,7 @@ class VeSyncAirBypass extends vesyncFan_1.VeSyncFan {
|
|
|
202
207
|
configModule: this.configModule,
|
|
203
208
|
payload: {
|
|
204
209
|
data: {
|
|
205
|
-
mode
|
|
210
|
+
mode: requested
|
|
206
211
|
},
|
|
207
212
|
method: 'setPurifierMode',
|
|
208
213
|
source: 'APP'
|
|
@@ -210,11 +215,11 @@ class VeSyncAirBypass extends vesyncFan_1.VeSyncFan {
|
|
|
210
215
|
}, helpers_1.Helpers.reqHeaderBypass());
|
|
211
216
|
const success = this.checkResponse([response, status], 'setMode');
|
|
212
217
|
if (success) {
|
|
213
|
-
this.details.mode =
|
|
218
|
+
this.details.mode = requested;
|
|
214
219
|
return true;
|
|
215
220
|
}
|
|
216
221
|
else {
|
|
217
|
-
logger_1.logger.error(`Failed to set mode to ${
|
|
222
|
+
logger_1.logger.error(`Failed to set mode to ${requested} for device: ${this.deviceName}`);
|
|
218
223
|
return false;
|
|
219
224
|
}
|
|
220
225
|
}
|
package/dist/lib/vesyncFan.d.ts
CHANGED
|
@@ -3,12 +3,15 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { VeSyncBaseDevice } from './vesyncBaseDevice';
|
|
5
5
|
import { VeSync } from './vesync';
|
|
6
|
+
interface FanConfigEntry {
|
|
7
|
+
module: 'VeSyncAirBypass' | 'VeSyncHumidifier' | 'VeSyncWarmHumidifier' | 'VeSyncTowerFan' | 'VeSyncAirBaseV2' | 'VeSyncSuperior6000S' | 'VeSyncHumid1000S' | 'VeSyncHumid200S' | 'VeSyncAir131';
|
|
8
|
+
features: string[];
|
|
9
|
+
levels?: number[];
|
|
10
|
+
modes?: ReadonlyArray<string>;
|
|
11
|
+
autoPreferences?: ReadonlyArray<string>;
|
|
12
|
+
}
|
|
6
13
|
interface FanConfig {
|
|
7
|
-
[key: string]:
|
|
8
|
-
module: 'VeSyncAirBypass' | 'VeSyncHumidifier' | 'VeSyncWarmHumidifier' | 'VeSyncTowerFan' | 'VeSyncAirBaseV2' | 'VeSyncSuperior6000S' | 'VeSyncHumid1000S' | 'VeSyncHumid200S' | 'VeSyncAir131';
|
|
9
|
-
features: string[];
|
|
10
|
-
levels?: number[];
|
|
11
|
-
};
|
|
14
|
+
[key: string]: FanConfigEntry;
|
|
12
15
|
}
|
|
13
16
|
export declare const fanConfig: FanConfig;
|
|
14
17
|
/**
|
|
@@ -42,16 +45,28 @@ export declare abstract class VeSyncFan extends VeSyncBaseDevice {
|
|
|
42
45
|
duration: number;
|
|
43
46
|
action: string;
|
|
44
47
|
} | null;
|
|
45
|
-
protected config:
|
|
46
|
-
module: 'VeSyncAirBypass' | 'VeSyncHumidifier' | 'VeSyncWarmHumidifier' | 'VeSyncTowerFan' | 'VeSyncAirBaseV2' | 'VeSyncSuperior6000S' | 'VeSyncHumid1000S' | 'VeSyncHumid200S' | 'VeSyncAir131';
|
|
47
|
-
features: string[];
|
|
48
|
-
levels?: number[];
|
|
49
|
-
};
|
|
48
|
+
protected config: FanConfigEntry;
|
|
50
49
|
constructor(details: Record<string, any>, manager: VeSync);
|
|
51
50
|
/**
|
|
52
51
|
* Check if feature is supported
|
|
53
52
|
*/
|
|
54
53
|
hasFeature(feature: string): boolean;
|
|
54
|
+
/**
|
|
55
|
+
* Get configured modes for the device, falling back to provided defaults.
|
|
56
|
+
*/
|
|
57
|
+
protected getConfigModes(defaultModes?: ReadonlyArray<string>): ReadonlyArray<string>;
|
|
58
|
+
/**
|
|
59
|
+
* Get configured auto preferences for the device, falling back to provided defaults.
|
|
60
|
+
*/
|
|
61
|
+
protected getConfigAutoPreferences(defaultPreferences?: ReadonlyArray<string>): ReadonlyArray<string>;
|
|
62
|
+
/**
|
|
63
|
+
* Public accessor for supported modes for consumers that need to inspect capability metadata.
|
|
64
|
+
*/
|
|
65
|
+
getSupportedModes(defaultModes?: ReadonlyArray<string>): ReadonlyArray<string>;
|
|
66
|
+
/**
|
|
67
|
+
* Public accessor for supported auto preference profiles.
|
|
68
|
+
*/
|
|
69
|
+
getSupportedAutoPreferences(defaultPreferences?: ReadonlyArray<string>): ReadonlyArray<string>;
|
|
55
70
|
/**
|
|
56
71
|
* Check if feature is supported in current mode
|
|
57
72
|
*/
|
package/dist/lib/vesyncFan.js
CHANGED
|
@@ -13,158 +13,217 @@ exports.fanConfig = {
|
|
|
13
13
|
'Core200S': {
|
|
14
14
|
module: 'VeSyncAirBypass',
|
|
15
15
|
features: ['display', 'child_lock', 'night_light', 'timer', 'fan_speed', 'sleep_mode', 'filter_life'],
|
|
16
|
-
levels: [1, 2, 3, 4] // 4 levels including sleep mode, matching reference plugin
|
|
16
|
+
levels: [1, 2, 3, 4], // 4 levels including sleep mode, matching reference plugin
|
|
17
|
+
modes: ['sleep', 'manual']
|
|
17
18
|
},
|
|
18
19
|
'Core300S': {
|
|
19
20
|
module: 'VeSyncAirBypass',
|
|
20
21
|
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_speed', 'auto_mode', 'sleep_mode', 'filter_life'],
|
|
21
|
-
levels: [1, 2, 3, 4]
|
|
22
|
+
levels: [1, 2, 3, 4],
|
|
23
|
+
modes: ['sleep', 'manual', 'auto'],
|
|
24
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
22
25
|
},
|
|
23
26
|
'Core400S': {
|
|
24
27
|
module: 'VeSyncAirBypass',
|
|
25
28
|
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_speed', 'auto_mode', 'sleep_mode', 'filter_life'],
|
|
26
|
-
levels: [1, 2, 3, 4]
|
|
29
|
+
levels: [1, 2, 3, 4],
|
|
30
|
+
modes: ['sleep', 'manual', 'auto'],
|
|
31
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
27
32
|
},
|
|
28
33
|
'Core600S': {
|
|
29
34
|
module: 'VeSyncAirBypass',
|
|
30
35
|
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_speed', 'auto_mode', 'sleep_mode', 'filter_life'],
|
|
31
|
-
levels: [1, 2, 3, 4]
|
|
36
|
+
levels: [1, 2, 3, 4],
|
|
37
|
+
modes: ['sleep', 'manual', 'auto'],
|
|
38
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
32
39
|
},
|
|
33
40
|
// LAP Series
|
|
34
41
|
'LAP-C201S-AUSR': {
|
|
35
42
|
module: 'VeSyncAirBypass',
|
|
36
|
-
features: ['display', 'child_lock', 'night_light', 'timer', 'fan_speed', '
|
|
37
|
-
levels: [1, 2, 3]
|
|
43
|
+
features: ['display', 'child_lock', 'night_light', 'timer', 'fan_speed', 'sleep_mode', 'filter_life'],
|
|
44
|
+
levels: [1, 2, 3],
|
|
45
|
+
modes: ['sleep', 'manual']
|
|
38
46
|
},
|
|
39
47
|
'LAP-C202S-WUSR': {
|
|
40
48
|
module: 'VeSyncAirBypass',
|
|
41
|
-
features: ['display', 'child_lock', 'night_light', 'timer', 'fan_speed', '
|
|
42
|
-
levels: [1, 2, 3]
|
|
49
|
+
features: ['display', 'child_lock', 'night_light', 'timer', 'fan_speed', 'sleep_mode', 'filter_life'],
|
|
50
|
+
levels: [1, 2, 3],
|
|
51
|
+
modes: ['sleep', 'manual']
|
|
43
52
|
},
|
|
44
53
|
'LAP-C301S-WJP': {
|
|
45
54
|
module: 'VeSyncAirBypass',
|
|
46
55
|
features: ['display', 'child_lock', 'night_light', 'timer', 'fan_speed', 'auto_mode', 'sleep_mode', 'filter_life'],
|
|
47
|
-
levels: [1, 2, 3, 4]
|
|
56
|
+
levels: [1, 2, 3, 4],
|
|
57
|
+
modes: ['sleep', 'manual', 'auto'],
|
|
58
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
48
59
|
},
|
|
49
60
|
'LAP-C302S-WUSB': {
|
|
50
61
|
module: 'VeSyncAirBypass',
|
|
51
62
|
features: ['display', 'child_lock', 'night_light', 'timer', 'fan_speed', 'auto_mode', 'sleep_mode', 'filter_life'],
|
|
52
|
-
levels: [1, 2, 3, 4]
|
|
63
|
+
levels: [1, 2, 3, 4],
|
|
64
|
+
modes: ['sleep', 'manual', 'auto'],
|
|
65
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
53
66
|
},
|
|
54
67
|
'LAP-C301S-WAAA': {
|
|
55
68
|
module: 'VeSyncAirBypass',
|
|
56
69
|
features: ['display', 'child_lock', 'night_light', 'timer', 'fan_speed', 'auto_mode', 'sleep_mode', 'filter_life'],
|
|
57
|
-
levels: [1, 2, 3, 4]
|
|
70
|
+
levels: [1, 2, 3, 4],
|
|
71
|
+
modes: ['sleep', 'manual', 'auto'],
|
|
72
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
58
73
|
},
|
|
59
74
|
'LAP-C401S-WJP': {
|
|
60
75
|
module: 'VeSyncAirBypass',
|
|
61
76
|
features: ['display', 'child_lock', 'night_light', 'timer', 'fan_speed', 'auto_mode', 'sleep_mode', 'filter_life'],
|
|
62
|
-
levels: [1, 2, 3, 4]
|
|
77
|
+
levels: [1, 2, 3, 4],
|
|
78
|
+
modes: ['sleep', 'manual', 'auto'],
|
|
79
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
63
80
|
},
|
|
64
81
|
'LAP-C401S-WUSR': {
|
|
65
82
|
module: 'VeSyncAirBypass',
|
|
66
83
|
features: ['display', 'child_lock', 'night_light', 'timer', 'fan_speed', 'auto_mode', 'sleep_mode', 'filter_life'],
|
|
67
|
-
levels: [1, 2, 3, 4]
|
|
84
|
+
levels: [1, 2, 3, 4],
|
|
85
|
+
modes: ['sleep', 'manual', 'auto'],
|
|
86
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
68
87
|
},
|
|
69
88
|
'LAP-C401S-WAAA': {
|
|
70
89
|
module: 'VeSyncAirBypass',
|
|
71
90
|
features: ['display', 'child_lock', 'night_light', 'timer', 'fan_speed', 'auto_mode', 'sleep_mode', 'filter_life'],
|
|
72
|
-
levels: [1, 2, 3, 4]
|
|
91
|
+
levels: [1, 2, 3, 4],
|
|
92
|
+
modes: ['sleep', 'manual', 'auto'],
|
|
93
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
73
94
|
},
|
|
74
95
|
'LAP-C601S-WUS': {
|
|
75
96
|
module: 'VeSyncAirBypass',
|
|
76
97
|
features: ['display', 'child_lock', 'night_light', 'timer', 'fan_speed', 'auto_mode', 'sleep_mode', 'filter_life'],
|
|
77
|
-
levels: [1, 2, 3, 4]
|
|
98
|
+
levels: [1, 2, 3, 4],
|
|
99
|
+
modes: ['sleep', 'manual', 'auto'],
|
|
100
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
78
101
|
},
|
|
79
102
|
'LAP-C601S-WUSR': {
|
|
80
103
|
module: 'VeSyncAirBypass',
|
|
81
104
|
features: ['display', 'child_lock', 'night_light', 'timer', 'fan_speed', 'auto_mode', 'sleep_mode', 'filter_life'],
|
|
82
|
-
levels: [1, 2, 3, 4]
|
|
105
|
+
levels: [1, 2, 3, 4],
|
|
106
|
+
modes: ['sleep', 'manual', 'auto'],
|
|
107
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
83
108
|
},
|
|
84
109
|
'LAP-C601S-WEU': {
|
|
85
110
|
module: 'VeSyncAirBypass',
|
|
86
111
|
features: ['display', 'child_lock', 'night_light', 'timer', 'fan_speed', 'auto_mode', 'sleep_mode', 'filter_life'],
|
|
87
|
-
levels: [1, 2, 3, 4]
|
|
112
|
+
levels: [1, 2, 3, 4],
|
|
113
|
+
modes: ['sleep', 'manual', 'auto'],
|
|
114
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
88
115
|
},
|
|
89
116
|
'LAP-V102S-AASR': {
|
|
90
117
|
module: 'VeSyncAirBaseV2',
|
|
91
|
-
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_speed', 'auto_mode', 'filter_life'],
|
|
92
|
-
levels: [1, 2, 3, 4]
|
|
118
|
+
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_speed', 'auto_mode', 'sleep_mode', 'pet_mode', 'filter_life'],
|
|
119
|
+
levels: [1, 2, 3, 4],
|
|
120
|
+
modes: ['sleep', 'manual', 'auto', 'pet'],
|
|
121
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
93
122
|
},
|
|
94
123
|
'LAP-V102S-WUS': {
|
|
95
124
|
module: 'VeSyncAirBaseV2',
|
|
96
|
-
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_speed', 'auto_mode', 'filter_life'],
|
|
97
|
-
levels: [1, 2, 3, 4]
|
|
125
|
+
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_speed', 'auto_mode', 'sleep_mode', 'pet_mode', 'filter_life'],
|
|
126
|
+
levels: [1, 2, 3, 4],
|
|
127
|
+
modes: ['sleep', 'manual', 'auto', 'pet'],
|
|
128
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
98
129
|
},
|
|
99
130
|
'LAP-V102S-WEU': {
|
|
100
131
|
module: 'VeSyncAirBaseV2',
|
|
101
|
-
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_speed', 'auto_mode', 'filter_life'],
|
|
102
|
-
levels: [1, 2, 3, 4]
|
|
132
|
+
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_speed', 'auto_mode', 'sleep_mode', 'pet_mode', 'filter_life'],
|
|
133
|
+
levels: [1, 2, 3, 4],
|
|
134
|
+
modes: ['sleep', 'manual', 'auto', 'pet'],
|
|
135
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
103
136
|
},
|
|
104
137
|
'LAP-V102S-AUSR': {
|
|
105
138
|
module: 'VeSyncAirBaseV2',
|
|
106
|
-
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_speed', 'auto_mode', 'filter_life'],
|
|
107
|
-
levels: [1, 2, 3, 4]
|
|
139
|
+
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_speed', 'auto_mode', 'sleep_mode', 'pet_mode', 'filter_life'],
|
|
140
|
+
levels: [1, 2, 3, 4],
|
|
141
|
+
modes: ['sleep', 'manual', 'auto', 'pet'],
|
|
142
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
108
143
|
},
|
|
109
144
|
'LAP-V102S-WJP': {
|
|
110
145
|
module: 'VeSyncAirBaseV2',
|
|
111
|
-
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_speed', 'auto_mode', 'filter_life'],
|
|
112
|
-
levels: [1, 2, 3, 4]
|
|
146
|
+
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_speed', 'auto_mode', 'sleep_mode', 'pet_mode', 'filter_life'],
|
|
147
|
+
levels: [1, 2, 3, 4],
|
|
148
|
+
modes: ['sleep', 'manual', 'auto', 'pet'],
|
|
149
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
113
150
|
},
|
|
114
151
|
'LAP-V201S-AASR': {
|
|
115
152
|
module: 'VeSyncAirBaseV2',
|
|
116
|
-
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'light_detection', 'fan_speed', 'auto_mode', 'filter_life'],
|
|
117
|
-
levels: [1, 2, 3, 4]
|
|
153
|
+
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'light_detection', 'fan_speed', 'auto_mode', 'sleep_mode', 'pet_mode', 'filter_life'],
|
|
154
|
+
levels: [1, 2, 3, 4],
|
|
155
|
+
modes: ['sleep', 'manual', 'auto', 'pet'],
|
|
156
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
118
157
|
},
|
|
119
158
|
'LAP-V201S-WJP': {
|
|
120
159
|
module: 'VeSyncAirBaseV2',
|
|
121
|
-
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'light_detection', 'fan_speed', 'auto_mode', 'filter_life'],
|
|
122
|
-
levels: [1, 2, 3, 4]
|
|
160
|
+
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'light_detection', 'fan_speed', 'auto_mode', 'sleep_mode', 'pet_mode', 'filter_life'],
|
|
161
|
+
levels: [1, 2, 3, 4],
|
|
162
|
+
modes: ['sleep', 'manual', 'auto', 'pet'],
|
|
163
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
123
164
|
},
|
|
124
165
|
'LAP-V201S-WEU': {
|
|
125
166
|
module: 'VeSyncAirBaseV2',
|
|
126
|
-
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'light_detection', 'fan_speed', 'auto_mode', 'filter_life'],
|
|
127
|
-
levels: [1, 2, 3, 4]
|
|
167
|
+
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'light_detection', 'fan_speed', 'auto_mode', 'sleep_mode', 'pet_mode', 'filter_life'],
|
|
168
|
+
levels: [1, 2, 3, 4],
|
|
169
|
+
modes: ['sleep', 'manual', 'auto', 'pet'],
|
|
170
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
128
171
|
},
|
|
129
172
|
'LAP-V201S-WUS': {
|
|
130
173
|
module: 'VeSyncAirBaseV2',
|
|
131
|
-
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'light_detection', 'fan_speed', 'auto_mode', 'filter_life'],
|
|
132
|
-
levels: [1, 2, 3, 4]
|
|
174
|
+
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'light_detection', 'fan_speed', 'auto_mode', 'sleep_mode', 'pet_mode', 'filter_life'],
|
|
175
|
+
levels: [1, 2, 3, 4],
|
|
176
|
+
modes: ['sleep', 'manual', 'auto', 'pet'],
|
|
177
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
133
178
|
},
|
|
134
179
|
'LAP-V201-AUSR': {
|
|
135
180
|
module: 'VeSyncAirBaseV2',
|
|
136
|
-
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'light_detection', 'fan_speed', 'auto_mode', 'filter_life'],
|
|
137
|
-
levels: [1, 2, 3, 4]
|
|
181
|
+
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'light_detection', 'fan_speed', 'auto_mode', 'sleep_mode', 'pet_mode', 'filter_life'],
|
|
182
|
+
levels: [1, 2, 3, 4],
|
|
183
|
+
modes: ['sleep', 'manual', 'auto', 'pet'],
|
|
184
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
138
185
|
},
|
|
139
186
|
'LAP-V201S-AUSR': {
|
|
140
187
|
module: 'VeSyncAirBaseV2',
|
|
141
|
-
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'light_detection', 'fan_speed', 'auto_mode', 'filter_life'],
|
|
142
|
-
levels: [1, 2, 3, 4]
|
|
188
|
+
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'light_detection', 'fan_speed', 'auto_mode', 'sleep_mode', 'pet_mode', 'filter_life'],
|
|
189
|
+
levels: [1, 2, 3, 4],
|
|
190
|
+
modes: ['sleep', 'manual', 'auto', 'pet'],
|
|
191
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
143
192
|
},
|
|
144
193
|
'LAP-V201S-AEUR': {
|
|
145
194
|
module: 'VeSyncAirBaseV2',
|
|
146
|
-
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'light_detection', 'fan_speed', 'auto_mode', 'filter_life'],
|
|
147
|
-
levels: [1, 2, 3, 4]
|
|
195
|
+
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'light_detection', 'fan_speed', 'auto_mode', 'sleep_mode', 'pet_mode', 'filter_life'],
|
|
196
|
+
levels: [1, 2, 3, 4],
|
|
197
|
+
modes: ['sleep', 'manual', 'auto', 'pet'],
|
|
198
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
148
199
|
},
|
|
149
200
|
'LAP-EL551S-AUS': {
|
|
150
201
|
module: 'VeSyncAirBaseV2',
|
|
151
|
-
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_rotate', 'fan_speed', 'auto_mode', 'filter_life'],
|
|
152
|
-
levels: [1, 2, 3]
|
|
202
|
+
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_rotate', 'fan_speed', 'auto_mode', 'sleep_mode', 'turbo_mode', 'light_detection', 'filter_life'],
|
|
203
|
+
levels: [1, 2, 3],
|
|
204
|
+
modes: ['sleep', 'manual', 'auto', 'turbo'],
|
|
205
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
153
206
|
},
|
|
154
207
|
'LAP-EL551S-AEUR': {
|
|
155
208
|
module: 'VeSyncAirBaseV2',
|
|
156
|
-
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_rotate', 'fan_speed', 'auto_mode', 'filter_life'],
|
|
157
|
-
levels: [1, 2, 3]
|
|
209
|
+
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_rotate', 'fan_speed', 'auto_mode', 'sleep_mode', 'turbo_mode', 'light_detection', 'filter_life'],
|
|
210
|
+
levels: [1, 2, 3],
|
|
211
|
+
modes: ['sleep', 'manual', 'auto', 'turbo'],
|
|
212
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
158
213
|
},
|
|
159
214
|
'LAP-EL551S-WEU': {
|
|
160
215
|
module: 'VeSyncAirBaseV2',
|
|
161
|
-
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_rotate', 'fan_speed', 'auto_mode', 'filter_life'],
|
|
162
|
-
levels: [1, 2, 3]
|
|
216
|
+
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_rotate', 'fan_speed', 'auto_mode', 'sleep_mode', 'turbo_mode', 'light_detection', 'filter_life'],
|
|
217
|
+
levels: [1, 2, 3],
|
|
218
|
+
modes: ['sleep', 'manual', 'auto', 'turbo'],
|
|
219
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
163
220
|
},
|
|
164
221
|
'LAP-EL551S-WUS': {
|
|
165
222
|
module: 'VeSyncAirBaseV2',
|
|
166
|
-
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_rotate', 'fan_speed', 'auto_mode', 'filter_life'],
|
|
167
|
-
levels: [1, 2, 3]
|
|
223
|
+
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_rotate', 'fan_speed', 'auto_mode', 'sleep_mode', 'turbo_mode', 'light_detection', 'filter_life'],
|
|
224
|
+
levels: [1, 2, 3],
|
|
225
|
+
modes: ['sleep', 'manual', 'auto', 'turbo'],
|
|
226
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
168
227
|
},
|
|
169
228
|
// LTF Series
|
|
170
229
|
'LTF-F422S-KEU': {
|
|
@@ -311,11 +370,25 @@ class VeSyncFan extends vesyncBaseDevice_1.VeSyncBaseDevice {
|
|
|
311
370
|
this.speed_dict = {};
|
|
312
371
|
this._timer = null;
|
|
313
372
|
this.details = details;
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
373
|
+
const entry = exports.fanConfig[this.deviceType];
|
|
374
|
+
if (entry) {
|
|
375
|
+
this.config = {
|
|
376
|
+
...entry,
|
|
377
|
+
features: [...entry.features],
|
|
378
|
+
levels: entry.levels ? [...entry.levels] : undefined,
|
|
379
|
+
modes: entry.modes ? [...entry.modes] : undefined,
|
|
380
|
+
autoPreferences: entry.autoPreferences ? [...entry.autoPreferences] : undefined
|
|
381
|
+
};
|
|
382
|
+
}
|
|
383
|
+
else {
|
|
384
|
+
this.config = {
|
|
385
|
+
module: 'VeSyncAirBypass',
|
|
386
|
+
features: [],
|
|
387
|
+
levels: [],
|
|
388
|
+
modes: [],
|
|
389
|
+
autoPreferences: []
|
|
390
|
+
};
|
|
391
|
+
}
|
|
319
392
|
}
|
|
320
393
|
/**
|
|
321
394
|
* Check if feature is supported
|
|
@@ -323,6 +396,36 @@ class VeSyncFan extends vesyncBaseDevice_1.VeSyncBaseDevice {
|
|
|
323
396
|
hasFeature(feature) {
|
|
324
397
|
return this.config.features.includes(feature);
|
|
325
398
|
}
|
|
399
|
+
/**
|
|
400
|
+
* Get configured modes for the device, falling back to provided defaults.
|
|
401
|
+
*/
|
|
402
|
+
getConfigModes(defaultModes = []) {
|
|
403
|
+
if (Array.isArray(this.config.modes) && this.config.modes.length > 0) {
|
|
404
|
+
return this.config.modes;
|
|
405
|
+
}
|
|
406
|
+
return defaultModes;
|
|
407
|
+
}
|
|
408
|
+
/**
|
|
409
|
+
* Get configured auto preferences for the device, falling back to provided defaults.
|
|
410
|
+
*/
|
|
411
|
+
getConfigAutoPreferences(defaultPreferences = []) {
|
|
412
|
+
if (Array.isArray(this.config.autoPreferences) && this.config.autoPreferences.length > 0) {
|
|
413
|
+
return this.config.autoPreferences;
|
|
414
|
+
}
|
|
415
|
+
return defaultPreferences;
|
|
416
|
+
}
|
|
417
|
+
/**
|
|
418
|
+
* Public accessor for supported modes for consumers that need to inspect capability metadata.
|
|
419
|
+
*/
|
|
420
|
+
getSupportedModes(defaultModes = []) {
|
|
421
|
+
return this.getConfigModes(defaultModes);
|
|
422
|
+
}
|
|
423
|
+
/**
|
|
424
|
+
* Public accessor for supported auto preference profiles.
|
|
425
|
+
*/
|
|
426
|
+
getSupportedAutoPreferences(defaultPreferences = []) {
|
|
427
|
+
return this.getConfigAutoPreferences(defaultPreferences);
|
|
428
|
+
}
|
|
326
429
|
/**
|
|
327
430
|
* Check if feature is supported in current mode
|
|
328
431
|
*/
|
|
@@ -355,7 +458,10 @@ class VeSyncFan extends vesyncBaseDevice_1.VeSyncBaseDevice {
|
|
|
355
458
|
* Get maximum fan speed level
|
|
356
459
|
*/
|
|
357
460
|
getMaxFanSpeed() {
|
|
358
|
-
|
|
461
|
+
if (this.config.levels && this.config.levels.length > 0) {
|
|
462
|
+
return Math.max(...this.config.levels);
|
|
463
|
+
}
|
|
464
|
+
return 3;
|
|
359
465
|
}
|
|
360
466
|
/**
|
|
361
467
|
* Get current mode
|
package/package.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tsvesync",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "A TypeScript library for interacting with VeSync smart home devices",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"build": "tsc",
|
|
9
9
|
"clean": "rm -rf dist",
|
|
10
|
+
"test:everest": "ts-node test/everest-air-parity.test.ts",
|
|
10
11
|
"prepare": "npm run build",
|
|
11
12
|
"version": "git add -A src",
|
|
12
13
|
"postversion": "git push && git push --tags"
|
|
@@ -10,7 +10,7 @@ export class VeSyncAirBaseV2 extends VeSyncAirBypass {
|
|
|
10
10
|
protected _lightDetection: boolean = false;
|
|
11
11
|
protected _lightDetectionState: boolean = false;
|
|
12
12
|
protected setSpeedLevel: number | null = null;
|
|
13
|
-
protected autoPreferences: string[]
|
|
13
|
+
protected autoPreferences: string[];
|
|
14
14
|
protected enabled: boolean = false;
|
|
15
15
|
protected _mode: string = '';
|
|
16
16
|
protected _speed: number = 0;
|
|
@@ -18,6 +18,7 @@ export class VeSyncAirBaseV2 extends VeSyncAirBypass {
|
|
|
18
18
|
|
|
19
19
|
constructor(details: Record<string, any>, manager: VeSync) {
|
|
20
20
|
super(details, manager);
|
|
21
|
+
this.autoPreferences = [...this.getConfigAutoPreferences(['default', 'efficient', 'quiet'])];
|
|
21
22
|
logger.debug(`Initialized VeSyncAirBaseV2 device: ${this.deviceName}`);
|
|
22
23
|
}
|
|
23
24
|
|
|
@@ -310,24 +311,41 @@ export class VeSyncAirBaseV2 extends VeSyncAirBypass {
|
|
|
310
311
|
* Override setMode to send workMode payloads for bypassV2 purifiers.
|
|
311
312
|
*/
|
|
312
313
|
override async setMode(mode: string): Promise<boolean> {
|
|
313
|
-
|
|
314
|
+
const targetMode = mode.toLowerCase();
|
|
315
|
+
const supportedModes = this.modes.map(m => m.toLowerCase());
|
|
316
|
+
|
|
317
|
+
if (!supportedModes.includes(targetMode)) {
|
|
314
318
|
const error = `Invalid mode: ${mode}. Must be one of: ${this.modes.join(', ')}`;
|
|
315
319
|
logger.error(`${error} for device: ${this.deviceName}`);
|
|
316
320
|
throw new Error(error);
|
|
317
321
|
}
|
|
318
322
|
|
|
319
323
|
// Special handling for Core200S stays the same for all models
|
|
320
|
-
if (this.deviceType.includes('Core200S') &&
|
|
324
|
+
if (this.deviceType.includes('Core200S') && targetMode === 'auto') {
|
|
321
325
|
logger.warn(`Auto mode not supported for ${this.deviceType}, using manual mode instead`);
|
|
322
326
|
return this.setMode('manual');
|
|
323
327
|
}
|
|
324
328
|
|
|
329
|
+
// Manual mode should leverage changeFanSpeed to mirror pyvesync behaviour
|
|
330
|
+
if (targetMode === 'manual') {
|
|
331
|
+
const defaultLevel = this.config.levels && this.config.levels.length > 0
|
|
332
|
+
? this.config.levels[0]
|
|
333
|
+
: 1;
|
|
334
|
+
const desiredLevel = this.details.manualSpeedLevel ?? this.speed ?? defaultLevel;
|
|
335
|
+
const success = await this.changeFanSpeed(desiredLevel);
|
|
336
|
+
if (success) {
|
|
337
|
+
this.details.mode = 'manual';
|
|
338
|
+
this.mode = 'manual';
|
|
339
|
+
}
|
|
340
|
+
return success;
|
|
341
|
+
}
|
|
342
|
+
|
|
325
343
|
// BypassV2 purifiers need the workMode payload; other models use the base implementation
|
|
326
344
|
if (this.requiresPowerSwitchPayload()) {
|
|
327
345
|
logger.debug(`Using bypassV2 mode payload for ${this.deviceName}`);
|
|
328
346
|
const [head, body] = this.buildApiDict('setPurifierMode');
|
|
329
347
|
body.payload.data = {
|
|
330
|
-
workMode:
|
|
348
|
+
workMode: targetMode
|
|
331
349
|
};
|
|
332
350
|
|
|
333
351
|
const [response, status] = await this.callApi(
|
|
@@ -339,8 +357,26 @@ export class VeSyncAirBaseV2 extends VeSyncAirBypass {
|
|
|
339
357
|
|
|
340
358
|
const success = this.checkV2Response(response, status, 'setMode');
|
|
341
359
|
if (success) {
|
|
342
|
-
this.details.mode =
|
|
343
|
-
this.
|
|
360
|
+
this.details.mode = targetMode;
|
|
361
|
+
this.mode = targetMode;
|
|
362
|
+
|
|
363
|
+
// Update cached speed snapshot for special modes
|
|
364
|
+
if (targetMode === 'sleep') {
|
|
365
|
+
this.speed = 0;
|
|
366
|
+
this.details.speed = 0;
|
|
367
|
+
} else if (targetMode === 'turbo') {
|
|
368
|
+
const maxSpeed = this.config.levels && this.config.levels.length > 0
|
|
369
|
+
? Math.max(...this.config.levels)
|
|
370
|
+
: this.speed;
|
|
371
|
+
if (typeof maxSpeed === 'number' && maxSpeed > 0) {
|
|
372
|
+
this.speed = maxSpeed;
|
|
373
|
+
this.details.speed = maxSpeed;
|
|
374
|
+
}
|
|
375
|
+
} else if (targetMode === 'auto') {
|
|
376
|
+
this.speed = 0;
|
|
377
|
+
this.details.speed = 0;
|
|
378
|
+
this.details.isAutoSentinel = true;
|
|
379
|
+
}
|
|
344
380
|
|
|
345
381
|
// Force a details update to sync state
|
|
346
382
|
setTimeout(() => {
|
|
@@ -351,7 +387,7 @@ export class VeSyncAirBaseV2 extends VeSyncAirBypass {
|
|
|
351
387
|
|
|
352
388
|
return true;
|
|
353
389
|
} else {
|
|
354
|
-
logger.error(`Failed to set mode to ${
|
|
390
|
+
logger.error(`Failed to set mode to ${targetMode} for device: ${this.deviceName}`);
|
|
355
391
|
return false;
|
|
356
392
|
}
|
|
357
393
|
} else {
|
|
@@ -360,6 +396,28 @@ export class VeSyncAirBaseV2 extends VeSyncAirBypass {
|
|
|
360
396
|
}
|
|
361
397
|
}
|
|
362
398
|
|
|
399
|
+
/**
|
|
400
|
+
* Convenience helper to enter turbo mode when supported.
|
|
401
|
+
*/
|
|
402
|
+
async turboMode(): Promise<boolean> {
|
|
403
|
+
if (!this.modes.map(m => m.toLowerCase()).includes('turbo')) {
|
|
404
|
+
logger.debug(`Turbo mode not supported for device: ${this.deviceName}`);
|
|
405
|
+
return false;
|
|
406
|
+
}
|
|
407
|
+
return this.setMode('turbo');
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
/**
|
|
411
|
+
* Convenience helper to enter pet mode when supported.
|
|
412
|
+
*/
|
|
413
|
+
async petMode(): Promise<boolean> {
|
|
414
|
+
if (!this.modes.map(m => m.toLowerCase()).includes('pet')) {
|
|
415
|
+
logger.debug(`Pet mode not supported for device: ${this.deviceName}`);
|
|
416
|
+
return false;
|
|
417
|
+
}
|
|
418
|
+
return this.setMode('pet');
|
|
419
|
+
}
|
|
420
|
+
|
|
363
421
|
/**
|
|
364
422
|
* Override changeFanSpeed to use manualSpeedLevel for bypassV2 purifiers.
|
|
365
423
|
*/
|
|
@@ -395,6 +453,10 @@ export class VeSyncAirBaseV2 extends VeSyncAirBypass {
|
|
|
395
453
|
if (success) {
|
|
396
454
|
this.speed = speed;
|
|
397
455
|
this.details.manualSpeedLevel = speed;
|
|
456
|
+
this.details.speed = speed;
|
|
457
|
+
this.details.mode = 'manual';
|
|
458
|
+
this.mode = 'manual';
|
|
459
|
+
this.details.isAutoSentinel = false;
|
|
398
460
|
|
|
399
461
|
// Force a details update to sync state
|
|
400
462
|
setTimeout(() => {
|
|
@@ -428,6 +490,10 @@ export class VeSyncAirBaseV2 extends VeSyncAirBypass {
|
|
|
428
490
|
if (success) {
|
|
429
491
|
this.speed = speed;
|
|
430
492
|
this.details.manualSpeedLevel = speed;
|
|
493
|
+
this.details.speed = speed;
|
|
494
|
+
this.details.mode = 'manual';
|
|
495
|
+
this.mode = 'manual';
|
|
496
|
+
this.details.isAutoSentinel = false;
|
|
431
497
|
return true;
|
|
432
498
|
} else {
|
|
433
499
|
logger.error(`Failed to change fan speed to ${speed} for device: ${this.deviceName}`);
|
|
@@ -441,7 +507,7 @@ export class VeSyncAirBaseV2 extends VeSyncAirBypass {
|
|
|
441
507
|
*/
|
|
442
508
|
async setAutoPreference(preference: string = 'default', roomSize: number = 600): Promise<boolean> {
|
|
443
509
|
if (!this.autoPreferences.includes(preference)) {
|
|
444
|
-
logger.debug(`Invalid preference: ${preference} - valid preferences are
|
|
510
|
+
logger.debug(`Invalid preference: ${preference} - valid preferences are ${this.autoPreferences.join(', ')}`);
|
|
445
511
|
return false;
|
|
446
512
|
}
|
|
447
513
|
|
|
@@ -7,7 +7,9 @@ import { logger } from '../logger';
|
|
|
7
7
|
* VeSync Air Purifier with Bypass
|
|
8
8
|
*/
|
|
9
9
|
export class VeSyncAirBypass extends VeSyncFan {
|
|
10
|
-
protected
|
|
10
|
+
protected get modes(): ReadonlyArray<string> {
|
|
11
|
+
return this.getConfigModes(['auto', 'manual', 'sleep']);
|
|
12
|
+
}
|
|
11
13
|
protected readonly displayModes = ['on', 'off'] as const;
|
|
12
14
|
protected readonly childLockModes = ['on', 'off'] as const;
|
|
13
15
|
|
|
@@ -216,16 +218,20 @@ export class VeSyncAirBypass extends VeSyncFan {
|
|
|
216
218
|
* Set device mode
|
|
217
219
|
*/
|
|
218
220
|
async setMode(mode: string): Promise<boolean> {
|
|
219
|
-
|
|
221
|
+
const requested = mode.toLowerCase();
|
|
222
|
+
const supported = this.modes.map(m => m.toLowerCase());
|
|
223
|
+
const allowsCore200AutoFallback = this.deviceType.includes('Core200S') && requested === 'auto';
|
|
224
|
+
|
|
225
|
+
if (!supported.includes(requested) && !allowsCore200AutoFallback) {
|
|
220
226
|
const error = `Invalid mode: ${mode}. Must be one of: ${this.modes.join(', ')}`;
|
|
221
227
|
logger.error(`${error} for device: ${this.deviceName}`);
|
|
222
228
|
throw new Error(error);
|
|
223
229
|
}
|
|
224
230
|
|
|
225
|
-
logger.debug(`Setting mode to ${
|
|
231
|
+
logger.debug(`Setting mode to ${requested} for device: ${this.deviceName}`);
|
|
226
232
|
|
|
227
233
|
// Special handling for Core200S auto mode
|
|
228
|
-
if (
|
|
234
|
+
if (allowsCore200AutoFallback) {
|
|
229
235
|
// Core200S doesn't support auto mode, so we'll set it to manual mode
|
|
230
236
|
logger.warn(`Auto mode not supported for ${this.deviceType}, using manual mode instead`);
|
|
231
237
|
return this.setMode('manual');
|
|
@@ -241,7 +247,7 @@ export class VeSyncAirBypass extends VeSyncFan {
|
|
|
241
247
|
configModule: this.configModule,
|
|
242
248
|
payload: {
|
|
243
249
|
data: {
|
|
244
|
-
mode
|
|
250
|
+
mode: requested
|
|
245
251
|
},
|
|
246
252
|
method: 'setPurifierMode',
|
|
247
253
|
source: 'APP'
|
|
@@ -252,10 +258,10 @@ export class VeSyncAirBypass extends VeSyncFan {
|
|
|
252
258
|
|
|
253
259
|
const success = this.checkResponse([response, status], 'setMode');
|
|
254
260
|
if (success) {
|
|
255
|
-
this.details.mode =
|
|
261
|
+
this.details.mode = requested;
|
|
256
262
|
return true;
|
|
257
263
|
} else {
|
|
258
|
-
logger.error(`Failed to set mode to ${
|
|
264
|
+
logger.error(`Failed to set mode to ${requested} for device: ${this.deviceName}`);
|
|
259
265
|
return false;
|
|
260
266
|
}
|
|
261
267
|
}
|
package/src/lib/vesyncFan.ts
CHANGED
|
@@ -7,12 +7,16 @@ import { VeSync } from './vesync';
|
|
|
7
7
|
import { logger } from './logger';
|
|
8
8
|
import { Helpers } from './helpers';
|
|
9
9
|
|
|
10
|
+
interface FanConfigEntry {
|
|
11
|
+
module: 'VeSyncAirBypass' | 'VeSyncHumidifier' | 'VeSyncWarmHumidifier' | 'VeSyncTowerFan' | 'VeSyncAirBaseV2' | 'VeSyncSuperior6000S' | 'VeSyncHumid1000S' | 'VeSyncHumid200S' | 'VeSyncAir131';
|
|
12
|
+
features: string[];
|
|
13
|
+
levels?: number[];
|
|
14
|
+
modes?: ReadonlyArray<string>;
|
|
15
|
+
autoPreferences?: ReadonlyArray<string>;
|
|
16
|
+
}
|
|
17
|
+
|
|
10
18
|
interface FanConfig {
|
|
11
|
-
[key: string]:
|
|
12
|
-
module: 'VeSyncAirBypass' | 'VeSyncHumidifier' | 'VeSyncWarmHumidifier' | 'VeSyncTowerFan' | 'VeSyncAirBaseV2' | 'VeSyncSuperior6000S' | 'VeSyncHumid1000S' | 'VeSyncHumid200S' | 'VeSyncAir131';
|
|
13
|
-
features: string[];
|
|
14
|
-
levels?: number[];
|
|
15
|
-
};
|
|
19
|
+
[key: string]: FanConfigEntry;
|
|
16
20
|
}
|
|
17
21
|
|
|
18
22
|
// Fan configuration
|
|
@@ -21,159 +25,218 @@ export const fanConfig: FanConfig = {
|
|
|
21
25
|
'Core200S': {
|
|
22
26
|
module: 'VeSyncAirBypass',
|
|
23
27
|
features: ['display', 'child_lock', 'night_light', 'timer', 'fan_speed', 'sleep_mode', 'filter_life'],
|
|
24
|
-
levels: [1, 2, 3, 4] // 4 levels including sleep mode, matching reference plugin
|
|
28
|
+
levels: [1, 2, 3, 4], // 4 levels including sleep mode, matching reference plugin
|
|
29
|
+
modes: ['sleep', 'manual']
|
|
25
30
|
},
|
|
26
31
|
'Core300S': {
|
|
27
32
|
module: 'VeSyncAirBypass',
|
|
28
33
|
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_speed', 'auto_mode', 'sleep_mode', 'filter_life'],
|
|
29
|
-
levels: [1, 2, 3, 4]
|
|
34
|
+
levels: [1, 2, 3, 4],
|
|
35
|
+
modes: ['sleep', 'manual', 'auto'],
|
|
36
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
30
37
|
},
|
|
31
38
|
'Core400S': {
|
|
32
39
|
module: 'VeSyncAirBypass',
|
|
33
40
|
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_speed', 'auto_mode', 'sleep_mode', 'filter_life'],
|
|
34
|
-
levels: [1, 2, 3, 4]
|
|
41
|
+
levels: [1, 2, 3, 4],
|
|
42
|
+
modes: ['sleep', 'manual', 'auto'],
|
|
43
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
35
44
|
},
|
|
36
45
|
'Core600S': {
|
|
37
46
|
module: 'VeSyncAirBypass',
|
|
38
47
|
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_speed', 'auto_mode', 'sleep_mode', 'filter_life'],
|
|
39
|
-
levels: [1, 2, 3, 4]
|
|
48
|
+
levels: [1, 2, 3, 4],
|
|
49
|
+
modes: ['sleep', 'manual', 'auto'],
|
|
50
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
40
51
|
},
|
|
41
52
|
|
|
42
53
|
// LAP Series
|
|
43
54
|
'LAP-C201S-AUSR': {
|
|
44
55
|
module: 'VeSyncAirBypass',
|
|
45
|
-
features: ['display', 'child_lock', 'night_light', 'timer', 'fan_speed', '
|
|
46
|
-
levels: [1, 2, 3]
|
|
56
|
+
features: ['display', 'child_lock', 'night_light', 'timer', 'fan_speed', 'sleep_mode', 'filter_life'],
|
|
57
|
+
levels: [1, 2, 3],
|
|
58
|
+
modes: ['sleep', 'manual']
|
|
47
59
|
},
|
|
48
60
|
'LAP-C202S-WUSR': {
|
|
49
61
|
module: 'VeSyncAirBypass',
|
|
50
|
-
features: ['display', 'child_lock', 'night_light', 'timer', 'fan_speed', '
|
|
51
|
-
levels: [1, 2, 3]
|
|
62
|
+
features: ['display', 'child_lock', 'night_light', 'timer', 'fan_speed', 'sleep_mode', 'filter_life'],
|
|
63
|
+
levels: [1, 2, 3],
|
|
64
|
+
modes: ['sleep', 'manual']
|
|
52
65
|
},
|
|
53
66
|
'LAP-C301S-WJP': {
|
|
54
67
|
module: 'VeSyncAirBypass',
|
|
55
68
|
features: ['display', 'child_lock', 'night_light', 'timer', 'fan_speed', 'auto_mode', 'sleep_mode', 'filter_life'],
|
|
56
|
-
levels: [1, 2, 3, 4]
|
|
69
|
+
levels: [1, 2, 3, 4],
|
|
70
|
+
modes: ['sleep', 'manual', 'auto'],
|
|
71
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
57
72
|
},
|
|
58
73
|
'LAP-C302S-WUSB': {
|
|
59
74
|
module: 'VeSyncAirBypass',
|
|
60
75
|
features: ['display', 'child_lock', 'night_light', 'timer', 'fan_speed', 'auto_mode', 'sleep_mode', 'filter_life'],
|
|
61
|
-
levels: [1, 2, 3, 4]
|
|
76
|
+
levels: [1, 2, 3, 4],
|
|
77
|
+
modes: ['sleep', 'manual', 'auto'],
|
|
78
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
62
79
|
},
|
|
63
80
|
'LAP-C301S-WAAA': {
|
|
64
81
|
module: 'VeSyncAirBypass',
|
|
65
82
|
features: ['display', 'child_lock', 'night_light', 'timer', 'fan_speed', 'auto_mode', 'sleep_mode', 'filter_life'],
|
|
66
|
-
levels: [1, 2, 3, 4]
|
|
83
|
+
levels: [1, 2, 3, 4],
|
|
84
|
+
modes: ['sleep', 'manual', 'auto'],
|
|
85
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
67
86
|
},
|
|
68
87
|
'LAP-C401S-WJP': {
|
|
69
88
|
module: 'VeSyncAirBypass',
|
|
70
89
|
features: ['display', 'child_lock', 'night_light', 'timer', 'fan_speed', 'auto_mode', 'sleep_mode', 'filter_life'],
|
|
71
|
-
levels: [1, 2, 3, 4]
|
|
90
|
+
levels: [1, 2, 3, 4],
|
|
91
|
+
modes: ['sleep', 'manual', 'auto'],
|
|
92
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
72
93
|
},
|
|
73
94
|
'LAP-C401S-WUSR': {
|
|
74
95
|
module: 'VeSyncAirBypass',
|
|
75
96
|
features: ['display', 'child_lock', 'night_light', 'timer', 'fan_speed', 'auto_mode', 'sleep_mode', 'filter_life'],
|
|
76
|
-
levels: [1, 2, 3, 4]
|
|
97
|
+
levels: [1, 2, 3, 4],
|
|
98
|
+
modes: ['sleep', 'manual', 'auto'],
|
|
99
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
77
100
|
},
|
|
78
101
|
'LAP-C401S-WAAA': {
|
|
79
102
|
module: 'VeSyncAirBypass',
|
|
80
103
|
features: ['display', 'child_lock', 'night_light', 'timer', 'fan_speed', 'auto_mode', 'sleep_mode', 'filter_life'],
|
|
81
|
-
levels: [1, 2, 3, 4]
|
|
104
|
+
levels: [1, 2, 3, 4],
|
|
105
|
+
modes: ['sleep', 'manual', 'auto'],
|
|
106
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
82
107
|
},
|
|
83
108
|
'LAP-C601S-WUS': {
|
|
84
109
|
module: 'VeSyncAirBypass',
|
|
85
110
|
features: ['display', 'child_lock', 'night_light', 'timer', 'fan_speed', 'auto_mode', 'sleep_mode', 'filter_life'],
|
|
86
|
-
levels: [1, 2, 3, 4]
|
|
111
|
+
levels: [1, 2, 3, 4],
|
|
112
|
+
modes: ['sleep', 'manual', 'auto'],
|
|
113
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
87
114
|
},
|
|
88
115
|
'LAP-C601S-WUSR': {
|
|
89
116
|
module: 'VeSyncAirBypass',
|
|
90
117
|
features: ['display', 'child_lock', 'night_light', 'timer', 'fan_speed', 'auto_mode', 'sleep_mode', 'filter_life'],
|
|
91
|
-
levels: [1, 2, 3, 4]
|
|
118
|
+
levels: [1, 2, 3, 4],
|
|
119
|
+
modes: ['sleep', 'manual', 'auto'],
|
|
120
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
92
121
|
},
|
|
93
122
|
'LAP-C601S-WEU': {
|
|
94
123
|
module: 'VeSyncAirBypass',
|
|
95
124
|
features: ['display', 'child_lock', 'night_light', 'timer', 'fan_speed', 'auto_mode', 'sleep_mode', 'filter_life'],
|
|
96
|
-
levels: [1, 2, 3, 4]
|
|
125
|
+
levels: [1, 2, 3, 4],
|
|
126
|
+
modes: ['sleep', 'manual', 'auto'],
|
|
127
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
97
128
|
},
|
|
98
129
|
'LAP-V102S-AASR': {
|
|
99
130
|
module: 'VeSyncAirBaseV2',
|
|
100
|
-
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_speed', 'auto_mode', 'filter_life'],
|
|
101
|
-
levels: [1, 2, 3, 4]
|
|
131
|
+
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_speed', 'auto_mode', 'sleep_mode', 'pet_mode', 'filter_life'],
|
|
132
|
+
levels: [1, 2, 3, 4],
|
|
133
|
+
modes: ['sleep', 'manual', 'auto', 'pet'],
|
|
134
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
102
135
|
},
|
|
103
136
|
'LAP-V102S-WUS': {
|
|
104
137
|
module: 'VeSyncAirBaseV2',
|
|
105
|
-
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_speed', 'auto_mode', 'filter_life'],
|
|
106
|
-
levels: [1, 2, 3, 4]
|
|
138
|
+
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_speed', 'auto_mode', 'sleep_mode', 'pet_mode', 'filter_life'],
|
|
139
|
+
levels: [1, 2, 3, 4],
|
|
140
|
+
modes: ['sleep', 'manual', 'auto', 'pet'],
|
|
141
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
107
142
|
},
|
|
108
143
|
'LAP-V102S-WEU': {
|
|
109
144
|
module: 'VeSyncAirBaseV2',
|
|
110
|
-
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_speed', 'auto_mode', 'filter_life'],
|
|
111
|
-
levels: [1, 2, 3, 4]
|
|
145
|
+
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_speed', 'auto_mode', 'sleep_mode', 'pet_mode', 'filter_life'],
|
|
146
|
+
levels: [1, 2, 3, 4],
|
|
147
|
+
modes: ['sleep', 'manual', 'auto', 'pet'],
|
|
148
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
112
149
|
},
|
|
113
150
|
'LAP-V102S-AUSR': {
|
|
114
151
|
module: 'VeSyncAirBaseV2',
|
|
115
|
-
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_speed', 'auto_mode', 'filter_life'],
|
|
116
|
-
levels: [1, 2, 3, 4]
|
|
152
|
+
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_speed', 'auto_mode', 'sleep_mode', 'pet_mode', 'filter_life'],
|
|
153
|
+
levels: [1, 2, 3, 4],
|
|
154
|
+
modes: ['sleep', 'manual', 'auto', 'pet'],
|
|
155
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
117
156
|
},
|
|
118
157
|
'LAP-V102S-WJP': {
|
|
119
158
|
module: 'VeSyncAirBaseV2',
|
|
120
|
-
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_speed', 'auto_mode', 'filter_life'],
|
|
121
|
-
levels: [1, 2, 3, 4]
|
|
159
|
+
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_speed', 'auto_mode', 'sleep_mode', 'pet_mode', 'filter_life'],
|
|
160
|
+
levels: [1, 2, 3, 4],
|
|
161
|
+
modes: ['sleep', 'manual', 'auto', 'pet'],
|
|
162
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
122
163
|
},
|
|
123
164
|
'LAP-V201S-AASR': {
|
|
124
165
|
module: 'VeSyncAirBaseV2',
|
|
125
|
-
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'light_detection', 'fan_speed', 'auto_mode', 'filter_life'],
|
|
126
|
-
levels: [1, 2, 3, 4]
|
|
166
|
+
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'light_detection', 'fan_speed', 'auto_mode', 'sleep_mode', 'pet_mode', 'filter_life'],
|
|
167
|
+
levels: [1, 2, 3, 4],
|
|
168
|
+
modes: ['sleep', 'manual', 'auto', 'pet'],
|
|
169
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
127
170
|
},
|
|
128
171
|
'LAP-V201S-WJP': {
|
|
129
172
|
module: 'VeSyncAirBaseV2',
|
|
130
|
-
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'light_detection', 'fan_speed', 'auto_mode', 'filter_life'],
|
|
131
|
-
levels: [1, 2, 3, 4]
|
|
173
|
+
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'light_detection', 'fan_speed', 'auto_mode', 'sleep_mode', 'pet_mode', 'filter_life'],
|
|
174
|
+
levels: [1, 2, 3, 4],
|
|
175
|
+
modes: ['sleep', 'manual', 'auto', 'pet'],
|
|
176
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
132
177
|
},
|
|
133
178
|
'LAP-V201S-WEU': {
|
|
134
179
|
module: 'VeSyncAirBaseV2',
|
|
135
|
-
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'light_detection', 'fan_speed', 'auto_mode', 'filter_life'],
|
|
136
|
-
levels: [1, 2, 3, 4]
|
|
180
|
+
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'light_detection', 'fan_speed', 'auto_mode', 'sleep_mode', 'pet_mode', 'filter_life'],
|
|
181
|
+
levels: [1, 2, 3, 4],
|
|
182
|
+
modes: ['sleep', 'manual', 'auto', 'pet'],
|
|
183
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
137
184
|
},
|
|
138
185
|
'LAP-V201S-WUS': {
|
|
139
186
|
module: 'VeSyncAirBaseV2',
|
|
140
|
-
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'light_detection', 'fan_speed', 'auto_mode', 'filter_life'],
|
|
141
|
-
levels: [1, 2, 3, 4]
|
|
187
|
+
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'light_detection', 'fan_speed', 'auto_mode', 'sleep_mode', 'pet_mode', 'filter_life'],
|
|
188
|
+
levels: [1, 2, 3, 4],
|
|
189
|
+
modes: ['sleep', 'manual', 'auto', 'pet'],
|
|
190
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
142
191
|
},
|
|
143
192
|
'LAP-V201-AUSR': {
|
|
144
193
|
module: 'VeSyncAirBaseV2',
|
|
145
|
-
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'light_detection', 'fan_speed', 'auto_mode', 'filter_life'],
|
|
146
|
-
levels: [1, 2, 3, 4]
|
|
194
|
+
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'light_detection', 'fan_speed', 'auto_mode', 'sleep_mode', 'pet_mode', 'filter_life'],
|
|
195
|
+
levels: [1, 2, 3, 4],
|
|
196
|
+
modes: ['sleep', 'manual', 'auto', 'pet'],
|
|
197
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
147
198
|
},
|
|
148
199
|
'LAP-V201S-AUSR': {
|
|
149
200
|
module: 'VeSyncAirBaseV2',
|
|
150
|
-
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'light_detection', 'fan_speed', 'auto_mode', 'filter_life'],
|
|
151
|
-
levels: [1, 2, 3, 4]
|
|
201
|
+
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'light_detection', 'fan_speed', 'auto_mode', 'sleep_mode', 'pet_mode', 'filter_life'],
|
|
202
|
+
levels: [1, 2, 3, 4],
|
|
203
|
+
modes: ['sleep', 'manual', 'auto', 'pet'],
|
|
204
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
152
205
|
},
|
|
153
206
|
'LAP-V201S-AEUR': {
|
|
154
207
|
module: 'VeSyncAirBaseV2',
|
|
155
|
-
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'light_detection', 'fan_speed', 'auto_mode', 'filter_life'],
|
|
156
|
-
levels: [1, 2, 3, 4]
|
|
208
|
+
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'light_detection', 'fan_speed', 'auto_mode', 'sleep_mode', 'pet_mode', 'filter_life'],
|
|
209
|
+
levels: [1, 2, 3, 4],
|
|
210
|
+
modes: ['sleep', 'manual', 'auto', 'pet'],
|
|
211
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
157
212
|
},
|
|
158
213
|
'LAP-EL551S-AUS': {
|
|
159
214
|
module: 'VeSyncAirBaseV2',
|
|
160
|
-
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_rotate', 'fan_speed', 'auto_mode', 'filter_life'],
|
|
161
|
-
levels: [1, 2, 3]
|
|
215
|
+
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_rotate', 'fan_speed', 'auto_mode', 'sleep_mode', 'turbo_mode', 'light_detection', 'filter_life'],
|
|
216
|
+
levels: [1, 2, 3],
|
|
217
|
+
modes: ['sleep', 'manual', 'auto', 'turbo'],
|
|
218
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
162
219
|
},
|
|
163
220
|
'LAP-EL551S-AEUR': {
|
|
164
221
|
module: 'VeSyncAirBaseV2',
|
|
165
|
-
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_rotate', 'fan_speed', 'auto_mode', 'filter_life'],
|
|
166
|
-
levels: [1, 2, 3]
|
|
222
|
+
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_rotate', 'fan_speed', 'auto_mode', 'sleep_mode', 'turbo_mode', 'light_detection', 'filter_life'],
|
|
223
|
+
levels: [1, 2, 3],
|
|
224
|
+
modes: ['sleep', 'manual', 'auto', 'turbo'],
|
|
225
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
167
226
|
},
|
|
168
227
|
'LAP-EL551S-WEU': {
|
|
169
228
|
module: 'VeSyncAirBaseV2',
|
|
170
|
-
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_rotate', 'fan_speed', 'auto_mode', 'filter_life'],
|
|
171
|
-
levels: [1, 2, 3]
|
|
229
|
+
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_rotate', 'fan_speed', 'auto_mode', 'sleep_mode', 'turbo_mode', 'light_detection', 'filter_life'],
|
|
230
|
+
levels: [1, 2, 3],
|
|
231
|
+
modes: ['sleep', 'manual', 'auto', 'turbo'],
|
|
232
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
172
233
|
},
|
|
173
234
|
'LAP-EL551S-WUS': {
|
|
174
235
|
module: 'VeSyncAirBaseV2',
|
|
175
|
-
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_rotate', 'fan_speed', 'auto_mode', 'filter_life'],
|
|
176
|
-
levels: [1, 2, 3]
|
|
236
|
+
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_rotate', 'fan_speed', 'auto_mode', 'sleep_mode', 'turbo_mode', 'light_detection', 'filter_life'],
|
|
237
|
+
levels: [1, 2, 3],
|
|
238
|
+
modes: ['sleep', 'manual', 'auto', 'turbo'],
|
|
239
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
177
240
|
},
|
|
178
241
|
|
|
179
242
|
// LTF Series
|
|
@@ -342,20 +405,29 @@ export abstract class VeSyncFan extends VeSyncBaseDevice {
|
|
|
342
405
|
protected mode_dict: Record<string, any> = {};
|
|
343
406
|
protected speed_dict: Record<string, any> = {};
|
|
344
407
|
protected _timer: number | { duration: number; action: string } | null = null;
|
|
345
|
-
protected config:
|
|
346
|
-
module: 'VeSyncAirBypass' | 'VeSyncHumidifier' | 'VeSyncWarmHumidifier' | 'VeSyncTowerFan' | 'VeSyncAirBaseV2' | 'VeSyncSuperior6000S' | 'VeSyncHumid1000S' | 'VeSyncHumid200S' | 'VeSyncAir131';
|
|
347
|
-
features: string[];
|
|
348
|
-
levels?: number[];
|
|
349
|
-
};
|
|
408
|
+
protected config: FanConfigEntry;
|
|
350
409
|
|
|
351
410
|
constructor(details: Record<string, any>, manager: VeSync) {
|
|
352
411
|
super(details, manager);
|
|
353
412
|
this.details = details;
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
413
|
+
const entry = fanConfig[this.deviceType];
|
|
414
|
+
if (entry) {
|
|
415
|
+
this.config = {
|
|
416
|
+
...entry,
|
|
417
|
+
features: [...entry.features],
|
|
418
|
+
levels: entry.levels ? [...entry.levels] : undefined,
|
|
419
|
+
modes: entry.modes ? [...entry.modes] : undefined,
|
|
420
|
+
autoPreferences: entry.autoPreferences ? [...entry.autoPreferences] : undefined
|
|
421
|
+
};
|
|
422
|
+
} else {
|
|
423
|
+
this.config = {
|
|
424
|
+
module: 'VeSyncAirBypass',
|
|
425
|
+
features: [],
|
|
426
|
+
levels: [],
|
|
427
|
+
modes: [],
|
|
428
|
+
autoPreferences: []
|
|
429
|
+
};
|
|
430
|
+
}
|
|
359
431
|
}
|
|
360
432
|
|
|
361
433
|
/**
|
|
@@ -365,6 +437,40 @@ export abstract class VeSyncFan extends VeSyncBaseDevice {
|
|
|
365
437
|
return this.config.features.includes(feature);
|
|
366
438
|
}
|
|
367
439
|
|
|
440
|
+
/**
|
|
441
|
+
* Get configured modes for the device, falling back to provided defaults.
|
|
442
|
+
*/
|
|
443
|
+
protected getConfigModes(defaultModes: ReadonlyArray<string> = []): ReadonlyArray<string> {
|
|
444
|
+
if (Array.isArray(this.config.modes) && this.config.modes.length > 0) {
|
|
445
|
+
return this.config.modes;
|
|
446
|
+
}
|
|
447
|
+
return defaultModes;
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
/**
|
|
451
|
+
* Get configured auto preferences for the device, falling back to provided defaults.
|
|
452
|
+
*/
|
|
453
|
+
protected getConfigAutoPreferences(defaultPreferences: ReadonlyArray<string> = []): ReadonlyArray<string> {
|
|
454
|
+
if (Array.isArray(this.config.autoPreferences) && this.config.autoPreferences.length > 0) {
|
|
455
|
+
return this.config.autoPreferences;
|
|
456
|
+
}
|
|
457
|
+
return defaultPreferences;
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
/**
|
|
461
|
+
* Public accessor for supported modes for consumers that need to inspect capability metadata.
|
|
462
|
+
*/
|
|
463
|
+
public getSupportedModes(defaultModes: ReadonlyArray<string> = []): ReadonlyArray<string> {
|
|
464
|
+
return this.getConfigModes(defaultModes);
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
/**
|
|
468
|
+
* Public accessor for supported auto preference profiles.
|
|
469
|
+
*/
|
|
470
|
+
public getSupportedAutoPreferences(defaultPreferences: ReadonlyArray<string> = []): ReadonlyArray<string> {
|
|
471
|
+
return this.getConfigAutoPreferences(defaultPreferences);
|
|
472
|
+
}
|
|
473
|
+
|
|
368
474
|
/**
|
|
369
475
|
* Check if feature is supported in current mode
|
|
370
476
|
*/
|
|
@@ -403,7 +509,10 @@ export abstract class VeSyncFan extends VeSyncBaseDevice {
|
|
|
403
509
|
* Get maximum fan speed level
|
|
404
510
|
*/
|
|
405
511
|
getMaxFanSpeed(): number {
|
|
406
|
-
|
|
512
|
+
if (this.config.levels && this.config.levels.length > 0) {
|
|
513
|
+
return Math.max(...this.config.levels);
|
|
514
|
+
}
|
|
515
|
+
return 3;
|
|
407
516
|
}
|
|
408
517
|
|
|
409
518
|
/**
|