UNPKG

homebridge-xfinityhome

Version:

A homebridge plugin to control your Xfinity Home security system.

217 lines 11.4 kB
"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