UNPKG

node-red-contrib-home-assistant-websocket

Version:
186 lines (185 loc) 7.52 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (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; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.SUPERVISOR_URL = exports.HaEvent = exports.homeAssistantConnections = void 0; exports.hasCredentials = hasCredentials; exports.createHomeAssistantClient = createHomeAssistantClient; exports.getHomeAssistant = getHomeAssistant; exports.closeHomeAssistant = closeHomeAssistant; const events_1 = require("events"); const url_1 = require("url"); const ClientEvents_1 = __importDefault(require("../common/events/ClientEvents")); const globals_1 = require("../globals"); const Comms_1 = __importDefault(require("../nodes/config-server/Comms")); const ConnectionLog_1 = __importDefault(require("../nodes/config-server/ConnectionLog")); const EditorContext_1 = __importDefault(require("../nodes/config-server/EditorContext")); const HomeAssistant_1 = __importDefault(require("./HomeAssistant")); const Http_1 = __importDefault(require("./Http")); const Websocket_1 = __importStar(require("./Websocket")); exports.homeAssistantConnections = new Map(); var HaEvent; (function (HaEvent) { HaEvent["AreaRegistryUpdated"] = "areas_updated"; HaEvent["AutomationTriggered"] = "automation_triggered"; HaEvent["DeviceRegistryUpdated"] = "devices_updated"; HaEvent["FloorRegistryUpdated"] = "floors_updated"; HaEvent["Integration"] = "nodered"; HaEvent["LabelRegistryUpdated"] = "labels_updated"; HaEvent["EntityRegistryUpdated"] = "entity_registry_updated"; HaEvent["ServicesUpdated"] = "services_updated"; HaEvent["StateChanged"] = "state_changed"; HaEvent["TagScanned"] = "tag_scanned"; HaEvent["ValueChange"] = "value_change"; })(HaEvent || (exports.HaEvent = HaEvent = {})); exports.SUPERVISOR_URL = 'http://supervisor/core'; function hasCredentials(credentials) { return !!credentials.host && !!credentials.access_token; } function createHomeAssistantClient(node) { let homeAssistant = exports.homeAssistantConnections.get(node.id); if (homeAssistant) return homeAssistant; if (!hasCredentials(node.credentials) && !node.config.addon) { throw new Error('No credentials provided'); } const eventBus = new events_1.EventEmitter(); eventBus.setMaxListeners(0); const creds = createCredentials(node.credentials, node.config); const httpConfig = createHttpConfig(creds, node.config); const websocketConfig = createWebsocketConfig(creds, node.config); const httpAPI = new Http_1.default(httpConfig); const websocketAPI = new Websocket_1.default(websocketConfig, eventBus); homeAssistant = new HomeAssistant_1.default({ websocketAPI, httpAPI, eventBus, }); const clientEvents = new ClientEvents_1.default({ node, emitter: homeAssistant.eventBus, }); clientEvents.addListener(Websocket_1.ClientEvent.Connected, homeAssistant.subscribeEvents.bind(homeAssistant), { once: true, }); // eslint-disable-next-line no-new new Comms_1.default(node.id, homeAssistant, clientEvents); // eslint-disable-next-line no-new new ConnectionLog_1.default(node, clientEvents); if (node.config.enableGlobalContextStore) { // eslint-disable-next-line no-new new EditorContext_1.default(node, clientEvents); } homeAssistant.websocket.connect().catch((e) => { node.error(e); }); exports.homeAssistantConnections.set(node.id, homeAssistant); return homeAssistant; } function createCredentials(credentials, config) { let host; if (!credentials) { throw new Error('No credentials'); } // eslint-disable-next-line camelcase let accessToken = credentials.access_token; // Check if using HA Add-on and import proxy token const addonBaseUrls = ['http://hassio/homeassistant', exports.SUPERVISOR_URL]; if (config.addon || addonBaseUrls.includes(credentials.host)) { if (!process.env.SUPERVISOR_TOKEN) { throw new Error('Supervisor token not found.'); } host = exports.SUPERVISOR_URL; // eslint-disable-next-line camelcase accessToken = process.env.SUPERVISOR_TOKEN; } else { host = getBaseUrl(credentials.host); } return { host, // eslint-disable-next-line camelcase access_token: accessToken, }; } function createHttpConfig(credentials, config) { return { access_token: credentials.access_token, host: credentials.host, rejectUnauthorizedCerts: config.rejectUnauthorizedCerts, }; } function createWebsocketConfig(credentials, config = { rejectUnauthorizedCerts: true, connectionDelay: true, }) { var _a, _b, _c; const connectionDelay = credentials.host !== exports.SUPERVISOR_URL ? false : ((_a = config.connectionDelay) !== null && _a !== void 0 ? _a : false); const heartbeatInterval = (_b = Number(config.heartbeatInterval)) !== null && _b !== void 0 ? _b : 0; const heartbeat = config.heartbeat && Number.isInteger(heartbeatInterval) ? heartbeatInterval : 0; return { access_token: credentials.access_token, host: credentials.host, rejectUnauthorizedCerts: (_c = config.rejectUnauthorizedCerts) !== null && _c !== void 0 ? _c : true, connectionDelay, heartbeatInterval: heartbeat, }; } function getBaseUrl(url) { validateBaseUrl(url); return url.trim(); } function validateBaseUrl(baseUrl) { if (!baseUrl) { throw new Error(globals_1.RED._('config-server.errors.empty_base_url')); } let parsedUrl; try { parsedUrl = new url_1.URL(baseUrl); } catch (e) { throw new Error(globals_1.RED._('config-server.errors.invalid_base_url')); } if (parsedUrl.protocol !== 'http:' && parsedUrl.protocol !== 'https:') { throw new Error(globals_1.RED._('config-server.errors.invalid_protocol')); } } function getHomeAssistant(serverNode) { var _a; return ((_a = exports.homeAssistantConnections.get(serverNode.id)) !== null && _a !== void 0 ? _a : createHomeAssistantClient(serverNode)); } function closeHomeAssistant(nodeId) { const homeAssistant = exports.homeAssistantConnections.get(nodeId); if (homeAssistant) { homeAssistant.close(); exports.homeAssistantConnections.delete(nodeId); } }