homebridge-tsvesync
Version:
Homebridge plugin for VeSync devices including Levoit air purifiers, humidifiers, and Etekcity smart outlets
175 lines • 7.09 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.LightAccessory = void 0;
const base_accessory_1 = require("./base.accessory");
// Constants for color temperature
const MIN_COLOR_TEMP = 140; // 7143K (cool)
const MAX_COLOR_TEMP = 500; // 2000K (warm)
const DEFAULT_COLOR_TEMP = MIN_COLOR_TEMP;
class LightAccessory extends base_accessory_1.BaseAccessory {
constructor(platform, accessory, device) {
super(platform, accessory, device);
this.device = device;
this.capabilities = this.getDeviceCapabilities();
}
setupService() {
// Get or create the light service
this.service = this.accessory.getService(this.platform.Service.Lightbulb) ||
this.accessory.addService(this.platform.Service.Lightbulb);
// Set up required characteristics
this.setupCharacteristic(this.platform.Characteristic.On, this.getOn.bind(this), this.setOn.bind(this));
// Set up optional characteristics based on device capabilities
const capabilities = this.getDeviceCapabilities();
if (capabilities.hasBrightness) {
this.setupCharacteristic(this.platform.Characteristic.Brightness, this.getBrightness.bind(this), this.setBrightness.bind(this));
}
if (capabilities.hasColorTemp) {
this.setupColorTemperature();
}
if (capabilities.hasColor) {
this.setupColor();
}
// Add Name characteristic
this.setupCharacteristic(this.platform.Characteristic.Name, async () => this.device.deviceName);
}
setupColorTemperature() {
this.service.getCharacteristic(this.platform.Characteristic.ColorTemperature)
.setProps({
minValue: MIN_COLOR_TEMP,
maxValue: MAX_COLOR_TEMP,
});
this.setupCharacteristic(this.platform.Characteristic.ColorTemperature, this.getColorTemperature.bind(this), this.setColorTemperature.bind(this));
}
setupColor() {
this.setupCharacteristic(this.platform.Characteristic.Hue, this.getHue.bind(this), this.setHue.bind(this));
this.setupCharacteristic(this.platform.Characteristic.Saturation, this.getSaturation.bind(this), this.setSaturation.bind(this));
}
/**
* Update device states based on the latest details
*/
async updateDeviceSpecificStates(details) {
const lightDetails = details;
// Update active state
const isActive = lightDetails.deviceStatus === 'on';
this.updateCharacteristicValue(this.platform.Characteristic.On, isActive);
// Update brightness if supported
if (this.capabilities.hasBrightness && lightDetails.brightness !== undefined) {
this.updateCharacteristicValue(this.platform.Characteristic.Brightness, lightDetails.brightness);
}
// Update color temperature if supported
if (this.capabilities.hasColorTemp && lightDetails.colorTemp !== undefined) {
this.updateCharacteristicValue(this.platform.Characteristic.ColorTemperature, lightDetails.colorTemp);
}
// Update color if supported
if (this.capabilities.hasColor) {
if (lightDetails.hue !== undefined) {
this.updateCharacteristicValue(this.platform.Characteristic.Hue, lightDetails.hue);
}
if (lightDetails.saturation !== undefined) {
this.updateCharacteristicValue(this.platform.Characteristic.Saturation, lightDetails.saturation);
}
}
}
getDeviceCapabilities() {
// Determine capabilities based on model
const model = this.device.deviceType.toUpperCase();
return {
hasBrightness: true,
hasColorTemp: model.includes('CW') || model.includes('MC'),
hasColor: model.includes('MC') || model === 'XYD0001',
hasSpeed: false,
hasHumidity: false,
hasAirQuality: false,
hasWaterLevel: false,
hasChildLock: false,
hasSwingMode: false,
};
}
async getOn() {
return this.device.deviceStatus === 'on';
}
async setOn(value) {
try {
const isOn = value;
const success = isOn ? await this.device.turnOn() : await this.device.turnOff();
if (!success) {
throw new Error(`Failed to turn ${isOn ? 'on' : 'off'} device`);
}
await this.persistDeviceState('deviceStatus', isOn ? 'on' : 'off');
}
catch (error) {
this.handleDeviceError('set on state', error);
}
}
async getBrightness() {
return this.device.brightness;
}
async setBrightness(value) {
try {
const success = await this.device.setBrightness(value);
if (!success) {
throw new Error(`Failed to set brightness to ${value}`);
}
await this.persistDeviceState('brightness', value);
}
catch (error) {
this.handleDeviceError('set brightness', error);
}
}
async getColorTemperature() {
return this.device.colorTemp || DEFAULT_COLOR_TEMP;
}
async setColorTemperature(value) {
try {
if (!this.device.setColorTemperature) {
throw new Error('Device does not support color temperature');
}
const success = await this.device.setColorTemperature(value);
if (!success) {
throw new Error(`Failed to set color temperature to ${value}`);
}
await this.persistDeviceState('colorTemp', value);
}
catch (error) {
this.handleDeviceError('set color temperature', error);
}
}
async getHue() {
return this.device.hue || 0;
}
async getSaturation() {
return this.device.saturation || 0;
}
async setHue(value) {
try {
if (!this.device.setColor) {
throw new Error('Device does not support color');
}
const success = await this.device.setColor(value, this.device.saturation || 0);
if (!success) {
throw new Error(`Failed to set hue to ${value}`);
}
await this.persistDeviceState('hue', value);
}
catch (error) {
this.handleDeviceError('set hue', error);
}
}
async setSaturation(value) {
try {
if (!this.device.setColor) {
throw new Error('Device does not support color');
}
const success = await this.device.setColor(this.device.hue || 0, value);
if (!success) {
throw new Error(`Failed to set saturation to ${value}`);
}
await this.persistDeviceState('saturation', value);
}
catch (error) {
this.handleDeviceError('set saturation', error);
}
}
}
exports.LightAccessory = LightAccessory;
//# sourceMappingURL=light.accessory.js.map