UNPKG

homebridge-lutron-caseta-leap-fast

Version:
104 lines 5.01 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.OccupancySensorRouter = void 0; const debug_1 = __importDefault(require("debug")); const util_1 = __importDefault(require("util")); const logDebug = (0, debug_1.default)('leap:bridge'); class OccupancySensorRouter { constructor() { this.cbMap = new Map(); this.subMap = new Map(); this.stateMap = new Map(); } makeKey(bridgeID, ocg) { return bridgeID + '_' + ocg.href; } updateState(bridgeID, update) { logDebug('update state'); logDebug(util_1.default.inspect(update, { depth: null })); for (const grpStat of update.OccupancyGroupStatuses) { const key = this.makeKey(bridgeID, grpStat.OccupancyGroup); logDebug(`handling update for ${util_1.default.inspect(key, { depth: null })} to ${grpStat.OccupancyStatus}`); this.stateMap.set(key, grpStat.OccupancyStatus); } } callRegistered(bridgeID, update) { for (const grpStat of update.OccupancyGroupStatuses) { const key = this.makeKey(bridgeID, grpStat.OccupancyGroup); logDebug(`calling cb for ${util_1.default.inspect(key, { depth: null })} to ${grpStat.OccupancyStatus}`); const cb = this.cbMap.get(key); if (cb) { cb(grpStat.OccupancyStatus); } } } static getInstance() { if (!OccupancySensorRouter.instance) { OccupancySensorRouter.instance = new OccupancySensorRouter(); } return OccupancySensorRouter.instance; } async subscribeToBridge(bridge) { // Subscribe to occupancy updates for the provided bridge. this.subMap.set(bridge.bridgeID, new Promise((resolve, reject) => { // update state and call all registered callbacks when we get an update const _handleOccupancyUpdate = (r) => { logDebug('subscription cb called'); this.updateState(bridge.bridgeID, r.Body); this.callRegistered(bridge.bridgeID, r.Body); }; // we get a complete listing of occupancy groups and their // statuses when we subscribe, so update our internal state // while we've got the info handy const _handleGlobalUpdate = (initial) => { logDebug(`response from subscription call recd: ${util_1.default.inspect(initial, { depth: null })}`); this.updateState(bridge.bridgeID, initial); }; // subscribe to occupancy updates for this bridge, and... bridge .subscribeToOccupancy(_handleOccupancyUpdate.bind(this)) .then(_handleGlobalUpdate.bind(this)) // resolve the promise that we'll subscribe to the bridge .then(() => resolve()) .catch((e) => reject(e)); // when the bridge is disconnected, subscriptions are lost. re-establish them. bridge.on('disconnected', () => { bridge.subscribeToOccupancy(_handleOccupancyUpdate.bind(this)).then(_handleGlobalUpdate.bind(this)); // WARNING: uncaught throw here will crash the program, but // there's nothing to be done if re-subscribing fails. // better to just blow it all up. }); })); } async register(bridge, occupancyGroup, cb) { // Register the specified bridge's occupancy group to have cb called // when there's an update. This function will subscribe to the bridge if // it hasn't already been done. // Create the key used for looking into the three state maps we're about to use const key = this.makeKey(bridge.bridgeID, occupancyGroup); // If we're not already subscribed to this bridge's updates, let's do that. if (!this.subMap.has(bridge.bridgeID)) { logDebug(`bridge ${bridge.bridgeID} is a new bridge`); this.subscribeToBridge(bridge); } await this.subMap.get(bridge.bridgeID); // Store this registration's callback this.cbMap.set(key, cb); // get stored state information for the occupancygroup that's // registering itself, and immediately call its callback to update it. // n.b. that this may not be this bridge's first registration request, // so the above nonsense about initial status might have happened on a // prior registration, and is async anyway. that's why we look in the // cache. const state = this.stateMap.get(key); if (state) { logDebug(`calling callback for ${key}`); cb(state); } } } exports.OccupancySensorRouter = OccupancySensorRouter; //# sourceMappingURL=OccupancySensorRouter.js.map