matterbridge-roborock-vacuum-plugin
Version:
Matterbridge Roborock Vacuum Plugin
97 lines • 4.5 kB
JavaScript
import crypto from 'node:crypto';
import * as axios from 'axios';
import { debugStringify } from 'matterbridge/logger';
import { getBaseUrl } from '../initialData/regionUrls.js';
import { RoborockAuthenticateApi } from '../roborockCommunication/api/authClient.js';
import { RoborockIoTApi } from '../roborockCommunication/api/iotClient.js';
import { RoborockService } from '../services/roborockService.js';
import { isSupportedDevice } from '../share/helper.js';
/**
* Handles device discovery: authentication, API calls, and device filtering.
*/
export class DeviceDiscovery {
platform;
configManager;
registry;
getPersistanceStorage;
toastMessage;
log;
roborockService;
constructor(platform, configManager, registry, getPersistanceStorage, toastMessage, log) {
this.platform = platform;
this.configManager = configManager;
this.registry = registry;
this.getPersistanceStorage = getPersistanceStorage;
this.toastMessage = toastMessage;
this.log = log;
}
async discoverDevices() {
this.log.info('startDeviceDiscovery start');
const cleanModeSettings = this.configManager.cleanModeSettings;
if (cleanModeSettings) {
this.log.notice(`Custom Clean Mode Mapping Enabled: ${this.configManager.isCustomCleanModeMappingEnabled ? 'Enabled' : 'Disabled'},
Clean Mode Settings: ${debugStringify(cleanModeSettings)}`);
}
const persist = this.getPersistanceStorage();
// Load or generate sessionId for consistent authentication
let sessionId = (await persist.getItem('sessionId'));
if (!sessionId) {
sessionId = crypto.randomUUID();
await persist.setItem('sessionId', sessionId);
this.log.debug('Generated new sessionId:', sessionId);
}
else {
this.log.debug('Using cached sessionId:', sessionId);
}
const axiosInstance = axios.default ?? axios;
const region = this.configManager.region;
const baseUrl = getBaseUrl(region);
this.log.debug(`Using region: ${region} (${baseUrl})`);
this.roborockService = new RoborockService({
authenticateApiFactory: (_, url) => new RoborockAuthenticateApi(this.log, axiosInstance, sessionId, url),
iotApiFactory: (_, ud) => new RoborockIoTApi(ud, this.log, axiosInstance),
refreshInterval: this.configManager.refreshInterval,
baseUrl,
persist,
configManager: this.configManager,
toastMessage: this.toastMessage,
}, this.log, this.configManager);
const { userData, shouldContinue, isSuccess } = await this.roborockService.authenticate();
if (!shouldContinue || !userData || !this.roborockService) {
this.log.info('Authentication incomplete, waiting for user action.');
return false;
}
if (isSuccess && this.configManager.alwaysExecuteAuthentication) {
const config = this.configManager.rawConfig;
config.authentication.forceAuthentication = false;
await this.platform.onConfigChanged(config);
}
this.log.debug('Initializing - userData:', debugStringify(userData));
const devices = await this.roborockService.listDevices();
this.log.notice('Initializing - devices: ', debugStringify(devices));
let vacuums = [];
for (const device of devices) {
const isDeviceAllowed = this.configManager.isDeviceAllowed({ duid: device.duid });
const isDeviceSupported = isSupportedDevice(device.specs.model);
if (isDeviceAllowed && isDeviceSupported) {
vacuums.push(device);
}
else {
this.log.warn(`Ignoring device: ${device.duid} isDeviceAllowed = ${isDeviceAllowed}, isDeviceSupported = ${isDeviceSupported}`);
}
}
if (vacuums.length === 0) {
this.log.error('Initializing: No device found');
return false;
}
if (!this.configManager.isServerModeEnabled) {
vacuums = [vacuums[0]]; // If server mode is not enabled, only use the first vacuum
}
for (const vacuum of vacuums) {
await this.roborockService.initializeMessageClient(vacuum, userData);
this.registry.registerDevice(vacuum);
}
return true;
}
}
//# sourceMappingURL=deviceDiscovery.js.map