tsvesync 1.3.12 → 1.3.13
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/air131.js +4 -0
- package/dist/lib/fans/airBaseV2.js +6 -0
- package/dist/lib/fans/airBypass.js +5 -0
- package/dist/lib/helpers.d.ts +4 -0
- package/dist/lib/helpers.js +44 -0
- package/dist/lib/vesyncFan.d.ts +9 -0
- package/dist/lib/vesyncFan.js +17 -0
- package/package.json +1 -1
- package/src/lib/fans/air131.ts +4 -0
- package/src/lib/fans/airBaseV2.ts +6 -0
- package/src/lib/fans/airBypass.ts +6 -0
- package/src/lib/helpers.ts +46 -0
- package/src/lib/vesyncFan.ts +20 -0
package/dist/lib/fans/air131.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.VeSyncAir131 = void 0;
|
|
4
4
|
const vesyncFan_1 = require("../vesyncFan");
|
|
5
|
+
const helpers_1 = require("../helpers");
|
|
5
6
|
const logger_1 = require("../logger");
|
|
6
7
|
/**
|
|
7
8
|
* VeSync Air Purifier 131 Series (LV-PUR131S, LV-RH131S)
|
|
@@ -78,6 +79,7 @@ class VeSyncAir131 extends vesyncFan_1.VeSyncFan {
|
|
|
78
79
|
logger_1.logger.debug(`${this.deviceName}: API response structure:`, JSON.stringify(data, null, 2));
|
|
79
80
|
}
|
|
80
81
|
}
|
|
82
|
+
const normalizedAirQuality = helpers_1.Helpers.normalizeAirQuality(data.airQuality);
|
|
81
83
|
this.details = {
|
|
82
84
|
mode: data.mode || 'manual', // Default to manual if not specified
|
|
83
85
|
speed: data.level || 0,
|
|
@@ -86,6 +88,8 @@ class VeSyncAir131 extends vesyncFan_1.VeSyncFan {
|
|
|
86
88
|
child_lock: data.childLock || false,
|
|
87
89
|
air_quality: data.airQuality || 'unknown',
|
|
88
90
|
air_quality_value: data.air_quality_value || 0,
|
|
91
|
+
air_quality_level: normalizedAirQuality.level >= 1 ? normalizedAirQuality.level : undefined,
|
|
92
|
+
air_quality_label: normalizedAirQuality.label,
|
|
89
93
|
active_time: data.activeTime || 0
|
|
90
94
|
};
|
|
91
95
|
// Store last known speed when device is on and has a valid speed
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.VeSyncAirBaseV2 = void 0;
|
|
4
4
|
const airBypass_1 = require("./airBypass");
|
|
5
5
|
const logger_1 = require("../logger");
|
|
6
|
+
const helpers_1 = require("../helpers");
|
|
6
7
|
/**
|
|
7
8
|
* VeSync Air Purifier with Bypass V2
|
|
8
9
|
*/
|
|
@@ -163,6 +164,11 @@ class VeSyncAirBaseV2 extends airBypass_1.VeSyncAirBypass {
|
|
|
163
164
|
if (this.hasFeature('air_quality')) {
|
|
164
165
|
this.details.air_quality_value = (_l = devDict.PM25) !== null && _l !== void 0 ? _l : 0;
|
|
165
166
|
this.details.air_quality = (_m = devDict.AQLevel) !== null && _m !== void 0 ? _m : 0;
|
|
167
|
+
const normalizedAirQuality = helpers_1.Helpers.normalizeAirQuality(devDict.AQLevel);
|
|
168
|
+
if (normalizedAirQuality.level >= 1) {
|
|
169
|
+
this.details.air_quality_level = normalizedAirQuality.level;
|
|
170
|
+
}
|
|
171
|
+
this.details.air_quality_label = normalizedAirQuality.label;
|
|
166
172
|
}
|
|
167
173
|
if ('PM1' in devDict)
|
|
168
174
|
this.details.pm1 = devDict.PM1;
|
|
@@ -78,6 +78,11 @@ class VeSyncAirBypass extends vesyncFan_1.VeSyncFan {
|
|
|
78
78
|
air_quality: result.air_quality || 0,
|
|
79
79
|
air_quality_value: result.air_quality_value || 0
|
|
80
80
|
};
|
|
81
|
+
const normalizedAirQuality = helpers_1.Helpers.normalizeAirQuality(result.air_quality);
|
|
82
|
+
if (normalizedAirQuality.level >= 1) {
|
|
83
|
+
this.details.air_quality_level = normalizedAirQuality.level;
|
|
84
|
+
}
|
|
85
|
+
this.details.air_quality_label = normalizedAirQuality.label;
|
|
81
86
|
// Capture additional air quality properties if available
|
|
82
87
|
if ('PM1' in result)
|
|
83
88
|
this.details.pm1 = result.PM1;
|
package/dist/lib/helpers.d.ts
CHANGED
|
@@ -106,6 +106,10 @@ export interface LoginResponse {
|
|
|
106
106
|
export declare class Helpers {
|
|
107
107
|
static shouldRedact: boolean;
|
|
108
108
|
static generateTraceId(): string;
|
|
109
|
+
static normalizeAirQuality(value: unknown): {
|
|
110
|
+
level: number;
|
|
111
|
+
label: string;
|
|
112
|
+
};
|
|
109
113
|
/**
|
|
110
114
|
* Calculate MD5 hash
|
|
111
115
|
*/
|
package/dist/lib/helpers.js
CHANGED
|
@@ -182,6 +182,50 @@ class Helpers {
|
|
|
182
182
|
static generateTraceId() {
|
|
183
183
|
return generateTraceId();
|
|
184
184
|
}
|
|
185
|
+
static normalizeAirQuality(value) {
|
|
186
|
+
const stringMap = {
|
|
187
|
+
'excellent': 1,
|
|
188
|
+
'very good': 1,
|
|
189
|
+
'good': 2,
|
|
190
|
+
'moderate': 3,
|
|
191
|
+
'fair': 3,
|
|
192
|
+
'inferior': 4,
|
|
193
|
+
'poor': 4,
|
|
194
|
+
'bad': 4,
|
|
195
|
+
};
|
|
196
|
+
if (typeof value === 'number') {
|
|
197
|
+
const level = Number.isFinite(value) ? Math.trunc(value) : -1;
|
|
198
|
+
if (level >= 1 && level <= 4) {
|
|
199
|
+
return {
|
|
200
|
+
level,
|
|
201
|
+
label: level === 1
|
|
202
|
+
? 'excellent'
|
|
203
|
+
: level === 2
|
|
204
|
+
? 'good'
|
|
205
|
+
: level === 3
|
|
206
|
+
? 'moderate'
|
|
207
|
+
: 'poor',
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
else if (typeof value === 'string') {
|
|
212
|
+
const normalized = value.trim().toLowerCase();
|
|
213
|
+
const level = stringMap[normalized];
|
|
214
|
+
if (level) {
|
|
215
|
+
return {
|
|
216
|
+
level,
|
|
217
|
+
label: level === 1
|
|
218
|
+
? 'excellent'
|
|
219
|
+
: level === 2
|
|
220
|
+
? 'good'
|
|
221
|
+
: level === 3
|
|
222
|
+
? 'moderate'
|
|
223
|
+
: 'poor',
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
return { level: -1, label: 'unknown' };
|
|
228
|
+
}
|
|
185
229
|
/**
|
|
186
230
|
* Calculate MD5 hash
|
|
187
231
|
*/
|
package/dist/lib/vesyncFan.d.ts
CHANGED
|
@@ -25,6 +25,8 @@ export declare abstract class VeSyncFan extends VeSyncBaseDevice {
|
|
|
25
25
|
child_lock?: boolean;
|
|
26
26
|
air_quality?: string | number;
|
|
27
27
|
air_quality_value?: number;
|
|
28
|
+
air_quality_level?: number;
|
|
29
|
+
air_quality_label?: string;
|
|
28
30
|
pm1?: number;
|
|
29
31
|
pm10?: number;
|
|
30
32
|
aq_percent?: number;
|
|
@@ -90,6 +92,13 @@ export declare abstract class VeSyncFan extends VeSyncBaseDevice {
|
|
|
90
92
|
* Get air quality value - PM2.5 in μg/m³ (if supported)
|
|
91
93
|
*/
|
|
92
94
|
get airQualityValue(): number;
|
|
95
|
+
/**
|
|
96
|
+
* Normalized air quality metadata aligned with pyvesync levels.
|
|
97
|
+
*/
|
|
98
|
+
getNormalizedAirQuality(): {
|
|
99
|
+
level: number;
|
|
100
|
+
label: string;
|
|
101
|
+
};
|
|
93
102
|
/**
|
|
94
103
|
* Get PM1 value (if supported)
|
|
95
104
|
*/
|
package/dist/lib/vesyncFan.js
CHANGED
|
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.VeSyncFan = exports.fanConfig = void 0;
|
|
7
7
|
const vesyncBaseDevice_1 = require("./vesyncBaseDevice");
|
|
8
8
|
const logger_1 = require("./logger");
|
|
9
|
+
const helpers_1 = require("./helpers");
|
|
9
10
|
// Fan configuration
|
|
10
11
|
exports.fanConfig = {
|
|
11
12
|
// Core Series
|
|
@@ -418,6 +419,22 @@ class VeSyncFan extends vesyncBaseDevice_1.VeSyncBaseDevice {
|
|
|
418
419
|
var _a;
|
|
419
420
|
return (_a = this.details.air_quality_value) !== null && _a !== void 0 ? _a : 0;
|
|
420
421
|
}
|
|
422
|
+
/**
|
|
423
|
+
* Normalized air quality metadata aligned with pyvesync levels.
|
|
424
|
+
*/
|
|
425
|
+
getNormalizedAirQuality() {
|
|
426
|
+
var _a;
|
|
427
|
+
if (typeof this.details.air_quality_level === 'number' && this.details.air_quality_level >= 1) {
|
|
428
|
+
const label = (_a = this.details.air_quality_label) !== null && _a !== void 0 ? _a : helpers_1.Helpers.normalizeAirQuality(this.details.air_quality_level).label;
|
|
429
|
+
return { level: this.details.air_quality_level, label };
|
|
430
|
+
}
|
|
431
|
+
const normalized = helpers_1.Helpers.normalizeAirQuality(this.details.air_quality);
|
|
432
|
+
if (normalized.level >= 1) {
|
|
433
|
+
this.details.air_quality_level = normalized.level;
|
|
434
|
+
this.details.air_quality_label = normalized.label;
|
|
435
|
+
}
|
|
436
|
+
return normalized;
|
|
437
|
+
}
|
|
421
438
|
/**
|
|
422
439
|
* Get PM1 value (if supported)
|
|
423
440
|
*/
|
package/package.json
CHANGED
package/src/lib/fans/air131.ts
CHANGED
|
@@ -88,6 +88,8 @@ export class VeSyncAir131 extends VeSyncFan {
|
|
|
88
88
|
}
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
+
const normalizedAirQuality = Helpers.normalizeAirQuality(data.airQuality);
|
|
92
|
+
|
|
91
93
|
this.details = {
|
|
92
94
|
mode: data.mode || 'manual', // Default to manual if not specified
|
|
93
95
|
speed: data.level || 0,
|
|
@@ -96,6 +98,8 @@ export class VeSyncAir131 extends VeSyncFan {
|
|
|
96
98
|
child_lock: data.childLock || false,
|
|
97
99
|
air_quality: data.airQuality || 'unknown',
|
|
98
100
|
air_quality_value: data.air_quality_value || 0,
|
|
101
|
+
air_quality_level: normalizedAirQuality.level >= 1 ? normalizedAirQuality.level : undefined,
|
|
102
|
+
air_quality_label: normalizedAirQuality.label,
|
|
99
103
|
active_time: data.activeTime || 0
|
|
100
104
|
};
|
|
101
105
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { VeSyncAirBypass } from './airBypass';
|
|
2
2
|
import { VeSync } from '../vesync';
|
|
3
3
|
import { logger } from '../logger';
|
|
4
|
+
import { Helpers } from '../helpers';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* VeSync Air Purifier with Bypass V2
|
|
@@ -189,6 +190,11 @@ export class VeSyncAirBaseV2 extends VeSyncAirBypass {
|
|
|
189
190
|
if (this.hasFeature('air_quality')) {
|
|
190
191
|
this.details.air_quality_value = devDict.PM25 ?? 0;
|
|
191
192
|
this.details.air_quality = devDict.AQLevel ?? 0;
|
|
193
|
+
const normalizedAirQuality = Helpers.normalizeAirQuality(devDict.AQLevel);
|
|
194
|
+
if (normalizedAirQuality.level >= 1) {
|
|
195
|
+
this.details.air_quality_level = normalizedAirQuality.level;
|
|
196
|
+
}
|
|
197
|
+
this.details.air_quality_label = normalizedAirQuality.label;
|
|
192
198
|
}
|
|
193
199
|
|
|
194
200
|
if ('PM1' in devDict) this.details.pm1 = devDict.PM1;
|
|
@@ -87,6 +87,12 @@ export class VeSyncAirBypass extends VeSyncFan {
|
|
|
87
87
|
air_quality_value: result.air_quality_value || 0
|
|
88
88
|
};
|
|
89
89
|
|
|
90
|
+
const normalizedAirQuality = Helpers.normalizeAirQuality(result.air_quality);
|
|
91
|
+
if (normalizedAirQuality.level >= 1) {
|
|
92
|
+
this.details.air_quality_level = normalizedAirQuality.level;
|
|
93
|
+
}
|
|
94
|
+
this.details.air_quality_label = normalizedAirQuality.label;
|
|
95
|
+
|
|
90
96
|
// Capture additional air quality properties if available
|
|
91
97
|
if ('PM1' in result) this.details.pm1 = result.PM1;
|
|
92
98
|
if ('PM10' in result) this.details.pm10 = result.PM10;
|
package/src/lib/helpers.ts
CHANGED
|
@@ -245,6 +245,52 @@ export class Helpers {
|
|
|
245
245
|
return generateTraceId();
|
|
246
246
|
}
|
|
247
247
|
|
|
248
|
+
static normalizeAirQuality(value: unknown): { level: number; label: string } {
|
|
249
|
+
const stringMap: Record<string, number> = {
|
|
250
|
+
'excellent': 1,
|
|
251
|
+
'very good': 1,
|
|
252
|
+
'good': 2,
|
|
253
|
+
'moderate': 3,
|
|
254
|
+
'fair': 3,
|
|
255
|
+
'inferior': 4,
|
|
256
|
+
'poor': 4,
|
|
257
|
+
'bad': 4,
|
|
258
|
+
};
|
|
259
|
+
|
|
260
|
+
if (typeof value === 'number') {
|
|
261
|
+
const level = Number.isFinite(value) ? Math.trunc(value) : -1;
|
|
262
|
+
if (level >= 1 && level <= 4) {
|
|
263
|
+
return {
|
|
264
|
+
level,
|
|
265
|
+
label: level === 1
|
|
266
|
+
? 'excellent'
|
|
267
|
+
: level === 2
|
|
268
|
+
? 'good'
|
|
269
|
+
: level === 3
|
|
270
|
+
? 'moderate'
|
|
271
|
+
: 'poor',
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
} else if (typeof value === 'string') {
|
|
275
|
+
const normalized = value.trim().toLowerCase();
|
|
276
|
+
const level = stringMap[normalized];
|
|
277
|
+
if (level) {
|
|
278
|
+
return {
|
|
279
|
+
level,
|
|
280
|
+
label: level === 1
|
|
281
|
+
? 'excellent'
|
|
282
|
+
: level === 2
|
|
283
|
+
? 'good'
|
|
284
|
+
: level === 3
|
|
285
|
+
? 'moderate'
|
|
286
|
+
: 'poor',
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
return { level: -1, label: 'unknown' };
|
|
292
|
+
}
|
|
293
|
+
|
|
248
294
|
/**
|
|
249
295
|
* Calculate MD5 hash
|
|
250
296
|
*/
|
package/src/lib/vesyncFan.ts
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import { VeSyncBaseDevice } from './vesyncBaseDevice';
|
|
6
6
|
import { VeSync } from './vesync';
|
|
7
7
|
import { logger } from './logger';
|
|
8
|
+
import { Helpers } from './helpers';
|
|
8
9
|
|
|
9
10
|
interface FanConfig {
|
|
10
11
|
[key: string]: {
|
|
@@ -327,6 +328,8 @@ export abstract class VeSyncFan extends VeSyncBaseDevice {
|
|
|
327
328
|
child_lock?: boolean;
|
|
328
329
|
air_quality?: string | number;
|
|
329
330
|
air_quality_value?: number;
|
|
331
|
+
air_quality_level?: number;
|
|
332
|
+
air_quality_label?: string;
|
|
330
333
|
pm1?: number;
|
|
331
334
|
pm10?: number;
|
|
332
335
|
aq_percent?: number;
|
|
@@ -468,6 +471,23 @@ export abstract class VeSyncFan extends VeSyncBaseDevice {
|
|
|
468
471
|
return this.details.air_quality_value ?? 0;
|
|
469
472
|
}
|
|
470
473
|
|
|
474
|
+
/**
|
|
475
|
+
* Normalized air quality metadata aligned with pyvesync levels.
|
|
476
|
+
*/
|
|
477
|
+
getNormalizedAirQuality(): { level: number; label: string } {
|
|
478
|
+
if (typeof this.details.air_quality_level === 'number' && this.details.air_quality_level >= 1) {
|
|
479
|
+
const label = this.details.air_quality_label ?? Helpers.normalizeAirQuality(this.details.air_quality_level).label;
|
|
480
|
+
return { level: this.details.air_quality_level, label };
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
const normalized = Helpers.normalizeAirQuality(this.details.air_quality);
|
|
484
|
+
if (normalized.level >= 1) {
|
|
485
|
+
this.details.air_quality_level = normalized.level;
|
|
486
|
+
this.details.air_quality_label = normalized.label;
|
|
487
|
+
}
|
|
488
|
+
return normalized;
|
|
489
|
+
}
|
|
490
|
+
|
|
471
491
|
/**
|
|
472
492
|
* Get PM1 value (if supported)
|
|
473
493
|
*/
|