homebridge-xfinityhome
Version:
A homebridge plugin to control your Xfinity Home security system.
217 lines • 11.4 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const Accessory_1 = __importDefault(require("./Accessory"));
class MotionAccessory extends Accessory_1.default {
constructor(platform, accessory, device) {
var _a, _b;
super(platform, accessory, device, accessory.getService(platform.Service.MotionSensor) ||
accessory.addService(platform.Service.MotionSensor));
this.platform = platform;
this.accessory = accessory;
this.device = device;
this.service.setCharacteristic(this.platform.Characteristic.Name, this.device.device.name);
this.service.getCharacteristic(this.platform.Characteristic.MotionDetected)
.onGet(this.getMotionDetected.bind(this))
.on('change', this.notifyMotionChange.bind(this));
this.service.getCharacteristic(this.platform.Characteristic.StatusActive)
.setProps({
perms: ["pr" /* Perms.PAIRED_READ */, "pw" /* Perms.PAIRED_WRITE */, "ev" /* Perms.NOTIFY */],
})
.onGet(this.getActive.bind(this))
.onSet(this.setActive.bind(this))
.on('change', this.notifyActiveChange.bind(this));
this.service.getCharacteristic(this.platform.Characteristic.StatusTampered)
.onGet(this.getTampered.bind(this))
.on('change', this.notifyTamperedChange.bind(this));
this.service.getCharacteristic(this.platform.Characteristic.StatusLowBattery)
.onGet(this.getLowBattery.bind(this))
.on('change', this.notifyLowBatteryChange.bind(this));
this.service.getCharacteristic(this.platform.Characteristic.StatusFault)
.onGet(this.getFaulted.bind(this))
.on('change', this.notifyFaultedChange.bind(this));
if ('temperature' in this.device.device.properties && ((_a = this.platform.config.temperatureSensors) !== null && _a !== void 0 ? _a : true)) {
this.temperatureService = this.accessory.getService(platform.Service.TemperatureSensor);
if (!this.temperatureService) {
this.log('info', 'Adding Temperature Support');
this.temperatureService = this.accessory.addService(platform.Service.TemperatureSensor);
}
this.temperatureService.setCharacteristic(platform.Characteristic.Name, device.device.name + ' Temperature');
this.temperatureService.getCharacteristic(platform.Characteristic.CurrentTemperature)
.setProps({
minStep: 0.01,
})
.onGet(this.getTemperature.bind(this))
.on('change', this.notifyTemperatureChange.bind(this));
}
else if (!((_b = this.platform.config.temperatureSensors) !== null && _b !== void 0 ? _b : true) && this.accessory.getService(this.platform.Service.TemperatureSensor)) {
this.log('warn', 'Removing Temperature Support');
this.accessory.removeService(this.accessory.getService(this.platform.Service.TemperatureSensor));
}
this.device.onevent = async (event) => {
var _a;
if (event.name === 'trouble') {
if (event.value === 'senTamp') {
this.service.updateCharacteristic(this.platform.Characteristic.StatusTampered, 1);
}
else if (event.value === 'senTampRes') {
this.service.updateCharacteristic(this.platform.Characteristic.StatusTampered, 0);
}
if (event.value === 'senPreLowBat' || event.value === 'senLowBat') {
this.service.updateCharacteristic(this.platform.Characteristic.StatusLowBattery, 1);
if (event.value === 'senLowBat') {
this.service.updateCharacteristic(this.platform.Characteristic.StatusFault, 1);
}
else {
this.service.updateCharacteristic(this.platform.Characteristic.StatusFault, 0);
}
}
}
if (event.name === 'isFaulted') {
this.device.device.properties.isFaulted = event.value === 'true';
this.service.updateCharacteristic(this.platform.Characteristic.MotionDetected, await this.getMotionDetected(true));
}
if (event.mediaType === 'event/zoneUpdated') {
this.device.device.properties.isBypassed = event.metadata.isBypassed === 'true';
this.service.updateCharacteristic(this.platform.Characteristic.StatusActive, this.getActive());
}
if ('sensorTemperature' in event.metadata) {
this.device.device.properties.temperature = JSON.parse(event.metadata.sensorTemperature);
(_a = this.temperatureService) === null || _a === void 0 ? void 0 : _a.updateCharacteristic(this.platform.Characteristic.CurrentTemperature, this.getTemperature());
}
};
this.device.onchange = async (_oldState, newState) => {
var _a;
/** Normally not updated until AFTER `onchange` function execution */
this.device.device = newState;
this.service.updateCharacteristic(this.platform.Characteristic.StatusTampered, this.getTampered());
this.service.updateCharacteristic(this.platform.Characteristic.StatusFault, this.getFaulted());
this.service.updateCharacteristic(this.platform.Characteristic.StatusLowBattery, this.getLowBattery());
this.service.updateCharacteristic(this.platform.Characteristic.MotionDetected, await this.getMotionDetected(true));
this.service.updateCharacteristic(this.platform.Characteristic.StatusActive, this.getActive());
(_a = this.temperatureService) === null || _a === void 0 ? void 0 : _a.updateCharacteristic(this.platform.Characteristic.CurrentTemperature, this.getTemperature());
this.accessory.context.logPath = this.logPath;
this.accessory.context.device = newState;
this.accessory.context.refreshToken = this.platform.xhome.refreshToken;
this.platform.api.updatePlatformAccessories([this.accessory]);
if (this.device.device.trouble.length && (!this.getTampered() && !this.getLowBattery())) {
this.log('warn', 'Unknown trouble detected!');
this.log('warn', 'Please open an issue about this.');
this.log('warn', JSON.stringify(this.device.device.trouble, null, 2));
}
};
}
async getMotionDetected(skipUpdate) {
if (skipUpdate !== true) {
if (this.platform.config.lazyUpdates) {
process.nextTick(() => {
this.device.get().catch(err => {
this.log('error', 'Failed To Fetch Motion State With Error:', err);
// throw new this.StatusError(HAPStatus.SERVICE_COMMUNICATION_FAILURE);
});
});
}
else {
try {
const device = await this.device.get();
return device.properties.isFaulted;
}
catch (err) {
this.log('error', 'Failed To Fetch Motion State With Error:', err);
return Promise.reject(new this.StatusError(-70402 /* HAPStatus.SERVICE_COMMUNICATION_FAILURE */));
}
}
}
return this.device.device.properties.isFaulted;
}
async notifyMotionChange(value) {
if (value.newValue !== value.oldValue) {
this.log(3, `Motion ${value.newValue ? 'Detected' : 'Cleared'}`);
}
}
getActive() {
return !this.device.device.properties.isBypassed;
}
async setActive(value) {
this.device.device.properties.isBypassed = !value;
try {
await this.device.bypass(!value);
}
catch (err) {
this.log('error', `Failed To ${!value ? 'Bypass' : 'Activate'} With Error:`, err);
return Promise.reject(new this.StatusError(-70402 /* HAPStatus.SERVICE_COMMUNICATION_FAILURE */));
}
}
async notifyActiveChange(value) {
if (value.newValue !== value.oldValue) {
this.log(2, value.newValue ? 'Activated' : 'Bypassed');
}
}
getTampered() {
return this.device.device.trouble.find(trouble => trouble.name === 'senTamp') ? 1 : 0;
}
async notifyTamperedChange(value) {
if (value.newValue !== value.oldValue) {
if (value.newValue) {
this.log('warn', 'Tampered');
}
else {
this.log(2, 'Fixed');
}
}
}
getFaulted() {
return this.device.device.trouble.find(trouble => trouble.name === 'senLowBat') ? 1 : 0;
}
async notifyFaultedChange(value) {
if (value.newValue !== value.oldValue) {
if (value.newValue) {
this.log('warn', 'Faulted (Battery Level Is Very Low)');
}
else {
this.log(2, 'Fault Restored');
}
}
}
getLowBattery() {
return this.device.device.trouble.find(trouble => trouble.name === 'senPreLowBat' || trouble.name === 'senLowBat') ? 1 : 0;
}
async notifyLowBatteryChange(value) {
if (value.newValue !== value.oldValue) {
if (value.newValue) {
this.device.device.trouble.forEach(trouble => {
if (trouble.name === 'senPreLowBat') {
this.log(1, 'Low Battery');
this.device.device.deviceHelp ?
this.log(1, `See ${this.device.device.deviceHelp.batteryReplacementWebUrl} for how to replace`) : undefined;
this.device.device.deviceHelp ?
this.log(1, `See ${this.device.device.deviceHelp.batteryPurchaseLink} for new batteries`) : undefined;
}
if (trouble.name === 'senLowBat') {
this.log('warn', 'Critically Low Battery');
this.device.device.deviceHelp ?
this.log(1, `See ${this.device.device.deviceHelp.batteryReplacementWebUrl} for how to replace`) : undefined;
this.device.device.deviceHelp ?
this.log(1, `See ${this.device.device.deviceHelp.batteryPurchaseLink} for new batteries`) : undefined;
}
});
this.log('warn', this.device.device.trouble[0].name === 'senPreLowBat' ? 'Low' : 'Critically Low', 'Battery');
}
else {
this.log(2, 'Fixed');
}
}
}
getTemperature() {
return this.device.device.properties.temperature / 100;
}
async notifyTemperatureChange(value) {
if (value.newValue !== value.oldValue) {
this.log(4, `Updating Temperature To ${value.newValue}°C`);
}
}
}
exports.default = MotionAccessory;
//# sourceMappingURL=MotionAccessory.js.map