UNPKG

@di-zed/yandex-smart-home

Version:

The Yandex Smart Home skills for the different device types.

248 lines (247 loc) 11.1 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const mqttRepository_1 = __importDefault(require("../repositories/mqttRepository")); const deviceService_1 = __importDefault(require("./deviceService")); /** * MQTT Service. */ class MqttService { /** * Get Topic Names. * * @param input * @returns Promise<MqttOutputTopicNames> */ getTopicNames(input) { return __awaiter(this, void 0, void 0, function* () { const topicNames = { stateTopic: '', configTopic: '', availableTopic: '', commandTopic: '', }; let deviceType = ''; (yield deviceService_1.default.getUserDevices(input.user.id)).forEach((userDevice) => { if (userDevice.id === input.deviceId) { deviceType = userDevice.type ? userDevice.type : ''; } }); (yield mqttRepository_1.default.getConfigTopics()).forEach((topicData) => { if (topicData.deviceType === deviceType) { topicNames.stateTopic = this.handleTopicName(topicData.stateTopic, input.user, input.deviceId); topicNames.configTopic = this.handleTopicName(topicData.configTopic, input.user, input.deviceId); topicNames.availableTopic = this.handleTopicName(topicData.availableTopic, input.user, input.deviceId); topicData.commandTopics.forEach((commandTopicData) => { const typeState = { capabilityType: input.capabilityType, capabilityStateInstance: input.capabilityStateInstance, propertyType: input.propertyType, propertyStateInstance: input.propertyStateInstance, }; if (this.matchTopicTypeState(commandTopicData, typeState)) { topicNames.commandTopic = this.handleTopicName(commandTopicData.topic, input.user, input.deviceId); } }); } }); return topicNames; }); } /** * Get Data from the Topic. * * @param topic * @param typeState * @returns Promise<TopicData | undefined> */ getTopicData(topic, typeState) { return __awaiter(this, void 0, void 0, function* () { let result = undefined; const configTopics = yield mqttRepository_1.default.getConfigTopics(); configTopics.every((item) => { const stateTopic = this.parseTopicName(item.stateTopic, topic); if (stateTopic !== undefined) { result = Object.assign(Object.assign({}, stateTopic), { topicType: 'stateTopic' }); return false; } const configTopic = this.parseTopicName(item.configTopic, topic); if (configTopic !== undefined) { result = Object.assign(Object.assign({}, configTopic), { topicType: 'configTopic' }); return false; } const availableTopic = this.parseTopicName(item.availableTopic, topic); if (availableTopic !== undefined) { result = Object.assign(Object.assign({}, availableTopic), { topicType: 'availableTopic' }); return false; } let isCommandTopic = false; item.commandTopics.every((itemCommandTopic) => { const commandTopic = this.parseTopicName(itemCommandTopic.topic, topic); if (commandTopic !== undefined) { if (typeState && !this.matchTopicTypeState(itemCommandTopic, typeState)) { return true; } result = Object.assign(Object.assign({}, commandTopic), { topicType: 'commandTopic' }); isCommandTopic = true; return false; } return true; }); return !isCommandTopic; }); return result; }); } /** * Get Data from the Command Topic. * * @param topic * @param deviceType * @param typeState * @returns Promise<CommandTopicData | undefined> */ getCommandTopicData(topic, deviceType, typeState) { return __awaiter(this, void 0, void 0, function* () { let result = undefined; const configTopics = yield mqttRepository_1.default.getConfigTopics(); configTopics.forEach((configTopic) => { if (configTopic.deviceType === deviceType) { configTopic.commandTopics.every((commandTopic) => { var _a, _b, _c, _d; const parsedTopicName = this.parseTopicName(commandTopic.topic, topic); if (parsedTopicName !== undefined) { if (typeState && !this.matchTopicTypeState(commandTopic, typeState)) { return true; } result = { deviceId: parsedTopicName.deviceId, deviceType: configTopic.deviceType, capabilityType: ((_a = commandTopic.capability) === null || _a === void 0 ? void 0 : _a.type) ? commandTopic.capability.type : '', capabilityStateInstance: ((_b = commandTopic.capability) === null || _b === void 0 ? void 0 : _b.stateInstance) ? commandTopic.capability.stateInstance : '', propertyType: ((_c = commandTopic.property) === null || _c === void 0 ? void 0 : _c.type) ? commandTopic.property.type : '', propertyStateInstance: ((_d = commandTopic.property) === null || _d === void 0 ? void 0 : _d.stateInstance) ? commandTopic.property.stateInstance : '', topicConfigKey: commandTopic.topicConfigKey || '', topicStateKeys: commandTopic.topicStateKeys || [], messageValueMapping: commandTopic.messageValueMapping || {}, userName: parsedTopicName.userName, }; return false; } return true; }); } }); return result; }); } /** * Check the Topic Type. * * @param topic * @param expectedType * @returns Promise<boolean> */ isTopicType(topic, expectedType) { return __awaiter(this, void 0, void 0, function* () { let result = false; const configTopics = yield mqttRepository_1.default.getConfigTopics(); configTopics.every((item) => __awaiter(this, void 0, void 0, function* () { if (expectedType === 'commandTopic') { item.commandTopics.every((commandItem) => __awaiter(this, void 0, void 0, function* () { const commandTopicName = this.parseTopicName(commandItem.topic, topic); if (commandTopicName !== undefined) { result = true; return false; } return true; })); return !result; } else { const topicName = this.parseTopicName(item[expectedType], topic); if (topicName !== undefined) { result = true; return false; } } return true; })); return result; }); } /** * Get Parsed Information from the Topic Name. * * @param patternTopic * @param topic * @returns ParsedTopicName | undefined */ parseTopicName(patternTopic, topic) { const pattern = patternTopic.replace('<user_name>', '([^/]*)').replace('<device_id>', '([^/]*)'); const re = new RegExp('^' + pattern + '$', 'g'); const match = re.exec(topic); if (match) { return { userName: match[1], deviceId: match[2], }; } return undefined; } /** * Get Username for the MQTT Topic. * * @param user * @returns string */ getTopicUserName(user) { // return user.fullName ? user.fullName.replace(/\s/g, '_') : user.email; return user.email; } /** * Handle Topic Name. * * @param topicName * @param user * @param deviceId * @returns string */ handleTopicName(topicName, user, deviceId) { return topicName.replace('<user_name>', this.getTopicUserName(user)).replace('<device_id>', deviceId); } /** * Match Type & State Instance. * * @param commandTopic * @param typeState * @returns boolean */ matchTopicTypeState(commandTopic, typeState) { var _a, _b, _c, _d; if (typeState.capabilityType && typeState.capabilityStateInstance) { if (((_a = commandTopic.capability) === null || _a === void 0 ? void 0 : _a.type) === typeState.capabilityType && ((_b = commandTopic.capability) === null || _b === void 0 ? void 0 : _b.stateInstance) === typeState.capabilityStateInstance) { return true; } } if (typeState.propertyType && typeState.propertyStateInstance) { if (((_c = commandTopic.property) === null || _c === void 0 ? void 0 : _c.type) === typeState.propertyType && ((_d = commandTopic.property) === null || _d === void 0 ? void 0 : _d.stateInstance) === typeState.propertyStateInstance) { return true; } } return false; } } exports.default = new MqttService();