UNPKG

node-red-contrib-home-assistant-websocket

Version:
261 lines (260 loc) 14.6 kB
"use strict"; var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { if (kind === "m") throw new TypeError("Private method is not writable"); if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; }; var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; var _JSONataService_homeAssistant, _JSONataService_node; Object.defineProperty(exports, "__esModule", { value: true }); const lodash_1 = require("lodash"); const globals_1 = require("../../globals"); const utils_1 = require("../../helpers/utils"); const JSONataError_1 = __importDefault(require("../errors/JSONataError")); function evaluateJSONataExpression(expr, message) { return new Promise((resolve, reject) => { globals_1.RED.util.evaluateJSONataExpression(expr, message, (err, res) => { if (err) { reject(err); } else { resolve(res); } }); }); } function isJSONataError(error) { if (typeof error !== 'object' || !error) return false; return ('code' in error && 'message' in error && 'stack' in error && 'token' in error); } class JSONataService { constructor({ homeAssistant, node, }) { _JSONataService_homeAssistant.set(this, void 0); _JSONataService_node.set(this, void 0); __classPrivateFieldSet(this, _JSONataService_homeAssistant, homeAssistant, "f"); __classPrivateFieldSet(this, _JSONataService_node, node, "f"); } async evaluate(expression, objs = {}) { let expr; try { expr = globals_1.RED.util.prepareJSONataExpression(expression, __classPrivateFieldGet(this, _JSONataService_node, "f")); } catch (err) { if (isJSONataError(err)) { throw new JSONataError_1.default(err); } throw err; } const { entity, message, prevEntity } = objs; expr.assign('areas', this.areas.bind(this)); expr.assign('areaDevices', this.areaDevices.bind(this)); expr.assign('areaEntities', this.areaEntities.bind(this)); expr.assign('deviceEntities', this.deviceEntities.bind(this)); expr.assign('device', this.device.bind(this)); expr.assign('entity', () => entity); expr.assign('entities', (val) => { var _a, _b; return (_b = (_a = __classPrivateFieldGet(this, _JSONataService_homeAssistant, "f")) === null || _a === void 0 ? void 0 : _a.websocket) === null || _b === void 0 ? void 0 : _b.getState(val); }); expr.assign('outputData', (obj) => { if (!obj) { const filtered = Object.keys(objs).reduce((acc, key) => { // ignore message as it already accessable if (key !== 'message' && objs[key] !== undefined) { acc[key] = objs[key]; } return acc; }, {}); return filtered; } return objs[obj]; }); expr.assign('prevEntity', () => prevEntity); expr.assign('randomNumber', lodash_1.random); expr.assign('sampleSize', lodash_1.sampleSize); try { // await here to catch JSONataError return await evaluateJSONataExpression(expr, message); } catch (err) { if (isJSONataError(err)) { throw new JSONataError_1.default(err); } throw err; } } /** * This method retrieves all devices associated with a specific area ID. * It first retrieves the area using the provided area ID. * If the area exists, it retrieves all devices. * It then iterates over each device, checking if it is associated with the area. * If the device is associated with the area, it is added to the list of devices in the area. * If the area does not exist, or if there are no devices associated with the area, it returns an empty array. * * @param areaId - The ID of the area for which to retrieve the devices. * @returns An array of devices associated with the area, or an empty array if the area does not exist or has no associated devices. */ areaDevices(areaId) { var _a, _b, _c, _d; const areas = (_b = (_a = __classPrivateFieldGet(this, _JSONataService_homeAssistant, "f")) === null || _a === void 0 ? void 0 : _a.websocket) === null || _b === void 0 ? void 0 : _b.getArea(areaId); const devicesInArea = []; if (areas) { const devices = (_d = (_c = __classPrivateFieldGet(this, _JSONataService_homeAssistant, "f")) === null || _c === void 0 ? void 0 : _c.websocket) === null || _d === void 0 ? void 0 : _d.getDevices(); if (devices) { devices.forEach((device) => { if (device.area_id === areaId) { devicesInArea.push(device); } }); } } return devicesInArea; } /** * This method retrieves all entities associated with a specific area ID. * It first retrieves the area using the provided area ID. * If the area exists, it retrieves all entities and devices. * It then iterates over each entity, checking if it is associated with the area either directly or through a device. * If the entity is associated with the area, it is added to the list of entities in the area. * If the area does not exist, or if there are no entities associated with the area, it returns an empty array. * * @param areaId - The ID of the area for which to retrieve the entities. * @returns An array of entities associated with the area, or an empty array if the area does not exist or has no associated entities. */ areaEntities(areaId) { var _a, _b, _c, _d, _e, _f; const areas = (_b = (_a = __classPrivateFieldGet(this, _JSONataService_homeAssistant, "f")) === null || _a === void 0 ? void 0 : _a.websocket) === null || _b === void 0 ? void 0 : _b.getArea(areaId); const entitiesInArea = []; if (areas) { const devices = (_d = (_c = __classPrivateFieldGet(this, _JSONataService_homeAssistant, "f")) === null || _c === void 0 ? void 0 : _c.websocket) === null || _d === void 0 ? void 0 : _d.getDevices(); (_f = (_e = __classPrivateFieldGet(this, _JSONataService_homeAssistant, "f")) === null || _e === void 0 ? void 0 : _e.websocket) === null || _f === void 0 ? void 0 : _f.getEntities().forEach((entry) => { var _a, _b; const entity = (_b = (_a = __classPrivateFieldGet(this, _JSONataService_homeAssistant, "f")) === null || _a === void 0 ? void 0 : _a.websocket) === null || _b === void 0 ? void 0 : _b.getState(entry.entity_id); if (entity) { if (entry.area_id === areaId) { entitiesInArea.push(entity); } else { const device = devices === null || devices === void 0 ? void 0 : devices.find((device) => device.id === entry.device_id); if ((device === null || device === void 0 ? void 0 : device.area_id) === areaId) { entitiesInArea.push(entity); } } } }); } return entitiesInArea; } areas(lookup) { var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k; if (typeof lookup !== 'string') { return (_b = (_a = __classPrivateFieldGet(this, _JSONataService_homeAssistant, "f")) === null || _a === void 0 ? void 0 : _a.websocket) === null || _b === void 0 ? void 0 : _b.getAreas(); } const areas = (_d = (_c = __classPrivateFieldGet(this, _JSONataService_homeAssistant, "f")) === null || _c === void 0 ? void 0 : _c.websocket) === null || _d === void 0 ? void 0 : _d.getAreas(); const area = areas === null || areas === void 0 ? void 0 : areas.find((area) => area.area_id === lookup); if (area) { return area; } if ((0, utils_1.validEntityId)(lookup)) { const entity = (_f = (_e = __classPrivateFieldGet(this, _JSONataService_homeAssistant, "f")) === null || _e === void 0 ? void 0 : _e.websocket) === null || _f === void 0 ? void 0 : _f.getEntity(lookup); if (entity) { // check if entity has area id and return area name if (entity.area_id) { const area = areas === null || areas === void 0 ? void 0 : areas.find((area) => area.area_id === entity.area_id); if (area) { return area; } } // check if entity has device id and return area name if (entity.device_id) { const device = (_h = (_g = __classPrivateFieldGet(this, _JSONataService_homeAssistant, "f")) === null || _g === void 0 ? void 0 : _g.websocket) === null || _h === void 0 ? void 0 : _h.getDevice(entity.device_id); if (device) { if (device.area_id) { const area = areas === null || areas === void 0 ? void 0 : areas.find((area) => area.area_id === device.area_id); if (area) { return area; } } } } } } // fallback to see if lookup is a device id const devices = (_k = (_j = __classPrivateFieldGet(this, _JSONataService_homeAssistant, "f")) === null || _j === void 0 ? void 0 : _j.websocket) === null || _k === void 0 ? void 0 : _k.getDevices(); const device = devices === null || devices === void 0 ? void 0 : devices.find((device) => device.id === lookup); if (device) { if (device.area_id) { const area = areas === null || areas === void 0 ? void 0 : areas.find((area) => area.area_id === device.area_id); if (area) { return area; } } } } /** * This method retrieves a device based on a provided lookup value. * The lookup value can be an entity ID or a device name. * If the lookup value is an entity ID, it retrieves the entity and checks if it has a device ID. * If the entity has a device ID, it retrieves the device that matches the device ID. * If the lookup value is a device name, it retrieves the device that matches the name. * If the lookup value does not match any entity or device, it returns undefined. * * @param lookup - The lookup value, which can be an entity ID or a device name. * @returns The device associated with the entity or the device that matches the name, or undefined if the lookup value does not match any entity or device. */ device(lookup) { var _a, _b, _c, _d; const entities = (_b = (_a = __classPrivateFieldGet(this, _JSONataService_homeAssistant, "f")) === null || _a === void 0 ? void 0 : _a.websocket) === null || _b === void 0 ? void 0 : _b.getEntity(lookup); const devices = (_d = (_c = __classPrivateFieldGet(this, _JSONataService_homeAssistant, "f")) === null || _c === void 0 ? void 0 : _c.websocket) === null || _d === void 0 ? void 0 : _d.getDevices(); if (entities) { if (devices) { return devices.find((device) => device.id === entities.device_id); } } const device = devices === null || devices === void 0 ? void 0 : devices.find((device) => device.name_by_user === lookup || device.name === lookup); if (device) { return device; } } /** * This method retrieves all entities associated with a specific device. * It first retrieves the device using the provided device ID. * If the device exists, it retrieves all entities. * It then filters the entities to include only those associated with the device. * If the device does not exist, or if there are no entities associated with the device, it returns an empty array. * * @param deviceId - The ID of the device for which to retrieve the entities. * @returns An array of entities associated with the device, or an empty array if the device does not exist or has no associated entities. */ deviceEntities(deviceId) { var _a, _b, _c, _d; const devices = (_b = (_a = __classPrivateFieldGet(this, _JSONataService_homeAssistant, "f")) === null || _a === void 0 ? void 0 : _a.websocket) === null || _b === void 0 ? void 0 : _b.getDevice(deviceId); const entities = []; if (devices) { (_d = (_c = __classPrivateFieldGet(this, _JSONataService_homeAssistant, "f")) === null || _c === void 0 ? void 0 : _c.websocket) === null || _d === void 0 ? void 0 : _d.getEntities().forEach((entry) => { var _a, _b; if (entry.device_id === deviceId) { const entity = (_b = (_a = __classPrivateFieldGet(this, _JSONataService_homeAssistant, "f")) === null || _a === void 0 ? void 0 : _a.websocket) === null || _b === void 0 ? void 0 : _b.getState(entry.entity_id); if (entity) { entities.push(entity); } } }); } return entities; } } _JSONataService_homeAssistant = new WeakMap(), _JSONataService_node = new WeakMap(); exports.default = JSONataService;