UNPKG

homebridge-hca

Version:

HCA plugin for Homebridge

134 lines (101 loc) 3.78 kB
// 'use strict'; const inherits = require('util').inherits; const AccessoryBase = require('../AccessoryBase'); const itemType = require('node-hca/lib/Design/itemType'); class HcaSwitch 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).', this.displayName, item.id); callback(); } } function init(accessory) { const service = accessory.getService(Service.Switch) || accessory.addService(Service.Switch, accessory.displayName); service .getCharacteristic(Characteristic.On) .onGet(getPowerState.bind(accessory)) .onSet(setPowerState.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; let isOn = item.state > 0; // programs require additional evaluation if (item.type == itemType.program && item.currentIconName.length > 0) { isOn = parseInt(item.currentIconRepresentation) > 0; } 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.Switch) .getCharacteristic(Characteristic.On) .updateValue(isOn); }); } 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); const typeName = getTypeName(item); const command = targetState == true ? `${typeName}.On` : `${typeName}.Off`; const 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(); } function getTypeName(item) { let typeName; switch (item.type) { case itemType.device: typeName = 'Device'; break; case itemType.program: typeName = 'Program'; break; case itemType.group: typeName = 'Group'; break; case itemType.controller: typeName = 'Controller'; break; default: break; } return typeName; } module.exports = function (accessory, service, characteristic, ouuid) { this.Accessory = accessory; this.Service = service; this.Characteristic = characteristic; this.uuid = ouuid; inherits(HcaSwitch, Accessory); return HcaSwitch; }; module.exports.HcaSwitch = HcaSwitch; module.exports.HcaSwitch.init = init;