UNPKG

tsvesync

Version:

A TypeScript library for interacting with VeSync smart home devices

447 lines (446 loc) 17.8 kB
"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;