UNPKG

node-red-contrib-home-assistant-websocket

Version:
234 lines (233 loc) 10.6 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.createRoutes = createRoutes; const bonjour_1 = __importDefault(require("bonjour")); const debug_1 = __importDefault(require("debug")); const flat_1 = __importDefault(require("flat")); const IssueService_1 = __importDefault(require("./common/services/IssueService")); const const_1 = require("./const"); const globals_1 = require("./globals"); const diagnostics_1 = require("./helpers/diagnostics"); const node_1 = require("./helpers/node"); const homeAssistant_1 = require("./homeAssistant"); function disableCache(req, res, next) { var _a; const node = globals_1.RED.nodes.getNode(req.params.id); if (((_a = node === null || node === void 0 ? void 0 : node.config) === null || _a === void 0 ? void 0 : _a.cacheJson) === false) { res.setHeader('Surrogate-Control', 'no-store'); res.setHeader('Cache-Control', 'no-store, no-cache, must-revalidate, proxy-revalidate'); res.setHeader('Pragma', 'no-cache'); res.setHeader('Expires', '0'); } next(); } function checkHomeAssistant(req, res, next) { try { const node = (0, node_1.getServerConfigNode)(req.params.serverId); req.homeAssistant = (0, homeAssistant_1.getHomeAssistant)(node); } catch (err) { const errorMessage = globals_1.RED._('config-server.errors.no_server_selected'); res.status(503).send({ error: errorMessage }); return; } next(); } async function getDeviceActions(req, res) { var _a, _b; let message; let success = true; const deviceId = (_a = req.query.deviceId) === null || _a === void 0 ? void 0 : _a.toString(); const actions = await ((_b = req === null || req === void 0 ? void 0 : req.homeAssistant) === null || _b === void 0 ? void 0 : _b.websocket.getDeviceActions(deviceId).catch((e) => { (0, debug_1.default)(`Error getting device actions. ${JSON.stringify(e)}`); success = false; message = e.message; return []; })); res.json({ success, data: actions !== null && actions !== void 0 ? actions : [], message }); } async function getDeviceActionCapabilities(req, res) { var _a; let success = true; let message; const queryEvent = req.query.event; let event; try { event = JSON.parse(queryEvent); } catch (e) { success = false; message = 'Invalid event'; res.json({ success, data: [], message }); return; } const capabilities = await ((_a = req === null || req === void 0 ? void 0 : req.homeAssistant) === null || _a === void 0 ? void 0 : _a.websocket.getDeviceActionCapabilities(event).catch((e) => { success = false; message = e.message; return []; })); res.json({ success, data: capabilities !== null && capabilities !== void 0 ? capabilities : [], message }); } async function getDeviceTriggers(req, res) { var _a, _b; let success = true; let message; const deviceId = (_a = req.query.deviceId) === null || _a === void 0 ? void 0 : _a.toString(); const triggers = await ((_b = req === null || req === void 0 ? void 0 : req.homeAssistant) === null || _b === void 0 ? void 0 : _b.websocket.getDeviceTriggers(deviceId).catch((e) => { success = false; message = e.message; return []; })); res.json({ success, data: triggers !== null && triggers !== void 0 ? triggers : [], message }); } async function getDeviceTriggerCapabilities(req, res) { var _a; let success = true; let message; const queryEvent = req.query.event; let event; try { event = JSON.parse(queryEvent); } catch (e) { success = false; message = 'Invalid event'; res.json({ success, data: [], message }); return; } const capabilities = await ((_a = req === null || req === void 0 ? void 0 : req.homeAssistant) === null || _a === void 0 ? void 0 : _a.websocket.getDeviceTriggerCapabilities(event).catch((e) => { success = false; message = e.message; return []; })); res.json({ success, data: capabilities !== null && capabilities !== void 0 ? capabilities : [], message }); } function getEntities(req, res) { var _a; const states = (_a = req === null || req === void 0 ? void 0 : req.homeAssistant) === null || _a === void 0 ? void 0 : _a.getEntities(); res.json(states !== null && states !== void 0 ? states : []); } function getStates(req, res) { var _a, _b, _c; const entityId = (_a = req.query.entityId) === null || _a === void 0 ? void 0 : _a.toString(); if (entityId === undefined) { res.json((_b = req === null || req === void 0 ? void 0 : req.homeAssistant) === null || _b === void 0 ? void 0 : _b.websocket.getStates()); return; } const entity = (_c = req === null || req === void 0 ? void 0 : req.homeAssistant) === null || _c === void 0 ? void 0 : _c.websocket.getState(entityId); res.json(entity !== null && entity !== void 0 ? entity : []); } function getServices(req, res) { var _a; const services = (_a = req === null || req === void 0 ? void 0 : req.homeAssistant) === null || _a === void 0 ? void 0 : _a.websocket.getServices(); res.json(services !== null && services !== void 0 ? services : []); } function getProperties(req, res) { var _a, _b, _c, _d; let flat = []; const entityId = (_a = req.query.entityId) === null || _a === void 0 ? void 0 : _a.toString(); const entity = entityId ? (_b = req === null || req === void 0 ? void 0 : req.homeAssistant) === null || _b === void 0 ? void 0 : _b.websocket.getState(entityId) : (_c = req === null || req === void 0 ? void 0 : req.homeAssistant) === null || _c === void 0 ? void 0 : _c.websocket.getStates(); if (Array.isArray(entity)) { flat = Object.keys((0, flat_1.default)(entity)).filter((e) => { var _a; return ((_a = req === null || req === void 0 ? void 0 : req.query) === null || _a === void 0 ? void 0 : _a.term) && e.indexOf(req.query.term.toString()) !== -1; }); } else { const entities = (_d = req.homeAssistant) === null || _d === void 0 ? void 0 : _d.websocket.getStates(); if (!entities) { res.json([]); return; } flat = Object.values(entities).map((entity) => Object.keys((0, flat_1.default)(entity))); } const uniqProperties = Array.from(new Set([].concat(...flat))); const sortedProperties = uniqProperties.sort((a, b) => { if (!a.includes('.') && b.includes('.')) return -1; if (a.includes('.') && !b.includes('.')) return 1; if (a < b) return -1; if (a > b) return 1; return 0; }); res.json(sortedProperties); } async function getTags(req, res) { const homeAssistant = req === null || req === void 0 ? void 0 : req.homeAssistant; const tags = req.query.update ? await (homeAssistant === null || homeAssistant === void 0 ? void 0 : homeAssistant.websocket.updateTagList()) : homeAssistant === null || homeAssistant === void 0 ? void 0 : homeAssistant.getTags(); const mappedTags = tags === null || tags === void 0 ? void 0 : tags.map((t) => { var _a; const tagName = (_a = homeAssistant === null || homeAssistant === void 0 ? void 0 : homeAssistant.websocket.getEntity(t.id)) === null || _a === void 0 ? void 0 : _a.name; return { id: t.id, name: tagName !== null && tagName !== void 0 ? tagName : t.name, }; }); res.json(mappedTags !== null && mappedTags !== void 0 ? mappedTags : []); } async function getTranslations(req, res) { var _a, _b, _c, _d; const category = (_a = req.query.cat) === null || _a === void 0 ? void 0 : _a.toString(); const language = (_c = (_b = req.query.lang) === null || _b === void 0 ? void 0 : _b.toString()) !== null && _c !== void 0 ? _c : 'en'; if (!category) { res.json({}); return; } const results = await ((_d = req === null || req === void 0 ? void 0 : req.homeAssistant) === null || _d === void 0 ? void 0 : _d.websocket.getTranslations(category, language)); res.json(results !== null && results !== void 0 ? results : []); } function getIntegrationVersion(req, res) { var _a, _b; res.json({ version: (_b = (_a = req === null || req === void 0 ? void 0 : req.homeAssistant) === null || _a === void 0 ? void 0 : _a.integrationVersion) !== null && _b !== void 0 ? _b : const_1.NO_VERSION, }); } function postHandleHiddenIssue(req, res) { const issue = req.body.issue; IssueService_1.default.toggleIssueHiddenStatus(issue); res.json({}); } function findServers(req, res) { const instances = []; const browser = (0, bonjour_1.default)().find({ type: 'home-assistant' }, (service) => { instances.push({ label: service.name ? `${service.name} (${service.txt.base_url})` : service.txt.base_url, value: service.txt.base_url, }); }); // Add a bit of delay for all services to be discovered setTimeout(() => { res.json(instances); browser.stop(); }, 3000); } function createRoutes() { const endpoints = { deviceActions: getDeviceActions, deviceActionCapabilities: getDeviceActionCapabilities, deviceTriggers: getDeviceTriggers, deviceTriggerCapabilities: getDeviceTriggerCapabilities, entities: getEntities, properties: getProperties, services: getServices, states: getStates, tags: getTags, translations: getTranslations, }; Object.entries(endpoints).forEach(([key, value]) => globals_1.RED.httpAdmin.get(`/homeassistant/${key}/:serverId?`, globals_1.RED.auth.needsPermission('server.read'), disableCache, checkHomeAssistant, value)); globals_1.RED.httpAdmin.get(`/homeassistant/version/:serverId`, globals_1.RED.auth.needsPermission('server.read'), checkHomeAssistant, getIntegrationVersion); globals_1.RED.httpAdmin.get('/homeassistant/discover', findServers); globals_1.RED.httpAdmin.get('/homeassistant/diagnostics', globals_1.RED.auth.needsPermission('server.read'), async (req, res) => { res.send(await (0, diagnostics_1.getEnvironmentData)()); }); globals_1.RED.httpAdmin.post('/homeassistant/issues/hidden', postHandleHiddenIssue); }