UNPKG

matterbridge-roborock-vacuum-plugin

Version:
205 lines 8.84 kB
import { randomInt } from 'node:crypto'; import { debugStringify } from 'matterbridge/logger'; import { CleanModeSetting } from '../../../behaviors/roborock.vacuum/core/CleanModeSetting.js'; import { CleanSequenceType } from '../../../behaviors/roborock.vacuum/enums/CleanSequenceType.js'; import { MapInfo } from '../../../core/application/models/index.js'; import { Q7CleanType, Q7ControlCode, Q7PropRequestCode, Q7RequestCode, Q7RequestMethod, } from '../../enums/Q7RequestCode.js'; import { B01VacuumModeResolver } from '../../helper/B01VacuumModeResolver.js'; import { RequestMessage } from '../../models/requestMessage.js'; export class Q7MessageDispatcher { logger; client; dispatcherName = 'Q7MessageDispatcher'; lastB01Id; // private readonly b01MapParser = new B01MapParser(); get messageId() { let tmpMessageId = Date.now(); if (tmpMessageId <= this.lastB01Id) { tmpMessageId = this.lastB01Id + 1; } this.lastB01Id = tmpMessageId; return this.lastB01Id; } constructor(logger, client) { this.logger = logger; this.client = client; this.lastB01Id = Date.now(); } async getNetworkInfo(duid) { // Q7 does not support getting network info, or maybe I just haven't found the right command yet. return undefined; } async getSerialNumber(duid) { return duid; } async getDeviceStatus(duid) { const request = new RequestMessage({ dps: this.createDps(Q7RequestMethod.get_prop, { property: [ Q7PropRequestCode.status, Q7PropRequestCode.fault, Q7PropRequestCode.sweep_type, Q7PropRequestCode.mode, Q7PropRequestCode.wind, Q7PropRequestCode.water, Q7PropRequestCode.clean_path_preference, Q7PropRequestCode.quantity, Q7PropRequestCode.cleaning_time, Q7PropRequestCode.cleaning_area, Q7PropRequestCode.clean_finish, ], }), }); await this.client.send(duid, request); return undefined; } // #region Core Data Retrieval async getHomeMap(duid) { return {}; } async getMapInfo(duid) { const request = new RequestMessage({ messageId: this.messageId, dps: this.createDps(Q7RequestMethod.get_map_list, {}), }); const response = await this.client.get(duid, request); this.logger.notice(`Get map info response for Q7 device ${duid}: ${response ? debugStringify(response) : 'no response'}`); return new MapInfo({ max_multi_map: 0, max_bak_map: 0, multi_map_count: 0, map_info: [] }); } async getRoomMap(duid, activeMap) { const request = new RequestMessage({ messageId: this.messageId, dps: this.createDps(Q7RequestMethod.get_room_mapping_backup_1, { map_id: activeMap, prefer_type: 1 }), }); const response = (await this.client.get(duid, request)) ?? []; this.logger.notice(`Get room map response for Q7 device ${duid}: ${response ? debugStringify(response) : 'no response'}`); return response; // TODO: Implement proper room mapping retrieval for Q7 } // public async getRoomMap(duid: string, activeMap: number): Promise<RawRoomMappingData> { // const request = new RequestMessage({ messageId: this.messageId, dps: this.createDps(Q7RequestMethod.get_room_mapping, { force: 1, map_type: 0 }) }); // const response = await this.client.get<ResponseBody>(duid, request); // if (!response) { // this.logger.error(`Get room map for Q7 device: ${duid}: no response`); // return []; // } // const responseData = response.get(Protocol.map_response) as Buffer; // const parsed = this.b01MapParser.parseRooms(responseData); // return parsed.rooms.map((x) => [x.roomId, x.roomName, x.roomTypeId ?? 0]); // } // #endregion Core Data Retrieval // #region Cleaning Commands async goHome(duid) { const request = new RequestMessage({ messageId: this.messageId, dps: this.createDps(Q7RequestMethod.app_charge, {}), }); await this.client.send(duid, request); } async startCleaning(duid) { await this.startRoomCleaning(duid, [], 1); } async startRoomCleaning(duid, roomIds, repeat) { const request = new RequestMessage({ messageId: this.messageId, dps: this.createDps(Q7RequestMethod.app_start_stop, { clean_type: Q7CleanType.room_clean, ctrl_value: Q7ControlCode.start, room_ids: roomIds, }), }); await this.client.send(duid, request); } async pauseCleaning(duid) { const request = new RequestMessage({ messageId: this.messageId, dps: this.createDps(Q7RequestMethod.app_start_stop, { clean_type: Q7CleanType.full_clean, ctrl_value: Q7ControlCode.pause, room_ids: [], }), }); await this.client.send(duid, request); } async resumeCleaning(duid) { await this.startCleaning(duid); } async resumeRoomCleaning(duid) { await this.startRoomCleaning(duid, [], 1); } async stopCleaning(duid) { const request = new RequestMessage({ messageId: this.messageId, dps: this.createDps(Q7RequestMethod.app_start_stop, { clean_type: Q7CleanType.full_clean, ctrl_value: Q7ControlCode.stop, room_ids: [], }), }); await this.client.send(duid, request); } async findMyRobot(duid) { const request = new RequestMessage({ messageId: this.messageId, dps: this.createDps(Q7RequestMethod.find_me, {}) }); await this.client.send(duid, request); } async sendCustomMessage(duid, def) { const request = new RequestMessage({ ...def, messageId: this.messageId }); await this.client.send(duid, request); } async getCustomMessage(duid, def) { const request = new RequestMessage({ ...def, messageId: this.messageId }); return this.client.get(duid, request); } async getCleanModeData(duid) { return new CleanModeSetting(0, 0, 0, 0, CleanSequenceType.Persist); // TODO: Implement retrieval of clean mode data for Q7 } async changeCleanMode(duid, setting) { const { suctionPower, waterFlow, distance_off, mopRoute } = setting; this.logger?.notice(`Change clean mode for ${duid} to suctionPower: ${suctionPower}, waterFlow: ${waterFlow}, mopRoute: ${mopRoute}, distance_off: ${distance_off}`); await this.setCleanMode(duid, suctionPower, waterFlow); if (suctionPower !== 0) { await this.setVacuumMode(duid, suctionPower); } if (waterFlow !== 0) { await this.setMopMode(duid, waterFlow); } } // #endregion Cleaning Commands // #region Private Helpers createDps(method, params) { const messageId = randomInt(100000000000, 999999999999).toString(); return { [Q7RequestCode.query]: { msgId: messageId, method: method, params: params } }; } async setCleanMode(duid, suctionPower, waterFlow) { const request = new RequestMessage({ messageId: this.messageId, dps: this.createDps(Q7RequestMethod.set_prop, { 'mode': B01VacuumModeResolver.resolveQ7CleanMode(suctionPower, waterFlow), }), }); await this.client.send(duid, request); } async setVacuumMode(duid, suctionPower) { const request = new RequestMessage({ messageId: this.messageId, dps: this.createDps(Q7RequestMethod.set_prop, { 'wind': B01VacuumModeResolver.resolveVacuumMode(suctionPower) }), }); await this.client.send(duid, request); } async setMopMode(duid, waterFlow) { const request = new RequestMessage({ messageId: this.messageId, dps: this.createDps(Q7RequestMethod.set_prop, { 'water': B01VacuumModeResolver.resolveMopMode(waterFlow) }), }); await this.client.send(duid, request); } async setCleanRoute(duid, mopRoute) { const request = new RequestMessage({ messageId: this.messageId, dps: this.createDps(Q7RequestMethod.set_prop, { 'clean_path_preference': B01VacuumModeResolver.resolveCleanRoute(mopRoute), }), }); await this.client.send(duid, request); } } //# sourceMappingURL=Q7MessageDispatcher.js.map