UNPKG

dirigera

Version:

A TypeScript client for IKEA's DIRIGERA smart home hub

150 lines (149 loc) 6.62 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.createDirigeraClient = createDirigeraClient; const node_os_1 = __importDefault(require("node:os")); const node_https_1 = require("node:https"); const authCode_1 = require("./authCode"); const certificate_1 = __importDefault(require("./certificate")); const mdnsDiscovery_1 = require("./mdnsDiscovery"); const ws_1 = require("./ws"); const hub_1 = __importDefault(require("./api/hub")); const devices_1 = __importDefault(require("./api/devices")); const lights_1 = __importDefault(require("./api/lights")); const outlets_1 = __importDefault(require("./api/outlets")); const controllers_1 = __importDefault(require("./api/controllers")); const speakers_1 = __importDefault(require("./api/speakers")); const blinds_1 = __importDefault(require("./api/blinds")); const airPurifiers_1 = __importDefault(require("./api/airPurifiers")); const repeaters_1 = __importDefault(require("./api/repeaters")); const motionSensors_1 = __importDefault(require("./api/motionSensors")); const lightSensors_1 = __importDefault(require("./api/lightSensors")); const environmentSensors_1 = __importDefault(require("./api/environmentSensors")); const openCloseSensors_1 = __importDefault(require("./api/openCloseSensors")); const waterSensors_1 = __importDefault(require("./api/waterSensors")); const deviceSets_1 = __importDefault(require("./api/deviceSets")); const rooms_1 = __importDefault(require("./api/rooms")); const scenes_1 = __importDefault(require("./api/scenes")); const music_1 = __importDefault(require("./api/music")); const users_1 = __importDefault(require("./api/users")); async function createDirigeraClient({ gatewayIP, accessToken, rejectUnauthorized = true, } = {}) { const ip = gatewayIP ?? (await (0, mdnsDiscovery_1.discoverGatewayIP)()); const { got } = await import('got'); const gotInstance = got.extend({ prefixUrl: `https://${ip}:8443/v1`, headers: { ...(accessToken ? { authorization: `Bearer ${accessToken}` } : null), }, ...(rejectUnauthorized ? { agent: { https: new node_https_1.Agent({ ca: [certificate_1.default], checkServerIdentity: () => undefined, }), }, } : { https: { rejectUnauthorized: false } }), hooks: { beforeError: [ (error) => { if (error.code === 'ERR_NON_2XX_3XX_RESPONSE' && error?.response?.body) { error.name = 'DirigeraError'; error.message = `${error.response.body}`; } return error; }, ], }, }); return { async authenticate({ verbose = false } = {}) { const codeVerifier = (0, authCode_1.generateCodeVerifier)(); const codeChallenge = (0, authCode_1.calculateCodeChallenge)(codeVerifier); const { code } = await gotInstance .get(`oauth/authorize`, { searchParams: { audience: 'homesmart.local', response_type: 'code', code_challenge: codeChallenge, code_challenge_method: authCode_1.CODE_CHALLENGE_METHOD, }, }) .json(); const { default: pRetry } = await import('p-retry'); if (verbose) { console.log('Press the Action Button on the bottom of your Dirigera Hub within 60 seconds.'); } return await pRetry(async () => { const { access_token } = await gotInstance .post(`oauth/token`, { form: { code, name: node_os_1.default.hostname(), grant_type: 'authorization_code', code_verifier: codeVerifier, }, }) .json(); if (!access_token) { throw new Error('Access token is missing.'); } if (verbose) { process.stdout.write('\n'); } return access_token; }, { retries: 59, minTimeout: 1000, factor: 1, onFailedAttempt: (error) => { if (verbose) { process.stdout.write(`\rTime left: ${String(error.retriesLeft).padStart(2, ' ')} seconds`); if (error.retriesLeft === 0) { process.stdout.write('\n'); } } }, }); }, async home() { return await gotInstance.get(`home`).json(); }, hub: (0, hub_1.default)(gotInstance), devices: (0, devices_1.default)(gotInstance), lights: (0, lights_1.default)(gotInstance), outlets: (0, outlets_1.default)(gotInstance), controllers: (0, controllers_1.default)(gotInstance), speakers: (0, speakers_1.default)(gotInstance), blinds: (0, blinds_1.default)(gotInstance), airPurifiers: (0, airPurifiers_1.default)(gotInstance), repeaters: (0, repeaters_1.default)(gotInstance), motionSensors: (0, motionSensors_1.default)(gotInstance), lightSensors: (0, lightSensors_1.default)(gotInstance), environmentSensors: (0, environmentSensors_1.default)(gotInstance), openCloseSensors: (0, openCloseSensors_1.default)(gotInstance), waterSensors: (0, waterSensors_1.default)(gotInstance), deviceSets: (0, deviceSets_1.default)(gotInstance), rooms: (0, rooms_1.default)(gotInstance), scenes: (0, scenes_1.default)(gotInstance), music: (0, music_1.default)(gotInstance), users: (0, users_1.default)(gotInstance), startListeningForUpdates(callback) { if (!accessToken) { throw new Error('Access token is missing.'); } (0, ws_1.initializeWebSocket)({ ip, accessToken, callback, }); }, stopListeningForUpdates() { (0, ws_1.closeWebSocket)(); }, }; }