homebridge-levoit-humidifiers
Version:
Homebridge plugin for Levoit Humidifiers
441 lines • 17.5 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Mode = void 0;
const async_lock_1 = __importDefault(require("async-lock"));
const deviceTypes_1 = __importStar(require("./deviceTypes"));
const VeSync_1 = require("./VeSync");
var Mode;
(function (Mode) {
Mode["Manual"] = "manual";
Mode["Sleep"] = "sleep";
Mode["Auto"] = "auto";
Mode["AutoPro"] = "autoPro";
Mode["Humidity"] = "humidity";
})(Mode = exports.Mode || (exports.Mode = {}));
class VeSyncFan {
get humidityLevel() {
return this._humidityLevel;
}
get targetHumidity() {
return this._targetHumidity;
}
get displayOn() {
return this._displayOn;
}
get brightnessLevel() {
return this._brightnessLevel;
}
get mistLevel() {
return this._mistLevel;
}
get warmLevel() {
return this._warmLevel;
}
get warmEnabled() {
return this._warmEnabled;
}
get lightOn() {
return this._lightOn;
}
get mode() {
return this._mode;
}
get targetReached() {
return this._targetReached;
}
get isOn() {
return this._isOn;
}
get getBlue() {
return this._blue;
}
get getGreen() {
return this._green;
}
get getColorMode() {
return this._colorMode;
}
get getColorSliderLocation() {
return this._colorSliderLocation;
}
get getLightSpeed() {
return this._lightSpeed;
}
get getRed() {
return this._red;
}
constructor(client, name, _mode, _isOn, _mistLevel, _warmLevel, _warmEnabled, _brightnessLevel, _humidityLevel, _targetHumidity, _targetReached, _lightOn, _lightSpeed, _red, _blue, _green, _colorMode, _colorSliderLocation, configModule, cid, region, model, mac, uuid) {
this.client = client;
this.name = name;
this._mode = _mode;
this._isOn = _isOn;
this._mistLevel = _mistLevel;
this._warmLevel = _warmLevel;
this._warmEnabled = _warmEnabled;
this._brightnessLevel = _brightnessLevel;
this._humidityLevel = _humidityLevel;
this._targetHumidity = _targetHumidity;
this._targetReached = _targetReached;
this._lightOn = _lightOn;
this._lightSpeed = _lightSpeed;
this._red = _red;
this._blue = _blue;
this._green = _green;
this._colorMode = _colorMode;
this._colorSliderLocation = _colorSliderLocation;
this.configModule = configModule;
this.cid = cid;
this.region = region;
this.model = model;
this.mac = mac;
this.uuid = uuid;
this.lock = new async_lock_1.default();
this.lastCheck = 0;
this._displayOn = true;
this.manufacturer = 'Levoit';
this.deviceType = deviceTypes_1.default.find(({ isValid }) => isValid(this.model));
}
async setPower(power) {
this.client.log.info('Setting Power to ' + power);
let switchJson;
if (deviceTypes_1.NewDevices.includes(this.model)) {
switchJson = {
powerSwitch: power ? 1 : 0,
id: 0,
};
}
else {
switchJson = {
enabled: power,
id: 0,
};
}
const success = await this.client.sendCommand(this, VeSync_1.BypassMethod.SWITCH, switchJson);
if (success) {
this._isOn = power;
if (!this._isOn) {
this._humidityLevel = 0;
this._targetHumidity = 0;
this._mistLevel = 0;
this._warmLevel = 0;
}
}
else {
this.client.log.error('Failed to setPower due to unreachable device.');
if (this.client.config.options.showOffWhenDisconnected) {
this._isOn = false;
this._humidityLevel = 0;
this._targetHumidity = 0;
this._displayOn = false;
this._mistLevel = 0;
this._warmLevel = 0;
this._brightnessLevel = 0;
this._lightOn = 'off';
}
else {
return false;
}
}
return success;
}
async setTargetHumidity(level) {
this.client.log.info('Setting Target Humidity to ' + level);
// Oasis 1000 uses camelcase instead of snakecase
let humidityJson;
if (deviceTypes_1.NewDevices.includes(this.model)) {
humidityJson = {
targetHumidity: level,
id: 0,
};
}
else {
humidityJson = {
target_humidity: level,
id: 0,
};
}
const success = await this.client.sendCommand(this, VeSync_1.BypassMethod.HUMIDITY, humidityJson);
if (success) {
this._targetHumidity = level;
}
return success;
}
async changeMode(mode) {
// LV600s models use "Humidity" mode instead of "Auto"
const humidity_models = [
deviceTypes_1.DeviceName.LV600S,
deviceTypes_1.DeviceName.LV600S_REMOTE,
deviceTypes_1.DeviceName.LV600S_EU,
deviceTypes_1.DeviceName.LV600S_UK,
deviceTypes_1.DeviceName.LV600S_JP,
];
if (humidity_models.includes(this.model) &&
mode == Mode.Auto) {
mode = Mode.Humidity;
}
// Some models use "AutoPro" mode instead of "Auto"
if (this.deviceType.hasAutoProMode && mode == Mode.Auto) {
mode = Mode.AutoPro;
}
let success;
// Oasis 1000 uses camelcase instead of snakecase
let modeJson;
if (deviceTypes_1.NewDevices.includes(this.model)) {
modeJson = {
workMode: mode.toString(),
};
}
else {
modeJson = {
mode: mode.toString(),
};
}
// Don't change the mode if we are already in that mode
if (this._mode == mode) {
success = true;
}
else {
this.client.log.info('Changing Mode to ' + mode);
success = await this.client.sendCommand(this, VeSync_1.BypassMethod.MODE, modeJson);
}
if (success) {
this._mode = mode;
}
return success;
}
async setBrightness(brightness) {
this.client.log.info('Setting Night Light to ' + brightness);
const success = await this.client.sendCommand(this, VeSync_1.BypassMethod.NIGHT_LIGHT_BRIGHTNESS, {
night_light_brightness: brightness,
});
if (success) {
this._brightnessLevel = brightness;
}
return success;
}
async setDisplay(power) {
this.client.log.info('Setting Display to ' + power);
// Oasis 1000 uses camelcase instead of snakecase
let displayJson;
if (deviceTypes_1.NewDevices.includes(this.model)) {
displayJson = {
screenSwitch: power ? 1 : 0,
id: 0,
};
}
else {
displayJson = {
state: power,
id: 0,
};
}
const success = await this.client.sendCommand(this, VeSync_1.BypassMethod.DISPLAY, displayJson);
if (success) {
this._displayOn = power;
}
return success;
}
async changeMistLevel(mistLevel) {
if (mistLevel > this.deviceType.mistLevels || mistLevel < 1) {
return false;
}
this.client.log.info('Setting Mist Level to ' + mistLevel);
// New models use different JSON keys
let mistJson;
const method = VeSync_1.BypassMethod.MIST_LEVEL;
if (deviceTypes_1.NewDevices.includes(this.model)) {
mistJson = {
virtualLevel: mistLevel,
levelType: 'mist',
id: 0,
};
}
else {
mistJson = {
level: mistLevel,
type: 'mist',
id: 0,
};
}
const success = await this.client.sendCommand(this, method, mistJson);
if (success) {
this._mistLevel = mistLevel;
}
return success;
}
async changeWarmMistLevel(warmMistLevel) {
if (!this.deviceType.warmMistLevels) {
this.client.log.error('Error: Attempted to set warm level on device without warmMistLevels field.');
return false;
}
if (warmMistLevel > this.deviceType.warmMistLevels || warmMistLevel < 0) {
return false;
}
this.client.log.info('Setting Warm Level to ' + warmMistLevel);
const success = await this.client.sendCommand(this, VeSync_1.BypassMethod.LEVEL, {
level: warmMistLevel,
type: 'warm',
id: 0,
});
if (success) {
this._warmLevel = warmMistLevel;
if (this._warmLevel == 0) {
this._warmEnabled = false;
}
else {
this._warmEnabled = true;
}
}
return success;
}
async setLightStatus(action, brightness) {
// Get the current RGB values and brightness %
const red = this.getRed;
const green = this.getGreen;
const blue = this.getBlue;
const currentBrightness = this.brightnessLevel;
let newRed;
let newGreen;
let newBlue;
// If we're changing brightness, calculate the RGB values to adjust to
if (brightness !== this._brightnessLevel) {
newRed = Math.round(red * (brightness / currentBrightness));
newGreen = Math.round(green * (brightness / currentBrightness));
newBlue = Math.round(blue * (brightness / currentBrightness));
}
const lightJson = {
action: action,
speed: this.getLightSpeed,
red: newRed || this.getRed,
green: newGreen || this.getGreen,
blue: newBlue || this.getBlue,
brightness: brightness,
colorMode: this.getColorMode,
colorSliderLocation: this.getColorSliderLocation,
};
this.client.log.debug('Setting Night Light Status to ' + JSON.stringify(lightJson));
const success = await this.client.sendCommand(this, VeSync_1.BypassMethod.LIGHT_STATUS, lightJson);
if (success) {
this._brightnessLevel = brightness;
this._blue = newBlue || this.getBlue;
this._green = newGreen || this.getGreen;
this._red = newRed || this.getRed;
this._lightOn = action;
}
return success;
}
async updateInfo() {
return this.lock.acquire('update-info', async () => {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
try {
if (Date.now() - this.lastCheck < 5 * 1000) {
return;
}
const data = await this.client.getDeviceInfo(this);
this.lastCheck = Date.now();
if (!((_a = data === null || data === void 0 ? void 0 : data.result) === null || _a === void 0 ? void 0 : _a.result) &&
this.client.config.options.showOffWhenDisconnected) {
this._isOn = false;
this._humidityLevel = 0;
this._targetHumidity = 0;
this._displayOn = false;
this._mistLevel = 0;
this._warmLevel = 0;
this._brightnessLevel = 0;
return;
}
else if (!((_b = data === null || data === void 0 ? void 0 : data.result) === null || _b === void 0 ? void 0 : _b.result)) {
return;
}
const result = (_c = data === null || data === void 0 ? void 0 : data.result) === null || _c === void 0 ? void 0 : _c.result;
this._humidityLevel = result.humidity;
// Fields are different on newer models
if (deviceTypes_1.NewDevices.includes(this.model)) {
this._targetHumidity = result.targetHumidity;
this._displayOn = result.screenSwitch;
this._mode = result.workMode;
this._isOn = result.powerSwitch;
this._targetReached = result.autoStopState;
this._mistLevel = result.virtualLevel;
}
else {
this._targetHumidity = (_d = result.configuration) === null || _d === void 0 ? void 0 : _d.auto_target_humidity;
this._displayOn = result.display;
this._mode = result.mode;
this._isOn = result.enabled;
this._targetReached = result.automatic_stop_reach_target;
this._mistLevel = result.mist_virtual_level;
}
this._warmLevel = result.warm_level;
this._warmEnabled = result.warm_enabled;
this._brightnessLevel =
(_e = result.night_light_brightness) !== null && _e !== void 0 ? _e : (_f = result.rgbNightLight) === null || _f === void 0 ? void 0 : _f.brightness;
// RGB Light Devices Only:
this._lightOn = (_g = result.rgbNightLight) === null || _g === void 0 ? void 0 : _g.action;
this._blue = (_h = result.rgbNightLight) === null || _h === void 0 ? void 0 : _h.blue;
this._green = (_j = result.rgbNightLight) === null || _j === void 0 ? void 0 : _j.green;
this._red = (_k = result.rgbNightLight) === null || _k === void 0 ? void 0 : _k.red;
this._colorMode = (_l = result.rgbNightLight) === null || _l === void 0 ? void 0 : _l.colorMode;
this._lightSpeed = (_m = result.rgbNightLight) === null || _m === void 0 ? void 0 : _m.speed;
this._colorSliderLocation = (_o = result.rgbNightLight) === null || _o === void 0 ? void 0 : _o.colorSliderLocation;
if (result.rgbNightLight) {
const lightJson = {
action: this._lightOn,
speed: this._lightSpeed,
green: this._green,
blue: this._blue,
red: this._red,
brightness: this._brightnessLevel,
colorMode: this._colorMode,
colorSliderLocation: this._colorSliderLocation,
};
this.client.debugMode.debug('[GET LIGHT JSON]', JSON.stringify(lightJson));
}
}
catch (err) {
this.client.log.error('Failed to updateInfo due to unreachable device: ' + (err === null || err === void 0 ? void 0 : err.message));
if (this.client.config.options.showOffWhenDisconnected) {
this._isOn = false;
this._humidityLevel = 0;
this._targetHumidity = 0;
this._displayOn = false;
this._mistLevel = 0;
this._warmLevel = 0;
this._brightnessLevel = 0;
}
else {
throw new Error('Device was unreachable. Ensure it is plugged in and connected to WiFi.');
}
}
});
}
}
exports.default = VeSyncFan;
VeSyncFan.fromResponse = (client) => ({ deviceName, mode, deviceStatus, mistLevel, warmLevel, warmEnabled, brightnessLevel, humidity, targetHumidity, targetReached, lightOn, lightSpeed, red, blue, green, colorMode, colorSliderLocation, configModule, cid, deviceRegion, deviceType, macID, uuid, }) => new VeSyncFan(client, deviceName, mode, deviceStatus, mistLevel, warmLevel, warmEnabled, brightnessLevel, humidity, targetHumidity, targetReached, lightOn, lightSpeed, red, blue, green, colorMode, colorSliderLocation, configModule, cid, deviceRegion, deviceType, macID, uuid);
//# sourceMappingURL=VeSyncFan.js.map