UNPKG

iobroker.bshb

Version:

Connects Bosch Smart Home Interface-Processes to ioBroker

235 lines 10.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.BshbAutomationHandler = void 0; const bshb_handler_1 = require("./bshb-handler"); const rxjs_1 = require("rxjs"); /** * This handler is used to detect automations of bshc * * @author Christopher Holomek * @since 18.01.2020 */ class BshbAutomationHandler extends bshb_handler_1.BshbHandler { automationRegex = /bshb\.\d+\.automations\.(.+?)\.(.+)/; handleDetection() { return this.detectAutomations().pipe((0, rxjs_1.tap)({ subscribe: () => this.bshb.log.info('Start detecting automations...'), finalize: () => this.bshb.log.info('Detecting automations finished'), })); } handleBshcUpdate(resultEntry) { if (resultEntry['@type'] === 'automationRule') { this.detectAutomations().subscribe(); return true; } return false; } sendUpdateToBshc(id, state) { const match = this.automationRegex.exec(id); let result = (0, rxjs_1.of)(false); if (match) { const automationId = match[1]; const key = match[2]; this.bshb.log.debug(`Found automation with id=${automationId}, key=${key} and value=${state.val}`); if (key === 'trigger') { result = this.getBshcClient() .triggerAutomation(automationId, { timeout: this.long_timeout }) .pipe((0, rxjs_1.delay)(1000), (0, rxjs_1.switchMap)(() => (0, rxjs_1.from)(this.bshb.setState(id, { val: false, ack: true, }))), (0, rxjs_1.tap)(this.handleBshcSendError(`id=${automationId}, value=${state.val}, key=${key}, automationId=${automationId}`)), (0, rxjs_1.map)(() => true)); } else { const idPrefix = 'automations.' + automationId; const data = {}; data['@type'] = 'automationRule'; data.id = automationId; result = (0, rxjs_1.from)(this.addAutomationValue(idPrefix, 'enabled', data) .then(() => this.addAutomationValue(idPrefix, 'name', data)) .then(() => this.addAutomationValue(idPrefix, 'automationConditions', data, val => JSON.parse(val))) .then(() => this.addAutomationValue(idPrefix, 'automationTriggers', data, val => JSON.parse(val))) .then(() => this.addAutomationValue(idPrefix, 'automationActions', data, val => JSON.parse(val))) .then(() => this.addAutomationValue(idPrefix, 'conditionLogicalOp', data))).pipe((0, rxjs_1.switchMap)(() => this.getBshcClient().setAutomation(automationId, data, { timeout: this.long_timeout, })), (0, rxjs_1.tap)(this.handleBshcSendError(`id=${automationId}, value=${state.val}, data=${JSON.stringify(data)}`)), (0, rxjs_1.map)(() => true)); } } return result; } async addAutomationValue(idPrefix, key, data, mapFnc) { const state = await this.bshb.getStateAsync(`${idPrefix}.${key}`); if (mapFnc) { return (data[key] = mapFnc(state.val)); } else { return (data[key] = state.val); } } detectAutomations() { return this.setObjectNotExistsAsync('automations', { type: 'folder', common: { name: 'automations', read: true, }, native: { id: 'automations', }, }).pipe((0, rxjs_1.switchMap)(() => this.getBshcClient().getAutomations(undefined, { timeout: this.long_timeout, })), (0, rxjs_1.switchMap)(response => this.deleteMissingAutomations(response.parsedResponse).pipe((0, rxjs_1.last)(undefined, void 0), (0, rxjs_1.switchMap)(() => (0, rxjs_1.from)(response.parsedResponse)))), (0, rxjs_1.mergeMap)(automation => { this.bshb.log.debug(`Found automation ${automation.id}, ${automation.name}`); const id = 'automations.' + automation.id; // we overwrite object here on purpose because we reflect 1-1 the data from controller here. return (0, rxjs_1.from)(this.bshb.setObject(id, { type: 'folder', common: { name: automation.name, type: 'boolean', role: 'switch', write: true, read: false, }, native: { id: automation.id, name: automation.name, }, })).pipe((0, rxjs_1.switchMap)(() => (0, rxjs_1.from)(this.bshb.setObject(`${id}.enabled`, { type: 'state', common: { name: 'enabled', type: 'boolean', role: 'switch', write: true, read: true, }, native: { id: `${id}.enabled`, name: 'enabled', }, }))), (0, rxjs_1.tap)(() => this.bshb.setState(`${id}.enabled`, { val: automation.enabled, ack: true, })), (0, rxjs_1.switchMap)(() => (0, rxjs_1.from)(this.bshb.setObject(`${id}.name`, { type: 'state', common: { name: 'name', type: 'string', role: 'text', write: true, read: true, }, native: { id: `${id}.name`, name: 'name', }, }))), (0, rxjs_1.tap)(() => this.bshb.setState(`${id}.name`, { val: automation.name, ack: true, })), (0, rxjs_1.switchMap)(() => (0, rxjs_1.from)(this.bshb.setObject(`${id}.trigger`, { type: 'state', common: { name: 'trigger', type: 'boolean', role: 'switch', write: true, read: false, }, native: { id: `${id}.trigger`, name: 'trigger', }, }))), (0, rxjs_1.tap)(() => this.bshb.setState(`${id}.trigger`, { val: false, ack: true })), (0, rxjs_1.switchMap)(() => (0, rxjs_1.from)(this.bshb.setObject(`${id}.automationConditions`, { type: 'state', common: { name: 'automationConditions', type: 'array', role: 'list', write: true, read: true, }, native: { id: `${id}.automationConditions`, name: 'automationConditions', }, }))), (0, rxjs_1.tap)(() => this.bshb.setState(`${id}.automationConditions`, { val: this.mapValueToStorage(automation.automationConditions), ack: true, })), (0, rxjs_1.switchMap)(() => (0, rxjs_1.from)(this.bshb.setObject(`${id}.automationTriggers`, { type: 'state', common: { name: 'automationTriggers', type: 'array', role: 'list', write: true, read: true, }, native: { id: `${id}.automationTriggers`, name: 'automationTriggers', }, }))), (0, rxjs_1.tap)(() => this.bshb.setState(`${id}.automationTriggers`, { val: this.mapValueToStorage(automation.automationTriggers), ack: true, })), (0, rxjs_1.switchMap)(() => (0, rxjs_1.from)(this.bshb.setObject(`${id}.automationActions`, { type: 'state', common: { name: 'automationActions', type: 'array', role: 'list', write: true, read: true, }, native: { id: `${id}.automationActions`, name: 'automationActions', }, }))), (0, rxjs_1.tap)(() => this.bshb.setState(`${id}.automationActions`, { val: this.mapValueToStorage(automation.automationActions), ack: true, })), (0, rxjs_1.switchMap)(() => (0, rxjs_1.from)(this.bshb.setObject(`${id}.conditionLogicalOp`, { type: 'state', common: { name: 'conditionLogicalOp', type: 'string', role: 'text', write: true, read: true, }, native: { id: `${id}.conditionLogicalOp`, name: 'conditionLogicalOp', }, }))), (0, rxjs_1.tap)(() => this.bshb.setState(`${id}.conditionLogicalOp`, { val: automation.conditionLogicalOp, ack: true, }))); }), (0, rxjs_1.switchMap)(() => (0, rxjs_1.of)(undefined))); } deleteMissingAutomations(automations) { return (0, rxjs_1.from)(this.bshb.getStatesOfAsync('automations', '')).pipe((0, rxjs_1.switchMap)(objects => (0, rxjs_1.from)(objects)), (0, rxjs_1.switchMap)(object => { let found = false; for (let i = 0; i < automations.length; i++) { if (object.native.id === automations[i].id) { // found automation found = true; break; } } if (!found) { return (0, rxjs_1.from)(this.bshb.delObjectAsync(`automations.${object.native.id}`)).pipe((0, rxjs_1.tap)(() => this.bshb.log.info(`automation with id=${object.native.id} removed because it does not exist anymore.`)), (0, rxjs_1.catchError)(err => { this.bshb.log.error(`Could not delete automation with id=${object.native.id} because: ` + err); return (0, rxjs_1.of)(undefined); })); } else { return (0, rxjs_1.of)(undefined); } })); } name() { return 'automationHandler'; } } exports.BshbAutomationHandler = BshbAutomationHandler; //# sourceMappingURL=bshb-automation-handler.js.map