tsvesync 1.0.70 → 1.0.72
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/humid1000S.d.ts +70 -0
- package/dist/lib/fans/humid1000S.js +222 -0
- package/dist/lib/fans/humid200S.d.ts +52 -0
- package/dist/lib/fans/humid200S.js +169 -0
- package/dist/lib/fans/humidifier.d.ts +20 -0
- package/dist/lib/fans/humidifier.js +28 -0
- package/dist/lib/fans/index.d.ts +3 -0
- package/dist/lib/fans/index.js +16 -7
- package/dist/lib/fans/superior6000S.d.ts +150 -0
- package/dist/lib/fans/superior6000S.js +360 -0
- package/dist/lib/vesyncFan.d.ts +2 -2
- package/dist/lib/vesyncFan.js +16 -11
- package/package.json +1 -1
- package/src/lib/fans/humid1000S.ts +276 -0
- package/src/lib/fans/humid200S.ts +199 -0
- package/src/lib/fans/humidifier.ts +32 -0
- package/src/lib/fans/index.ts +12 -6
- package/src/lib/fans/superior6000S.ts +466 -0
- package/src/lib/vesyncFan.ts +18 -13
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
import { VeSyncHumid200300S } from './humid200300S';
|
|
2
|
+
import { VeSync } from '../vesync';
|
|
3
|
+
import { Helpers } from '../helpers';
|
|
4
|
+
import { logger } from '../logger';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* VeSync Humid1000S Humidifier Class
|
|
8
|
+
* Implementation based on PyVeSync's VeSyncHumid1000S class
|
|
9
|
+
* For OASISMIST1000S models (LUH-M101S-WUS and LUH-M101S-WEUR)
|
|
10
|
+
*/
|
|
11
|
+
export class VeSyncHumid1000S extends VeSyncHumid200300S {
|
|
12
|
+
protected readonly _apiModes = [
|
|
13
|
+
'getHumidifierStatus',
|
|
14
|
+
'setSwitch',
|
|
15
|
+
'setVirtualLevel',
|
|
16
|
+
'setTargetHumidity',
|
|
17
|
+
'setHumidityMode',
|
|
18
|
+
'setDisplay',
|
|
19
|
+
'setNightLight',
|
|
20
|
+
'setAutoStopSwitch',
|
|
21
|
+
];
|
|
22
|
+
|
|
23
|
+
constructor(details: Record<string, any>, manager: VeSync) {
|
|
24
|
+
super(details, manager);
|
|
25
|
+
|
|
26
|
+
// Update config for Humid1000S
|
|
27
|
+
this.config = {
|
|
28
|
+
module: 'VeSyncHumid1000S',
|
|
29
|
+
features: ['display', 'humidity', 'mist', 'timer', 'auto_mode', 'night_light'],
|
|
30
|
+
levels: [1, 2, 3, 4, 5, 6, 7, 8, 9]
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
logger.debug(`Initialized VeSyncHumid1000S device: ${this.deviceName}`);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Build API dictionary for humidifier
|
|
38
|
+
*/
|
|
39
|
+
protected buildApiDict(method: string): [Record<string, any>, Record<string, any>] {
|
|
40
|
+
if (!this._apiModes.includes(method)) {
|
|
41
|
+
logger.debug(`Invalid mode - ${method}`);
|
|
42
|
+
throw new Error(`Invalid mode - ${method}`);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const head = Helpers.reqHeaderBypass();
|
|
46
|
+
const body = {
|
|
47
|
+
...Helpers.reqBody(this.manager, 'bypassV2'),
|
|
48
|
+
cid: this.cid,
|
|
49
|
+
configModule: this.configModule,
|
|
50
|
+
payload: {
|
|
51
|
+
method: method,
|
|
52
|
+
source: 'APP',
|
|
53
|
+
data: {}
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
return [head, body];
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Get device details
|
|
62
|
+
*/
|
|
63
|
+
async getDetails(): Promise<Boolean> {
|
|
64
|
+
logger.debug(`Getting details for device: ${this.deviceName}`);
|
|
65
|
+
const [head, body] = this.buildApiDict('getHumidifierStatus');
|
|
66
|
+
|
|
67
|
+
const [response, status] = await this.callApi(
|
|
68
|
+
'/cloud/v2/deviceManaged/bypassV2',
|
|
69
|
+
'post',
|
|
70
|
+
body,
|
|
71
|
+
head
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
const success = this.checkResponse([response, status], 'getDetails');
|
|
75
|
+
if (success && response?.result?.result) {
|
|
76
|
+
const result = response.result.result;
|
|
77
|
+
|
|
78
|
+
// Update device status based on powerSwitch field
|
|
79
|
+
this.deviceStatus = result.powerSwitch === 1 ? 'on' : 'off';
|
|
80
|
+
|
|
81
|
+
// Build details object with Humid1000S specific fields
|
|
82
|
+
this.details = {
|
|
83
|
+
mode: result.workMode || '',
|
|
84
|
+
humidity: result.humidity || 0,
|
|
85
|
+
target_humidity: result.targetHumidity || 0,
|
|
86
|
+
mist_level: result.mistLevel || 0,
|
|
87
|
+
mist_virtual_level: result.virtualLevel || 0,
|
|
88
|
+
water_lacks: result.waterLacksState || false,
|
|
89
|
+
water_tank_lifted: result.waterTankLifted || false,
|
|
90
|
+
display: result.screenSwitch === 1,
|
|
91
|
+
night_light_status: result.nightLightStatus || 'off',
|
|
92
|
+
night_light_brightness: result.nightLightBrightness || 0,
|
|
93
|
+
connection_status: result.connectionStatus || null,
|
|
94
|
+
configuration: result.configuration || {}
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
logger.debug(`Successfully got details for device: ${this.deviceName}`);
|
|
98
|
+
}
|
|
99
|
+
return success;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Turn device on
|
|
104
|
+
*/
|
|
105
|
+
async turnOn(): Promise<boolean> {
|
|
106
|
+
return this.toggleSwitch(true);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Turn device off
|
|
111
|
+
*/
|
|
112
|
+
async turnOff(): Promise<boolean> {
|
|
113
|
+
return this.toggleSwitch(false);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Toggle device power
|
|
118
|
+
*/
|
|
119
|
+
async toggleSwitch(enabled: boolean): Promise<boolean> {
|
|
120
|
+
logger.info(`Setting device power to ${enabled ? 'on' : 'off'}: ${this.deviceName}`);
|
|
121
|
+
const [head, body] = this.buildApiDict('setSwitch');
|
|
122
|
+
|
|
123
|
+
body.payload.data = {
|
|
124
|
+
powerSwitch: enabled ? 1 : 0,
|
|
125
|
+
switchIdx: 0
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
const [response, status] = await this.callApi(
|
|
129
|
+
'/cloud/v2/deviceManaged/bypassV2',
|
|
130
|
+
'post',
|
|
131
|
+
body,
|
|
132
|
+
head
|
|
133
|
+
);
|
|
134
|
+
|
|
135
|
+
const success = this.checkResponse([response, status], 'toggleSwitch');
|
|
136
|
+
if (success) {
|
|
137
|
+
this.deviceStatus = enabled ? 'on' : 'off';
|
|
138
|
+
return true;
|
|
139
|
+
}
|
|
140
|
+
logger.error(`Failed to set device power to ${enabled ? 'on' : 'off'} for device: ${this.deviceName}`);
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Set night light
|
|
146
|
+
*/
|
|
147
|
+
async setNightLight(enabled: boolean, brightness?: number): Promise<boolean> {
|
|
148
|
+
if (!this.hasFeature('night_light')) {
|
|
149
|
+
logger.error(`Night light feature not supported for device: ${this.deviceName}`);
|
|
150
|
+
return false;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
logger.debug(`Setting night light to ${enabled ? 'on' : 'off'} for device: ${this.deviceName}`);
|
|
154
|
+
const [head, body] = this.buildApiDict('setNightLight');
|
|
155
|
+
|
|
156
|
+
body.payload.data = {
|
|
157
|
+
nightLightSwitch: enabled ? 1 : 0
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
// Add brightness if provided
|
|
161
|
+
if (enabled && brightness !== undefined) {
|
|
162
|
+
if (brightness < 1 || brightness > 100) {
|
|
163
|
+
logger.error(`Invalid night light brightness: ${brightness}. Must be between 1 and 100.`);
|
|
164
|
+
return false;
|
|
165
|
+
}
|
|
166
|
+
body.payload.data.nightLightBrightness = brightness;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
const [response, status] = await this.callApi(
|
|
170
|
+
'/cloud/v2/deviceManaged/bypassV2',
|
|
171
|
+
'post',
|
|
172
|
+
body,
|
|
173
|
+
head
|
|
174
|
+
);
|
|
175
|
+
|
|
176
|
+
const success = this.checkResponse([response, status], 'setNightLight');
|
|
177
|
+
if (success) {
|
|
178
|
+
this.details.night_light_status = enabled ? 'on' : 'off';
|
|
179
|
+
if (enabled && brightness !== undefined) {
|
|
180
|
+
this.details.night_light_brightness = brightness;
|
|
181
|
+
}
|
|
182
|
+
return true;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// Check for API error code 11000000 (feature not supported)
|
|
186
|
+
if (response?.code === 11000000) {
|
|
187
|
+
logger.warn(`Night light control not supported via API for device: ${this.deviceName}`);
|
|
188
|
+
return false;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
logger.error(`Failed to set night light for device: ${this.deviceName}`);
|
|
192
|
+
return false;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Connection status is available in details.connection_status
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Get night light status
|
|
199
|
+
* Returns the night light status (on/off)
|
|
200
|
+
*/
|
|
201
|
+
get nightLightStatus(): string {
|
|
202
|
+
return this.details.night_light_status || 'off';
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Get night light brightness
|
|
207
|
+
* Returns the night light brightness (0-100)
|
|
208
|
+
*/
|
|
209
|
+
get nightLightBrightness(): number {
|
|
210
|
+
return this.details.night_light_brightness || 0;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Set automatic stop
|
|
215
|
+
* Enable or disable automatic stop when target humidity is reached
|
|
216
|
+
*/
|
|
217
|
+
async setAutomaticStop(enabled: boolean): Promise<boolean> {
|
|
218
|
+
logger.debug(`Setting automatic stop to ${enabled ? 'enabled' : 'disabled'} for device: ${this.deviceName}`);
|
|
219
|
+
const [head, body] = this.buildApiDict('setAutoStopSwitch');
|
|
220
|
+
|
|
221
|
+
body.payload.data = {
|
|
222
|
+
autoStopSwitch: enabled ? 1 : 0
|
|
223
|
+
};
|
|
224
|
+
|
|
225
|
+
const [response, status] = await this.callApi(
|
|
226
|
+
'/cloud/v2/deviceManaged/bypassV2',
|
|
227
|
+
'post',
|
|
228
|
+
body,
|
|
229
|
+
head
|
|
230
|
+
);
|
|
231
|
+
|
|
232
|
+
const success = this.checkResponse([response, status], 'setAutomaticStop');
|
|
233
|
+
if (success) {
|
|
234
|
+
if (!this.details.configuration) {
|
|
235
|
+
this.details.configuration = {};
|
|
236
|
+
}
|
|
237
|
+
this.details.configuration.automatic_stop = enabled;
|
|
238
|
+
return true;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
logger.error(`Failed to set automatic stop for device: ${this.deviceName}`);
|
|
242
|
+
return false;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Turn automatic stop on
|
|
247
|
+
* Enable automatic stop when target humidity is reached
|
|
248
|
+
*/
|
|
249
|
+
async automaticStopOn(): Promise<boolean> {
|
|
250
|
+
return this.setAutomaticStop(true);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Turn automatic stop off
|
|
255
|
+
* Disable automatic stop when target humidity is reached
|
|
256
|
+
*/
|
|
257
|
+
async automaticStopOff(): Promise<boolean> {
|
|
258
|
+
return this.setAutomaticStop(false);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Get target humidity
|
|
263
|
+
* Returns the target humidity setting
|
|
264
|
+
*/
|
|
265
|
+
get targetHumidity(): number {
|
|
266
|
+
return this.details.target_humidity || 0;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* Get automatic stop setting
|
|
271
|
+
* Returns whether automatic stop is enabled
|
|
272
|
+
*/
|
|
273
|
+
get automaticStop(): boolean {
|
|
274
|
+
return this.details.configuration?.automatic_stop || false;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import { VeSyncHumidifier } from './humidifier';
|
|
2
|
+
import { VeSync } from '../vesync';
|
|
3
|
+
import { Helpers } from '../helpers';
|
|
4
|
+
import { logger } from '../logger';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* VeSync Humid200S Humidifier Class
|
|
8
|
+
* Implementation based on PyVeSync's VeSyncHumid200S class
|
|
9
|
+
* For Classic200S models
|
|
10
|
+
*/
|
|
11
|
+
export class VeSyncHumid200S extends VeSyncHumidifier {
|
|
12
|
+
protected readonly modes = ['auto', 'manual', 'sleep'] as const;
|
|
13
|
+
protected readonly features = ['humidity', 'mist', 'display', 'timer', 'auto_mode'];
|
|
14
|
+
protected readonly mistLevels = [1, 2, 3];
|
|
15
|
+
protected readonly humidityRange = { min: 30, max: 80 };
|
|
16
|
+
|
|
17
|
+
constructor(details: Record<string, any>, manager: VeSync) {
|
|
18
|
+
super(details, manager);
|
|
19
|
+
|
|
20
|
+
// Update config for Humid200S
|
|
21
|
+
this.config = {
|
|
22
|
+
module: 'VeSyncHumid200S',
|
|
23
|
+
features: ['display', 'humidity', 'mist', 'timer', 'auto_mode'],
|
|
24
|
+
levels: [1, 2, 3]
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
logger.debug(`Initialized VeSyncHumid200S device: ${this.deviceName}`);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Get device details
|
|
32
|
+
*/
|
|
33
|
+
async getDetails(): Promise<Boolean> {
|
|
34
|
+
logger.debug(`Getting details for device: ${this.deviceName}`);
|
|
35
|
+
const [response, status] = await this.callApi(
|
|
36
|
+
'/cloud/v2/deviceManaged/bypassV2',
|
|
37
|
+
'post',
|
|
38
|
+
{
|
|
39
|
+
...Helpers.reqBody(this.manager, 'bypassV2'),
|
|
40
|
+
cid: this.cid,
|
|
41
|
+
configModule: this.configModule,
|
|
42
|
+
payload: {
|
|
43
|
+
data: {},
|
|
44
|
+
method: 'getHumidifierStatus',
|
|
45
|
+
source: 'APP'
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
Helpers.reqHeaderBypass()
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
const success = this.checkResponse([response, status], 'getDetails');
|
|
52
|
+
if (success && response?.result?.result) {
|
|
53
|
+
const result = response.result.result;
|
|
54
|
+
|
|
55
|
+
// Update device status based on enabled field
|
|
56
|
+
this.deviceStatus = result.enabled ? 'on' : 'off';
|
|
57
|
+
|
|
58
|
+
this.details = {
|
|
59
|
+
mode: result.mode || '',
|
|
60
|
+
humidity: result.humidity || 0,
|
|
61
|
+
target_humidity: result.configuration?.auto_target_humidity || result.target_humidity || 0,
|
|
62
|
+
mist_level: result.mist_level || 0,
|
|
63
|
+
water_lacks: result.water_lacks || false,
|
|
64
|
+
humidity_high: result.humidity_high || false,
|
|
65
|
+
water_tank_lifted: result.water_tank_lifted || false,
|
|
66
|
+
display: result.display || false,
|
|
67
|
+
automatic_stop: result.automatic_stop_reach_target || false,
|
|
68
|
+
automatic_stop_configured: result.configuration?.automatic_stop || false,
|
|
69
|
+
auto_target_humidity: result.configuration?.auto_target_humidity || 0,
|
|
70
|
+
configuration: result.configuration || {}
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
logger.debug(`Successfully got details for device: ${this.deviceName}`);
|
|
74
|
+
}
|
|
75
|
+
return success;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Set display
|
|
80
|
+
* Override to use setIndicatorLightSwitch method
|
|
81
|
+
*/
|
|
82
|
+
async setDisplay(enabled: boolean): Promise<boolean> {
|
|
83
|
+
logger.info(`Setting display to ${enabled ? 'on' : 'off'} for device: ${this.deviceName}`);
|
|
84
|
+
const [response, status] = await this.callApi(
|
|
85
|
+
'/cloud/v2/deviceManaged/bypassV2',
|
|
86
|
+
'post',
|
|
87
|
+
{
|
|
88
|
+
...Helpers.reqBody(this.manager, 'bypassV2'),
|
|
89
|
+
cid: this.cid,
|
|
90
|
+
configModule: this.configModule,
|
|
91
|
+
payload: {
|
|
92
|
+
data: {
|
|
93
|
+
enabled: enabled
|
|
94
|
+
},
|
|
95
|
+
method: 'setIndicatorLightSwitch',
|
|
96
|
+
source: 'APP'
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
Helpers.reqHeaderBypass()
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
const success = this.checkResponse([response, status], 'setDisplay');
|
|
103
|
+
if (success) {
|
|
104
|
+
this.details.display = enabled;
|
|
105
|
+
// Get latest state and log it
|
|
106
|
+
await this.getDetails();
|
|
107
|
+
logger.debug(`Device state after display change: ${JSON.stringify(this.details)}`);
|
|
108
|
+
} else {
|
|
109
|
+
logger.error(`Failed to set display to ${enabled ? 'on' : 'off'} for device: ${this.deviceName}`);
|
|
110
|
+
}
|
|
111
|
+
return success;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Set mist level
|
|
116
|
+
*/
|
|
117
|
+
async setMistLevel(level: number): Promise<boolean> {
|
|
118
|
+
if (!this.mistLevels.includes(level)) {
|
|
119
|
+
const error = `Invalid mist level: ${level}. Must be one of: ${this.mistLevels.join(', ')}`;
|
|
120
|
+
logger.error(`${error} for device: ${this.deviceName}`);
|
|
121
|
+
throw new Error(error);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
logger.info(`Setting mist level to ${level} for device: ${this.deviceName}`);
|
|
125
|
+
const [response, status] = await this.callApi(
|
|
126
|
+
'/cloud/v2/deviceManaged/bypassV2',
|
|
127
|
+
'post',
|
|
128
|
+
{
|
|
129
|
+
...Helpers.reqBody(this.manager, 'bypassV2'),
|
|
130
|
+
cid: this.cid,
|
|
131
|
+
configModule: this.configModule,
|
|
132
|
+
payload: {
|
|
133
|
+
data: {
|
|
134
|
+
level: level
|
|
135
|
+
},
|
|
136
|
+
method: 'setMistLevel', // Use setMistLevel for Classic200S
|
|
137
|
+
source: 'APP'
|
|
138
|
+
}
|
|
139
|
+
},
|
|
140
|
+
Helpers.reqHeaderBypass()
|
|
141
|
+
);
|
|
142
|
+
|
|
143
|
+
const success = this.checkResponse([response, status], 'setMistLevel');
|
|
144
|
+
if (success) {
|
|
145
|
+
this.details.mist_level = level;
|
|
146
|
+
// Get latest state and log it
|
|
147
|
+
await this.getDetails();
|
|
148
|
+
logger.debug(`Device state after mist level change: ${JSON.stringify(this.details)}`);
|
|
149
|
+
} else {
|
|
150
|
+
logger.error(`Failed to set mist level to ${level} for device: ${this.deviceName}`);
|
|
151
|
+
}
|
|
152
|
+
return success;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Get current humidity
|
|
157
|
+
* Provides access to the current humidity reading
|
|
158
|
+
*/
|
|
159
|
+
get currentHumidity(): number {
|
|
160
|
+
return this.details.humidity || 0;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Get target humidity
|
|
165
|
+
*/
|
|
166
|
+
get targetHumidity(): number {
|
|
167
|
+
return this.details.target_humidity || 0;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Get water lacks status
|
|
172
|
+
*/
|
|
173
|
+
get waterLacks(): boolean {
|
|
174
|
+
return this.details.water_lacks || false;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Get water tank lifted status
|
|
179
|
+
*/
|
|
180
|
+
get waterTankLifted(): boolean {
|
|
181
|
+
return this.details.water_tank_lifted || false;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Return JSON details for humidifier
|
|
186
|
+
* Override to include current humidity and target humidity
|
|
187
|
+
*/
|
|
188
|
+
displayJSON(): string {
|
|
189
|
+
const baseInfo = JSON.parse(super.displayJSON());
|
|
190
|
+
|
|
191
|
+
// Add current humidity from details
|
|
192
|
+
baseInfo['Humidity'] = this.details.humidity?.toString() || '0';
|
|
193
|
+
|
|
194
|
+
// Add target humidity from configuration
|
|
195
|
+
baseInfo['Target Humidity'] = this.details.target_humidity?.toString() || '0';
|
|
196
|
+
|
|
197
|
+
return JSON.stringify(baseInfo, null, 4);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
@@ -475,4 +475,36 @@ export class VeSyncHumidifier extends VeSyncFan {
|
|
|
475
475
|
get currentHumidity(): number {
|
|
476
476
|
return this.details.humidity || 0;
|
|
477
477
|
}
|
|
478
|
+
|
|
479
|
+
/**
|
|
480
|
+
* Check if water tank is empty
|
|
481
|
+
* Returns true if water tank is empty and needs to be refilled
|
|
482
|
+
*/
|
|
483
|
+
get waterLacks(): boolean {
|
|
484
|
+
return this.details.water_lacks || false;
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
/**
|
|
488
|
+
* Check if water tank is lifted
|
|
489
|
+
* Returns true if water tank is lifted/removed from the device
|
|
490
|
+
*/
|
|
491
|
+
get waterTankLifted(): boolean {
|
|
492
|
+
return this.details.water_tank_lifted || false;
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
/**
|
|
496
|
+
* Check if humidity is higher than target
|
|
497
|
+
* Returns true if current humidity is higher than target humidity
|
|
498
|
+
*/
|
|
499
|
+
get humidityHigh(): boolean {
|
|
500
|
+
return this.details.humidity_high || false;
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
/**
|
|
504
|
+
* Check if automatic stop is active
|
|
505
|
+
* Returns true if automatic stop is currently active
|
|
506
|
+
*/
|
|
507
|
+
get automaticStop(): boolean {
|
|
508
|
+
return this.details.automatic_stop || false;
|
|
509
|
+
}
|
|
478
510
|
}
|
package/src/lib/fans/index.ts
CHANGED
|
@@ -4,6 +4,9 @@ import { VeSyncTowerFan } from './towerFan';
|
|
|
4
4
|
import { VeSyncHumidifier } from './humidifier';
|
|
5
5
|
import { VeSyncWarmHumidifier } from './warmHumidifier';
|
|
6
6
|
import { VeSyncHumid200300S } from './humid200300S';
|
|
7
|
+
import { VeSyncSuperior6000S } from './superior6000S';
|
|
8
|
+
import { VeSyncHumid1000S } from './humid1000S';
|
|
9
|
+
import { VeSyncHumid200S } from './humid200S';
|
|
7
10
|
import { VeSyncFan } from '../vesyncFan';
|
|
8
11
|
import { VeSync } from '../vesync';
|
|
9
12
|
|
|
@@ -14,6 +17,9 @@ export { VeSyncTowerFan } from './towerFan';
|
|
|
14
17
|
export { VeSyncHumidifier } from './humidifier';
|
|
15
18
|
export { VeSyncWarmHumidifier } from './warmHumidifier';
|
|
16
19
|
export { VeSyncHumid200300S } from './humid200300S';
|
|
20
|
+
export { VeSyncSuperior6000S } from './superior6000S';
|
|
21
|
+
export { VeSyncHumid1000S } from './humid1000S';
|
|
22
|
+
export { VeSyncHumid200S } from './humid200S';
|
|
17
23
|
|
|
18
24
|
// Export fan modules dictionary
|
|
19
25
|
export const fanModules: Record<string, new (details: Record<string, any>, manager: VeSync) => VeSyncFan> = {
|
|
@@ -66,7 +72,7 @@ export const fanModules: Record<string, new (details: Record<string, any>, manag
|
|
|
66
72
|
|
|
67
73
|
// Classic Series
|
|
68
74
|
'Classic300S': VeSyncHumidifier,
|
|
69
|
-
'Classic200S':
|
|
75
|
+
'Classic200S': VeSyncHumid200S,
|
|
70
76
|
|
|
71
77
|
// Dual Series
|
|
72
78
|
'Dual200S': VeSyncHumidifier,
|
|
@@ -88,12 +94,12 @@ export const fanModules: Record<string, new (details: Record<string, any>, manag
|
|
|
88
94
|
'LUH-O451S-WUSR': VeSyncHumid200300S,
|
|
89
95
|
'LUH-O601S-WUS': VeSyncHumid200300S,
|
|
90
96
|
'LUH-O601S-KUS': VeSyncHumid200300S,
|
|
91
|
-
'LUH-M101S-WUS':
|
|
92
|
-
'LUH-M101S-WEUR':
|
|
97
|
+
'LUH-M101S-WUS': VeSyncHumid1000S,
|
|
98
|
+
'LUH-M101S-WEUR': VeSyncHumid1000S,
|
|
93
99
|
|
|
94
|
-
// LEH Series
|
|
95
|
-
'LEH-S601S-WUS':
|
|
96
|
-
'LEH-S601S-WUSR':
|
|
100
|
+
// LEH Series - Superior 6000S
|
|
101
|
+
'LEH-S601S-WUS': VeSyncSuperior6000S,
|
|
102
|
+
'LEH-S601S-WUSR': VeSyncSuperior6000S,
|
|
97
103
|
|
|
98
104
|
// LV Series
|
|
99
105
|
'LV-PUR131S': VeSyncAirBypass,
|