UNPKG

homebridge-bold

Version:
171 lines (170 loc) 9.14 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.BoldPlatform = void 0; const fs_extra_1 = __importDefault(require("fs-extra")); const bold_1 = require("./bold"); const types_1 = require("./types"); const const_1 = require("./const"); const lock_accessory_1 = require("./accessories/lock-accessory"); const switch_accessory_1 = require("./accessories/switch-accessory"); exports.default = (api) => { api.registerPlatform(const_1.PLATFORM_NAME, BoldPlatform); }; class BoldPlatform { constructor(log, config, api) { this.log = log; this.api = api; this.accessories = []; this.hap = api.hap; this.config = config; this.bold = new bold_1.BoldAPI(this.config, this.log); api.on("didFinishLaunching" /* DID_FINISH_LAUNCHING */, () => __awaiter(this, void 0, void 0, function* () { yield this.refreshAccessToken(); yield this.updateDevices(); this.refreshInterval = setInterval(() => __awaiter(this, void 0, void 0, function* () { yield this.refreshAccessToken(); yield this.updateDevices(); }), 24 * 60 * 60 * 1000); })); api.on("shutdown" /* SHUTDOWN */, () => { if (this.refreshInterval != null) { clearInterval(this.refreshInterval); } }); } // Accessories isSwitchAccessory(device) { return device.type.id == types_1.DeviceType.Connect && !this.config.showControllerAsLock; } configureAccessory(accessory) { let device = accessory.context.device; if (!device) { this.log.warn(`Device not found for accessory ${accessory.UUID}. Removing...`); this.removeAccessory(accessory); return; } if (accessory.context.isSwitchAccessory) { new switch_accessory_1.SwitchAccessory(this, accessory, device); } else { new lock_accessory_1.LockAccessory(this, accessory, device); } this.accessories.push(accessory); } addAccessory(device) { let accessory; // Separate UUIDs for lock and switch in case the config option is changed when the device already exists. if (this.isSwitchAccessory(device)) { let uuid = this.hap.uuid.generate(`BoldSwitch${device.id}`); accessory = new this.api.platformAccessory(device.name, uuid, 8 /* SWITCH */); accessory.context.isSwitchAccessory = true; } else { let uuid = this.hap.uuid.generate(`BoldLock${device.id}`); accessory = new this.api.platformAccessory(device.name, uuid, 6 /* DOOR_LOCK */); accessory.context.isSwitchAccessory = false; } accessory.context.device = device; // Services & Characteristics initialized by configureAccessory() this.configureAccessory(accessory); this.api.registerPlatformAccessories(const_1.PLUGIN_NAME, const_1.PLATFORM_NAME, [accessory]); } removeAccessory(accessory) { let index = this.accessories.indexOf(accessory); delete this.accessories[index]; this.api.unregisterPlatformAccessories(const_1.PLUGIN_NAME, const_1.PLATFORM_NAME, [accessory]); } // Bold API updateDevices() { return __awaiter(this, void 0, void 0, function* () { let devices; try { devices = yield this.bold.getDevices(); } catch (error) { if (this.accessories.length == 0) { this.log.error('Unable to get devices. Check your authentication details.'); } else { this.log.warn('Unable to refresh devices. Preserving cached accessories, which might be incorrect. Check your authentication details.'); } return; } // Add devices let addDevices = devices.filter((device) => !this.accessories.find((accessory) => accessory.context.device.id == device.id && accessory.context.isSwitchAccessory == this.isSwitchAccessory(device))); if (addDevices.length > 0) this.log.info(`Found ${addDevices.length} new device${addDevices.length != 1 ? 's' : ''} supporting remote activation.`); addDevices.forEach(this.addAccessory.bind(this)); // Remove devices let removeAccessories = this.accessories.filter((accessory) => !devices.find((device) => accessory.context.device.id == device.id && accessory.context.isSwitchAccessory == this.isSwitchAccessory(device))); if (removeAccessories.length > 0) this.log.info(`Removing ${removeAccessories.length} old device${removeAccessories.length != 1 ? 's' : ''}.`); removeAccessories.forEach(this.removeAccessory.bind(this)); // Update existing devices for (let accessory of this.accessories.filter((accessory) => devices.find((device) => accessory.context.device.id == device.id && accessory.context.isSwitchAccessory == this.isSwitchAccessory(device)))) { accessory.context.device = devices.find((device) => device.id == accessory.context.device.id); this.api.updatePlatformAccessories(this.accessories); } }); } refreshAccessToken() { return __awaiter(this, void 0, void 0, function* () { let config; try { config = yield fs_extra_1.default.readJSON(this.api.user.configPath()); } catch (error) { this.log.error(`Error while reading config for access token refresh: ${error}`); return; } let platformIndex = config.platforms.findIndex((platform) => platform.platform == const_1.PLATFORM_NAME && platform.accessToken == this.bold.config.accessToken); let hasWarned = false; if (platformIndex == -1) { this.log.warn("Warning while reading config for access token refresh: Couldn't find platform with current access token. Using first entry of Bold config."); hasWarned = true; platformIndex = config.platforms.findIndex((platform) => platform.platform == const_1.PLATFORM_NAME); } if (platformIndex == -1) { this.log.error("Error while reading config for access token refresh: Couldn't find entry of Bold platform. Skipping token refresh."); return; } let refreshedTokens = yield this.bold.refresh(); if (!refreshedTokens) { return; } // Reloading config in case it was updated while refreshing try { config = yield fs_extra_1.default.readJSON(this.api.user.configPath()); } catch (error) { this.log.error(`Error while reading config for access token refresh: ${error}`); return; } platformIndex = config.platforms.findIndex((platform) => platform.platform == const_1.PLATFORM_NAME && platform.accessToken == this.bold.config.accessToken); if (platformIndex == -1 && !hasWarned) { this.log.warn("Warning while reading config for access token refresh: Couldn't find platform with current access token. Using first entry of Bold config."); platformIndex = config.platforms.findIndex((platform) => platform.platform == const_1.PLATFORM_NAME); } if (platformIndex == -1) { this.log.error("Error while reading config for access token refresh: Couldn't find entry of Bold platform. Skipping token refresh."); } config.platforms[platformIndex].accessToken = refreshedTokens.accessToken; config.platforms[platformIndex].refreshToken = refreshedTokens.refreshToken; yield fs_extra_1.default.writeJSON(this.api.user.configPath(), config, { spaces: 4 }); this.bold.config = Object.assign(Object.assign({}, this.bold.config), { accessToken: refreshedTokens.accessToken, refreshToken: refreshedTokens.refreshToken }); }); } } exports.BoldPlatform = BoldPlatform;