tsvesync 1.0.63 → 1.0.65

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.
@@ -0,0 +1,101 @@
1
+ import { VeSyncAirBypass } from './airBypass';
2
+ import { VeSyncAirBaseV2 } from './airBaseV2';
3
+ import { VeSyncTowerFan } from './towerFan';
4
+ import { VeSyncHumidifier } from './humidifier';
5
+ import { VeSyncWarmHumidifier } from './warmHumidifier';
6
+ import { VeSyncHumid200300S } from './humid200300S';
7
+ import { VeSyncFan } from '../vesyncFan';
8
+ import { VeSync } from '../vesync';
9
+
10
+ // Re-export all classes
11
+ export { VeSyncAirBypass } from './airBypass';
12
+ export { VeSyncAirBaseV2 } from './airBaseV2';
13
+ export { VeSyncTowerFan } from './towerFan';
14
+ export { VeSyncHumidifier } from './humidifier';
15
+ export { VeSyncWarmHumidifier } from './warmHumidifier';
16
+ export { VeSyncHumid200300S } from './humid200300S';
17
+
18
+ // Export fan modules dictionary
19
+ export const fanModules: Record<string, new (details: Record<string, any>, manager: VeSync) => VeSyncFan> = {
20
+ // Core Series
21
+ 'Core200S': VeSyncAirBypass,
22
+ 'Core300S': VeSyncAirBypass,
23
+ 'Core400S': VeSyncAirBypass,
24
+ 'Core600S': VeSyncAirBypass,
25
+
26
+ // LAP Series
27
+ 'LAP-C201S-AUSR': VeSyncAirBypass,
28
+ 'LAP-C202S-WUSR': VeSyncAirBypass,
29
+ 'LAP-C301S-WJP': VeSyncAirBypass,
30
+ 'LAP-C302S-WUSB': VeSyncAirBypass,
31
+ 'LAP-C301S-WAAA': VeSyncAirBypass,
32
+ 'LAP-C401S-WJP': VeSyncAirBypass,
33
+ 'LAP-C401S-WUSR': VeSyncAirBypass,
34
+ 'LAP-C401S-WAAA': VeSyncAirBypass,
35
+ 'LAP-C601S-WUS': VeSyncAirBypass,
36
+ 'LAP-C601S-WUSR': VeSyncAirBypass,
37
+ 'LAP-C601S-WEU': VeSyncAirBypass,
38
+
39
+ // Vital100S Series - Using VeSyncAirBaseV2
40
+ 'LAP-V102S-AASR': VeSyncAirBaseV2,
41
+ 'LAP-V102S-WUS': VeSyncAirBaseV2,
42
+ 'LAP-V102S-WEU': VeSyncAirBaseV2,
43
+ 'LAP-V102S-AUSR': VeSyncAirBaseV2,
44
+ 'LAP-V102S-WJP': VeSyncAirBaseV2,
45
+
46
+ // Vital200S Series - Using VeSyncAirBaseV2
47
+ 'LAP-V201S-AASR': VeSyncAirBaseV2,
48
+ 'LAP-V201S-WJP': VeSyncAirBaseV2,
49
+ 'LAP-V201S-WEU': VeSyncAirBaseV2,
50
+ 'LAP-V201S-WUS': VeSyncAirBaseV2,
51
+ 'LAP-V201-AUSR': VeSyncAirBaseV2,
52
+ 'LAP-V201S-AUSR': VeSyncAirBaseV2,
53
+ 'LAP-V201S-AEUR': VeSyncAirBaseV2,
54
+
55
+ // EverestAir Series - Using VeSyncAirBaseV2
56
+ 'LAP-EL551S-AUS': VeSyncAirBaseV2,
57
+ 'LAP-EL551S-AEUR': VeSyncAirBaseV2,
58
+ 'LAP-EL551S-WEU': VeSyncAirBaseV2,
59
+ 'LAP-EL551S-WUS': VeSyncAirBaseV2,
60
+
61
+ // LTF Series
62
+ 'LTF-F422S-KEU': VeSyncTowerFan,
63
+ 'LTF-F422S-WUSR': VeSyncTowerFan,
64
+ 'LTF-F422_WJP': VeSyncTowerFan,
65
+ 'LTF-F422S-WUS': VeSyncTowerFan,
66
+
67
+ // Classic Series
68
+ 'Classic300S': VeSyncHumidifier,
69
+ 'Classic200S': VeSyncHumidifier,
70
+
71
+ // Dual Series
72
+ 'Dual200S': VeSyncHumidifier,
73
+
74
+ // LUH Series
75
+ 'LUH-A601S-WUSB': VeSyncHumid200300S,
76
+ 'LUH-A601S-AUSW': VeSyncHumid200300S,
77
+ 'LUH-D301S-WUSR': VeSyncHumid200300S,
78
+ 'LUH-D301S-WJP': VeSyncHumid200300S,
79
+ 'LUH-D301S-WEU': VeSyncHumid200300S,
80
+ 'LUH-A602S-WUSR': VeSyncHumid200300S,
81
+ 'LUH-A602S-WUS': VeSyncHumid200300S,
82
+ 'LUH-A602S-WEUR': VeSyncHumid200300S,
83
+ 'LUH-A602S-WEU': VeSyncHumid200300S,
84
+ 'LUH-A602S-WJP': VeSyncHumid200300S,
85
+ 'LUH-A602S-WUSC': VeSyncHumid200300S,
86
+ 'LUH-O451S-WEU': VeSyncHumid200300S,
87
+ 'LUH-O451S-WUS': VeSyncHumid200300S,
88
+ 'LUH-O451S-WUSR': VeSyncHumid200300S,
89
+ 'LUH-O601S-WUS': VeSyncHumid200300S,
90
+ 'LUH-O601S-KUS': VeSyncHumid200300S,
91
+ 'LUH-M101S-WUS': VeSyncHumid200300S,
92
+ 'LUH-M101S-WEUR': VeSyncHumid200300S,
93
+
94
+ // LEH Series
95
+ 'LEH-S601S-WUS': VeSyncHumid200300S,
96
+ 'LEH-S601S-WUSR': VeSyncHumid200300S,
97
+
98
+ // LV Series
99
+ 'LV-PUR131S': VeSyncAirBypass,
100
+ 'LV-RH131S': VeSyncAirBypass
101
+ };
@@ -0,0 +1,335 @@
1
+ import { VeSyncAirBaseV2 } from './airBaseV2';
2
+ import { VeSync } from '../vesync';
3
+ import { logger } from '../logger';
4
+
5
+ /**
6
+ * VeSync Tower Fan Implementation
7
+ */
8
+ export class VeSyncTowerFan extends VeSyncAirBaseV2 {
9
+ protected readonly towerModes = ['normal', 'advancedSleep', 'off'] as const;
10
+
11
+ constructor(details: Record<string, any>, manager: VeSync) {
12
+ super(details, manager);
13
+ logger.debug(`Initialized VeSyncTowerFan device: ${this.deviceName}`);
14
+ }
15
+
16
+ /**
17
+ * Get device details
18
+ */
19
+ async getDetails(): Promise<Boolean> {
20
+ logger.debug(`Getting details for device: ${this.deviceName}`);
21
+ const [head, body] = this.buildApiDict('getTowerFanStatus');
22
+
23
+ const [response, status] = await this.callApi(
24
+ '/cloud/v2/deviceManaged/bypassV2',
25
+ 'post',
26
+ body,
27
+ head
28
+ );
29
+
30
+ if (!this.checkResponse([response, status], 'getDetails') || !response?.result) {
31
+ logger.debug('Error getting tower fan details');
32
+ this.connectionStatus = 'offline';
33
+ return false;
34
+ }
35
+
36
+ const innerResponse = response.result;
37
+ if (innerResponse.code !== 0 || !innerResponse.result) {
38
+ logger.debug('Error in inner response from tower fan');
39
+ this.connectionStatus = 'offline';
40
+ return false;
41
+ }
42
+
43
+ const deviceData = innerResponse.result;
44
+ this.deviceStatus = deviceData.powerSwitch === 1 ? 'on' : 'off';
45
+ this.details = {
46
+ powerSwitch: deviceData.powerSwitch,
47
+ workMode: deviceData.workMode,
48
+ manualSpeedLevel: deviceData.manualSpeedLevel,
49
+ fanSpeedLevel: deviceData.fanSpeedLevel,
50
+ screenState: deviceData.screenState,
51
+ screenSwitch: deviceData.screenSwitch,
52
+ oscillationState: deviceData.oscillationState,
53
+ oscillationSwitch: deviceData.oscillationSwitch,
54
+ timerRemain: deviceData.timerRemain,
55
+ temperature: deviceData.temperature || 0,
56
+ humidity: deviceData.humidity || 0,
57
+ thermalComfort: deviceData.thermalComfort,
58
+ sleepPreference: deviceData.sleepPreference || {},
59
+ scheduleCount: deviceData.scheduleCount,
60
+ displayingType: deviceData.displayingType,
61
+ errorCode: deviceData.errorCode
62
+ };
63
+
64
+ logger.debug(`Successfully got details for device: ${this.deviceName}`);
65
+ return true;
66
+ }
67
+
68
+ /**
69
+ * Toggle device power
70
+ */
71
+ async toggleSwitch(toggle: boolean): Promise<boolean> {
72
+ if (typeof toggle !== 'boolean') {
73
+ logger.debug('Invalid toggle value for tower fan switch');
74
+ return false;
75
+ }
76
+
77
+ const [head, body] = this.buildApiDict('setSwitch');
78
+ body.payload.data = {
79
+ powerSwitch: toggle ? 1 : 0,
80
+ switchIdx: 0
81
+ };
82
+
83
+ const [response, status] = await this.callApi(
84
+ '/cloud/v2/deviceManaged/bypassV2',
85
+ 'post',
86
+ body,
87
+ head
88
+ );
89
+
90
+ const success = this.checkResponse([response, status], 'toggleSwitch');
91
+ if (success) {
92
+ this.deviceStatus = toggle ? 'on' : 'off';
93
+ } else {
94
+ logger.debug('Error toggling tower fan power');
95
+ }
96
+ return success;
97
+ }
98
+
99
+ /**
100
+ * Turn device on
101
+ */
102
+ async turnOn(): Promise<boolean> {
103
+ logger.debug(`Turning on device: ${this.deviceName}`);
104
+ return this.toggleSwitch(true);
105
+ }
106
+
107
+ /**
108
+ * Turn device off
109
+ */
110
+ async turnOff(): Promise<boolean> {
111
+ logger.debug(`Turning off device: ${this.deviceName}`);
112
+ return this.toggleSwitch(false);
113
+ }
114
+
115
+ /**
116
+ * Set tower fan mode
117
+ */
118
+ async mode_toggle(mode: string): Promise<boolean> {
119
+ if (!this.towerModes.includes(mode as any)) {
120
+ logger.debug(`Invalid mode: ${mode}. Must be one of: ${this.towerModes.join(', ')}`);
121
+ return false;
122
+ }
123
+
124
+ if (mode === 'off') {
125
+ return this.turnOff();
126
+ }
127
+
128
+ const [head, body] = this.buildApiDict('setTowerFanMode');
129
+ body.deviceId = this.cid;
130
+ body.payload.data = {
131
+ workMode: mode
132
+ };
133
+
134
+ const [response, status] = await this.callApi(
135
+ '/cloud/v2/deviceManaged/bypassV2',
136
+ 'post',
137
+ body,
138
+ head
139
+ );
140
+
141
+ const success = this.checkResponse([response, status], 'mode_toggle');
142
+ if (success) {
143
+ this.details.workMode = mode;
144
+ } else {
145
+ logger.error(`Failed to set ${mode} mode for device: ${this.deviceName}`);
146
+ }
147
+ return success;
148
+ }
149
+
150
+ /**
151
+ * Change fan speed
152
+ */
153
+ async changeFanSpeed(speed: number): Promise<boolean> {
154
+ // const speeds = this.config.levels ?? [];
155
+ // if (!speeds.includes(speed)) {
156
+ // logger.debug(`Invalid speed: ${speed}. Must be one of: ${speeds.join(', ')}`);
157
+ // return false;
158
+ // }
159
+
160
+ const [head, body] = this.buildApiDict('setLevel');
161
+ body.payload.data = {
162
+ levelIdx: 0,
163
+ levelType: 'wind',
164
+ manualSpeedLevel: speed
165
+ };
166
+
167
+ const [response, status] = await this.callApi(
168
+ '/cloud/v2/deviceManaged/bypassV2',
169
+ 'post',
170
+ body,
171
+ head
172
+ );
173
+
174
+ const success = this.checkResponse([response, status], 'changeFanSpeed');
175
+ if (success) {
176
+ this.details.manualSpeedLevel = speed;
177
+ } else {
178
+ logger.debug('Error setting fan speed');
179
+ }
180
+ return success;
181
+ }
182
+
183
+ /**
184
+ * Set normal mode
185
+ */
186
+ async normal_mode(): Promise<boolean> {
187
+ logger.debug(`Setting normal mode for device: ${this.deviceName}`);
188
+ return this.mode_toggle('normal');
189
+ }
190
+
191
+ /**
192
+ * Set manual mode - adapter to set mode to normal
193
+ */
194
+ async manual_mode(): Promise<boolean> {
195
+ logger.debug(`Setting manual mode for device: ${this.deviceName}`);
196
+ return this.normal_mode();
197
+ }
198
+
199
+ /**
200
+ * Set advanced sleep mode
201
+ */
202
+ async advanced_sleep_mode(): Promise<boolean> {
203
+ logger.debug(`Setting advanced sleep mode for device: ${this.deviceName}`);
204
+ return this.mode_toggle('advancedSleep');
205
+ }
206
+
207
+ /**
208
+ * Set sleep mode - adapter for advanced sleep mode
209
+ */
210
+ async sleep_mode(): Promise<boolean> {
211
+ logger.debug(`Setting sleep mode for device: ${this.deviceName}`);
212
+ return this.advanced_sleep_mode();
213
+ }
214
+
215
+ /**
216
+ * Override setMode to handle tower fan specific modes
217
+ */
218
+ async setMode(mode: string): Promise<boolean> {
219
+ return this.mode_toggle(mode);
220
+ }
221
+
222
+ /**
223
+ * Get current speed
224
+ */
225
+ get speed(): number {
226
+ return this.details.manualSpeedLevel || 0;
227
+ }
228
+
229
+ /**
230
+ * Get display status
231
+ */
232
+ get displayState(): boolean {
233
+ return Boolean(this.details.screenState);
234
+ }
235
+
236
+ /**
237
+ * Get oscillation status
238
+ */
239
+ get oscillationState(): boolean {
240
+ return Boolean(this.details.oscillationState);
241
+ }
242
+
243
+ /**
244
+ * Get mute status
245
+ */
246
+ get muteState(): boolean {
247
+ return Boolean(this.details.muteState);
248
+ }
249
+
250
+ /**
251
+ * Get temperature (in tenths of a degree)
252
+ */
253
+ get temperature(): number {
254
+ return this.details.temperature || 0;
255
+ }
256
+
257
+ /**
258
+ * Get humidity percentage
259
+ */
260
+ get humidity(): number {
261
+ return this.details.humidity || 0;
262
+ }
263
+
264
+ /**
265
+ * Get thermal comfort level
266
+ */
267
+ get thermalComfort(): number {
268
+ return this.details.thermalComfort || 0;
269
+ }
270
+
271
+ /**
272
+ * Get sleep preferences
273
+ */
274
+ get sleepPreference(): Record<string, any> {
275
+ return this.details.sleepPreference || {};
276
+ }
277
+
278
+ /**
279
+ * Get schedule count
280
+ */
281
+ get scheduleCount(): number {
282
+ return this.details.scheduleCount || 0;
283
+ }
284
+
285
+ /**
286
+ * Get error code
287
+ */
288
+ get errorCode(): number {
289
+ return this.details.errorCode || 0;
290
+ }
291
+
292
+ /**
293
+ * Turn oscillation on
294
+ */
295
+ async setOscillationOn(): Promise<boolean> {
296
+ return this.setOscillation(true);
297
+ }
298
+
299
+ /**
300
+ * Turn oscillation off
301
+ */
302
+ async setOscillationOff(): Promise<boolean> {
303
+ return this.setOscillation(false);
304
+ }
305
+
306
+ /**
307
+ * Display device info
308
+ */
309
+ override display(): void {
310
+ super.display();
311
+ const info = [
312
+ ['Mode: ', this.details.workMode || ''],
313
+ ['Speed: ', this.speed],
314
+ ['Fan Speed Level: ', this.details.fanSpeedLevel || 0],
315
+ ['Display: ', this.displayState],
316
+ ['Display Switch: ', this.details.screenSwitch],
317
+ ['Oscillation: ', this.oscillationState],
318
+ ['Oscillation Switch: ', this.details.oscillationSwitch],
319
+ ['Mute: ', this.muteState],
320
+ ['Mute Switch: ', this.details.muteSwitch],
321
+ ['Timer: ', this.timer],
322
+ ['Temperature: ', this.temperature / 10, '°C'],
323
+ ['Humidity: ', this.humidity, '%'],
324
+ ['Thermal Comfort: ', this.thermalComfort],
325
+ ['Sleep Preference: ', JSON.stringify(this.sleepPreference)],
326
+ ['Schedule Count: ', this.scheduleCount],
327
+ ['Displaying Type: ', this.details.displayingType],
328
+ ['Error Code: ', this.errorCode]
329
+ ];
330
+
331
+ for (const [key, value, unit = ''] of info) {
332
+ logger.info(`${key.toString().padEnd(30, '.')} ${value}${unit}`);
333
+ }
334
+ }
335
+ }
@@ -0,0 +1,202 @@
1
+ import { VeSyncHumidifier } from './humidifier';
2
+ import { VeSync } from '../vesync';
3
+ import { Helpers } from '../helpers';
4
+ import { logger } from '../logger';
5
+
6
+ /**
7
+ * VeSync Warm Humidifier Class
8
+ */
9
+ export class VeSyncWarmHumidifier extends VeSyncHumidifier {
10
+ protected readonly warmLevels = [1, 2, 3];
11
+
12
+ constructor(details: Record<string, any>, manager: VeSync) {
13
+ super(details, manager);
14
+ logger.debug(`Initialized VeSyncWarmHumidifier device: ${this.deviceName}`);
15
+ }
16
+
17
+ /**
18
+ * Get device details
19
+ */
20
+ async getDetails(): Promise<Boolean> {
21
+ const success = await super.getDetails();
22
+ if (success && this.details) {
23
+ // Add warm humidifier specific fields
24
+ this.details = {
25
+ ...this.details,
26
+ warm_enabled: Boolean(this.details.warm_level && this.details.warm_level > 0),
27
+ drying_mode_enabled: this.details.autoDryingSwitch === 1,
28
+ drying_mode_state: this.details.dryingMode || '',
29
+ drying_mode_level: this.details.dryingLevel || 0,
30
+ drying_mode_seconds_remaining: this.details.dryingRemainTime || 0
31
+ };
32
+ }
33
+ return success;
34
+ }
35
+
36
+ /**
37
+ * Change fan speed - Implemented to satisfy interface but redirects to setMistLevel
38
+ */
39
+ async changeFanSpeed(speed: number): Promise<boolean> {
40
+ logger.debug(`Redirecting fan speed change to mist level for device: ${this.deviceName}`);
41
+ return this.setMistLevel(speed);
42
+ }
43
+
44
+ /**
45
+ * Set device mode
46
+ */
47
+ async setMode(mode: string): Promise<boolean> {
48
+ if (!this.modes.includes(mode as any)) {
49
+ const error = `Invalid mode: ${mode}. Must be one of: ${this.modes.join(', ')}`;
50
+ logger.error(`${error} for device: ${this.deviceName}`);
51
+ throw new Error(error);
52
+ }
53
+
54
+ logger.debug(`Setting mode to ${mode} for device: ${this.deviceName}`);
55
+ const [response, status] = await this.callApi(
56
+ '/cloud/v2/deviceManaged/bypassV2',
57
+ 'post',
58
+ {
59
+ ...Helpers.reqBody(this.manager, 'bypassV2'),
60
+ cid: this.cid,
61
+ configModule: this.configModule,
62
+ payload: {
63
+ data: {
64
+ mode
65
+ },
66
+ method: 'setHumidityMode',
67
+ source: 'APP'
68
+ }
69
+ },
70
+ Helpers.reqHeaderBypass()
71
+ );
72
+
73
+ const success = this.checkResponse([response, status], 'setMode');
74
+ if (success) {
75
+ this.details.mode = mode;
76
+ } else {
77
+ logger.error(`Failed to set mode to ${mode} for device: ${this.deviceName}`);
78
+ }
79
+ return success;
80
+ }
81
+
82
+ /**
83
+ * Set warm mist level
84
+ */
85
+ async setWarmLevel(level: number): Promise<boolean> {
86
+ if (!this.hasFeature('warm')) {
87
+ const error = 'Warm mist control not supported';
88
+ logger.error(`${error} for device: ${this.deviceName}`);
89
+ throw new Error(error);
90
+ }
91
+
92
+ if (!this.warmLevels.includes(level)) {
93
+ const error = `Invalid warm level: ${level}. Must be one of: ${this.warmLevels.join(', ')}`;
94
+ logger.error(`${error} for device: ${this.deviceName}`);
95
+ throw new Error(error);
96
+ }
97
+
98
+ logger.debug(`Setting warm level to ${level} for device: ${this.deviceName}`);
99
+ const [response, status] = await this.callApi(
100
+ '/cloud/v2/deviceManaged/bypassV2',
101
+ 'post',
102
+ {
103
+ ...Helpers.reqBody(this.manager, 'bypassV2'),
104
+ cid: this.cid,
105
+ configModule: this.configModule,
106
+ payload: {
107
+ data: {
108
+ id: 0,
109
+ level: level,
110
+ type: 'warm'
111
+ },
112
+ method: 'setLevel',
113
+ source: 'APP'
114
+ }
115
+ },
116
+ Helpers.reqHeaderBypass()
117
+ );
118
+
119
+ const success = this.checkResponse([response, status], 'setWarmLevel');
120
+ if (success) {
121
+ this.details.warm_level = level;
122
+ this.details.warm_enabled = level > 0;
123
+ } else {
124
+ logger.error(`Failed to set warm level to ${level} for device: ${this.deviceName}`);
125
+ }
126
+ return success;
127
+ }
128
+
129
+ /**
130
+ * Set drying mode enabled
131
+ */
132
+ async setDryingModeEnabled(enabled: boolean): Promise<boolean> {
133
+ if (!this.hasFeature('drying')) {
134
+ const error = 'Drying mode not supported';
135
+ logger.error(`${error} for device: ${this.deviceName}`);
136
+ throw new Error(error);
137
+ }
138
+
139
+ logger.debug(`Setting drying mode to ${enabled} for device: ${this.deviceName}`);
140
+ const [response, status] = await this.callApi(
141
+ '/cloud/v2/deviceManaged/bypassV2',
142
+ 'post',
143
+ {
144
+ ...Helpers.reqBody(this.manager, 'bypassV2'),
145
+ cid: this.cid,
146
+ configModule: this.configModule,
147
+ payload: {
148
+ data: {
149
+ autoDryingSwitch: enabled ? 1 : 0
150
+ },
151
+ method: 'setDryingMode',
152
+ source: 'APP'
153
+ }
154
+ },
155
+ Helpers.reqHeaderBypass()
156
+ );
157
+
158
+ const success = this.checkResponse([response, status], 'setDryingModeEnabled');
159
+ if (success) {
160
+ this.details.drying_mode_enabled = enabled;
161
+ this.details.autoDryingSwitch = enabled ? 1 : 0;
162
+ } else {
163
+ logger.error(`Failed to set drying mode to ${enabled} for device: ${this.deviceName}`);
164
+ }
165
+ return success;
166
+ }
167
+
168
+ /**
169
+ * Get warm mist enabled status
170
+ */
171
+ get warmMistEnabled(): boolean {
172
+ return this.details.warm_enabled || false;
173
+ }
174
+
175
+ /**
176
+ * Get drying mode enabled status
177
+ */
178
+ get dryingModeEnabled(): boolean {
179
+ return this.details.drying_mode_enabled || false;
180
+ }
181
+
182
+ /**
183
+ * Get drying mode state
184
+ */
185
+ get dryingModeState(): string {
186
+ return this.details.drying_mode_state || '';
187
+ }
188
+
189
+ /**
190
+ * Get drying mode level
191
+ */
192
+ get dryingModeLevel(): number {
193
+ return this.details.drying_mode_level || 0;
194
+ }
195
+
196
+ /**
197
+ * Get drying mode seconds remaining
198
+ */
199
+ get dryingModeSecondsRemaining(): number {
200
+ return this.details.drying_mode_seconds_remaining || 0;
201
+ }
202
+ }
@@ -19,7 +19,7 @@ export const fanConfig: FanConfig = {
19
19
  // Core Series
20
20
  'Core200S': {
21
21
  module: 'VeSyncAirBypass',
22
- features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer'],
22
+ features: ['display', 'child_lock', 'night_light', 'air_quality', 'timer', 'fan_speed', 'auto_mode'],
23
23
  levels: [1, 2, 3]
24
24
  },
25
25
  'Core300S': {
@@ -318,7 +318,7 @@ export abstract class VeSyncFan extends VeSyncBaseDevice {
318
318
  mode?: string;
319
319
  speed?: number;
320
320
  filter_life?: number;
321
- screen_status?: string;
321
+ screen_status?: 'on' | 'off';
322
322
  child_lock?: boolean;
323
323
  air_quality?: string;
324
324
  humidity?: number;
@@ -377,8 +377,8 @@ export abstract class VeSyncFan extends VeSyncBaseDevice {
377
377
  /**
378
378
  * Get screen status
379
379
  */
380
- get screenStatus(): string {
381
- return this.details.screen_status ?? '';
380
+ get screenStatus(): 'on' | 'off' {
381
+ return this.details.screen_status ?? 'off';
382
382
  }
383
383
 
384
384
  /**
@@ -519,4 +519,4 @@ export abstract class VeSyncFan extends VeSyncBaseDevice {
519
519
  abstract turnOff(): Promise<boolean>;
520
520
  abstract changeFanSpeed(speed: number): Promise<boolean>;
521
521
  abstract setMode(mode: string): Promise<boolean>;
522
- }
522
+ }