UNPKG

node-red-contrib-home-assistant-websocket

Version:
244 lines (243 loc) 14.7 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 _GetEntitiesController_instances, _GetEntitiesController_comparatorService, _GetEntitiesController_homeAssistant, _GetEntitiesController_currentDevice, _GetEntitiesController_currentArea, _GetEntitiesController_currentFloor, _GetEntitiesController_getEntities, _GetEntitiesController_checkConditions, _GetEntitiesController_checkLabelCondition, _GetEntitiesController_getPropertyValue, _GetEntitiesController_getDevice, _GetEntitiesController_getArea, _GetEntitiesController_getFloor, _GetEntitiesController_resetCurrent; Object.defineProperty(exports, "__esModule", { value: true }); const lodash_1 = require("lodash"); const selectn_1 = __importDefault(require("selectn")); const const_1 = require("../../common/const"); const InputOutputController_1 = __importDefault(require("../../common/controllers/InputOutputController")); const SendSplitMixin_1 = __importDefault(require("../../common/controllers/SendSplitMixin")); const const_2 = require("../../const"); const const_3 = require("./const"); const helpers_1 = require("./helpers"); const operators_1 = require("./operators"); const SendSplitController = (0, SendSplitMixin_1.default)((InputOutputController_1.default)); class GetEntitiesController extends SendSplitController { constructor(params) { super(params); _GetEntitiesController_instances.add(this); _GetEntitiesController_comparatorService.set(this, void 0); _GetEntitiesController_homeAssistant.set(this, void 0); // Store the current device and area to avoid multiple lookups _GetEntitiesController_currentDevice.set(this, void 0); _GetEntitiesController_currentArea.set(this, void 0); _GetEntitiesController_currentFloor.set(this, void 0); __classPrivateFieldSet(this, _GetEntitiesController_comparatorService, params.comparatorService, "f"); __classPrivateFieldSet(this, _GetEntitiesController_homeAssistant, params.homeAssistant, "f"); } async onInput({ message, parsedMessage, send, done, }) { let noPayload = false; const entities = await __classPrivateFieldGet(this, _GetEntitiesController_instances, "m", _GetEntitiesController_getEntities).call(this, parsedMessage.rules.value, message); let statusText = [ 'ha-get-entities.status.number_of_results', { count: entities.length }, ]; let payload = []; switch (parsedMessage.outputType.value) { case const_3.OutputType.Count: payload = entities.length; break; case const_3.OutputType.Split: if (entities.length === 0) { noPayload = true; break; } this.status.setSuccess(statusText); this.sendSplit(message, entities, send); done(); return; case const_3.OutputType.Random: { if (entities.length === 0) { noPayload = true; break; } const maxReturned = Number(parsedMessage.outputResultsCount.value) || 1; const max = entities.length <= maxReturned ? entities.length : maxReturned; const shuffledEntities = (0, lodash_1.shuffle)(entities); payload = shuffledEntities.slice(0, max); if (maxReturned === 1) { payload = payload[0]; statusText = [ 'ha-get-entities.status.number_of_random_resuls', { count: 1 }, ]; } else { statusText = [ 'ha-get-entities.status.number_of_random_resuls', { count: Array.isArray(payload) ? payload.length : 0 }, ]; } break; } case const_3.OutputType.Array: default: if (entities.length === 0 && !parsedMessage.outputEmptyResults.value) { noPayload = true; } payload = entities; break; } if (noPayload) { this.status.setFailed('ha-get-entities.status.no_results'); done(); return; } this.status.setSuccess(statusText); this.contextService.set(payload, parsedMessage.outputLocationType.value, parsedMessage.outputLocation.value, message); send(message); done(); } } _GetEntitiesController_comparatorService = new WeakMap(), _GetEntitiesController_homeAssistant = new WeakMap(), _GetEntitiesController_currentDevice = new WeakMap(), _GetEntitiesController_currentArea = new WeakMap(), _GetEntitiesController_currentFloor = new WeakMap(), _GetEntitiesController_instances = new WeakSet(), _GetEntitiesController_getEntities = async function _GetEntitiesController_getEntities(conditions, message) { const currentTime = Date.now(); const filteredEntities = []; const states = __classPrivateFieldGet(this, _GetEntitiesController_homeAssistant, "f").websocket.getStates(); const sortedConditions = (0, helpers_1.sortConditions)(conditions); const stateKeys = Object.keys(states); for (let i = 0; i < stateKeys.length; i++) { const entityStateId = stateKeys[i]; const entityState = states[entityStateId]; __classPrivateFieldGet(this, _GetEntitiesController_instances, "m", _GetEntitiesController_resetCurrent).call(this); // TODO: Remove for version 1.0 if (entityState === null || entityState === void 0 ? void 0 : entityState.last_changed) { entityState.timeSinceChangedMs = currentTime - new Date(entityState.last_changed).getTime(); } const entity = __classPrivateFieldGet(this, _GetEntitiesController_homeAssistant, "f").websocket.getEntity(entityState.entity_id); const ruleMatched = await __classPrivateFieldGet(this, _GetEntitiesController_instances, "m", _GetEntitiesController_checkConditions).call(this, sortedConditions, entityState, entity, message); if (ruleMatched && entityState) { filteredEntities.push(entityState); } } return filteredEntities; }, _GetEntitiesController_checkConditions = async function _GetEntitiesController_checkConditions(conditions, entityState, entity, message) { for (let i = 0; i < conditions.length; i++) { const rule = conditions[i]; if (rule.condition === const_1.PropertySelectorType.State || // If the condition is not set, it is a state condition rule.condition === undefined) { const value = (0, selectn_1.default)(rule.property, entityState); const result = await __classPrivateFieldGet(this, _GetEntitiesController_comparatorService, "f").getComparatorResult(rule.logic, rule.value, value, rule.valueType, { message, entity: entityState, }); if ((rule.logic !== const_2.TypedInputTypes.JSONata && value === undefined) || !result) { return false; } } else if (rule.condition === const_1.PropertySelectorType.Label) { if (!entity) return false; const labelCheck = await __classPrivateFieldGet(this, _GetEntitiesController_instances, "m", _GetEntitiesController_checkLabelCondition).call(this, rule, entity, entityState, message); if (!labelCheck) { return false; } } else { const propertyValue = __classPrivateFieldGet(this, _GetEntitiesController_instances, "m", _GetEntitiesController_getPropertyValue).call(this, rule.condition, rule.property, entity); if (!propertyValue) return false; const result = (0, operators_1.simpleComparison)(rule.logic, propertyValue, await this.typedInputService.getValue(rule.value, rule.valueType, { message, entity: entityState, })); if (!result) { return false; } } } return true; }, _GetEntitiesController_checkLabelCondition = async function _GetEntitiesController_checkLabelCondition(rule, entity, entityState, message) { const value = await this.typedInputService.getValue(rule.value, rule.valueType, { message, entity: entityState }); const hasMatchingLabel = (labelIds) => { if (!labelIds) return false; for (const labelId of labelIds) { const label = __classPrivateFieldGet(this, _GetEntitiesController_homeAssistant, "f").websocket.getLabel(labelId); if (!label) continue; const result = (0, operators_1.simpleComparison)(rule.logic, label[rule.property], value); if (result) return true; } return false; }; // Check entity labels if (hasMatchingLabel(entity.labels)) return true; // Check device labels const device = __classPrivateFieldGet(this, _GetEntitiesController_instances, "m", _GetEntitiesController_getDevice).call(this, entity); if (hasMatchingLabel(device === null || device === void 0 ? void 0 : device.labels)) return true; // Check area labels const area = __classPrivateFieldGet(this, _GetEntitiesController_instances, "m", _GetEntitiesController_getArea).call(this, entity); if (hasMatchingLabel(area === null || area === void 0 ? void 0 : area.labels)) return true; return false; }, _GetEntitiesController_getPropertyValue = function _GetEntitiesController_getPropertyValue(condition, property, entity) { var _a, _b, _c; if (!entity) return undefined; switch (condition) { case const_1.PropertySelectorType.Device: return (_a = __classPrivateFieldGet(this, _GetEntitiesController_instances, "m", _GetEntitiesController_getDevice).call(this, entity)) === null || _a === void 0 ? void 0 : _a[property]; case const_1.PropertySelectorType.Area: return (_b = __classPrivateFieldGet(this, _GetEntitiesController_instances, "m", _GetEntitiesController_getArea).call(this, entity)) === null || _b === void 0 ? void 0 : _b[property]; case const_1.PropertySelectorType.Floor: return (_c = __classPrivateFieldGet(this, _GetEntitiesController_instances, "m", _GetEntitiesController_getFloor).call(this, entity)) === null || _c === void 0 ? void 0 : _c[property]; default: return undefined; } }, _GetEntitiesController_getDevice = function _GetEntitiesController_getDevice(entity) { if (!__classPrivateFieldGet(this, _GetEntitiesController_currentDevice, "f") && entity.device_id) { __classPrivateFieldSet(this, _GetEntitiesController_currentDevice, __classPrivateFieldGet(this, _GetEntitiesController_homeAssistant, "f").websocket.getDevice(entity.device_id), "f"); } return __classPrivateFieldGet(this, _GetEntitiesController_currentDevice, "f"); }, _GetEntitiesController_getArea = function _GetEntitiesController_getArea(entity) { if (__classPrivateFieldGet(this, _GetEntitiesController_currentArea, "f")) { return __classPrivateFieldGet(this, _GetEntitiesController_currentArea, "f"); } if (entity.area_id) { __classPrivateFieldSet(this, _GetEntitiesController_currentArea, __classPrivateFieldGet(this, _GetEntitiesController_homeAssistant, "f").websocket.getArea(entity.area_id), "f"); } if (!__classPrivateFieldGet(this, _GetEntitiesController_currentArea, "f") && entity.device_id) { const device = __classPrivateFieldGet(this, _GetEntitiesController_instances, "m", _GetEntitiesController_getDevice).call(this, entity); if (device === null || device === void 0 ? void 0 : device.area_id) { __classPrivateFieldSet(this, _GetEntitiesController_currentArea, __classPrivateFieldGet(this, _GetEntitiesController_homeAssistant, "f").websocket.getArea(device.area_id), "f"); } } return __classPrivateFieldGet(this, _GetEntitiesController_currentArea, "f"); }, _GetEntitiesController_getFloor = function _GetEntitiesController_getFloor(entity) { if (__classPrivateFieldGet(this, _GetEntitiesController_currentFloor, "f")) { return __classPrivateFieldGet(this, _GetEntitiesController_currentFloor, "f"); } const area = __classPrivateFieldGet(this, _GetEntitiesController_instances, "m", _GetEntitiesController_getArea).call(this, entity); if (area === null || area === void 0 ? void 0 : area.floor_id) { __classPrivateFieldSet(this, _GetEntitiesController_currentFloor, __classPrivateFieldGet(this, _GetEntitiesController_homeAssistant, "f").websocket.getFloor(area.floor_id), "f"); } return __classPrivateFieldGet(this, _GetEntitiesController_currentFloor, "f"); }, _GetEntitiesController_resetCurrent = function _GetEntitiesController_resetCurrent() { __classPrivateFieldSet(this, _GetEntitiesController_currentDevice, undefined, "f"); __classPrivateFieldSet(this, _GetEntitiesController_currentArea, undefined, "f"); __classPrivateFieldSet(this, _GetEntitiesController_currentFloor, undefined, "f"); }; exports.default = GetEntitiesController;