tsvesync 1.0.64 → 1.0.66
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 +68 -0
- package/dist/lib/fans/airBaseV2.js +226 -0
- package/dist/lib/fans/airBypass.d.ts +79 -0
- package/dist/lib/fans/airBypass.js +484 -0
- package/dist/lib/fans/humid200300S.d.ts +41 -0
- package/dist/lib/fans/humid200300S.js +129 -0
- package/dist/lib/fans/humidifier.d.ts +83 -0
- package/dist/lib/fans/humidifier.js +388 -0
- package/dist/lib/fans/index.d.ts +9 -0
- package/dist/lib/fans/index.js +95 -0
- package/dist/lib/fans/towerFan.d.ts +105 -0
- package/dist/lib/fans/towerFan.js +279 -0
- package/dist/lib/fans/warmHumidifier.d.ts +49 -0
- package/dist/lib/fans/warmHumidifier.js +174 -0
- package/dist/lib/vesyncFan.d.ts +2 -2
- package/dist/lib/vesyncFan.js +2 -2
- package/dist/lib/vesyncFanImpl.d.ts +1 -436
- package/dist/lib/vesyncFanImpl.js +16 -1848
- package/package.json +1 -1
- package/src/lib/fans/airBaseV2.ts +276 -0
- package/src/lib/fans/airBypass.ts +594 -0
- package/src/lib/fans/humid200300S.ts +148 -0
- package/src/lib/fans/humidifier.ts +470 -0
- package/src/lib/fans/index.ts +101 -0
- package/src/lib/fans/towerFan.ts +335 -0
- package/src/lib/fans/warmHumidifier.ts +202 -0
- package/src/lib/vesyncFan.ts +5 -5
- package/src/lib/vesyncFanImpl.ts +2 -2262
|
@@ -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,41 @@
|
|
|
1
|
+
import { VeSyncHumidifier } from './humidifier';
|
|
2
|
+
import { VeSync } from '../vesync';
|
|
3
|
+
/**
|
|
4
|
+
* VeSync Humidifier 200/300S Class
|
|
5
|
+
*/
|
|
6
|
+
export declare class VeSyncHumid200300S extends VeSyncHumidifier {
|
|
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
|
+
* Get configuration
|
|
25
|
+
*/
|
|
26
|
+
get configuration(): any;
|
|
27
|
+
/**
|
|
28
|
+
* Get mist level
|
|
29
|
+
* Override base class to return virtual level
|
|
30
|
+
*/
|
|
31
|
+
get mistLevel(): number;
|
|
32
|
+
/**
|
|
33
|
+
* Get target humidity
|
|
34
|
+
* Override base class to return target humidity from configuration
|
|
35
|
+
*/
|
|
36
|
+
get humidity(): number;
|
|
37
|
+
/**
|
|
38
|
+
* Get automatic stop configuration
|
|
39
|
+
*/
|
|
40
|
+
get automaticStopConfigured(): boolean;
|
|
41
|
+
}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.VeSyncHumid200300S = void 0;
|
|
4
|
+
const humidifier_1 = require("./humidifier");
|
|
5
|
+
const helpers_1 = require("../helpers");
|
|
6
|
+
const logger_1 = require("../logger");
|
|
7
|
+
/**
|
|
8
|
+
* VeSync Humidifier 200/300S Class
|
|
9
|
+
*/
|
|
10
|
+
class VeSyncHumid200300S extends humidifier_1.VeSyncHumidifier {
|
|
11
|
+
constructor(details, manager) {
|
|
12
|
+
super(details, manager);
|
|
13
|
+
this.modes = ['auto', 'manual', 'sleep'];
|
|
14
|
+
this.features = ['humidity', 'mist', 'display', 'timer', 'auto_mode'];
|
|
15
|
+
this.mistLevels = [1, 2, 3, 4, 5, 6, 7, 8, 9];
|
|
16
|
+
this.humidityRange = { min: 30, max: 80 };
|
|
17
|
+
logger_1.logger.debug(`Initialized VeSyncHumid200300S device: ${this.deviceName}`);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Get device details
|
|
21
|
+
*/
|
|
22
|
+
async getDetails() {
|
|
23
|
+
var _a, _b, _c;
|
|
24
|
+
logger_1.logger.debug(`Getting details for device: ${this.deviceName}`);
|
|
25
|
+
const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', {
|
|
26
|
+
...helpers_1.Helpers.reqBody(this.manager, 'bypassV2'),
|
|
27
|
+
cid: this.cid,
|
|
28
|
+
configModule: this.configModule,
|
|
29
|
+
payload: {
|
|
30
|
+
data: {},
|
|
31
|
+
method: 'getHumidifierStatus',
|
|
32
|
+
source: 'APP'
|
|
33
|
+
}
|
|
34
|
+
}, helpers_1.Helpers.reqHeaderBypass());
|
|
35
|
+
const success = this.checkResponse([response, status], 'getDetails');
|
|
36
|
+
if (success && ((_a = response === null || response === void 0 ? void 0 : response.result) === null || _a === void 0 ? void 0 : _a.result)) {
|
|
37
|
+
const result = response.result.result;
|
|
38
|
+
// Update device status based on enabled field
|
|
39
|
+
this.deviceStatus = result.enabled ? 'on' : 'off';
|
|
40
|
+
this.details = {
|
|
41
|
+
mode: result.mode || '',
|
|
42
|
+
humidity: result.humidity || 0, // Current humidity
|
|
43
|
+
target_humidity: result.target_humidity || result.humidity || 0, // Target humidity
|
|
44
|
+
mist_level: result.mist_level || 0,
|
|
45
|
+
mist_virtual_level: result.mist_virtual_level || 0,
|
|
46
|
+
water_lacks: result.water_lacks || false,
|
|
47
|
+
humidity_high: result.humidity_high || false,
|
|
48
|
+
water_tank_lifted: result.water_tank_lifted || false,
|
|
49
|
+
display: result.display || false,
|
|
50
|
+
automatic_stop: result.automatic_stop_reach_target || false,
|
|
51
|
+
automatic_stop_configured: ((_b = result.configuration) === null || _b === void 0 ? void 0 : _b.automatic_stop) || false,
|
|
52
|
+
auto_target_humidity: ((_c = result.configuration) === null || _c === void 0 ? void 0 : _c.auto_target_humidity) || 0,
|
|
53
|
+
configuration: result.configuration || {},
|
|
54
|
+
connection_status: result.connection_status || null
|
|
55
|
+
};
|
|
56
|
+
// Log raw response for debugging
|
|
57
|
+
logger_1.logger.debug(`Raw API Response: ${JSON.stringify(response)}`);
|
|
58
|
+
logger_1.logger.debug(`Parsed Result: ${JSON.stringify(result)}`);
|
|
59
|
+
logger_1.logger.debug(`Successfully got details for device: ${this.deviceName}`);
|
|
60
|
+
}
|
|
61
|
+
return success;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Set mist level
|
|
65
|
+
*/
|
|
66
|
+
async setMistLevel(level) {
|
|
67
|
+
if (!this.mistLevels.includes(level)) {
|
|
68
|
+
const error = `Invalid mist level: ${level}. Must be one of: ${this.mistLevels.join(', ')}`;
|
|
69
|
+
logger_1.logger.error(`${error} for device: ${this.deviceName}`);
|
|
70
|
+
throw new Error(error);
|
|
71
|
+
}
|
|
72
|
+
logger_1.logger.info(`Setting mist level to ${level} for device: ${this.deviceName}`);
|
|
73
|
+
const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', {
|
|
74
|
+
...helpers_1.Helpers.reqBody(this.manager, 'bypassV2'),
|
|
75
|
+
cid: this.cid,
|
|
76
|
+
configModule: this.configModule,
|
|
77
|
+
payload: {
|
|
78
|
+
data: {
|
|
79
|
+
id: 0,
|
|
80
|
+
level: level,
|
|
81
|
+
type: 'mist'
|
|
82
|
+
},
|
|
83
|
+
method: 'setVirtualLevel', // Use setVirtualLevel per YAML spec
|
|
84
|
+
source: 'APP'
|
|
85
|
+
}
|
|
86
|
+
}, helpers_1.Helpers.reqHeaderBypass());
|
|
87
|
+
const success = this.checkResponse([response, status], 'setMistLevel');
|
|
88
|
+
logger_1.logger.debug(`Mist Level API Response: ${JSON.stringify(response)}`);
|
|
89
|
+
logger_1.logger.debug(`Mist Level API Status: ${status}`);
|
|
90
|
+
if (success) {
|
|
91
|
+
this.details.mist_level = level;
|
|
92
|
+
this.details.mist_virtual_level = level;
|
|
93
|
+
// Get latest state and log it
|
|
94
|
+
await this.getDetails();
|
|
95
|
+
logger_1.logger.debug(`Device state after mist level change: ${JSON.stringify(this.details)}`);
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
logger_1.logger.error(`Failed to set mist level to ${level} for device: ${this.deviceName}`);
|
|
99
|
+
}
|
|
100
|
+
return success;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Get configuration
|
|
104
|
+
*/
|
|
105
|
+
get configuration() {
|
|
106
|
+
return this.details.configuration || {};
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Get mist level
|
|
110
|
+
* Override base class to return virtual level
|
|
111
|
+
*/
|
|
112
|
+
get mistLevel() {
|
|
113
|
+
return this.details.mist_virtual_level || 0;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Get target humidity
|
|
117
|
+
* Override base class to return target humidity from configuration
|
|
118
|
+
*/
|
|
119
|
+
get humidity() {
|
|
120
|
+
return this.details.auto_target_humidity || 0;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Get automatic stop configuration
|
|
124
|
+
*/
|
|
125
|
+
get automaticStopConfigured() {
|
|
126
|
+
return this.details.automatic_stop_configured || false;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
exports.VeSyncHumid200300S = VeSyncHumid200300S;
|