UNPKG

homebridge-hca

Version:

HCA plugin for Homebridge

157 lines (115 loc) 4.71 kB
// 'use strict'; const inherits = require('util').inherits; const AccessoryBase = require('../AccessoryBase'); class HcaFan extends AccessoryBase { constructor(log, item, client) { super(log, item, client); } // TODO: Move outside of class so it's callable when restored. identify(paired, callback) { const item = this.context.item; this.log.info('Identifying %s (%s).', item.name, item.id); callback(); } } function init(accessory) { const item = accessory.context.item; const service = accessory.getService(Service.Fan) || accessory.addService(Service.Fan, accessory.displayName); service .getCharacteristic(Characteristic.On) .onGet(getPowerState.bind(accessory)) .onSet(setPowerState.bind(accessory)); if (item.isDimmable) { service .getCharacteristic(Characteristic.RotationSpeed) .onGet(getRotationSpeed.bind(accessory)) .onSet(setRotationSpeed.bind(accessory)); } bindUpdates(accessory); } // Inform HomeKit about changes that occurred outside of HomeKit function bindUpdates(accessory) { const item = accessory.context.item; accessory.client.designManager .on('Design:Updated:' + item.id, function (e) { const lastKnownState = accessory.context.lastKnownState; const currentState = item.state; // Ignore duplicate messages. (HCA may send the same message when device or room state changes, based on a change from the other). if (lastKnownState === currentState) return; accessory.context.lastKnownState = currentState; const isReachable = e.errorState == 0; const isOn = item.state > 0; const rotationSpeed = item.state; accessory.log.debug('%s (%s) has been updated:', accessory.displayName, item.id, JSON.stringify(item)); if (!isReachable) accessory.log.warn('%s (%s) did not acknowledge receipt of this request.', accessory.displayName, item.id) accessory.log.info("%s (%s) has been turned %s.", accessory.displayName, item.id, isOn ? "on" : "off"); accessory.log.debug('Updating %s (%s) power state to \'%s\'.', accessory.displayName, item.id, isOn); accessory .getService(Service.Fan) .getCharacteristic(Characteristic.On) .updateValue(isOn); if (item.isDimmable) { accessory.log.debug('Updating %s (%s) rotation speed to \'%s\'.', accessory.displayName, item.id, rotationSpeed); accessory .getService(Service.Fan) .getCharacteristic(Characteristic.RotationSpeed) .updateValue(rotationSpeed); } }); } async function getPowerState() { const accessory = this; const item = accessory.context.item; const isOn = item.state > 0; accessory.log.debug("%s (%s) is %s.", accessory.displayName, item.id, isOn ? "on" : "off"); return Promise.resolve(isOn); } async function setPowerState(value) { const accessory = this; const item = accessory.context.item; const currentState = item.state > 0; const targetState = Boolean(value); // prevent excessive updates when changing rotation speed if (currentState === targetState) { return Promise.resolve(); } const command = targetState == true ? 'Device.On' : 'Device.Off', params = ['HCAObject', command, item.id]; accessory.log.info("Turning %s (%s) %s.", accessory.displayName, item.id, targetState ? "on" : "off"); accessory.client.send(params); return Promise.resolve(); } async function getRotationSpeed() { const accessory = this; const item = accessory.context.item; accessory.log.debug("%s (%s) speed is %s.", accessory.displayName, item.id, item.state); return Promise.resolve(item.state); } async function setRotationSpeed(value) { const accessory = this; const item = accessory.context.item; const targetSpeed = value; // const targetSpeed = Math.ceil(value / 25) * 25; // 0, 25, 50, 75, or 100 // if (item.state == targetSpeed) { // prevent excessive updates // accessory.log.warn("Ignoring request. %s (%s) is already set to speed %s.", accessory.displayName, item.id, targetSpeed) // callback(); // return; // } accessory.log.info("Setting %s (%s) speed to %s.", accessory.displayName, item.id, targetSpeed); const params = ['HCAObject', 'Device.DimToPercent', item.id, targetSpeed]; accessory.client.send(params); return Promise.resolve(); } module.exports = function (accessory, service, characteristic, ouuid) { this.Accessory = accessory; this.Service = service; this.Characteristic = characteristic; this.uuid = ouuid; inherits(HcaFan, Accessory); return HcaFan; }; module.exports.HcaFan = HcaFan; module.exports.HcaFan.init = init;