matterbridge-roborock-vacuum-plugin
Version:
Matterbridge Roborock Vacuum Plugin
214 lines • 8.63 kB
JavaScript
import { randomInt } from 'node:crypto';
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';
supportsMapQueryResponse = false;
lastB01Id;
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;
}
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,
],
}),
});
return this.client.send(duid, request);
}
// #region Core Data Retrieval
async getHomeMap(duid) {
return {};
}
async getMapInfo(duid) {
await this.client.send(duid, new RequestMessage({ messageId: this.messageId, dps: this.createDps(Q7RequestMethod.get_map_list, {}) }));
return new MapInfo({ max_multi_map: 0, max_bak_map: 0, multi_map_count: 0, map_info: [] });
}
getMapInfoV2(duid) {
return this.client.send(duid, new RequestMessage({ messageId: this.messageId, dps: this.createDps(Q7RequestMethod.get_map_list, {}) }));
}
async getRoomMap(duid, activeMap) {
await this.client.send(duid, new RequestMessage({
messageId: this.messageId,
dps: this.createDps(Q7RequestMethod.get_room_mapping, { force: 1, map_type: 0 }),
}));
return [];
}
getRoomMapV2(duid, activeMap) {
return this.client.send(duid, new RequestMessage({
messageId: this.messageId,
dps: this.createDps(Q7RequestMethod.get_room_mapping, { force: 1, map_type: 0 }),
}));
}
async switchMap(duid, mapId) {
await this.client.send(duid, new RequestMessage({
messageId: this.messageId,
dps: this.createDps(Q7RequestMethod.set_cur_map, { map_id: mapId }),
}));
}
// #endregion Core Data Retrieval
// #region Cleaning Commands
goHome(duid) {
const request = new RequestMessage({
messageId: this.messageId,
dps: this.createDps(Q7RequestMethod.app_charge, {}),
});
return this.client.send(duid, request);
}
async startCleaning(duid) {
await this.startRoomCleaning(duid, [], 1);
}
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,
}),
});
return this.client.send(duid, request);
}
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: [],
}),
});
return this.client.send(duid, request);
}
async resumeCleaning(duid) {
await this.startCleaning(duid);
}
async resumeRoomCleaning(duid) {
await this.startRoomCleaning(duid, [], 1);
}
skipRoomCleaning(duid) {
throw new Error(`skipRoomCleaning is not supported on ${this.dispatcherName}`);
}
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: [],
}),
});
return this.client.send(duid, request);
}
findMyRobot(duid) {
const request = new RequestMessage({ messageId: this.messageId, dps: this.createDps(Q7RequestMethod.find_me, {}) });
return this.client.send(duid, request);
}
sendCustomMessage(duid, def) {
const request = new RequestMessage({ ...def, messageId: this.messageId });
return this.client.send(duid, request);
}
async getCustomMessage(duid, def) {
const request = new RequestMessage({ ...def, messageId: this.messageId });
const result = await this.client.query(duid, request, (msg) => {
if (!msg.body)
return undefined;
const data = msg.body.data;
if (!data)
return undefined;
const values = Object.values(data);
return values.length > 0 ? values[0] : undefined;
});
return result;
}
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 } };
}
setCleanMode(duid, suctionPower, waterFlow) {
const request = new RequestMessage({
messageId: this.messageId,
dps: this.createDps(Q7RequestMethod.set_prop, {
'mode': B01VacuumModeResolver.resolveQ7CleanMode(suctionPower, waterFlow),
}),
});
return this.client.send(duid, request);
}
setVacuumMode(duid, suctionPower) {
const request = new RequestMessage({
messageId: this.messageId,
dps: this.createDps(Q7RequestMethod.set_prop, {
'wind': B01VacuumModeResolver.resolveQ7VacuumMode(suctionPower),
}),
});
return this.client.send(duid, request);
}
setMopMode(duid, waterFlow) {
const request = new RequestMessage({
messageId: this.messageId,
dps: this.createDps(Q7RequestMethod.set_prop, { 'water': B01VacuumModeResolver.resolveMopMode(waterFlow) }),
});
return this.client.send(duid, request);
}
setCleanRoute(duid, mopRoute) {
const request = new RequestMessage({
messageId: this.messageId,
dps: this.createDps(Q7RequestMethod.set_prop, {
'clean_path_preference': B01VacuumModeResolver.resolveCleanRoute(mopRoute),
}),
});
return this.client.send(duid, request);
}
}
//# sourceMappingURL=Q7MessageDispatcher.js.map