UNPKG

matterbridge-roborock-vacuum-plugin

Version:
97 lines 4.5 kB
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