homebridge-hca
Version:
HCA plugin for Homebridge
115 lines (85 loc) • 3.58 kB
JavaScript
// 'use strict';
const inherits = require('util').inherits;
const AccessoryBase = require('../AccessoryBase');
// const itemType = require('node-hca/lib/Design/itemType');
class HcaMotionSensor extends AccessoryBase {
constructor(log, item, client) {
super(log, item, client);
}
identify(paired, callback) {
const item = this.context.item;
this.log.info('Identifying %s (%s).', this.name, item.id);
callback();
}
}
function init(accessory) {
const service =
accessory.getService(Service.MotionSensor) ||
accessory.addService(Service.MotionSensor, accessory.displayName);
service
.getCharacteristic(Characteristic.MotionDetected)
.onGet(getMotionStatus.bind(accessory));
const statusLowBattery =
service.getCharacteristic(Characteristic.StatusLowBattery) ||
service.addCharacteristic(Characteristic.StatusLowBattery);
statusLowBattery
.onGet(getBatteryStatus.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 motionDetected = item.state > 0;
const lowBattery = false; // HCA doesn't support this
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 triggered %s.", accessory.displayName, item.id, motionDetected ? "on" : "off");
accessory.log.debug('Updating %s (%s) motion state to \'%s\'.', accessory.displayName, item.id, motionDetected);
accessory
.getService(Service.MotionSensor)
.getCharacteristic(Characteristic.MotionDetected)
.updateValue(motionDetected);
accessory
.getService(Service.MotionSensor)
.getCharacteristic(Characteristic.StatusLowBattery)
.updateValue(lowBattery);
});
}
async function getMotionStatus() {
const accessory = this;
const item = accessory.context.item;
const motionDetected = item.state > 0;
accessory.log.debug("%s (%s) is %s.", accessory.displayName, item.id, motionDetected ? "on" : "off");
return Promise.resolve(motionDetected);
}
async function getBatteryStatus() {
const accessory = this;
const item = accessory.context.item;
const lowBattery = false; // HCA doesn't support this
const msg = `${accessory.displayName} (${item.id}) battery is ${lowBattery ? "low" : "normal"}.`
if (lowBattery) {
accessory.log.warn(msg);
} else {
accessory.log.debug(msg);
}
return Promise.resolve(lowBattery ? 1 : 0); // 0 = normal, 1 = low
}
module.exports = function (accessory, service, characteristic, ouuid) {
this.Accessory = accessory;
this.Service = service;
this.Characteristic = characteristic;
this.uuid = ouuid;
inherits(HcaMotionSensor, Accessory);
return HcaMotionSensor;
};
module.exports.HcaMotionSensor = HcaMotionSensor;
module.exports.HcaMotionSensor.init = init;