UNPKG

homebridge-bond

Version:

A homebridge plugin to control your Bond devices over the v2 API.

345 lines (344 loc) 15 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.CeilingFanAccessory = void 0; const Device_1 = require("../interface/Device"); const Services_1 = require("../Services"); const Observer_1 = require("../Observer"); class CeilingFanAccessory { constructor(platform, accessory, bond) { const config = platform.config; this.platform = platform; this.accessory = accessory; const fanSpeedValues = config.fan_speed_values; const includeDimmer = config.include_dimmer; const includeToggle = config.include_toggle_state; const device = accessory.context.device; this.values = Device_1.Device.fanSpeeds(device); this.minStep = Math.floor(100 / this.values.length); this.maxValue = this.minStep * this.values.length; if (fanSpeedValues) { this.minStep = 1; this.maxValue = this.values.length; } this.fanService = new Services_1.FanService(platform, accessory); if (device.properties.max_speed === undefined) { if (Device_1.Device.canIncreaseDecreaseSpeed(device)) { this.increaseSpeedService = new Services_1.ButtonService(platform, accessory, `${accessory.displayName} Increase Speed`, 'IncreaseSpeed'); this.decreaseSpeedService = new Services_1.ButtonService(platform, accessory, `${accessory.displayName} Decrease Speed`, 'DecreaseSpeed'); } else { this.removeService(`${accessory.displayName} Increase Speed`); this.removeService(`${accessory.displayName} Decrease Speed`); this.platform.error(accessory, 'Fan Speed is not supported (missing max_speed property or IncreaseSpeed/DescreaseSpeed actions).'); } } if (Device_1.Device.CFhasUpDownLight(device)) { this.upLightService = new Services_1.LightbulbService(platform, accessory, `${accessory.displayName} Up Light`, 'UpLight'); this.downLightService = new Services_1.LightbulbService(platform, accessory, `${accessory.displayName} Down Light`, 'DownLight'); if (includeToggle) { this.toggleUpLightService = new Services_1.ButtonService(platform, accessory, 'Toggle Up Light State', 'ToggleUpLight'); this.toggleDownLightService = new Services_1.ButtonService(platform, accessory, 'Toggle Down Light State', 'ToggleDownLight'); } else { // Remove services if previously added this.removeService('Toggle Up Light State'); this.removeService('Toggle Down Light State'); } if (includeDimmer && Device_1.Device.HasDimmer(device)) { this.upLightDimmerService = new Services_1.SwitchService(platform, accessory, `${accessory.displayName} Up Light Dimmer`, 'UpLight'); this.downLightDimmerService = new Services_1.SwitchService(platform, accessory, `${accessory.displayName} Down Light Dimmer`, 'DownLight'); } else { // Remove services if previously added this.removeService(`${accessory.displayName} Up Light Dimmer`); this.removeService(`${accessory.displayName} Down Light Dimmer`); } } else if (Device_1.Device.CFhasLightbulb(device)) { this.lightService = new Services_1.LightbulbService(platform, accessory, `${accessory.displayName} Light`); if (includeToggle) { this.toggleLightService = new Services_1.ButtonService(platform, accessory, 'Toggle Light State', 'ToggleState'); } else { this.removeService('Toggle Light State'); } if (includeDimmer && Device_1.Device.HasDimmer(device)) { this.dimmerService = new Services_1.SwitchService(platform, accessory, `${accessory.displayName} Dimmer`, 'Dimmer'); } else { // Remove service if previously added this.removeService(`${accessory.displayName} Dimmer`); } } if (includeDimmer && Device_1.Device.HasSeparateDimmers(device)) { this.increaseBrightnessService = new Services_1.SwitchService(platform, accessory, `${accessory.displayName} Increase Brightness`, 'IncreaseBrightness'); this.decreaseBrightnessService = new Services_1.SwitchService(platform, accessory, `${accessory.displayName} Decrease Brightness`, 'DecreaseBrightness'); } else { // Remove service if previously added this.removeService(`${accessory.displayName} Increase Brightness`); this.removeService(`${accessory.displayName} Decrease Brightness`); } this.observe(bond); } updateState(state) { // Power this.fanService.on.updateValue(state.power === 1); // Speed if (this.fanService.rotationSpeed) { let value = 0; if (state.speed && state.power === 1) { const index = this.values.indexOf(state.speed) + 1; const step = index * this.minStep; value = step; } this.fanService.rotationSpeed.updateValue(value); } // Rotation direction if (this.fanService.rotationDirection) { let direction = 0; if (state.direction) { // Bond state direction is 1 / -1, Homekit direction is 1 / 0 direction = state.direction === 1 ? 1 : 0; this.fanService.rotationDirection.updateValue(direction); } } // Light if (this.lightService) { this.lightService.updateState(state); } // Up Light if (this.upLightService) { this.upLightService.updateState(state); } // Down Light if (this.downLightService) { this.downLightService.updateState(state); } } observe(bond) { const device = this.accessory.context.device; this.observeFanPower(bond, device); this.observeFanSpeed(bond, device); this.observeFanDirection(bond, device); this.observeFanIncreaseSpeed(bond, device); this.observeFanDecreaseSpeed(bond, device); if (this.lightService) { this.lightService.observe(this.platform, bond, this.accessory); } this.observeLightToggle(bond, device, this.toggleLightService); this.observeLightDimmer(bond, device, this.dimmerService); if (this.upLightService) { this.upLightService.observe(this.platform, bond, this.accessory); } this.observeLightToggle(bond, device, this.toggleUpLightService); this.observeLightDimmer(bond, device, this.upLightDimmerService); if (this.downLightService) { this.downLightService.observe(this.platform, bond, this.accessory); } this.observeLightToggle(bond, device, this.toggleDownLightService); this.observeLightDimmer(bond, device, this.downLightDimmerService); this.observeLightIncreaseBrightness(bond, device, this.decreaseBrightnessService); this.observeLightDecreaseBrightness(bond, device, this.increaseBrightnessService); // Set initial state bond.api.getState(device.id).then(state => { this.updateState(state); }); } observeFanPower(bond, device) { if (!Device_1.Device.hasOffOn(device)) { this.platform.error(this.accessory, 'CeilingFanAccessory does not have required actions for fan service.'); return; } Observer_1.Observer.set(this.fanService.on, (value, callback) => { bond.api.toggleFan(device, value, callback) .then(() => { this.platform.debug(this.accessory, `Set fan power: ${value}`); }) .catch((error) => { this.platform.error(this.accessory, `Error setting fan power: ${error}`); }); }); } observeFanSpeed(bond, device) { if (!this.fanService.rotationSpeed) { return; } const props = { maxValue: this.maxValue, minStep: this.minStep, }; this.fanService.rotationSpeed.setProps(props); Observer_1.Observer.set(this.fanService.rotationSpeed, (step, callback) => { if (step === 0) { // Step of 0 is the same as turning the fan off. This is handled in the fan power observer callback(null); return; } const index = step / this.minStep - 1; const speed = this.values[index]; bond.api.setFanSpeed(device, speed, callback) .then(() => { this.platform.debug(this.accessory, `Set fan speed: ${speed}`); }) .catch((error) => { this.platform.error(this.accessory, `Error setting fan speed: ${error}`); }); }); } observeFanDirection(bond, device) { if (!this.fanService.rotationDirection) { return; } Observer_1.Observer.set(this.fanService.rotationDirection, (value, callback) => { bond.api.toggleDirection(device, callback) .then(() => { this.platform.debug(this.accessory, `Set fan direction: ${value}`); }) .catch((error) => { this.platform.error(this.accessory, `Error setting fan direction: ${error}`); }); }); } observeFanIncreaseSpeed(bond, device) { if (!this.increaseSpeedService) { return; } Observer_1.Observer.set(this.increaseSpeedService.on, (value, callback) => { bond.api.increaseSpeed(device, callback) .then(() => { this.platform.debug(this.accessory, `Increased fan speed: ${value}`); }) .catch((error) => { this.platform.error(this.accessory, `Error increasing fan speed: ${error}`); }); }); } observeFanDecreaseSpeed(bond, device) { if (!this.decreaseSpeedService) { return; } Observer_1.Observer.set(this.decreaseSpeedService.on, (value, callback) => { bond.api.decreaseSpeed(device, callback) .then(() => { this.platform.debug(this.accessory, `Decreased fan speed: ${value}`); }) .catch((error) => { this.platform.error(this.accessory, `Error decreasing fan speed: ${error}`); }); }); } observeLightToggle(bond, device, service) { if (!service) { return; } Observer_1.Observer.set(service.on, (_, callback) => { let promise; const subtype = service.subType; if (subtype === 'UpLight') { promise = bond.api.toggleState(device, 'up_light', callback); } else if (subtype === 'DownLight') { promise = bond.api.toggleState(device, 'down_light', callback); } else { promise = bond.api.toggleState(device, 'light', callback); } promise .then(() => { this.platform.debug(this.accessory, 'Light state toggled'); }) .catch((error) => { this.platform.error(this.accessory, `Error toggling light state: ${error}`); }); }); } observeLightDimmer(bond, device, service) { if (!service) { return; } Observer_1.Observer.set(service.on, (value, callback) => { let promise; if (value === true) { const subtype = service.subType; if (subtype === 'UpLight') { promise = bond.api.startUpLightDimmer(device, callback); } else if (subtype === 'DownLight') { promise = bond.api.startDownLightDimmer(device, callback); } else { promise = bond.api.startDimmer(device, callback); } } else { promise = bond.api.stop(device, callback); } promise .then(() => { this.platform.debug(this.accessory, `Toggled dimmer: ${value}`); }) .catch((error) => { this.platform.error(this.accessory, `Error toggling dimmer: ${error}`); }); }); } observeLightIncreaseBrightness(bond, device, downService) { if (!this.increaseBrightnessService) { return; } Observer_1.Observer.set(this.increaseBrightnessService.on, (value, callback) => { let promise; if (value === true) { if (downService) { bond.api.stop(device); downService.on.updateValue(false); } promise = bond.api.startIncreasingBrightness(device, callback); } else { promise = bond.api.stop(device, callback); } promise .then(() => { this.platform.debug(this.accessory, `Increased Brightness: ${value}`); }) .catch((error) => { this.platform.error(this.accessory, `Error increasing brightness: ${error}`); }); }); } observeLightDecreaseBrightness(bond, device, upService) { if (!this.decreaseBrightnessService) { return; } Observer_1.Observer.set(this.decreaseBrightnessService.on, (value, callback) => { let promise; if (value === true) { if (upService) { bond.api.stop(device); upService.on.updateValue(false); } promise = bond.api.startDecreasingBrightness(device, callback); } else { promise = bond.api.stop(device, callback); } promise .then(() => { this.platform.debug(this.accessory, `Decreased Brightness: ${value}`); }) .catch((error) => { this.platform.error(this.accessory, `Error decreasing brightness: ${error}`); }); }); } removeService(serviceName) { const service = this.accessory.getService(serviceName); if (service) { this.accessory.removeService(service); this.platform.log(`Removing Service ${serviceName}`); } } } exports.CeilingFanAccessory = CeilingFanAccessory;