tsvesync
Version:
A TypeScript library for interacting with VeSync smart home devices
447 lines (446 loc) • 17.8 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.VeSyncAir131 = void 0;
const vesyncFan_1 = require("../vesyncFan");
const logger_1 = require("../logger");
/**
* VeSync Air Purifier 131 Series (LV-PUR131S, LV-RH131S)
* This class implements the specific API for LV series devices
*/
class VeSyncAir131 extends vesyncFan_1.VeSyncFan {
constructor(details, manager) {
super(details, manager);
this.modes = ['auto', 'manual', 'sleep'];
this.displayModes = ['on', 'off'];
this.childLockModes = ['on', 'off'];
logger_1.logger.debug(`Initialized VeSyncAir131 device: ${this.deviceName}`);
}
/**
* Get device details
*/
async getDetails() {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
logger_1.logger.debug(`Getting details for device: ${this.deviceName}`);
const [response, status] = await this.callApi('/131airPurifier/v1/device/devicedetail', 'post', {
acceptLanguage: 'en',
accountID: this.manager.accountId,
appVersion: '2.8.6',
method: 'devicedetail',
mobileId: '1234567890123456',
phoneBrand: 'SM N9005',
phoneOS: 'Android',
timeZone: this.manager.timeZone,
token: this.manager.token,
uuid: this.uuid
}, {
'accept-language': 'en',
'accountId': this.manager.accountId,
'appVersion': '2.8.6',
'content-type': 'application/json',
'tk': this.manager.token,
'tz': this.manager.timeZone
});
const success = this.checkResponse([response, status], 'getDetails');
if (success && response) {
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';
this.details = {
mode: ((_d = (_c = response.result) === null || _c === void 0 ? void 0 : _c.result) === null || _d === void 0 ? void 0 : _d.mode) || '',
speed: ((_f = (_e = response.result) === null || _e === void 0 ? void 0 : _e.result) === null || _f === void 0 ? void 0 : _f.level) || 0,
filterLife: ((_h = (_g = response.result) === null || _g === void 0 ? void 0 : _g.result) === null || _h === void 0 ? void 0 : _h.filterLife) || 0,
screenStatus: ((_k = (_j = response.result) === null || _j === void 0 ? void 0 : _j.result) === null || _k === void 0 ? void 0 : _k.display) ? 'on' : 'off',
childLock: ((_m = (_l = response.result) === null || _l === void 0 ? void 0 : _l.result) === null || _m === void 0 ? void 0 : _m.childLock) || false,
airQuality: ((_p = (_o = response.result) === null || _o === void 0 ? void 0 : _o.result) === null || _p === void 0 ? void 0 : _p.airQuality) || 0,
active_time: ((_r = (_q = response.result) === null || _q === void 0 ? void 0 : _q.result) === null || _r === void 0 ? void 0 : _r.activeTime) || 0
};
return true;
}
return false;
}
/**
* Turn device on
*/
async turnOn() {
logger_1.logger.info(`Turning on device: ${this.deviceName}`);
const [response, status] = await this.callApi('/131airPurifier/v1/device/deviceStatus', 'put', {
acceptLanguage: 'en',
accountID: this.manager.accountId,
status: 'on',
timeZone: this.manager.timeZone,
token: this.manager.token,
uuid: this.uuid
}, {
'accept-language': 'en',
'accountId': this.manager.accountId,
'appVersion': '2.8.6',
'content-type': 'application/json',
'tk': this.manager.token,
'tz': this.manager.timeZone
});
const success = this.checkResponse([response, status], 'turnOn');
if (!success) {
logger_1.logger.error(`Failed to turn on device: ${this.deviceName}`);
}
return success;
}
/**
* Turn device off
*/
async turnOff() {
logger_1.logger.info(`Turning off device: ${this.deviceName}`);
const [response, status] = await this.callApi('/131airPurifier/v1/device/deviceStatus', 'put', {
acceptLanguage: 'en',
accountID: this.manager.accountId,
status: 'off',
timeZone: this.manager.timeZone,
token: this.manager.token,
uuid: this.uuid
}, {
'accept-language': 'en',
'accountId': this.manager.accountId,
'appVersion': '2.8.6',
'content-type': 'application/json',
'tk': this.manager.token,
'tz': this.manager.timeZone
});
const success = this.checkResponse([response, status], 'turnOff');
if (!success) {
logger_1.logger.error(`Failed to turn off device: ${this.deviceName}`);
}
return success;
}
/**
* Change fan speed
*/
async changeFanSpeed(speed) {
logger_1.logger.info(`Changing fan speed to ${speed} for device: ${this.deviceName}`);
// Check if device is in manual mode
if (this.details.mode !== 'manual') {
logger_1.logger.debug(`${this.deviceName} not in manual mode, cannot change speed`);
return false;
}
// Validate speed for LV series (1-3)
if (speed < 1 || speed > 3) {
logger_1.logger.error(`Invalid fan speed: ${speed}. Must be between 1 and 3 for device: ${this.deviceName}`);
return false;
}
const [response, status] = await this.callApi('/131airPurifier/v1/device/updateSpeed', 'put', {
acceptLanguage: 'en',
accountID: this.manager.accountId,
level: speed,
timeZone: this.manager.timeZone,
token: this.manager.token,
uuid: this.uuid
}, {
'accept-language': 'en',
'accountId': this.manager.accountId,
'appVersion': '2.8.6',
'content-type': 'application/json',
'tk': this.manager.token,
'tz': this.manager.timeZone
});
const success = this.checkResponse([response, status], 'changeFanSpeed');
if (success) {
this.details.speed = speed;
return true;
}
else {
logger_1.logger.error(`Failed to change fan speed to ${speed} for device: ${this.deviceName}`);
return false;
}
}
/**
* Set device mode
*/
async setMode(mode) {
if (!this.modes.includes(mode)) {
const error = `Invalid mode: ${mode}. Must be one of: ${this.modes.join(', ')}`;
logger_1.logger.error(`${error} for device: ${this.deviceName}`);
throw new Error(error);
}
logger_1.logger.debug(`Setting mode to ${mode} for device: ${this.deviceName}`);
const payload = {
acceptLanguage: 'en',
accountID: this.manager.accountId,
mode: mode,
timeZone: this.manager.timeZone,
token: this.manager.token,
uuid: this.uuid
};
// For manual mode, we need to set the level
if (mode === 'manual') {
payload.level = this.details.speed || 1;
}
const [response, status] = await this.callApi('/131airPurifier/v1/device/updateMode', 'put', payload, {
'accept-language': 'en',
'accountId': this.manager.accountId,
'appVersion': '2.8.6',
'content-type': 'application/json',
'tk': this.manager.token,
'tz': this.manager.timeZone
});
const success = this.checkResponse([response, status], 'setMode');
if (success) {
this.details.mode = mode;
return true;
}
else {
logger_1.logger.error(`Failed to set mode to ${mode} for device: ${this.deviceName}`);
return false;
}
}
/**
* Set display status
*/
async setDisplay(enabled) {
if (!this.hasFeature('display')) {
const error = 'Display control not supported';
logger_1.logger.error(`${error} for device: ${this.deviceName}`);
throw new Error(error);
}
// Check if device is in sleep mode - display control may not work in sleep mode
if (this.details.mode === 'sleep') {
logger_1.logger.warn(`Device ${this.deviceName} is in sleep mode, display control may not work`);
}
logger_1.logger.debug(`Setting display to ${enabled ? 'on' : 'off'} for device: ${this.deviceName}`);
const [response, status] = await this.callApi('/131airPurifier/v1/device/updateScreen', 'put', {
acceptLanguage: 'en',
accountID: this.manager.accountId,
status: enabled ? 'on' : 'off',
timeZone: this.manager.timeZone,
token: this.manager.token,
uuid: this.uuid
}, {
'accept-language': 'en',
'accountId': this.manager.accountId,
'appVersion': '2.8.6',
'content-type': 'application/json',
'tk': this.manager.token,
'tz': this.manager.timeZone
});
const success = this.checkResponse([response, status], 'setDisplay');
if (success) {
this.details.screenStatus = enabled ? 'on' : 'off';
return true;
}
else {
logger_1.logger.error(`Failed to set display to ${enabled ? 'on' : 'off'} for device: ${this.deviceName}`);
return false;
}
}
/**
* Set child lock
*/
async setChildLock(enabled) {
if (!this.hasFeature('child_lock')) {
const error = 'Child lock not supported';
logger_1.logger.error(`${error} for device: ${this.deviceName}`);
throw new Error(error);
}
// Check if device is in sleep mode - child lock may not work in sleep mode
if (this.details.mode === 'sleep') {
logger_1.logger.warn(`Device ${this.deviceName} is in sleep mode, child lock control may not work`);
}
logger_1.logger.debug(`Setting child lock to ${enabled ? 'on' : 'off'} for device: ${this.deviceName}`);
const [response, status] = await this.callApi('/131airPurifier/v1/device/updateChildLock', 'put', {
acceptLanguage: 'en',
accountID: this.manager.accountId,
status: enabled ? 'on' : 'off',
timeZone: this.manager.timeZone,
token: this.manager.token,
uuid: this.uuid
}, {
'accept-language': 'en',
'accountId': this.manager.accountId,
'appVersion': '2.8.6',
'content-type': 'application/json',
'tk': this.manager.token,
'tz': this.manager.timeZone
});
const success = this.checkResponse([response, status], 'setChildLock');
if (success) {
this.details.childLock = enabled;
return true;
}
else {
// Check for error code 11000000 (feature not supported)
if ((response === null || response === void 0 ? void 0 : response.code) === 11000000) {
logger_1.logger.warn(`Child lock control not supported via API for device: ${this.deviceName}`);
return false;
}
logger_1.logger.error(`Failed to set child lock to ${enabled ? 'on' : 'off'} for device: ${this.deviceName}`);
return false;
}
}
/**
* Set timer
*/
async setTimer(hours) {
if (!this.hasFeature('timer')) {
const error = 'Timer not supported';
logger_1.logger.error(`${error} for device: ${this.deviceName}`);
throw new Error(error);
}
logger_1.logger.debug(`Setting timer to ${hours} hours for device: ${this.deviceName}`);
const [response, status] = await this.callApi('/131airPurifier/v1/device/updateTimer', 'put', {
acceptLanguage: 'en',
accountID: this.manager.accountId,
action: 'off',
duration: hours,
timeZone: this.manager.timeZone,
token: this.manager.token,
uuid: this.uuid
}, {
'accept-language': 'en',
'accountId': this.manager.accountId,
'appVersion': '2.8.6',
'content-type': 'application/json',
'tk': this.manager.token,
'tz': this.manager.timeZone
});
const success = this.checkResponse([response, status], 'setTimer');
if (success) {
this.timer = { duration: hours * 3600, action: 'off' };
return true;
}
else {
logger_1.logger.error(`Failed to set timer to ${hours} hours for device: ${this.deviceName}`);
return false;
}
}
/**
* Clear timer
*/
async clearTimer() {
if (!this.hasFeature('timer')) {
const error = 'Timer not supported';
logger_1.logger.error(`${error} for device: ${this.deviceName}`);
throw new Error(error);
}
// If no timer is set, return success
if (!this.timer) {
logger_1.logger.debug(`No timer to clear for device: ${this.deviceName}`);
return true;
}
logger_1.logger.debug(`Clearing timer for device: ${this.deviceName}`);
const [response, status] = await this.callApi('/131airPurifier/v1/device/cancelTimer', 'put', {
acceptLanguage: 'en',
accountID: this.manager.accountId,
timeZone: this.manager.timeZone,
token: this.manager.token,
uuid: this.uuid
}, {
'accept-language': 'en',
'accountId': this.manager.accountId,
'appVersion': '2.8.6',
'content-type': 'application/json',
'tk': this.manager.token,
'tz': this.manager.timeZone
});
const success = this.checkResponse([response, status], 'clearTimer');
if (success) {
this.timer = null;
return true;
}
else {
logger_1.logger.error(`Failed to clear timer for device: ${this.deviceName}`);
return false;
}
}
/**
* Set auto mode
*/
async autoMode() {
logger_1.logger.debug(`Setting auto mode for device: ${this.deviceName}`);
const success = await this.setMode('auto');
if (!success) {
logger_1.logger.error(`Failed to set auto mode for device: ${this.deviceName}`);
}
return success;
}
/**
* Set manual mode
*/
async manualMode() {
logger_1.logger.debug(`Setting manual mode for device: ${this.deviceName}`);
const success = await this.setMode('manual');
if (!success) {
logger_1.logger.error(`Failed to set manual mode for device: ${this.deviceName}`);
}
return success;
}
/**
* Set sleep mode
*/
async sleepMode() {
logger_1.logger.debug(`Setting sleep mode for device: ${this.deviceName}`);
const success = await this.setMode('sleep');
if (!success) {
logger_1.logger.error(`Failed to set sleep mode for device: ${this.deviceName}`);
}
return success;
}
/**
* Turn off display
*/
async turnOffDisplay() {
logger_1.logger.debug(`Turning off display for device: ${this.deviceName}`);
const success = await this.setDisplay(false);
if (!success) {
logger_1.logger.error(`Failed to turn off display for device: ${this.deviceName}`);
}
return success;
}
/**
* Turn on display
*/
async turnOnDisplay() {
logger_1.logger.debug(`Turning on display for device: ${this.deviceName}`);
const success = await this.setDisplay(true);
if (!success) {
logger_1.logger.error(`Failed to turn on display for device: ${this.deviceName}`);
}
return success;
}
/**
* Get active time in minutes
*/
get activeTime() {
return this.details.active_time || 0;
}
/**
* Display device info
*/
display() {
super.display();
const info = [
['Mode: ', this.mode],
['Speed: ', this.speed],
['Filter Life: ', this.filterLife, '%'],
['Screen Status: ', this.screenStatus],
['Child Lock: ', this.childLock ? 'Enabled' : 'Disabled'],
['Air Quality: ', this.airQuality],
['Active Time: ', this.activeTime, 'minutes']
];
for (const [key, value, unit = ''] of info) {
logger_1.logger.info(`${key.toString().padEnd(30, '.')} ${value}${unit}`);
}
}
/**
* Return JSON details for device
*/
displayJSON() {
const baseInfo = JSON.parse(super.displayJSON());
const details = {
...baseInfo,
'Mode': this.mode,
'Speed': this.speed.toString(),
'Filter Life': this.filterLife.toString(),
'Screen Status': this.screenStatus,
'Child Lock': this.childLock ? 'Enabled' : 'Disabled',
'Air Quality': this.airQuality,
'Active Time': this.activeTime.toString()
};
return JSON.stringify(details, null, 4);
}
}
exports.VeSyncAir131 = VeSyncAir131;