tsvesync 1.0.43 → 1.0.45
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/vesync.js +25 -8
- package/dist/lib/vesyncFan.d.ts +13 -2
- package/dist/lib/vesyncFan.js +48 -33
- package/dist/lib/vesyncFanImpl.d.ts +99 -14
- package/dist/lib/vesyncFanImpl.js +408 -69
- package/package.json +1 -1
- package/src/lib/vesync.ts +26 -7
- package/src/lib/vesyncFan.ts +49 -34
- package/src/lib/vesyncFanImpl.ts +491 -70
|
@@ -19,6 +19,23 @@ class VeSyncAirBypass extends vesyncFan_1.VeSyncFan {
|
|
|
19
19
|
this.childLockModes = ['on', 'off'];
|
|
20
20
|
logger_1.logger.debug(`Initialized VeSyncAirBypass device: ${this.deviceName}`);
|
|
21
21
|
}
|
|
22
|
+
/**
|
|
23
|
+
* Build API dictionary
|
|
24
|
+
*/
|
|
25
|
+
buildApiDict(method) {
|
|
26
|
+
const head = helpers_1.Helpers.reqHeaderBypass();
|
|
27
|
+
const body = {
|
|
28
|
+
...helpers_1.Helpers.reqBody(this.manager, 'bypassV2'),
|
|
29
|
+
cid: this.cid,
|
|
30
|
+
configModule: this.configModule,
|
|
31
|
+
payload: {
|
|
32
|
+
method,
|
|
33
|
+
source: 'APP',
|
|
34
|
+
data: {}
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
return [head, body];
|
|
38
|
+
}
|
|
22
39
|
/**
|
|
23
40
|
* Get device details
|
|
24
41
|
*/
|
|
@@ -1035,8 +1052,37 @@ class VeSyncAirBaseV2 extends VeSyncAirBypass {
|
|
|
1035
1052
|
super(details, manager);
|
|
1036
1053
|
this._lightDetection = false;
|
|
1037
1054
|
this._lightDetectionState = false;
|
|
1055
|
+
this.setSpeedLevel = null;
|
|
1056
|
+
this.autoPreferences = ['default', 'efficient', 'quiet'];
|
|
1057
|
+
this.enabled = false;
|
|
1058
|
+
this._mode = '';
|
|
1059
|
+
this._speed = 0;
|
|
1060
|
+
this._timer = null;
|
|
1038
1061
|
logger_1.logger.debug(`Initialized VeSyncAirBaseV2 device: ${this.deviceName}`);
|
|
1039
1062
|
}
|
|
1063
|
+
buildConfigDict(configDict) {
|
|
1064
|
+
if (configDict) {
|
|
1065
|
+
this.config = configDict;
|
|
1066
|
+
}
|
|
1067
|
+
}
|
|
1068
|
+
get mode() {
|
|
1069
|
+
return this._mode;
|
|
1070
|
+
}
|
|
1071
|
+
set mode(value) {
|
|
1072
|
+
this._mode = value;
|
|
1073
|
+
}
|
|
1074
|
+
get speed() {
|
|
1075
|
+
return this._speed;
|
|
1076
|
+
}
|
|
1077
|
+
set speed(value) {
|
|
1078
|
+
this._speed = value;
|
|
1079
|
+
}
|
|
1080
|
+
get timer() {
|
|
1081
|
+
return this._timer;
|
|
1082
|
+
}
|
|
1083
|
+
set timer(value) {
|
|
1084
|
+
this._timer = value;
|
|
1085
|
+
}
|
|
1040
1086
|
/**
|
|
1041
1087
|
* Build API dictionary
|
|
1042
1088
|
*/
|
|
@@ -1044,7 +1090,7 @@ class VeSyncAirBaseV2 extends VeSyncAirBypass {
|
|
|
1044
1090
|
const head = helpers_1.Helpers.reqHeaderBypass();
|
|
1045
1091
|
const body = {
|
|
1046
1092
|
...helpers_1.Helpers.reqBody(this.manager, 'bypassV2'),
|
|
1047
|
-
|
|
1093
|
+
cid: this.cid,
|
|
1048
1094
|
configModule: this.configModule,
|
|
1049
1095
|
payload: {
|
|
1050
1096
|
method,
|
|
@@ -1054,74 +1100,355 @@ class VeSyncAirBaseV2 extends VeSyncAirBypass {
|
|
|
1054
1100
|
};
|
|
1055
1101
|
return [head, body];
|
|
1056
1102
|
}
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1103
|
+
/**
|
|
1104
|
+
* Get device details
|
|
1105
|
+
*/
|
|
1106
|
+
async getDetails() {
|
|
1107
|
+
logger_1.logger.debug(`Getting details for device: ${this.deviceName}`);
|
|
1108
|
+
const [head, body] = this.buildApiDict('getPurifierStatus');
|
|
1109
|
+
const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', body, head);
|
|
1110
|
+
if (!this.checkResponse([response, status], 'getDetails') || !(response === null || response === void 0 ? void 0 : response.result)) {
|
|
1111
|
+
logger_1.logger.debug('Error getting purifier details');
|
|
1112
|
+
this.connectionStatus = 'offline';
|
|
1113
|
+
return false;
|
|
1114
|
+
}
|
|
1115
|
+
const innerResponse = response.result;
|
|
1116
|
+
if (innerResponse.code !== 0 || !innerResponse.result) {
|
|
1117
|
+
logger_1.logger.debug('Error in inner response from purifier');
|
|
1118
|
+
this.connectionStatus = 'offline';
|
|
1119
|
+
return false;
|
|
1120
|
+
}
|
|
1121
|
+
const deviceData = innerResponse.result;
|
|
1122
|
+
this.buildPurifierDict(deviceData);
|
|
1123
|
+
if (deviceData.configuration) {
|
|
1124
|
+
this.buildConfigDict(deviceData.configuration);
|
|
1125
|
+
}
|
|
1126
|
+
return true;
|
|
1062
1127
|
}
|
|
1063
|
-
|
|
1064
|
-
|
|
1128
|
+
/**
|
|
1129
|
+
* Build purifier dictionary
|
|
1130
|
+
*/
|
|
1131
|
+
buildPurifierDict(devDict) {
|
|
1132
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
|
|
1133
|
+
this.connectionStatus = 'online';
|
|
1134
|
+
const powerSwitch = Boolean((_a = devDict.powerSwitch) !== null && _a !== void 0 ? _a : 0);
|
|
1135
|
+
this.enabled = powerSwitch;
|
|
1136
|
+
this.deviceStatus = powerSwitch ? 'on' : 'off';
|
|
1137
|
+
this.mode = (_b = devDict.workMode) !== null && _b !== void 0 ? _b : 'manual';
|
|
1138
|
+
this.speed = (_c = devDict.fanSpeedLevel) !== null && _c !== void 0 ? _c : 0;
|
|
1139
|
+
this.setSpeedLevel = (_d = devDict.manualSpeedLevel) !== null && _d !== void 0 ? _d : 1;
|
|
1140
|
+
this.details = {
|
|
1141
|
+
...this.details,
|
|
1142
|
+
filter_life: (_e = devDict.filterLifePercent) !== null && _e !== void 0 ? _e : 0,
|
|
1143
|
+
child_lock: Boolean((_f = devDict.childLockSwitch) !== null && _f !== void 0 ? _f : 0),
|
|
1144
|
+
display: Boolean((_g = devDict.screenState) !== null && _g !== void 0 ? _g : 0),
|
|
1145
|
+
light_detection_switch: Boolean((_h = devDict.lightDetectionSwitch) !== null && _h !== void 0 ? _h : 0),
|
|
1146
|
+
environment_light_state: Boolean((_j = devDict.environmentLightState) !== null && _j !== void 0 ? _j : 0),
|
|
1147
|
+
screen_switch: Boolean((_k = devDict.screenSwitch) !== null && _k !== void 0 ? _k : 0)
|
|
1148
|
+
};
|
|
1149
|
+
if (this.hasFeature('air_quality')) {
|
|
1150
|
+
this.details.air_quality_value = (_l = devDict.PM25) !== null && _l !== void 0 ? _l : 0;
|
|
1151
|
+
this.details.air_quality = (_m = devDict.AQLevel) !== null && _m !== void 0 ? _m : 0;
|
|
1152
|
+
}
|
|
1153
|
+
if ('PM1' in devDict)
|
|
1154
|
+
this.details.pm1 = devDict.PM1;
|
|
1155
|
+
if ('PM10' in devDict)
|
|
1156
|
+
this.details.pm10 = devDict.PM10;
|
|
1157
|
+
if ('AQPercent' in devDict)
|
|
1158
|
+
this.details.aq_percent = devDict.AQPercent;
|
|
1159
|
+
if ('fanRotateAngle' in devDict)
|
|
1160
|
+
this.details.fan_rotate_angle = devDict.fanRotateAngle;
|
|
1161
|
+
if ('filterOpenState' in devDict)
|
|
1162
|
+
this.details.filter_open_state = Boolean(devDict.filterOpenState);
|
|
1163
|
+
if (((_o = devDict.timerRemain) !== null && _o !== void 0 ? _o : 0) > 0) {
|
|
1164
|
+
this.timer = { duration: devDict.timerRemain, action: 'off' };
|
|
1165
|
+
}
|
|
1166
|
+
if (typeof devDict.autoPreference === 'object' && devDict.autoPreference) {
|
|
1167
|
+
this.details.auto_preference_type = (_q = (_p = devDict.autoPreference) === null || _p === void 0 ? void 0 : _p.autoPreferenceType) !== null && _q !== void 0 ? _q : 'default';
|
|
1168
|
+
}
|
|
1169
|
+
else {
|
|
1170
|
+
this.details.auto_preference_type = null;
|
|
1171
|
+
}
|
|
1065
1172
|
}
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1173
|
+
/**
|
|
1174
|
+
* Toggle device power
|
|
1175
|
+
*/
|
|
1176
|
+
async toggleSwitch(toggle) {
|
|
1177
|
+
if (typeof toggle !== 'boolean') {
|
|
1178
|
+
logger_1.logger.debug('Invalid toggle value for purifier switch');
|
|
1069
1179
|
return false;
|
|
1070
1180
|
}
|
|
1071
|
-
body
|
|
1181
|
+
const [head, body] = this.buildApiDict('setSwitch');
|
|
1182
|
+
body.payload.data = {
|
|
1183
|
+
powerSwitch: toggle ? 1 : 0,
|
|
1184
|
+
switchIdx: 0
|
|
1185
|
+
};
|
|
1072
1186
|
const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', body, head);
|
|
1073
|
-
const success = this.checkResponse([response, status], '
|
|
1187
|
+
const success = this.checkResponse([response, status], 'toggleSwitch');
|
|
1074
1188
|
if (success) {
|
|
1075
|
-
this.
|
|
1189
|
+
this.deviceStatus = toggle ? 'on' : 'off';
|
|
1076
1190
|
}
|
|
1077
1191
|
return success;
|
|
1078
1192
|
}
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
async
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
async turboMode() {
|
|
1086
|
-
return this.mode_toggle('turbo');
|
|
1193
|
+
/**
|
|
1194
|
+
* Turn device on - compatibility method that proxies to toggleSwitch
|
|
1195
|
+
*/
|
|
1196
|
+
async turnOn() {
|
|
1197
|
+
logger_1.logger.info(`Turning on device: ${this.deviceName}`);
|
|
1198
|
+
return this.toggleSwitch(true);
|
|
1087
1199
|
}
|
|
1088
|
-
|
|
1089
|
-
|
|
1200
|
+
/**
|
|
1201
|
+
* Turn device off - compatibility method that proxies to toggleSwitch
|
|
1202
|
+
*/
|
|
1203
|
+
async turnOff() {
|
|
1204
|
+
logger_1.logger.info(`Turning off device: ${this.deviceName}`);
|
|
1205
|
+
return this.toggleSwitch(false);
|
|
1090
1206
|
}
|
|
1091
1207
|
/**
|
|
1092
|
-
*
|
|
1208
|
+
* Change fan speed
|
|
1093
1209
|
*/
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1210
|
+
async changeFanSpeed(speed) {
|
|
1211
|
+
var _a, _b, _c;
|
|
1212
|
+
const speeds = (_b = (_a = this.config) === null || _a === void 0 ? void 0 : _a.levels) !== null && _b !== void 0 ? _b : [];
|
|
1213
|
+
const currentSpeed = (_c = this.setSpeedLevel) !== null && _c !== void 0 ? _c : 0;
|
|
1214
|
+
if (speed !== undefined) {
|
|
1215
|
+
if (!speeds.includes(speed)) {
|
|
1216
|
+
logger_1.logger.debug(`Invalid speed: ${speed}. Must be one of: ${speeds.join(', ')}`);
|
|
1217
|
+
return false;
|
|
1218
|
+
}
|
|
1219
|
+
}
|
|
1220
|
+
else {
|
|
1221
|
+
if (currentSpeed === speeds[speeds.length - 1] || currentSpeed === 0) {
|
|
1222
|
+
speed = speeds[0];
|
|
1223
|
+
}
|
|
1224
|
+
else {
|
|
1225
|
+
const currentIndex = speeds.indexOf(currentSpeed);
|
|
1226
|
+
speed = speeds[currentIndex + 1];
|
|
1227
|
+
}
|
|
1228
|
+
}
|
|
1229
|
+
const [head, body] = this.buildApiDict('setLevel');
|
|
1230
|
+
body.payload.data = {
|
|
1231
|
+
levelIdx: 0,
|
|
1232
|
+
manualSpeedLevel: speed,
|
|
1233
|
+
levelType: 'wind'
|
|
1234
|
+
};
|
|
1235
|
+
const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', body, head);
|
|
1236
|
+
const success = this.checkResponse([response, status], 'changeFanSpeed');
|
|
1237
|
+
if (success) {
|
|
1238
|
+
this.setSpeedLevel = speed;
|
|
1239
|
+
this.mode = 'manual';
|
|
1097
1240
|
}
|
|
1241
|
+
return success;
|
|
1098
1242
|
}
|
|
1099
1243
|
/**
|
|
1100
1244
|
* Set mode
|
|
1101
1245
|
*/
|
|
1102
|
-
async
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
logger_1.logger.debug(`Invalid mode used - ${mode}`);
|
|
1246
|
+
async setMode(mode) {
|
|
1247
|
+
if (!this.modes.includes(mode)) {
|
|
1248
|
+
logger_1.logger.debug(`Invalid mode: ${mode}. Must be one of: ${this.modes.join(', ')}`);
|
|
1106
1249
|
return false;
|
|
1107
1250
|
}
|
|
1251
|
+
if (mode === 'manual') {
|
|
1252
|
+
if (!this.speed || this.speed === 0) {
|
|
1253
|
+
return this.changeFanSpeed(1);
|
|
1254
|
+
}
|
|
1255
|
+
return this.changeFanSpeed(this.speed);
|
|
1256
|
+
}
|
|
1257
|
+
if (mode === 'off') {
|
|
1258
|
+
return this.turnOff();
|
|
1259
|
+
}
|
|
1108
1260
|
const [head, body] = this.buildApiDict('setPurifierMode');
|
|
1109
|
-
|
|
1261
|
+
body.payload.data = {
|
|
1262
|
+
workMode: mode
|
|
1263
|
+
};
|
|
1264
|
+
const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', body, head);
|
|
1265
|
+
const success = this.checkResponse([response, status], 'setMode');
|
|
1266
|
+
if (success) {
|
|
1267
|
+
this.mode = mode;
|
|
1268
|
+
}
|
|
1269
|
+
return success;
|
|
1270
|
+
}
|
|
1271
|
+
/**
|
|
1272
|
+
* Set display status
|
|
1273
|
+
*/
|
|
1274
|
+
async setDisplay(enabled) {
|
|
1275
|
+
if (!this.hasFeature('display')) {
|
|
1276
|
+
const error = 'Display control not supported';
|
|
1277
|
+
logger_1.logger.error(`${error} for device: ${this.deviceName}`);
|
|
1278
|
+
throw new Error(error);
|
|
1279
|
+
}
|
|
1280
|
+
const [head, body] = this.buildApiDict('setDisplay');
|
|
1281
|
+
body.payload.data = {
|
|
1282
|
+
screenSwitch: enabled ? 1 : 0
|
|
1283
|
+
};
|
|
1284
|
+
const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', body, head);
|
|
1285
|
+
const success = this.checkResponse([response, status], 'setDisplay');
|
|
1286
|
+
if (success) {
|
|
1287
|
+
this.details.screen_switch = enabled;
|
|
1288
|
+
}
|
|
1289
|
+
return success;
|
|
1290
|
+
}
|
|
1291
|
+
/**
|
|
1292
|
+
* Set child lock
|
|
1293
|
+
*/
|
|
1294
|
+
async setChildLock(enabled) {
|
|
1295
|
+
if (!this.hasFeature('child_lock')) {
|
|
1296
|
+
const error = 'Child lock not supported';
|
|
1297
|
+
logger_1.logger.error(`${error} for device: ${this.deviceName}`);
|
|
1298
|
+
throw new Error(error);
|
|
1299
|
+
}
|
|
1300
|
+
const [head, body] = this.buildApiDict('setChildLock');
|
|
1301
|
+
body.payload.data = {
|
|
1302
|
+
childLockSwitch: enabled ? 1 : 0
|
|
1303
|
+
};
|
|
1304
|
+
const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', body, head);
|
|
1305
|
+
const success = this.checkResponse([response, status], 'setChildLock');
|
|
1306
|
+
if (success) {
|
|
1307
|
+
this.details.child_lock = enabled;
|
|
1308
|
+
}
|
|
1309
|
+
return success;
|
|
1310
|
+
}
|
|
1311
|
+
/**
|
|
1312
|
+
* Set timer
|
|
1313
|
+
*/
|
|
1314
|
+
async setTimer(timerDuration, action = 'off', method = 'powerSwitch') {
|
|
1315
|
+
if (!this.hasFeature('timer')) {
|
|
1316
|
+
const error = 'Timer not supported';
|
|
1317
|
+
logger_1.logger.error(`${error} for device: ${this.deviceName}`);
|
|
1318
|
+
throw new Error(error);
|
|
1319
|
+
}
|
|
1320
|
+
if (!['on', 'off'].includes(action)) {
|
|
1321
|
+
logger_1.logger.debug('Invalid action for timer');
|
|
1322
|
+
return false;
|
|
1323
|
+
}
|
|
1324
|
+
if (method !== 'powerSwitch') {
|
|
1325
|
+
logger_1.logger.debug('Invalid method for timer');
|
|
1110
1326
|
return false;
|
|
1111
1327
|
}
|
|
1328
|
+
const [head, body] = this.buildApiDict('addTimerV2');
|
|
1329
|
+
body.payload.subDeviceNo = 0;
|
|
1112
1330
|
body.payload.data = {
|
|
1113
|
-
|
|
1331
|
+
startAct: [{
|
|
1332
|
+
type: method,
|
|
1333
|
+
num: 0,
|
|
1334
|
+
act: action === 'on' ? 1 : 0
|
|
1335
|
+
}],
|
|
1336
|
+
total: timerDuration,
|
|
1337
|
+
subDeviceNo: 0
|
|
1114
1338
|
};
|
|
1115
1339
|
const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', body, head);
|
|
1116
|
-
const success = this.checkResponse([response, status], '
|
|
1340
|
+
const success = this.checkResponse([response, status], 'setTimer');
|
|
1117
1341
|
if (success) {
|
|
1118
|
-
this.
|
|
1342
|
+
this.timer = { duration: timerDuration, action };
|
|
1119
1343
|
}
|
|
1120
|
-
|
|
1121
|
-
|
|
1344
|
+
return success;
|
|
1345
|
+
}
|
|
1346
|
+
/**
|
|
1347
|
+
* Clear timer
|
|
1348
|
+
*/
|
|
1349
|
+
async clearTimer() {
|
|
1350
|
+
if (!this.hasFeature('timer')) {
|
|
1351
|
+
const error = 'Timer not supported';
|
|
1352
|
+
logger_1.logger.error(`${error} for device: ${this.deviceName}`);
|
|
1353
|
+
throw new Error(error);
|
|
1354
|
+
}
|
|
1355
|
+
const [head, body] = this.buildApiDict('delTimerV2');
|
|
1356
|
+
body.payload.subDeviceNo = 0;
|
|
1357
|
+
body.payload.data = { id: 1, subDeviceNo: 0 };
|
|
1358
|
+
const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', body, head);
|
|
1359
|
+
const success = this.checkResponse([response, status], 'clearTimer');
|
|
1360
|
+
if (success) {
|
|
1361
|
+
this.timer = null;
|
|
1362
|
+
}
|
|
1363
|
+
return success;
|
|
1364
|
+
}
|
|
1365
|
+
/**
|
|
1366
|
+
* Set auto preference
|
|
1367
|
+
*/
|
|
1368
|
+
async setAutoPreference(preference = 'default', roomSize = 600) {
|
|
1369
|
+
if (!this.autoPreferences.includes(preference)) {
|
|
1370
|
+
logger_1.logger.debug(`Invalid preference: ${preference} - valid preferences are default, efficient, quiet`);
|
|
1371
|
+
return false;
|
|
1372
|
+
}
|
|
1373
|
+
const [head, body] = this.buildApiDict('setAutoPreference');
|
|
1374
|
+
body.payload.data = {
|
|
1375
|
+
autoPreference: preference,
|
|
1376
|
+
roomSize: roomSize
|
|
1377
|
+
};
|
|
1378
|
+
const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', body, head);
|
|
1379
|
+
const success = this.checkResponse([response, status], 'setAutoPreference');
|
|
1380
|
+
if (success) {
|
|
1381
|
+
this.details.auto_preference = preference;
|
|
1122
1382
|
}
|
|
1123
1383
|
return success;
|
|
1124
1384
|
}
|
|
1385
|
+
/**
|
|
1386
|
+
* Set light detection
|
|
1387
|
+
*/
|
|
1388
|
+
async setLightDetection(enabled) {
|
|
1389
|
+
const [head, body] = this.buildApiDict('setLightDetection');
|
|
1390
|
+
body.payload.data = {
|
|
1391
|
+
lightDetectionSwitch: enabled ? 1 : 0
|
|
1392
|
+
};
|
|
1393
|
+
const [response, status] = await this.callApi('/cloud/v2/deviceManaged/bypassV2', 'post', body, head);
|
|
1394
|
+
const success = this.checkResponse([response, status], 'setLightDetection');
|
|
1395
|
+
if (success) {
|
|
1396
|
+
this.details.light_detection_switch = enabled;
|
|
1397
|
+
}
|
|
1398
|
+
return success;
|
|
1399
|
+
}
|
|
1400
|
+
/**
|
|
1401
|
+
* Get light detection status
|
|
1402
|
+
*/
|
|
1403
|
+
get lightDetection() {
|
|
1404
|
+
return Boolean(this.details.light_detection_switch);
|
|
1405
|
+
}
|
|
1406
|
+
/**
|
|
1407
|
+
* Get light detection state
|
|
1408
|
+
*/
|
|
1409
|
+
get lightDetectionState() {
|
|
1410
|
+
return Boolean(this.details.environment_light_state);
|
|
1411
|
+
}
|
|
1412
|
+
/**
|
|
1413
|
+
* Get auto preference type
|
|
1414
|
+
*/
|
|
1415
|
+
get autoPreferenceType() {
|
|
1416
|
+
return this.details.auto_preference_type;
|
|
1417
|
+
}
|
|
1418
|
+
/**
|
|
1419
|
+
* Display JSON details
|
|
1420
|
+
*/
|
|
1421
|
+
displayJSON() {
|
|
1422
|
+
var _a, _b;
|
|
1423
|
+
const baseInfo = JSON.parse(super.displayJSON());
|
|
1424
|
+
const details = {
|
|
1425
|
+
...baseInfo,
|
|
1426
|
+
'Mode': this.mode,
|
|
1427
|
+
'Filter Life': this.details.filter_life.toString(),
|
|
1428
|
+
'Fan Level': this.speed.toString(),
|
|
1429
|
+
'Display On': this.details.display.toString(),
|
|
1430
|
+
'Child Lock': this.details.child_lock.toString(),
|
|
1431
|
+
'Display Set On': this.details.screen_switch.toString(),
|
|
1432
|
+
'Light Detection Enabled': this.details.light_detection_switch.toString(),
|
|
1433
|
+
'Environment Light State': this.details.environment_light_state.toString()
|
|
1434
|
+
};
|
|
1435
|
+
if (this.hasFeature('air_quality')) {
|
|
1436
|
+
details['Air Quality Level'] = ((_a = this.details.air_quality) !== null && _a !== void 0 ? _a : '').toString();
|
|
1437
|
+
details['Air Quality Value'] = ((_b = this.details.air_quality_value) !== null && _b !== void 0 ? _b : '').toString();
|
|
1438
|
+
}
|
|
1439
|
+
const everestKeys = {
|
|
1440
|
+
'pm1': 'PM1',
|
|
1441
|
+
'pm10': 'PM10',
|
|
1442
|
+
'fan_rotate_angle': 'Fan Rotate Angle',
|
|
1443
|
+
'filter_open_state': 'Filter Open State'
|
|
1444
|
+
};
|
|
1445
|
+
for (const [key, value] of Object.entries(everestKeys)) {
|
|
1446
|
+
if (key in this.details) {
|
|
1447
|
+
details[value] = this.details[key].toString();
|
|
1448
|
+
}
|
|
1449
|
+
}
|
|
1450
|
+
return JSON.stringify(details, null, 4);
|
|
1451
|
+
}
|
|
1125
1452
|
}
|
|
1126
1453
|
exports.VeSyncAirBaseV2 = VeSyncAirBaseV2;
|
|
1127
1454
|
/**
|
|
@@ -1134,20 +1461,35 @@ class VeSyncTowerFan extends VeSyncAirBaseV2 {
|
|
|
1134
1461
|
this.speeds = Array.from({ length: 12 }, (_, i) => i + 1);
|
|
1135
1462
|
logger_1.logger.debug(`Initialized VeSyncTowerFan device: ${this.deviceName}`);
|
|
1136
1463
|
}
|
|
1464
|
+
/**
|
|
1465
|
+
* Get timer status (in seconds)
|
|
1466
|
+
*/
|
|
1467
|
+
get timer() {
|
|
1468
|
+
const timerRemain = this.details.timerRemain || 0;
|
|
1469
|
+
return timerRemain > 0 ? { duration: timerRemain, action: 'off' } : null;
|
|
1470
|
+
}
|
|
1471
|
+
set timer(value) {
|
|
1472
|
+
if (value) {
|
|
1473
|
+
this.details.timerRemain = value.duration;
|
|
1474
|
+
}
|
|
1475
|
+
else {
|
|
1476
|
+
this.details.timerRemain = 0;
|
|
1477
|
+
}
|
|
1478
|
+
}
|
|
1137
1479
|
/**
|
|
1138
1480
|
* Build API dictionary
|
|
1139
1481
|
*/
|
|
1140
1482
|
buildApiDict(method) {
|
|
1141
1483
|
const head = helpers_1.Helpers.reqHeaderBypass();
|
|
1142
|
-
const body =
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1484
|
+
const body = {
|
|
1485
|
+
...helpers_1.Helpers.reqBody(this.manager, 'bypassV2'),
|
|
1486
|
+
cid: this.cid,
|
|
1487
|
+
configModule: this.configModule,
|
|
1488
|
+
payload: {
|
|
1489
|
+
method,
|
|
1490
|
+
source: 'APP',
|
|
1491
|
+
data: {}
|
|
1492
|
+
}
|
|
1151
1493
|
};
|
|
1152
1494
|
return [head, body];
|
|
1153
1495
|
}
|
|
@@ -1340,12 +1682,6 @@ class VeSyncTowerFan extends VeSyncAirBaseV2 {
|
|
|
1340
1682
|
get muteState() {
|
|
1341
1683
|
return Boolean(this.details.muteState);
|
|
1342
1684
|
}
|
|
1343
|
-
/**
|
|
1344
|
-
* Get timer status (in seconds)
|
|
1345
|
-
*/
|
|
1346
|
-
get timer() {
|
|
1347
|
-
return this.details.timerRemain || 0;
|
|
1348
|
-
}
|
|
1349
1685
|
/**
|
|
1350
1686
|
* Get temperature (in tenths of a degree)
|
|
1351
1687
|
*/
|
|
@@ -1455,22 +1791,25 @@ exports.fanModules = {
|
|
|
1455
1791
|
'LAP-C601S-WUS': VeSyncAirBypass,
|
|
1456
1792
|
'LAP-C601S-WUSR': VeSyncAirBypass,
|
|
1457
1793
|
'LAP-C601S-WEU': VeSyncAirBypass,
|
|
1458
|
-
|
|
1459
|
-
'LAP-V102S-
|
|
1460
|
-
'LAP-V102S-
|
|
1461
|
-
'LAP-V102S-
|
|
1462
|
-
'LAP-V102S-
|
|
1463
|
-
'LAP-
|
|
1464
|
-
|
|
1465
|
-
'LAP-V201S-
|
|
1466
|
-
'LAP-V201S-
|
|
1467
|
-
'LAP-
|
|
1468
|
-
'LAP-V201S-
|
|
1469
|
-
'LAP-
|
|
1470
|
-
'LAP-
|
|
1471
|
-
'LAP-
|
|
1472
|
-
|
|
1473
|
-
'LAP-EL551S-
|
|
1794
|
+
// Vital100S Series - Using VeSyncAirBaseV2
|
|
1795
|
+
'LAP-V102S-AASR': VeSyncAirBaseV2,
|
|
1796
|
+
'LAP-V102S-WUS': VeSyncAirBaseV2,
|
|
1797
|
+
'LAP-V102S-WEU': VeSyncAirBaseV2,
|
|
1798
|
+
'LAP-V102S-AUSR': VeSyncAirBaseV2,
|
|
1799
|
+
'LAP-V102S-WJP': VeSyncAirBaseV2,
|
|
1800
|
+
// Vital200S Series - Using VeSyncAirBaseV2
|
|
1801
|
+
'LAP-V201S-AASR': VeSyncAirBaseV2,
|
|
1802
|
+
'LAP-V201S-WJP': VeSyncAirBaseV2,
|
|
1803
|
+
'LAP-V201S-WEU': VeSyncAirBaseV2,
|
|
1804
|
+
'LAP-V201S-WUS': VeSyncAirBaseV2,
|
|
1805
|
+
'LAP-V201-AUSR': VeSyncAirBaseV2,
|
|
1806
|
+
'LAP-V201S-AUSR': VeSyncAirBaseV2,
|
|
1807
|
+
'LAP-V201S-AEUR': VeSyncAirBaseV2,
|
|
1808
|
+
// EverestAir Series - Using VeSyncAirBaseV2
|
|
1809
|
+
'LAP-EL551S-AUS': VeSyncAirBaseV2,
|
|
1810
|
+
'LAP-EL551S-AEUR': VeSyncAirBaseV2,
|
|
1811
|
+
'LAP-EL551S-WEU': VeSyncAirBaseV2,
|
|
1812
|
+
'LAP-EL551S-WUS': VeSyncAirBaseV2,
|
|
1474
1813
|
// LTF Series
|
|
1475
1814
|
'LTF-F422S-KEU': VeSyncTowerFan,
|
|
1476
1815
|
'LTF-F422S-WUSR': VeSyncTowerFan,
|
package/package.json
CHANGED
package/src/lib/vesync.ts
CHANGED
|
@@ -419,10 +419,25 @@ export class VeSync {
|
|
|
419
419
|
this
|
|
420
420
|
);
|
|
421
421
|
|
|
422
|
-
if (response
|
|
423
|
-
|
|
424
|
-
|
|
422
|
+
if (!response) {
|
|
423
|
+
logger.error('No response received from VeSync API');
|
|
424
|
+
return false;
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
if (response.error) {
|
|
428
|
+
logger.error('API error:', response.msg || 'Unknown error');
|
|
429
|
+
return false;
|
|
430
|
+
}
|
|
425
431
|
|
|
432
|
+
if (!response.result?.list) {
|
|
433
|
+
logger.error('No device list found in response');
|
|
434
|
+
return false;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
const deviceList = response.result.list;
|
|
438
|
+
success = this.processDevices(deviceList);
|
|
439
|
+
|
|
440
|
+
if (success) {
|
|
426
441
|
// Log device discovery results
|
|
427
442
|
logger.debug('\n=== Device Discovery Summary ===');
|
|
428
443
|
logger.debug(`Total devices processed: ${deviceList.length}`);
|
|
@@ -455,12 +470,16 @@ export class VeSync {
|
|
|
455
470
|
}
|
|
456
471
|
|
|
457
472
|
logger.debug('\n=== End of Device Discovery ===\n');
|
|
473
|
+
}
|
|
474
|
+
} catch (err) {
|
|
475
|
+
const error = err as { code?: string; message?: string };
|
|
476
|
+
if (error.code === 'ECONNABORTED') {
|
|
477
|
+
logger.error('VeSync API request timed out');
|
|
478
|
+
} else if (error.code === 'ECONNREFUSED') {
|
|
479
|
+
logger.error('Unable to connect to VeSync API');
|
|
458
480
|
} else {
|
|
459
|
-
logger.error('
|
|
460
|
-
logger.error(response.code, response.msg);
|
|
481
|
+
logger.error('Error getting device list:', error.message || 'Unknown error');
|
|
461
482
|
}
|
|
462
|
-
} catch (error) {
|
|
463
|
-
logger.error('Unable to get device list:', error);
|
|
464
483
|
}
|
|
465
484
|
|
|
466
485
|
this._inProcess = false;
|