tsvesync 1.0.64 → 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.
- 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 +50 -0
- package/dist/lib/fans/humid200300S.js +200 -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 +234 -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
package/package.json
CHANGED
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
import { VeSyncAirBypass } from './airBypass';
|
|
2
|
+
import { VeSync } from '../vesync';
|
|
3
|
+
import { Helpers } from '../helpers';
|
|
4
|
+
import { logger } from '../logger';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* VeSync Air Purifier with Bypass V2
|
|
8
|
+
*/
|
|
9
|
+
export class VeSyncAirBaseV2 extends VeSyncAirBypass {
|
|
10
|
+
protected _lightDetection: boolean = false;
|
|
11
|
+
protected _lightDetectionState: boolean = false;
|
|
12
|
+
protected setSpeedLevel: number | null = null;
|
|
13
|
+
protected autoPreferences: string[] = ['default', 'efficient', 'quiet'];
|
|
14
|
+
protected enabled: boolean = false;
|
|
15
|
+
protected _mode: string = '';
|
|
16
|
+
protected _speed: number = 0;
|
|
17
|
+
protected _timer: { duration: number; action: string } | null = null;
|
|
18
|
+
|
|
19
|
+
constructor(details: Record<string, any>, manager: VeSync) {
|
|
20
|
+
super(details, manager);
|
|
21
|
+
logger.debug(`Initialized VeSyncAirBaseV2 device: ${this.deviceName}`);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
protected buildConfigDict(configDict: Record<string, any>): void {
|
|
25
|
+
if (configDict) {
|
|
26
|
+
this.config = {
|
|
27
|
+
...this.config, // Preserve existing config
|
|
28
|
+
...configDict // Merge in new config
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
get mode(): string {
|
|
34
|
+
return this._mode;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
set mode(value: string) {
|
|
38
|
+
this._mode = value;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
get speed(): number {
|
|
42
|
+
return this._speed;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
set speed(value: number) {
|
|
46
|
+
this._speed = value;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
get timer(): { duration: number; action: string } | null {
|
|
50
|
+
return this._timer;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
set timer(value: { duration: number; action: string } | null) {
|
|
54
|
+
this._timer = value;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Get device details
|
|
59
|
+
*/
|
|
60
|
+
async getDetails(): Promise<Boolean> {
|
|
61
|
+
logger.debug(`Getting details for device: ${this.deviceName}`);
|
|
62
|
+
const [head, body] = this.buildApiDict('getPurifierStatus');
|
|
63
|
+
|
|
64
|
+
const [response, status] = await this.callApi(
|
|
65
|
+
'/cloud/v2/deviceManaged/bypassV2',
|
|
66
|
+
'post',
|
|
67
|
+
body,
|
|
68
|
+
head
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
if (!this.checkResponse([response, status], 'getDetails') || !response?.result) {
|
|
72
|
+
logger.debug('Error getting purifier details');
|
|
73
|
+
this.connectionStatus = 'offline';
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const innerResponse = response.result;
|
|
78
|
+
if (innerResponse.code !== 0 || !innerResponse.result) {
|
|
79
|
+
logger.debug('Error in inner response from purifier');
|
|
80
|
+
this.connectionStatus = 'offline';
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const deviceData = innerResponse.result;
|
|
85
|
+
this.buildPurifierDict(deviceData);
|
|
86
|
+
if (deviceData.configuration) {
|
|
87
|
+
this.buildConfigDict(deviceData.configuration);
|
|
88
|
+
}
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Build purifier dictionary
|
|
94
|
+
*/
|
|
95
|
+
protected buildPurifierDict(devDict: Record<string, any>): void {
|
|
96
|
+
this.connectionStatus = 'online';
|
|
97
|
+
const powerSwitch = Boolean(devDict.powerSwitch ?? 0);
|
|
98
|
+
this.enabled = powerSwitch;
|
|
99
|
+
this.deviceStatus = powerSwitch ? 'on' : 'off';
|
|
100
|
+
this.mode = devDict.workMode ?? 'manual';
|
|
101
|
+
|
|
102
|
+
this.speed = devDict.fanSpeedLevel ?? 0;
|
|
103
|
+
this.setSpeedLevel = devDict.manualSpeedLevel ?? 1;
|
|
104
|
+
|
|
105
|
+
this.details = {
|
|
106
|
+
...this.details,
|
|
107
|
+
filter_life: devDict.filterLifePercent ?? 0,
|
|
108
|
+
child_lock: Boolean(devDict.childLockSwitch ?? 0),
|
|
109
|
+
display: Boolean(devDict.screenState ?? 0),
|
|
110
|
+
light_detection_switch: Boolean(devDict.lightDetectionSwitch ?? 0),
|
|
111
|
+
environment_light_state: Boolean(devDict.environmentLightState ?? 0),
|
|
112
|
+
screen_switch: Boolean(devDict.screenSwitch ?? 0),
|
|
113
|
+
screenStatus: Boolean(devDict.screenSwitch ?? 0) ? 'on' : 'off'
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
if (this.hasFeature('air_quality')) {
|
|
117
|
+
this.details.air_quality_value = devDict.PM25 ?? 0;
|
|
118
|
+
this.details.air_quality = devDict.AQLevel ?? 0;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if ('PM1' in devDict) this.details.pm1 = devDict.PM1;
|
|
122
|
+
if ('PM10' in devDict) this.details.pm10 = devDict.PM10;
|
|
123
|
+
if ('AQPercent' in devDict) this.details.aq_percent = devDict.AQPercent;
|
|
124
|
+
if ('fanRotateAngle' in devDict) this.details.fan_rotate_angle = devDict.fanRotateAngle;
|
|
125
|
+
if ('filterOpenState' in devDict) this.details.filter_open_state = Boolean(devDict.filterOpenState);
|
|
126
|
+
|
|
127
|
+
if ((devDict.timerRemain ?? 0) > 0) {
|
|
128
|
+
this.timer = { duration: devDict.timerRemain, action: 'off' };
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (typeof devDict.autoPreference === 'object' && devDict.autoPreference) {
|
|
132
|
+
this.details.auto_preference_type = devDict.autoPreference?.autoPreferenceType ?? 'default';
|
|
133
|
+
} else {
|
|
134
|
+
this.details.auto_preference_type = null;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Set auto preference
|
|
140
|
+
*/
|
|
141
|
+
async setAutoPreference(preference: string = 'default', roomSize: number = 600): Promise<boolean> {
|
|
142
|
+
if (!this.autoPreferences.includes(preference)) {
|
|
143
|
+
logger.debug(`Invalid preference: ${preference} - valid preferences are default, efficient, quiet`);
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const [head, body] = this.buildApiDict('setAutoPreference');
|
|
148
|
+
body.payload.data = {
|
|
149
|
+
autoPreference: preference,
|
|
150
|
+
roomSize: roomSize
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
const [response, status] = await this.callApi(
|
|
154
|
+
'/cloud/v2/deviceManaged/bypassV2',
|
|
155
|
+
'post',
|
|
156
|
+
body,
|
|
157
|
+
head
|
|
158
|
+
);
|
|
159
|
+
|
|
160
|
+
const success = this.checkResponse([response, status], 'setAutoPreference');
|
|
161
|
+
if (success) {
|
|
162
|
+
this.details.auto_preference = preference;
|
|
163
|
+
}
|
|
164
|
+
return success;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Set light detection
|
|
169
|
+
*/
|
|
170
|
+
async setLightDetection(enabled: boolean): Promise<boolean> {
|
|
171
|
+
const [head, body] = this.buildApiDict('setLightDetection');
|
|
172
|
+
body.payload.data = {
|
|
173
|
+
lightDetectionSwitch: enabled ? 1 : 0
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
const [response, status] = await this.callApi(
|
|
177
|
+
'/cloud/v2/deviceManaged/bypassV2',
|
|
178
|
+
'post',
|
|
179
|
+
body,
|
|
180
|
+
head
|
|
181
|
+
);
|
|
182
|
+
|
|
183
|
+
const success = this.checkResponse([response, status], 'setLightDetection');
|
|
184
|
+
if (success) {
|
|
185
|
+
this.details.light_detection_switch = enabled;
|
|
186
|
+
}
|
|
187
|
+
return success;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Get light detection status
|
|
192
|
+
*/
|
|
193
|
+
get lightDetection(): boolean {
|
|
194
|
+
return Boolean(this.details.light_detection_switch);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Get light detection state
|
|
199
|
+
*/
|
|
200
|
+
get lightDetectionState(): boolean {
|
|
201
|
+
return Boolean(this.details.environment_light_state);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Get auto preference type
|
|
206
|
+
*/
|
|
207
|
+
get autoPreferenceType(): string | null {
|
|
208
|
+
return this.details.auto_preference_type;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Display JSON details
|
|
213
|
+
*/
|
|
214
|
+
override displayJSON(): string {
|
|
215
|
+
const baseInfo = JSON.parse(super.displayJSON());
|
|
216
|
+
const details: Record<string, string> = {
|
|
217
|
+
...baseInfo,
|
|
218
|
+
'Mode': this.mode,
|
|
219
|
+
'Filter Life': (this.details.filter_life ?? 0).toString(),
|
|
220
|
+
'Fan Level': this.speed.toString(),
|
|
221
|
+
'Display On': this.details.display?.toString() ?? 'false',
|
|
222
|
+
'Child Lock': (this.details.child_lock ?? false).toString(),
|
|
223
|
+
'Night Light': (this.details.night_light ?? '').toString(),
|
|
224
|
+
'Display Set On': (this.details.screen_switch ?? false).toString(),
|
|
225
|
+
'Light Detection Enabled': (this.details.light_detection_switch ?? false).toString(),
|
|
226
|
+
'Environment Light State': (this.details.environment_light_state ?? false).toString()
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
if (this.hasFeature('air_quality')) {
|
|
230
|
+
details['Air Quality Level'] = (this.details.air_quality ?? '').toString();
|
|
231
|
+
details['Air Quality Value'] = (this.details.air_quality_value ?? '').toString();
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
const everestKeys: Record<string, string> = {
|
|
235
|
+
'pm1': 'PM1',
|
|
236
|
+
'pm10': 'PM10',
|
|
237
|
+
'fan_rotate_angle': 'Fan Rotate Angle',
|
|
238
|
+
'filter_open_state': 'Filter Open State'
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
for (const [key, value] of Object.entries(everestKeys)) {
|
|
242
|
+
if (key in this.details) {
|
|
243
|
+
details[value] = this.details[key]?.toString() ?? '';
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
return JSON.stringify(details, null, 4);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Set oscillation state
|
|
252
|
+
*/
|
|
253
|
+
async setOscillation(toggle: boolean): Promise<boolean> {
|
|
254
|
+
logger.debug(`Setting oscillation to ${toggle ? 'on' : 'off'} for device: ${this.deviceName}`);
|
|
255
|
+
|
|
256
|
+
const [head, body] = this.buildApiDict('setSwitch');
|
|
257
|
+
body.payload.data = {
|
|
258
|
+
oscillationSwitch: toggle ? 1 : 0,
|
|
259
|
+
switchIdx: 0
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
const [response, status] = await this.callApi(
|
|
263
|
+
'/cloud/v2/deviceManaged/bypassV2',
|
|
264
|
+
'post',
|
|
265
|
+
body,
|
|
266
|
+
head
|
|
267
|
+
);
|
|
268
|
+
|
|
269
|
+
const success = this.checkResponse([response, status], 'setOscillation');
|
|
270
|
+
if (success) {
|
|
271
|
+
this.details.oscillationState = toggle;
|
|
272
|
+
this.details.oscillationSwitch = toggle ? 1 : 0;
|
|
273
|
+
}
|
|
274
|
+
return success;
|
|
275
|
+
}
|
|
276
|
+
}
|