UNPKG

homebridge-better-miot

Version:
134 lines 5.08 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.GenericDevice = void 0; const miio = __importStar(require("miio-api")); const DELAY_MS = 250; // 0.25 sec const API_CALL_OPTIONS = { attempts: 5, delay: DELAY_MS, timeout: 14 * DELAY_MS, // 3 sec }; class GenericDevice { constructor({ address, token, properties }) { this.properties = {}; this.listeners = {}; this.propertiesConfigMap = {}; this.config = { address, token, properties }; this.setProperties(properties); this.getDevice() .then(() => this.fetchProperties()); } async getDevice() { const { address, token } = this.config; if (!this.connectedDevice) { try { this.connectedDevice = await miio.device({ address, token }, API_CALL_OPTIONS); this.info = await this.connectedDevice.call('miIO.info'); } catch (_a) { throw new Error('Something went wrong while connecting'); } } return this.connectedDevice; } subscribe(property, cb) { if (!Array.isArray(this.listeners[property])) { this.listeners[property] = []; } this.listeners[property].push(cb); } notifyUpdate(property) { if (Array.isArray(this.listeners[property])) { this.listeners[property].forEach((cb) => cb(this.properties[property])); } } setProperties(properties) { properties.forEach((property) => { const { name, title, mapper = (value) => value, } = property; const propertyTitle = title || name; this.propertiesConfigMap[propertyTitle] = { name, mapper, title: propertyTitle, }; }); } // TODO: make 2 requests if properties.length > 15 async loadProperties(config) { const propertyNameTitleMap = Object.values(config) .reduce((acc, { name, title }) => { acc[name] = title; return acc; }, {}); const propertyNames = Object.keys(propertyNameTitleMap); const device = await this.getDevice(); const result = await device.call('get_prop', propertyNames, API_CALL_OPTIONS); const notifyQueue = []; result === null || result === void 0 ? void 0 : result.forEach((value, index) => { const name = propertyNames[index]; const title = propertyNameTitleMap[name]; const mapper = config[title].mapper; const parsedValue = mapper(value); if (this.properties[title] !== parsedValue) { notifyQueue.push(title); } this.properties[title] = parsedValue; }); notifyQueue.forEach((property) => this.notifyUpdate(property)); } async fetchProperty(propertyTitle) { const titles = typeof propertyTitle === 'string' ? [propertyTitle] : propertyTitle; if (!titles.every((title) => title in this.propertiesConfigMap)) { return; } const propertiesConfig = titles.reduce((acc, propertyTitle) => { acc[propertyTitle] = this.propertiesConfigMap[propertyTitle]; return acc; }, {}); return this.loadProperties(propertiesConfig); } async fetchProperties() { return this.loadProperties(this.propertiesConfigMap); } async call(method, params, refetch) { const device = await this.getDevice(); try { const result = await device.call(method, params, API_CALL_OPTIONS); if (result && Array.isArray(refetch)) { return new Promise((resolve) => { setTimeout(async () => { await this.fetchProperty(refetch); resolve(result); }, DELAY_MS); }); } return result; } catch (err) { throw Error(`Can't make ${method} api call`); } } } exports.GenericDevice = GenericDevice; //# sourceMappingURL=GenericDevice.js.map