tsvesync 1.3.12 → 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/air131.js +4 -0
- package/dist/lib/fans/airBaseV2.d.ts +8 -0
- package/dist/lib/fans/airBaseV2.js +77 -8
- package/dist/lib/fans/airBypass.d.ts +1 -1
- package/dist/lib/fans/airBypass.js +17 -7
- package/dist/lib/helpers.d.ts +4 -0
- package/dist/lib/helpers.js +44 -0
- package/dist/lib/vesyncFan.d.ts +34 -10
- package/dist/lib/vesyncFan.js +178 -55
- package/package.json +2 -1
- package/src/lib/fans/air131.ts +4 -0
- package/src/lib/fans/airBaseV2.ts +80 -8
- package/src/lib/fans/airBypass.ts +19 -7
- package/src/lib/helpers.ts +46 -0
- package/src/lib/vesyncFan.ts +194 -65
|
@@ -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
|
|
|
@@ -87,6 +89,12 @@ export class VeSyncAirBypass extends VeSyncFan {
|
|
|
87
89
|
air_quality_value: result.air_quality_value || 0
|
|
88
90
|
};
|
|
89
91
|
|
|
92
|
+
const normalizedAirQuality = Helpers.normalizeAirQuality(result.air_quality);
|
|
93
|
+
if (normalizedAirQuality.level >= 1) {
|
|
94
|
+
this.details.air_quality_level = normalizedAirQuality.level;
|
|
95
|
+
}
|
|
96
|
+
this.details.air_quality_label = normalizedAirQuality.label;
|
|
97
|
+
|
|
90
98
|
// Capture additional air quality properties if available
|
|
91
99
|
if ('PM1' in result) this.details.pm1 = result.PM1;
|
|
92
100
|
if ('PM10' in result) this.details.pm10 = result.PM10;
|
|
@@ -210,16 +218,20 @@ export class VeSyncAirBypass extends VeSyncFan {
|
|
|
210
218
|
* Set device mode
|
|
211
219
|
*/
|
|
212
220
|
async setMode(mode: string): Promise<boolean> {
|
|
213
|
-
|
|
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) {
|
|
214
226
|
const error = `Invalid mode: ${mode}. Must be one of: ${this.modes.join(', ')}`;
|
|
215
227
|
logger.error(`${error} for device: ${this.deviceName}`);
|
|
216
228
|
throw new Error(error);
|
|
217
229
|
}
|
|
218
230
|
|
|
219
|
-
logger.debug(`Setting mode to ${
|
|
231
|
+
logger.debug(`Setting mode to ${requested} for device: ${this.deviceName}`);
|
|
220
232
|
|
|
221
233
|
// Special handling for Core200S auto mode
|
|
222
|
-
if (
|
|
234
|
+
if (allowsCore200AutoFallback) {
|
|
223
235
|
// Core200S doesn't support auto mode, so we'll set it to manual mode
|
|
224
236
|
logger.warn(`Auto mode not supported for ${this.deviceType}, using manual mode instead`);
|
|
225
237
|
return this.setMode('manual');
|
|
@@ -235,7 +247,7 @@ export class VeSyncAirBypass extends VeSyncFan {
|
|
|
235
247
|
configModule: this.configModule,
|
|
236
248
|
payload: {
|
|
237
249
|
data: {
|
|
238
|
-
mode
|
|
250
|
+
mode: requested
|
|
239
251
|
},
|
|
240
252
|
method: 'setPurifierMode',
|
|
241
253
|
source: 'APP'
|
|
@@ -246,10 +258,10 @@ export class VeSyncAirBypass extends VeSyncFan {
|
|
|
246
258
|
|
|
247
259
|
const success = this.checkResponse([response, status], 'setMode');
|
|
248
260
|
if (success) {
|
|
249
|
-
this.details.mode =
|
|
261
|
+
this.details.mode = requested;
|
|
250
262
|
return true;
|
|
251
263
|
} else {
|
|
252
|
-
logger.error(`Failed to set mode to ${
|
|
264
|
+
logger.error(`Failed to set mode to ${requested} for device: ${this.deviceName}`);
|
|
253
265
|
return false;
|
|
254
266
|
}
|
|
255
267
|
}
|
package/src/lib/helpers.ts
CHANGED
|
@@ -245,6 +245,52 @@ export class Helpers {
|
|
|
245
245
|
return generateTraceId();
|
|
246
246
|
}
|
|
247
247
|
|
|
248
|
+
static normalizeAirQuality(value: unknown): { level: number; label: string } {
|
|
249
|
+
const stringMap: Record<string, number> = {
|
|
250
|
+
'excellent': 1,
|
|
251
|
+
'very good': 1,
|
|
252
|
+
'good': 2,
|
|
253
|
+
'moderate': 3,
|
|
254
|
+
'fair': 3,
|
|
255
|
+
'inferior': 4,
|
|
256
|
+
'poor': 4,
|
|
257
|
+
'bad': 4,
|
|
258
|
+
};
|
|
259
|
+
|
|
260
|
+
if (typeof value === 'number') {
|
|
261
|
+
const level = Number.isFinite(value) ? Math.trunc(value) : -1;
|
|
262
|
+
if (level >= 1 && level <= 4) {
|
|
263
|
+
return {
|
|
264
|
+
level,
|
|
265
|
+
label: level === 1
|
|
266
|
+
? 'excellent'
|
|
267
|
+
: level === 2
|
|
268
|
+
? 'good'
|
|
269
|
+
: level === 3
|
|
270
|
+
? 'moderate'
|
|
271
|
+
: 'poor',
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
} else if (typeof value === 'string') {
|
|
275
|
+
const normalized = value.trim().toLowerCase();
|
|
276
|
+
const level = stringMap[normalized];
|
|
277
|
+
if (level) {
|
|
278
|
+
return {
|
|
279
|
+
level,
|
|
280
|
+
label: level === 1
|
|
281
|
+
? 'excellent'
|
|
282
|
+
: level === 2
|
|
283
|
+
? 'good'
|
|
284
|
+
: level === 3
|
|
285
|
+
? 'moderate'
|
|
286
|
+
: 'poor',
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
return { level: -1, label: 'unknown' };
|
|
292
|
+
}
|
|
293
|
+
|
|
248
294
|
/**
|
|
249
295
|
* Calculate MD5 hash
|
|
250
296
|
*/
|
package/src/lib/vesyncFan.ts
CHANGED
|
@@ -5,13 +5,18 @@
|
|
|
5
5
|
import { VeSyncBaseDevice } from './vesyncBaseDevice';
|
|
6
6
|
import { VeSync } from './vesync';
|
|
7
7
|
import { logger } from './logger';
|
|
8
|
+
import { Helpers } from './helpers';
|
|
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
|
+
}
|
|
8
17
|
|
|
9
18
|
interface FanConfig {
|
|
10
|
-
[key: string]:
|
|
11
|
-
module: 'VeSyncAirBypass' | 'VeSyncHumidifier' | 'VeSyncWarmHumidifier' | 'VeSyncTowerFan' | 'VeSyncAirBaseV2' | 'VeSyncSuperior6000S' | 'VeSyncHumid1000S' | 'VeSyncHumid200S' | 'VeSyncAir131';
|
|
12
|
-
features: string[];
|
|
13
|
-
levels?: number[];
|
|
14
|
-
};
|
|
19
|
+
[key: string]: FanConfigEntry;
|
|
15
20
|
}
|
|
16
21
|
|
|
17
22
|
// Fan configuration
|
|
@@ -20,159 +25,218 @@ export const fanConfig: FanConfig = {
|
|
|
20
25
|
'Core200S': {
|
|
21
26
|
module: 'VeSyncAirBypass',
|
|
22
27
|
features: ['display', 'child_lock', 'night_light', 'timer', 'fan_speed', 'sleep_mode', 'filter_life'],
|
|
23
|
-
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']
|
|
24
30
|
},
|
|
25
31
|
'Core300S': {
|
|
26
32
|
module: 'VeSyncAirBypass',
|
|
27
33
|
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_speed', 'auto_mode', 'sleep_mode', 'filter_life'],
|
|
28
|
-
levels: [1, 2, 3, 4]
|
|
34
|
+
levels: [1, 2, 3, 4],
|
|
35
|
+
modes: ['sleep', 'manual', 'auto'],
|
|
36
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
29
37
|
},
|
|
30
38
|
'Core400S': {
|
|
31
39
|
module: 'VeSyncAirBypass',
|
|
32
40
|
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_speed', 'auto_mode', 'sleep_mode', 'filter_life'],
|
|
33
|
-
levels: [1, 2, 3, 4]
|
|
41
|
+
levels: [1, 2, 3, 4],
|
|
42
|
+
modes: ['sleep', 'manual', 'auto'],
|
|
43
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
34
44
|
},
|
|
35
45
|
'Core600S': {
|
|
36
46
|
module: 'VeSyncAirBypass',
|
|
37
47
|
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_speed', 'auto_mode', 'sleep_mode', 'filter_life'],
|
|
38
|
-
levels: [1, 2, 3, 4]
|
|
48
|
+
levels: [1, 2, 3, 4],
|
|
49
|
+
modes: ['sleep', 'manual', 'auto'],
|
|
50
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
39
51
|
},
|
|
40
52
|
|
|
41
53
|
// LAP Series
|
|
42
54
|
'LAP-C201S-AUSR': {
|
|
43
55
|
module: 'VeSyncAirBypass',
|
|
44
|
-
features: ['display', 'child_lock', 'night_light', 'timer', 'fan_speed', '
|
|
45
|
-
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']
|
|
46
59
|
},
|
|
47
60
|
'LAP-C202S-WUSR': {
|
|
48
61
|
module: 'VeSyncAirBypass',
|
|
49
|
-
features: ['display', 'child_lock', 'night_light', 'timer', 'fan_speed', '
|
|
50
|
-
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']
|
|
51
65
|
},
|
|
52
66
|
'LAP-C301S-WJP': {
|
|
53
67
|
module: 'VeSyncAirBypass',
|
|
54
68
|
features: ['display', 'child_lock', 'night_light', 'timer', 'fan_speed', 'auto_mode', 'sleep_mode', 'filter_life'],
|
|
55
|
-
levels: [1, 2, 3, 4]
|
|
69
|
+
levels: [1, 2, 3, 4],
|
|
70
|
+
modes: ['sleep', 'manual', 'auto'],
|
|
71
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
56
72
|
},
|
|
57
73
|
'LAP-C302S-WUSB': {
|
|
58
74
|
module: 'VeSyncAirBypass',
|
|
59
75
|
features: ['display', 'child_lock', 'night_light', 'timer', 'fan_speed', 'auto_mode', 'sleep_mode', 'filter_life'],
|
|
60
|
-
levels: [1, 2, 3, 4]
|
|
76
|
+
levels: [1, 2, 3, 4],
|
|
77
|
+
modes: ['sleep', 'manual', 'auto'],
|
|
78
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
61
79
|
},
|
|
62
80
|
'LAP-C301S-WAAA': {
|
|
63
81
|
module: 'VeSyncAirBypass',
|
|
64
82
|
features: ['display', 'child_lock', 'night_light', 'timer', 'fan_speed', 'auto_mode', 'sleep_mode', 'filter_life'],
|
|
65
|
-
levels: [1, 2, 3, 4]
|
|
83
|
+
levels: [1, 2, 3, 4],
|
|
84
|
+
modes: ['sleep', 'manual', 'auto'],
|
|
85
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
66
86
|
},
|
|
67
87
|
'LAP-C401S-WJP': {
|
|
68
88
|
module: 'VeSyncAirBypass',
|
|
69
89
|
features: ['display', 'child_lock', 'night_light', 'timer', 'fan_speed', 'auto_mode', 'sleep_mode', 'filter_life'],
|
|
70
|
-
levels: [1, 2, 3, 4]
|
|
90
|
+
levels: [1, 2, 3, 4],
|
|
91
|
+
modes: ['sleep', 'manual', 'auto'],
|
|
92
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
71
93
|
},
|
|
72
94
|
'LAP-C401S-WUSR': {
|
|
73
95
|
module: 'VeSyncAirBypass',
|
|
74
96
|
features: ['display', 'child_lock', 'night_light', 'timer', 'fan_speed', 'auto_mode', 'sleep_mode', 'filter_life'],
|
|
75
|
-
levels: [1, 2, 3, 4]
|
|
97
|
+
levels: [1, 2, 3, 4],
|
|
98
|
+
modes: ['sleep', 'manual', 'auto'],
|
|
99
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
76
100
|
},
|
|
77
101
|
'LAP-C401S-WAAA': {
|
|
78
102
|
module: 'VeSyncAirBypass',
|
|
79
103
|
features: ['display', 'child_lock', 'night_light', 'timer', 'fan_speed', 'auto_mode', 'sleep_mode', 'filter_life'],
|
|
80
|
-
levels: [1, 2, 3, 4]
|
|
104
|
+
levels: [1, 2, 3, 4],
|
|
105
|
+
modes: ['sleep', 'manual', 'auto'],
|
|
106
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
81
107
|
},
|
|
82
108
|
'LAP-C601S-WUS': {
|
|
83
109
|
module: 'VeSyncAirBypass',
|
|
84
110
|
features: ['display', 'child_lock', 'night_light', 'timer', 'fan_speed', 'auto_mode', 'sleep_mode', 'filter_life'],
|
|
85
|
-
levels: [1, 2, 3, 4]
|
|
111
|
+
levels: [1, 2, 3, 4],
|
|
112
|
+
modes: ['sleep', 'manual', 'auto'],
|
|
113
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
86
114
|
},
|
|
87
115
|
'LAP-C601S-WUSR': {
|
|
88
116
|
module: 'VeSyncAirBypass',
|
|
89
117
|
features: ['display', 'child_lock', 'night_light', 'timer', 'fan_speed', 'auto_mode', 'sleep_mode', 'filter_life'],
|
|
90
|
-
levels: [1, 2, 3, 4]
|
|
118
|
+
levels: [1, 2, 3, 4],
|
|
119
|
+
modes: ['sleep', 'manual', 'auto'],
|
|
120
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
91
121
|
},
|
|
92
122
|
'LAP-C601S-WEU': {
|
|
93
123
|
module: 'VeSyncAirBypass',
|
|
94
124
|
features: ['display', 'child_lock', 'night_light', 'timer', 'fan_speed', 'auto_mode', 'sleep_mode', 'filter_life'],
|
|
95
|
-
levels: [1, 2, 3, 4]
|
|
125
|
+
levels: [1, 2, 3, 4],
|
|
126
|
+
modes: ['sleep', 'manual', 'auto'],
|
|
127
|
+
autoPreferences: ['default', 'efficient', 'quiet']
|
|
96
128
|
},
|
|
97
129
|
'LAP-V102S-AASR': {
|
|
98
130
|
module: 'VeSyncAirBaseV2',
|
|
99
|
-
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_speed', 'auto_mode', 'filter_life'],
|
|
100
|
-
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']
|
|
101
135
|
},
|
|
102
136
|
'LAP-V102S-WUS': {
|
|
103
137
|
module: 'VeSyncAirBaseV2',
|
|
104
|
-
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_speed', 'auto_mode', 'filter_life'],
|
|
105
|
-
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']
|
|
106
142
|
},
|
|
107
143
|
'LAP-V102S-WEU': {
|
|
108
144
|
module: 'VeSyncAirBaseV2',
|
|
109
|
-
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_speed', 'auto_mode', 'filter_life'],
|
|
110
|
-
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']
|
|
111
149
|
},
|
|
112
150
|
'LAP-V102S-AUSR': {
|
|
113
151
|
module: 'VeSyncAirBaseV2',
|
|
114
|
-
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_speed', 'auto_mode', 'filter_life'],
|
|
115
|
-
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']
|
|
116
156
|
},
|
|
117
157
|
'LAP-V102S-WJP': {
|
|
118
158
|
module: 'VeSyncAirBaseV2',
|
|
119
|
-
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_speed', 'auto_mode', 'filter_life'],
|
|
120
|
-
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']
|
|
121
163
|
},
|
|
122
164
|
'LAP-V201S-AASR': {
|
|
123
165
|
module: 'VeSyncAirBaseV2',
|
|
124
|
-
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'light_detection', 'fan_speed', 'auto_mode', 'filter_life'],
|
|
125
|
-
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']
|
|
126
170
|
},
|
|
127
171
|
'LAP-V201S-WJP': {
|
|
128
172
|
module: 'VeSyncAirBaseV2',
|
|
129
|
-
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'light_detection', 'fan_speed', 'auto_mode', 'filter_life'],
|
|
130
|
-
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']
|
|
131
177
|
},
|
|
132
178
|
'LAP-V201S-WEU': {
|
|
133
179
|
module: 'VeSyncAirBaseV2',
|
|
134
|
-
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'light_detection', 'fan_speed', 'auto_mode', 'filter_life'],
|
|
135
|
-
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']
|
|
136
184
|
},
|
|
137
185
|
'LAP-V201S-WUS': {
|
|
138
186
|
module: 'VeSyncAirBaseV2',
|
|
139
|
-
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'light_detection', 'fan_speed', 'auto_mode', 'filter_life'],
|
|
140
|
-
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']
|
|
141
191
|
},
|
|
142
192
|
'LAP-V201-AUSR': {
|
|
143
193
|
module: 'VeSyncAirBaseV2',
|
|
144
|
-
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'light_detection', 'fan_speed', 'auto_mode', 'filter_life'],
|
|
145
|
-
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']
|
|
146
198
|
},
|
|
147
199
|
'LAP-V201S-AUSR': {
|
|
148
200
|
module: 'VeSyncAirBaseV2',
|
|
149
|
-
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'light_detection', 'fan_speed', 'auto_mode', 'filter_life'],
|
|
150
|
-
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']
|
|
151
205
|
},
|
|
152
206
|
'LAP-V201S-AEUR': {
|
|
153
207
|
module: 'VeSyncAirBaseV2',
|
|
154
|
-
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'light_detection', 'fan_speed', 'auto_mode', 'filter_life'],
|
|
155
|
-
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']
|
|
156
212
|
},
|
|
157
213
|
'LAP-EL551S-AUS': {
|
|
158
214
|
module: 'VeSyncAirBaseV2',
|
|
159
|
-
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_rotate', 'fan_speed', 'auto_mode', 'filter_life'],
|
|
160
|
-
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']
|
|
161
219
|
},
|
|
162
220
|
'LAP-EL551S-AEUR': {
|
|
163
221
|
module: 'VeSyncAirBaseV2',
|
|
164
|
-
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_rotate', 'fan_speed', 'auto_mode', 'filter_life'],
|
|
165
|
-
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']
|
|
166
226
|
},
|
|
167
227
|
'LAP-EL551S-WEU': {
|
|
168
228
|
module: 'VeSyncAirBaseV2',
|
|
169
|
-
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_rotate', 'fan_speed', 'auto_mode', 'filter_life'],
|
|
170
|
-
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']
|
|
171
233
|
},
|
|
172
234
|
'LAP-EL551S-WUS': {
|
|
173
235
|
module: 'VeSyncAirBaseV2',
|
|
174
|
-
features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_rotate', 'fan_speed', 'auto_mode', 'filter_life'],
|
|
175
|
-
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']
|
|
176
240
|
},
|
|
177
241
|
|
|
178
242
|
// LTF Series
|
|
@@ -327,6 +391,8 @@ export abstract class VeSyncFan extends VeSyncBaseDevice {
|
|
|
327
391
|
child_lock?: boolean;
|
|
328
392
|
air_quality?: string | number;
|
|
329
393
|
air_quality_value?: number;
|
|
394
|
+
air_quality_level?: number;
|
|
395
|
+
air_quality_label?: string;
|
|
330
396
|
pm1?: number;
|
|
331
397
|
pm10?: number;
|
|
332
398
|
aq_percent?: number;
|
|
@@ -339,20 +405,29 @@ export abstract class VeSyncFan extends VeSyncBaseDevice {
|
|
|
339
405
|
protected mode_dict: Record<string, any> = {};
|
|
340
406
|
protected speed_dict: Record<string, any> = {};
|
|
341
407
|
protected _timer: number | { duration: number; action: string } | null = null;
|
|
342
|
-
protected config:
|
|
343
|
-
module: 'VeSyncAirBypass' | 'VeSyncHumidifier' | 'VeSyncWarmHumidifier' | 'VeSyncTowerFan' | 'VeSyncAirBaseV2' | 'VeSyncSuperior6000S' | 'VeSyncHumid1000S' | 'VeSyncHumid200S' | 'VeSyncAir131';
|
|
344
|
-
features: string[];
|
|
345
|
-
levels?: number[];
|
|
346
|
-
};
|
|
408
|
+
protected config: FanConfigEntry;
|
|
347
409
|
|
|
348
410
|
constructor(details: Record<string, any>, manager: VeSync) {
|
|
349
411
|
super(details, manager);
|
|
350
412
|
this.details = details;
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
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
|
+
}
|
|
356
431
|
}
|
|
357
432
|
|
|
358
433
|
/**
|
|
@@ -362,6 +437,40 @@ export abstract class VeSyncFan extends VeSyncBaseDevice {
|
|
|
362
437
|
return this.config.features.includes(feature);
|
|
363
438
|
}
|
|
364
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
|
+
|
|
365
474
|
/**
|
|
366
475
|
* Check if feature is supported in current mode
|
|
367
476
|
*/
|
|
@@ -400,7 +509,10 @@ export abstract class VeSyncFan extends VeSyncBaseDevice {
|
|
|
400
509
|
* Get maximum fan speed level
|
|
401
510
|
*/
|
|
402
511
|
getMaxFanSpeed(): number {
|
|
403
|
-
|
|
512
|
+
if (this.config.levels && this.config.levels.length > 0) {
|
|
513
|
+
return Math.max(...this.config.levels);
|
|
514
|
+
}
|
|
515
|
+
return 3;
|
|
404
516
|
}
|
|
405
517
|
|
|
406
518
|
/**
|
|
@@ -468,6 +580,23 @@ export abstract class VeSyncFan extends VeSyncBaseDevice {
|
|
|
468
580
|
return this.details.air_quality_value ?? 0;
|
|
469
581
|
}
|
|
470
582
|
|
|
583
|
+
/**
|
|
584
|
+
* Normalized air quality metadata aligned with pyvesync levels.
|
|
585
|
+
*/
|
|
586
|
+
getNormalizedAirQuality(): { level: number; label: string } {
|
|
587
|
+
if (typeof this.details.air_quality_level === 'number' && this.details.air_quality_level >= 1) {
|
|
588
|
+
const label = this.details.air_quality_label ?? Helpers.normalizeAirQuality(this.details.air_quality_level).label;
|
|
589
|
+
return { level: this.details.air_quality_level, label };
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
const normalized = Helpers.normalizeAirQuality(this.details.air_quality);
|
|
593
|
+
if (normalized.level >= 1) {
|
|
594
|
+
this.details.air_quality_level = normalized.level;
|
|
595
|
+
this.details.air_quality_label = normalized.label;
|
|
596
|
+
}
|
|
597
|
+
return normalized;
|
|
598
|
+
}
|
|
599
|
+
|
|
471
600
|
/**
|
|
472
601
|
* Get PM1 value (if supported)
|
|
473
602
|
*/
|