tsvesync 1.0.73 → 1.0.75

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,80 @@
1
+ import { VeSyncFan } from '../vesyncFan';
2
+ import { VeSync } from '../vesync';
3
+ /**
4
+ * VeSync Air Purifier 131 Series (LV-PUR131S, LV-RH131S)
5
+ * This class implements the specific API for LV series devices
6
+ */
7
+ export declare class VeSyncAir131 extends VeSyncFan {
8
+ protected readonly modes: readonly ["auto", "manual", "sleep"];
9
+ protected readonly displayModes: readonly ["on", "off"];
10
+ protected readonly childLockModes: readonly ["on", "off"];
11
+ constructor(details: Record<string, any>, manager: VeSync);
12
+ /**
13
+ * Get device details
14
+ */
15
+ getDetails(): Promise<Boolean>;
16
+ /**
17
+ * Turn device on
18
+ */
19
+ turnOn(): Promise<boolean>;
20
+ /**
21
+ * Turn device off
22
+ */
23
+ turnOff(): Promise<boolean>;
24
+ /**
25
+ * Change fan speed
26
+ */
27
+ changeFanSpeed(speed: number): Promise<boolean>;
28
+ /**
29
+ * Set device mode
30
+ */
31
+ setMode(mode: string): Promise<boolean>;
32
+ /**
33
+ * Set display status
34
+ */
35
+ setDisplay(enabled: boolean): Promise<boolean>;
36
+ /**
37
+ * Set child lock
38
+ */
39
+ setChildLock(enabled: boolean): Promise<boolean>;
40
+ /**
41
+ * Set timer
42
+ */
43
+ setTimer(hours: number): Promise<boolean>;
44
+ /**
45
+ * Clear timer
46
+ */
47
+ clearTimer(): Promise<boolean>;
48
+ /**
49
+ * Set auto mode
50
+ */
51
+ autoMode(): Promise<boolean>;
52
+ /**
53
+ * Set manual mode
54
+ */
55
+ manualMode(): Promise<boolean>;
56
+ /**
57
+ * Set sleep mode
58
+ */
59
+ sleepMode(): Promise<boolean>;
60
+ /**
61
+ * Turn off display
62
+ */
63
+ turnOffDisplay(): Promise<boolean>;
64
+ /**
65
+ * Turn on display
66
+ */
67
+ turnOnDisplay(): Promise<boolean>;
68
+ /**
69
+ * Get active time in minutes
70
+ */
71
+ get activeTime(): number;
72
+ /**
73
+ * Display device info
74
+ */
75
+ display(): void;
76
+ /**
77
+ * Return JSON details for device
78
+ */
79
+ displayJSON(): string;
80
+ }
@@ -0,0 +1,446 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.VeSyncAir131 = void 0;
4
+ const vesyncFan_1 = require("../vesyncFan");
5
+ const logger_1 = require("../logger");
6
+ /**
7
+ * VeSync Air Purifier 131 Series (LV-PUR131S, LV-RH131S)
8
+ * This class implements the specific API for LV series devices
9
+ */
10
+ class VeSyncAir131 extends vesyncFan_1.VeSyncFan {
11
+ constructor(details, manager) {
12
+ super(details, manager);
13
+ this.modes = ['auto', 'manual', 'sleep'];
14
+ this.displayModes = ['on', 'off'];
15
+ this.childLockModes = ['on', 'off'];
16
+ logger_1.logger.debug(`Initialized VeSyncAir131 device: ${this.deviceName}`);
17
+ }
18
+ /**
19
+ * Get device details
20
+ */
21
+ async getDetails() {
22
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
23
+ logger_1.logger.debug(`Getting details for device: ${this.deviceName}`);
24
+ const [response, status] = await this.callApi('/131airPurifier/v1/device/devicedetail', 'post', {
25
+ acceptLanguage: 'en',
26
+ accountID: this.manager.accountId,
27
+ appVersion: '2.8.6',
28
+ method: 'devicedetail',
29
+ mobileId: '1234567890123456',
30
+ phoneBrand: 'SM N9005',
31
+ phoneOS: 'Android',
32
+ timeZone: this.manager.timeZone,
33
+ token: this.manager.token,
34
+ uuid: this.uuid
35
+ }, {
36
+ 'accept-language': 'en',
37
+ 'accountId': this.manager.accountId,
38
+ 'appVersion': '2.8.6',
39
+ 'content-type': 'application/json',
40
+ 'tk': this.manager.token,
41
+ 'tz': this.manager.timeZone
42
+ });
43
+ const success = this.checkResponse([response, status], 'getDetails');
44
+ if (success && response) {
45
+ this.deviceStatus = ((_b = (_a = response.result) === null || _a === void 0 ? void 0 : _a.result) === null || _b === void 0 ? void 0 : _b.deviceStatus) === 'on' ? 'on' : 'off';
46
+ this.details = {
47
+ mode: ((_d = (_c = response.result) === null || _c === void 0 ? void 0 : _c.result) === null || _d === void 0 ? void 0 : _d.mode) || '',
48
+ speed: ((_f = (_e = response.result) === null || _e === void 0 ? void 0 : _e.result) === null || _f === void 0 ? void 0 : _f.level) || 0,
49
+ filterLife: ((_h = (_g = response.result) === null || _g === void 0 ? void 0 : _g.result) === null || _h === void 0 ? void 0 : _h.filterLife) || 0,
50
+ screenStatus: ((_k = (_j = response.result) === null || _j === void 0 ? void 0 : _j.result) === null || _k === void 0 ? void 0 : _k.display) ? 'on' : 'off',
51
+ childLock: ((_m = (_l = response.result) === null || _l === void 0 ? void 0 : _l.result) === null || _m === void 0 ? void 0 : _m.childLock) || false,
52
+ airQuality: ((_p = (_o = response.result) === null || _o === void 0 ? void 0 : _o.result) === null || _p === void 0 ? void 0 : _p.airQuality) || 0,
53
+ active_time: ((_r = (_q = response.result) === null || _q === void 0 ? void 0 : _q.result) === null || _r === void 0 ? void 0 : _r.activeTime) || 0
54
+ };
55
+ return true;
56
+ }
57
+ return false;
58
+ }
59
+ /**
60
+ * Turn device on
61
+ */
62
+ async turnOn() {
63
+ logger_1.logger.info(`Turning on device: ${this.deviceName}`);
64
+ const [response, status] = await this.callApi('/131airPurifier/v1/device/deviceStatus', 'put', {
65
+ acceptLanguage: 'en',
66
+ accountID: this.manager.accountId,
67
+ status: 'on',
68
+ timeZone: this.manager.timeZone,
69
+ token: this.manager.token,
70
+ uuid: this.uuid
71
+ }, {
72
+ 'accept-language': 'en',
73
+ 'accountId': this.manager.accountId,
74
+ 'appVersion': '2.8.6',
75
+ 'content-type': 'application/json',
76
+ 'tk': this.manager.token,
77
+ 'tz': this.manager.timeZone
78
+ });
79
+ const success = this.checkResponse([response, status], 'turnOn');
80
+ if (!success) {
81
+ logger_1.logger.error(`Failed to turn on device: ${this.deviceName}`);
82
+ }
83
+ return success;
84
+ }
85
+ /**
86
+ * Turn device off
87
+ */
88
+ async turnOff() {
89
+ logger_1.logger.info(`Turning off device: ${this.deviceName}`);
90
+ const [response, status] = await this.callApi('/131airPurifier/v1/device/deviceStatus', 'put', {
91
+ acceptLanguage: 'en',
92
+ accountID: this.manager.accountId,
93
+ status: 'off',
94
+ timeZone: this.manager.timeZone,
95
+ token: this.manager.token,
96
+ uuid: this.uuid
97
+ }, {
98
+ 'accept-language': 'en',
99
+ 'accountId': this.manager.accountId,
100
+ 'appVersion': '2.8.6',
101
+ 'content-type': 'application/json',
102
+ 'tk': this.manager.token,
103
+ 'tz': this.manager.timeZone
104
+ });
105
+ const success = this.checkResponse([response, status], 'turnOff');
106
+ if (!success) {
107
+ logger_1.logger.error(`Failed to turn off device: ${this.deviceName}`);
108
+ }
109
+ return success;
110
+ }
111
+ /**
112
+ * Change fan speed
113
+ */
114
+ async changeFanSpeed(speed) {
115
+ logger_1.logger.info(`Changing fan speed to ${speed} for device: ${this.deviceName}`);
116
+ // Check if device is in manual mode
117
+ if (this.details.mode !== 'manual') {
118
+ logger_1.logger.debug(`${this.deviceName} not in manual mode, cannot change speed`);
119
+ return false;
120
+ }
121
+ // Validate speed for LV series (1-3)
122
+ if (speed < 1 || speed > 3) {
123
+ logger_1.logger.error(`Invalid fan speed: ${speed}. Must be between 1 and 3 for device: ${this.deviceName}`);
124
+ return false;
125
+ }
126
+ const [response, status] = await this.callApi('/131airPurifier/v1/device/updateSpeed', 'put', {
127
+ acceptLanguage: 'en',
128
+ accountID: this.manager.accountId,
129
+ level: speed,
130
+ timeZone: this.manager.timeZone,
131
+ token: this.manager.token,
132
+ uuid: this.uuid
133
+ }, {
134
+ 'accept-language': 'en',
135
+ 'accountId': this.manager.accountId,
136
+ 'appVersion': '2.8.6',
137
+ 'content-type': 'application/json',
138
+ 'tk': this.manager.token,
139
+ 'tz': this.manager.timeZone
140
+ });
141
+ const success = this.checkResponse([response, status], 'changeFanSpeed');
142
+ if (success) {
143
+ this.details.speed = speed;
144
+ return true;
145
+ }
146
+ else {
147
+ logger_1.logger.error(`Failed to change fan speed to ${speed} for device: ${this.deviceName}`);
148
+ return false;
149
+ }
150
+ }
151
+ /**
152
+ * Set device mode
153
+ */
154
+ async setMode(mode) {
155
+ if (!this.modes.includes(mode)) {
156
+ const error = `Invalid mode: ${mode}. Must be one of: ${this.modes.join(', ')}`;
157
+ logger_1.logger.error(`${error} for device: ${this.deviceName}`);
158
+ throw new Error(error);
159
+ }
160
+ logger_1.logger.debug(`Setting mode to ${mode} for device: ${this.deviceName}`);
161
+ const payload = {
162
+ acceptLanguage: 'en',
163
+ accountID: this.manager.accountId,
164
+ mode: mode,
165
+ timeZone: this.manager.timeZone,
166
+ token: this.manager.token,
167
+ uuid: this.uuid
168
+ };
169
+ // For manual mode, we need to set the level
170
+ if (mode === 'manual') {
171
+ payload.level = this.details.speed || 1;
172
+ }
173
+ const [response, status] = await this.callApi('/131airPurifier/v1/device/updateMode', 'put', payload, {
174
+ 'accept-language': 'en',
175
+ 'accountId': this.manager.accountId,
176
+ 'appVersion': '2.8.6',
177
+ 'content-type': 'application/json',
178
+ 'tk': this.manager.token,
179
+ 'tz': this.manager.timeZone
180
+ });
181
+ const success = this.checkResponse([response, status], 'setMode');
182
+ if (success) {
183
+ this.details.mode = mode;
184
+ return true;
185
+ }
186
+ else {
187
+ logger_1.logger.error(`Failed to set mode to ${mode} for device: ${this.deviceName}`);
188
+ return false;
189
+ }
190
+ }
191
+ /**
192
+ * Set display status
193
+ */
194
+ async setDisplay(enabled) {
195
+ if (!this.hasFeature('display')) {
196
+ const error = 'Display control not supported';
197
+ logger_1.logger.error(`${error} for device: ${this.deviceName}`);
198
+ throw new Error(error);
199
+ }
200
+ // Check if device is in sleep mode - display control may not work in sleep mode
201
+ if (this.details.mode === 'sleep') {
202
+ logger_1.logger.warn(`Device ${this.deviceName} is in sleep mode, display control may not work`);
203
+ }
204
+ logger_1.logger.debug(`Setting display to ${enabled ? 'on' : 'off'} for device: ${this.deviceName}`);
205
+ const [response, status] = await this.callApi('/131airPurifier/v1/device/updateScreen', 'put', {
206
+ acceptLanguage: 'en',
207
+ accountID: this.manager.accountId,
208
+ status: enabled ? 'on' : 'off',
209
+ timeZone: this.manager.timeZone,
210
+ token: this.manager.token,
211
+ uuid: this.uuid
212
+ }, {
213
+ 'accept-language': 'en',
214
+ 'accountId': this.manager.accountId,
215
+ 'appVersion': '2.8.6',
216
+ 'content-type': 'application/json',
217
+ 'tk': this.manager.token,
218
+ 'tz': this.manager.timeZone
219
+ });
220
+ const success = this.checkResponse([response, status], 'setDisplay');
221
+ if (success) {
222
+ this.details.screenStatus = enabled ? 'on' : 'off';
223
+ return true;
224
+ }
225
+ else {
226
+ logger_1.logger.error(`Failed to set display to ${enabled ? 'on' : 'off'} for device: ${this.deviceName}`);
227
+ return false;
228
+ }
229
+ }
230
+ /**
231
+ * Set child lock
232
+ */
233
+ async setChildLock(enabled) {
234
+ if (!this.hasFeature('child_lock')) {
235
+ const error = 'Child lock not supported';
236
+ logger_1.logger.error(`${error} for device: ${this.deviceName}`);
237
+ throw new Error(error);
238
+ }
239
+ // Check if device is in sleep mode - child lock may not work in sleep mode
240
+ if (this.details.mode === 'sleep') {
241
+ logger_1.logger.warn(`Device ${this.deviceName} is in sleep mode, child lock control may not work`);
242
+ }
243
+ logger_1.logger.debug(`Setting child lock to ${enabled ? 'on' : 'off'} for device: ${this.deviceName}`);
244
+ const [response, status] = await this.callApi('/131airPurifier/v1/device/updateChildLock', 'put', {
245
+ acceptLanguage: 'en',
246
+ accountID: this.manager.accountId,
247
+ status: enabled ? 'on' : 'off',
248
+ timeZone: this.manager.timeZone,
249
+ token: this.manager.token,
250
+ uuid: this.uuid
251
+ }, {
252
+ 'accept-language': 'en',
253
+ 'accountId': this.manager.accountId,
254
+ 'appVersion': '2.8.6',
255
+ 'content-type': 'application/json',
256
+ 'tk': this.manager.token,
257
+ 'tz': this.manager.timeZone
258
+ });
259
+ const success = this.checkResponse([response, status], 'setChildLock');
260
+ if (success) {
261
+ this.details.childLock = enabled;
262
+ return true;
263
+ }
264
+ else {
265
+ // Check for error code 11000000 (feature not supported)
266
+ if ((response === null || response === void 0 ? void 0 : response.code) === 11000000) {
267
+ logger_1.logger.warn(`Child lock control not supported via API for device: ${this.deviceName}`);
268
+ return false;
269
+ }
270
+ logger_1.logger.error(`Failed to set child lock to ${enabled ? 'on' : 'off'} for device: ${this.deviceName}`);
271
+ return false;
272
+ }
273
+ }
274
+ /**
275
+ * Set timer
276
+ */
277
+ async setTimer(hours) {
278
+ if (!this.hasFeature('timer')) {
279
+ const error = 'Timer not supported';
280
+ logger_1.logger.error(`${error} for device: ${this.deviceName}`);
281
+ throw new Error(error);
282
+ }
283
+ logger_1.logger.debug(`Setting timer to ${hours} hours for device: ${this.deviceName}`);
284
+ const [response, status] = await this.callApi('/131airPurifier/v1/device/updateTimer', 'put', {
285
+ acceptLanguage: 'en',
286
+ accountID: this.manager.accountId,
287
+ action: 'off',
288
+ duration: hours,
289
+ timeZone: this.manager.timeZone,
290
+ token: this.manager.token,
291
+ uuid: this.uuid
292
+ }, {
293
+ 'accept-language': 'en',
294
+ 'accountId': this.manager.accountId,
295
+ 'appVersion': '2.8.6',
296
+ 'content-type': 'application/json',
297
+ 'tk': this.manager.token,
298
+ 'tz': this.manager.timeZone
299
+ });
300
+ const success = this.checkResponse([response, status], 'setTimer');
301
+ if (success) {
302
+ this.timer = { duration: hours * 3600, action: 'off' };
303
+ return true;
304
+ }
305
+ else {
306
+ logger_1.logger.error(`Failed to set timer to ${hours} hours for device: ${this.deviceName}`);
307
+ return false;
308
+ }
309
+ }
310
+ /**
311
+ * Clear timer
312
+ */
313
+ async clearTimer() {
314
+ if (!this.hasFeature('timer')) {
315
+ const error = 'Timer not supported';
316
+ logger_1.logger.error(`${error} for device: ${this.deviceName}`);
317
+ throw new Error(error);
318
+ }
319
+ // If no timer is set, return success
320
+ if (!this.timer) {
321
+ logger_1.logger.debug(`No timer to clear for device: ${this.deviceName}`);
322
+ return true;
323
+ }
324
+ logger_1.logger.debug(`Clearing timer for device: ${this.deviceName}`);
325
+ const [response, status] = await this.callApi('/131airPurifier/v1/device/cancelTimer', 'put', {
326
+ acceptLanguage: 'en',
327
+ accountID: this.manager.accountId,
328
+ timeZone: this.manager.timeZone,
329
+ token: this.manager.token,
330
+ uuid: this.uuid
331
+ }, {
332
+ 'accept-language': 'en',
333
+ 'accountId': this.manager.accountId,
334
+ 'appVersion': '2.8.6',
335
+ 'content-type': 'application/json',
336
+ 'tk': this.manager.token,
337
+ 'tz': this.manager.timeZone
338
+ });
339
+ const success = this.checkResponse([response, status], 'clearTimer');
340
+ if (success) {
341
+ this.timer = null;
342
+ return true;
343
+ }
344
+ else {
345
+ logger_1.logger.error(`Failed to clear timer for device: ${this.deviceName}`);
346
+ return false;
347
+ }
348
+ }
349
+ /**
350
+ * Set auto mode
351
+ */
352
+ async autoMode() {
353
+ logger_1.logger.debug(`Setting auto mode for device: ${this.deviceName}`);
354
+ const success = await this.setMode('auto');
355
+ if (!success) {
356
+ logger_1.logger.error(`Failed to set auto mode for device: ${this.deviceName}`);
357
+ }
358
+ return success;
359
+ }
360
+ /**
361
+ * Set manual mode
362
+ */
363
+ async manualMode() {
364
+ logger_1.logger.debug(`Setting manual mode for device: ${this.deviceName}`);
365
+ const success = await this.setMode('manual');
366
+ if (!success) {
367
+ logger_1.logger.error(`Failed to set manual mode for device: ${this.deviceName}`);
368
+ }
369
+ return success;
370
+ }
371
+ /**
372
+ * Set sleep mode
373
+ */
374
+ async sleepMode() {
375
+ logger_1.logger.debug(`Setting sleep mode for device: ${this.deviceName}`);
376
+ const success = await this.setMode('sleep');
377
+ if (!success) {
378
+ logger_1.logger.error(`Failed to set sleep mode for device: ${this.deviceName}`);
379
+ }
380
+ return success;
381
+ }
382
+ /**
383
+ * Turn off display
384
+ */
385
+ async turnOffDisplay() {
386
+ logger_1.logger.debug(`Turning off display for device: ${this.deviceName}`);
387
+ const success = await this.setDisplay(false);
388
+ if (!success) {
389
+ logger_1.logger.error(`Failed to turn off display for device: ${this.deviceName}`);
390
+ }
391
+ return success;
392
+ }
393
+ /**
394
+ * Turn on display
395
+ */
396
+ async turnOnDisplay() {
397
+ logger_1.logger.debug(`Turning on display for device: ${this.deviceName}`);
398
+ const success = await this.setDisplay(true);
399
+ if (!success) {
400
+ logger_1.logger.error(`Failed to turn on display for device: ${this.deviceName}`);
401
+ }
402
+ return success;
403
+ }
404
+ /**
405
+ * Get active time in minutes
406
+ */
407
+ get activeTime() {
408
+ return this.details.active_time || 0;
409
+ }
410
+ /**
411
+ * Display device info
412
+ */
413
+ display() {
414
+ super.display();
415
+ const info = [
416
+ ['Mode: ', this.mode],
417
+ ['Speed: ', this.speed],
418
+ ['Filter Life: ', this.filterLife, '%'],
419
+ ['Screen Status: ', this.screenStatus],
420
+ ['Child Lock: ', this.childLock ? 'Enabled' : 'Disabled'],
421
+ ['Air Quality: ', this.airQuality],
422
+ ['Active Time: ', this.activeTime, 'minutes']
423
+ ];
424
+ for (const [key, value, unit = ''] of info) {
425
+ logger_1.logger.info(`${key.toString().padEnd(30, '.')} ${value}${unit}`);
426
+ }
427
+ }
428
+ /**
429
+ * Return JSON details for device
430
+ */
431
+ displayJSON() {
432
+ const baseInfo = JSON.parse(super.displayJSON());
433
+ const details = {
434
+ ...baseInfo,
435
+ 'Mode': this.mode,
436
+ 'Speed': this.speed.toString(),
437
+ 'Filter Life': this.filterLife.toString(),
438
+ 'Screen Status': this.screenStatus,
439
+ 'Child Lock': this.childLock ? 'Enabled' : 'Disabled',
440
+ 'Air Quality': this.airQuality,
441
+ 'Active Time': this.activeTime.toString()
442
+ };
443
+ return JSON.stringify(details, null, 4);
444
+ }
445
+ }
446
+ exports.VeSyncAir131 = VeSyncAir131;
@@ -76,4 +76,8 @@ export declare class VeSyncAirBypass extends VeSyncFan {
76
76
  * Turn on display
77
77
  */
78
78
  turnOnDisplay(): Promise<boolean>;
79
+ /**
80
+ * Get night light state
81
+ */
82
+ get nightLight(): string;
79
83
  }