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,484 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.VeSyncAirBypass = void 0;
4
+ const vesyncFan_1 = require("../vesyncFan");
5
+ const helpers_1 = require("../helpers");
6
+ const logger_1 = require("../logger");
7
+ /**
8
+ * VeSync Air Purifier with Bypass
9
+ */
10
+ class VeSyncAirBypass 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 VeSyncAirBypass device: ${this.deviceName}`);
17
+ }
18
+ /**
19
+ * Build API dictionary
20
+ */
21
+ buildApiDict(method) {
22
+ const head = helpers_1.Helpers.reqHeaderBypass();
23
+ const body = {
24
+ ...helpers_1.Helpers.reqBody(this.manager, 'bypassV2'),
25
+ cid: this.cid,
26
+ configModule: this.configModule,
27
+ payload: {
28
+ method,
29
+ source: 'APP',
30
+ data: {}
31
+ }
32
+ };
33
+ return [head, body];
34
+ }
35
+ /**
36
+ * Get device details
37
+ */
38
+ async getDetails() {
39
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
40
+ logger_1.logger.debug(`Getting details for device: ${this.deviceName}`);
41
+ // Special handling for LV series
42
+ if (this.deviceType.startsWith('LV-')) {
43
+ const [response, status] = await this.callApi('/131airPurifier/v1/device/devicedetail', 'post', {
44
+ acceptLanguage: 'en',
45
+ accountID: this.manager.accountId,
46
+ appVersion: '2.8.6',
47
+ method: 'devicedetail',
48
+ mobileId: '1234567890123456',
49
+ phoneBrand: 'SM N9005',
50
+ phoneOS: 'Android',
51
+ timeZone: this.manager.timeZone,
52
+ token: this.manager.token,
53
+ uuid: this.uuid
54
+ }, {
55
+ 'accept-language': 'en',
56
+ 'accountId': this.manager.accountId,
57
+ 'appVersion': '2.8.6',
58
+ 'content-type': 'application/json',
59
+ 'tk': this.manager.token,
60
+ 'tz': this.manager.timeZone
61
+ });
62
+ const success = this.checkResponse([response, status], 'getDetails');
63
+ if (success && response) {
64
+ 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';
65
+ this.details = {
66
+ mode: ((_d = (_c = response.result) === null || _c === void 0 ? void 0 : _c.result) === null || _d === void 0 ? void 0 : _d.mode) || '',
67
+ speed: ((_f = (_e = response.result) === null || _e === void 0 ? void 0 : _e.result) === null || _f === void 0 ? void 0 : _f.level) || 0,
68
+ filterLife: ((_h = (_g = response.result) === null || _g === void 0 ? void 0 : _g.result) === null || _h === void 0 ? void 0 : _h.filterLife) || 0,
69
+ screenStatus: ((_k = (_j = response.result) === null || _j === void 0 ? void 0 : _j.result) === null || _k === void 0 ? void 0 : _k.display) ? 'on' : 'off',
70
+ childLock: ((_m = (_l = response.result) === null || _l === void 0 ? void 0 : _l.result) === null || _m === void 0 ? void 0 : _m.childLock) || false,
71
+ airQuality: ((_p = (_o = response.result) === null || _o === void 0 ? void 0 : _o.result) === null || _p === void 0 ? void 0 : _p.airQuality) || 0
72
+ };
73
+ return true;
74
+ }
75
+ return false;
76
+ }
77
+ // Original implementation for other devices
78
+ const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', {
79
+ ...helpers_1.Helpers.reqBody(this.manager, 'bypassV2'),
80
+ cid: this.cid,
81
+ configModule: this.configModule,
82
+ payload: {
83
+ data: {},
84
+ method: 'getPurifierStatus',
85
+ source: 'APP'
86
+ }
87
+ }, helpers_1.Helpers.reqHeaderBypass());
88
+ const success = this.checkResponse([response, status], 'getDetails');
89
+ if (success) {
90
+ const result = (_q = response === null || response === void 0 ? void 0 : response.result) === null || _q === void 0 ? void 0 : _q.result;
91
+ if (result) {
92
+ this.deviceStatus = result.enabled ? 'on' : 'off';
93
+ this.details = {
94
+ mode: result.mode || '',
95
+ speed: result.level || 0,
96
+ filterLife: result.filter_life || 0,
97
+ screenStatus: result.display ? 'on' : 'off',
98
+ childLock: result.child_lock || false,
99
+ airQuality: result.air_quality || 0
100
+ };
101
+ // Don't overwrite config as it contains features array
102
+ if (result.configuration) {
103
+ this.details.configuration = result.configuration;
104
+ }
105
+ logger_1.logger.debug(`Successfully got details for device: ${this.deviceName}`);
106
+ }
107
+ }
108
+ return success;
109
+ }
110
+ /**
111
+ * Turn device on
112
+ */
113
+ async turnOn() {
114
+ logger_1.logger.info(`Turning on device: ${this.deviceName}`);
115
+ // Special handling for LV series
116
+ if (this.deviceType.startsWith('LV-')) {
117
+ const [response, status] = await this.callApi('/131airPurifier/v1/device/deviceStatus', 'put', {
118
+ acceptLanguage: 'en',
119
+ accountID: this.manager.accountId,
120
+ status: 'on',
121
+ timeZone: this.manager.timeZone,
122
+ token: this.manager.token,
123
+ uuid: this.uuid
124
+ }, {
125
+ 'accept-language': 'en',
126
+ 'accountId': this.manager.accountId,
127
+ 'appVersion': '2.8.6',
128
+ 'content-type': 'application/json',
129
+ 'tk': this.manager.token,
130
+ 'tz': this.manager.timeZone
131
+ });
132
+ const success = this.checkResponse([response, status], 'turnOn');
133
+ if (!success) {
134
+ logger_1.logger.error(`Failed to turn on device: ${this.deviceName}`);
135
+ }
136
+ return success;
137
+ }
138
+ // Original implementation for other devices
139
+ const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', {
140
+ ...helpers_1.Helpers.reqBody(this.manager, 'bypassV2'),
141
+ cid: this.cid,
142
+ configModule: this.configModule,
143
+ payload: {
144
+ data: {
145
+ enabled: true,
146
+ id: 0
147
+ },
148
+ method: 'setSwitch',
149
+ source: 'APP'
150
+ }
151
+ }, helpers_1.Helpers.reqHeaderBypass());
152
+ const success = this.checkResponse([response, status], 'turnOn');
153
+ if (!success) {
154
+ logger_1.logger.error(`Failed to turn on device: ${this.deviceName}`);
155
+ }
156
+ return success;
157
+ }
158
+ /**
159
+ * Turn device off
160
+ */
161
+ async turnOff() {
162
+ logger_1.logger.info(`Turning off device: ${this.deviceName}`);
163
+ // Special handling for LV series
164
+ if (this.deviceType.startsWith('LV-')) {
165
+ const [response, status] = await this.callApi('/131airPurifier/v1/device/deviceStatus', 'put', {
166
+ acceptLanguage: 'en',
167
+ accountID: this.manager.accountId,
168
+ status: 'off',
169
+ timeZone: this.manager.timeZone,
170
+ token: this.manager.token,
171
+ uuid: this.uuid
172
+ }, {
173
+ 'accept-language': 'en',
174
+ 'accountId': this.manager.accountId,
175
+ 'appVersion': '2.8.6',
176
+ 'content-type': 'application/json',
177
+ 'tk': this.manager.token,
178
+ 'tz': this.manager.timeZone
179
+ });
180
+ const success = this.checkResponse([response, status], 'turnOff');
181
+ if (!success) {
182
+ logger_1.logger.error(`Failed to turn off device: ${this.deviceName}`);
183
+ }
184
+ return success;
185
+ }
186
+ // Original implementation for other devices
187
+ const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', {
188
+ ...helpers_1.Helpers.reqBody(this.manager, 'bypassV2'),
189
+ cid: this.cid,
190
+ configModule: this.configModule,
191
+ payload: {
192
+ data: {
193
+ enabled: false,
194
+ id: 0
195
+ },
196
+ method: 'setSwitch',
197
+ source: 'APP'
198
+ }
199
+ }, helpers_1.Helpers.reqHeaderBypass());
200
+ const success = this.checkResponse([response, status], 'turnOff');
201
+ if (!success) {
202
+ logger_1.logger.error(`Failed to turn off device: ${this.deviceName}`);
203
+ }
204
+ return success;
205
+ }
206
+ /**
207
+ * Change fan speed
208
+ */
209
+ async changeFanSpeed(speed) {
210
+ // const speeds = this.config.levels ?? [];
211
+ // if (!speeds.includes(speed)) {
212
+ // logger.error(`Invalid speed: ${speed}. Must be one of: ${speeds.join(', ')} for device: ${this.deviceName}`);
213
+ // return false;
214
+ // }
215
+ logger_1.logger.info(`Changing fan speed to ${speed} for device: ${this.deviceName}`);
216
+ const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', {
217
+ ...helpers_1.Helpers.reqBody(this.manager, 'bypassV2'),
218
+ cid: this.cid,
219
+ configModule: this.configModule,
220
+ payload: {
221
+ data: {
222
+ id: 0,
223
+ level: speed,
224
+ mode: 'manual',
225
+ type: 'wind'
226
+ },
227
+ method: 'setLevel',
228
+ source: 'APP'
229
+ }
230
+ }, helpers_1.Helpers.reqHeaderBypass());
231
+ const success = this.checkResponse([response, status], 'changeFanSpeed');
232
+ if (!success) {
233
+ logger_1.logger.error(`Failed to change fan speed to ${speed} for device: ${this.deviceName}`);
234
+ }
235
+ return success;
236
+ }
237
+ /**
238
+ * Set device mode
239
+ */
240
+ async setMode(mode) {
241
+ if (!this.modes.includes(mode)) {
242
+ const error = `Invalid mode: ${mode}. Must be one of: ${this.modes.join(', ')}`;
243
+ logger_1.logger.error(`${error} for device: ${this.deviceName}`);
244
+ throw new Error(error);
245
+ }
246
+ logger_1.logger.debug(`Setting mode to ${mode} for device: ${this.deviceName}`);
247
+ const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', {
248
+ ...helpers_1.Helpers.reqBody(this.manager, 'bypassV2'),
249
+ cid: this.cid,
250
+ configModule: this.configModule,
251
+ payload: {
252
+ data: {
253
+ mode
254
+ },
255
+ method: 'setPurifierMode',
256
+ source: 'APP'
257
+ }
258
+ }, helpers_1.Helpers.reqHeaderBypass());
259
+ const success = this.checkResponse([response, status], 'setMode');
260
+ if (!success) {
261
+ logger_1.logger.error(`Failed to set mode to ${mode} for device: ${this.deviceName}`);
262
+ }
263
+ return success;
264
+ }
265
+ /**
266
+ * Set display status
267
+ */
268
+ async setDisplay(enabled) {
269
+ if (!this.hasFeature('display')) {
270
+ const error = 'Display control not supported';
271
+ logger_1.logger.error(`${error} for device: ${this.deviceName}`);
272
+ throw new Error(error);
273
+ }
274
+ logger_1.logger.debug(`Setting display to ${enabled ? 'on' : 'off'} for device: ${this.deviceName}`);
275
+ const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', {
276
+ ...helpers_1.Helpers.reqBody(this.manager, 'bypassV2'),
277
+ cid: this.cid,
278
+ configModule: this.configModule,
279
+ payload: {
280
+ data: {
281
+ state: enabled
282
+ },
283
+ method: 'setDisplay',
284
+ source: 'APP'
285
+ }
286
+ }, helpers_1.Helpers.reqHeaderBypass());
287
+ const success = this.checkResponse([response, status], 'setDisplay');
288
+ if (success) {
289
+ this.details.screenStatus = enabled ? 'on' : 'off';
290
+ }
291
+ else {
292
+ logger_1.logger.error(`Failed to set display to ${enabled ? 'on' : 'off'} for device: ${this.deviceName}`);
293
+ }
294
+ return success;
295
+ }
296
+ /**
297
+ * Set child lock
298
+ */
299
+ async setChildLock(enabled) {
300
+ if (!this.hasFeature('child_lock')) {
301
+ const error = 'Child lock not supported';
302
+ logger_1.logger.error(`${error} for device: ${this.deviceName}`);
303
+ throw new Error(error);
304
+ }
305
+ logger_1.logger.debug(`Setting child lock to ${enabled ? 'on' : 'off'} for device: ${this.deviceName}`);
306
+ const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', {
307
+ ...helpers_1.Helpers.reqBody(this.manager, 'bypassV2'),
308
+ cid: this.cid,
309
+ configModule: this.configModule,
310
+ payload: {
311
+ data: {
312
+ state: enabled
313
+ },
314
+ method: 'setChildLock',
315
+ source: 'APP'
316
+ }
317
+ }, helpers_1.Helpers.reqHeaderBypass());
318
+ const success = this.checkResponse([response, status], 'setChildLock');
319
+ if (success) {
320
+ this.details.child_lock = enabled;
321
+ }
322
+ else {
323
+ logger_1.logger.error(`Failed to set child lock to ${enabled ? 'on' : 'off'} for device: ${this.deviceName}`);
324
+ }
325
+ return success;
326
+ }
327
+ /**
328
+ * Set timer
329
+ */
330
+ async setTimer(hours) {
331
+ if (!this.hasFeature('timer')) {
332
+ const error = 'Timer not supported';
333
+ logger_1.logger.error(`${error} for device: ${this.deviceName}`);
334
+ throw new Error(error);
335
+ }
336
+ logger_1.logger.debug(`Setting timer to ${hours} hours for device: ${this.deviceName}`);
337
+ const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', {
338
+ ...helpers_1.Helpers.reqBody(this.manager, 'bypassV2'),
339
+ cid: this.cid,
340
+ configModule: this.configModule,
341
+ payload: {
342
+ data: {
343
+ action: 'off',
344
+ total: hours * 3600
345
+ },
346
+ method: 'addTimer',
347
+ source: 'APP'
348
+ }
349
+ }, helpers_1.Helpers.reqHeaderBypass());
350
+ const success = this.checkResponse([response, status], 'setTimer');
351
+ if (!success) {
352
+ logger_1.logger.error(`Failed to set timer to ${hours} hours for device: ${this.deviceName}`);
353
+ }
354
+ return success;
355
+ }
356
+ /**
357
+ * Clear timer
358
+ */
359
+ async clearTimer() {
360
+ if (!this.hasFeature('timer')) {
361
+ const error = 'Timer not supported';
362
+ logger_1.logger.error(`${error} for device: ${this.deviceName}`);
363
+ throw new Error(error);
364
+ }
365
+ logger_1.logger.debug(`Clearing timer for device: ${this.deviceName}`);
366
+ const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', {
367
+ ...helpers_1.Helpers.reqBody(this.manager, 'bypassV2'),
368
+ cid: this.cid,
369
+ configModule: this.configModule,
370
+ payload: {
371
+ data: {},
372
+ method: 'deleteTimer',
373
+ source: 'APP'
374
+ }
375
+ }, helpers_1.Helpers.reqHeaderBypass());
376
+ const success = this.checkResponse([response, status], 'clearTimer');
377
+ if (!success) {
378
+ logger_1.logger.error(`Failed to clear timer for device: ${this.deviceName}`);
379
+ }
380
+ return success;
381
+ }
382
+ /**
383
+ * Turn automatic stop on
384
+ */
385
+ async automaticStopOn() {
386
+ logger_1.logger.debug(`Setting automatic stop on for device: ${this.deviceName}`);
387
+ const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', {
388
+ ...helpers_1.Helpers.reqBody(this.manager, 'bypassV2'),
389
+ cid: this.cid,
390
+ configModule: this.configModule,
391
+ payload: {
392
+ data: {
393
+ enabled: true
394
+ },
395
+ method: 'setAutomaticStop',
396
+ source: 'APP'
397
+ }
398
+ }, helpers_1.Helpers.reqHeaderBypass());
399
+ const success = this.checkResponse([response, status], 'automaticStopOn');
400
+ if (!success) {
401
+ logger_1.logger.error(`Failed to set automatic stop on for device: ${this.deviceName}`);
402
+ }
403
+ return success;
404
+ }
405
+ /**
406
+ * Turn automatic stop off
407
+ */
408
+ async automaticStopOff() {
409
+ logger_1.logger.debug(`Setting automatic stop off for device: ${this.deviceName}`);
410
+ const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', {
411
+ ...helpers_1.Helpers.reqBody(this.manager, 'bypassV2'),
412
+ cid: this.cid,
413
+ configModule: this.configModule,
414
+ payload: {
415
+ data: {
416
+ enabled: false
417
+ },
418
+ method: 'setAutomaticStop',
419
+ source: 'APP'
420
+ }
421
+ }, helpers_1.Helpers.reqHeaderBypass());
422
+ const success = this.checkResponse([response, status], 'automaticStopOff');
423
+ if (!success) {
424
+ logger_1.logger.error(`Failed to set automatic stop off for device: ${this.deviceName}`);
425
+ }
426
+ return success;
427
+ }
428
+ /**
429
+ * Set auto mode
430
+ */
431
+ async autoMode() {
432
+ logger_1.logger.debug(`Setting auto mode for device: ${this.deviceName}`);
433
+ const success = await this.setMode('auto');
434
+ if (!success) {
435
+ logger_1.logger.error(`Failed to set auto mode for device: ${this.deviceName}`);
436
+ }
437
+ return success;
438
+ }
439
+ /**
440
+ * Set manual mode
441
+ */
442
+ async manualMode() {
443
+ logger_1.logger.debug(`Setting manual mode for device: ${this.deviceName}`);
444
+ const success = await this.setMode('manual');
445
+ if (!success) {
446
+ logger_1.logger.error(`Failed to set manual mode for device: ${this.deviceName}`);
447
+ }
448
+ return success;
449
+ }
450
+ /**
451
+ * Set sleep mode
452
+ */
453
+ async sleepMode() {
454
+ logger_1.logger.debug(`Setting sleep mode for device: ${this.deviceName}`);
455
+ const success = await this.setMode('sleep');
456
+ if (!success) {
457
+ logger_1.logger.error(`Failed to set sleep mode for device: ${this.deviceName}`);
458
+ }
459
+ return success;
460
+ }
461
+ /**
462
+ * Turn off display
463
+ */
464
+ async turnOffDisplay() {
465
+ logger_1.logger.debug(`Turning off display for device: ${this.deviceName}`);
466
+ const success = await this.setDisplay(false);
467
+ if (!success) {
468
+ logger_1.logger.error(`Failed to turn off display for device: ${this.deviceName}`);
469
+ }
470
+ return success;
471
+ }
472
+ /**
473
+ * Turn on display
474
+ */
475
+ async turnOnDisplay() {
476
+ logger_1.logger.debug(`Turning on display for device: ${this.deviceName}`);
477
+ const success = await this.setDisplay(true);
478
+ if (!success) {
479
+ logger_1.logger.error(`Failed to turn on display for device: ${this.deviceName}`);
480
+ }
481
+ return success;
482
+ }
483
+ }
484
+ exports.VeSyncAirBypass = VeSyncAirBypass;
@@ -0,0 +1,50 @@
1
+ import { VeSyncWarmHumidifier } from './warmHumidifier';
2
+ import { VeSync } from '../vesync';
3
+ /**
4
+ * VeSync Humidifier 200/300S Class
5
+ */
6
+ export declare class VeSyncHumid200300S extends VeSyncWarmHumidifier {
7
+ protected readonly modes: readonly ["auto", "manual", "sleep"];
8
+ protected readonly features: string[];
9
+ protected readonly mistLevels: number[];
10
+ protected readonly humidityRange: {
11
+ min: number;
12
+ max: number;
13
+ };
14
+ constructor(details: Record<string, any>, manager: VeSync);
15
+ /**
16
+ * Get device details
17
+ */
18
+ getDetails(): Promise<Boolean>;
19
+ /**
20
+ * Set mist level
21
+ */
22
+ setMistLevel(level: number): Promise<boolean>;
23
+ /**
24
+ * Set night light brightness
25
+ */
26
+ setNightLightBrightness(brightness: number): Promise<boolean>;
27
+ /**
28
+ * Get night light brightness
29
+ */
30
+ get nightLightBrightness(): number;
31
+ /**
32
+ * Get configuration
33
+ */
34
+ get configuration(): any;
35
+ /**
36
+ * Get mist level
37
+ * Override base class to return virtual level
38
+ */
39
+ get mistLevel(): number;
40
+ /**
41
+ * Get target humidity
42
+ * Override base class to return target humidity instead of current humidity
43
+ */
44
+ get humidity(): number;
45
+ /**
46
+ * Set target humidity
47
+ * Override base class to properly update target humidity
48
+ */
49
+ setHumidity(humidity: number): Promise<boolean>;
50
+ }