UNPKG

matterbridge-roborock-vacuum-plugin

Version:
131 lines 7.06 kB
import { RoboticVacuumCleaner } from 'matterbridge/devices'; import { debugStringify } from 'matterbridge/logger'; import { RvcOperationalState } from 'matterbridge/matter/clusters'; import { CommandNames } from '../behaviors/BehaviorDeviceGeneric.js'; import { baseRunModeConfigs, getRunModeOptions } from '../behaviors/roborock.vacuum/core/runModeConfig.js'; import { getOperationalStates, getSupportedAreas, getSupportedCleanModes, getSupportedRoutines, } from '../initialData/index.js'; export class RoborockVacuumCleaner extends RoboticVacuumCleaner { device; homeInFo; dockStationStatus; cleanModeSetting; /** * Create a new Roborock Vacuum Cleaner device. * Initializes the device with supported cleaning modes, run modes, areas, and routines. */ constructor(device, homeInFo, configManager, roborockService, log) { const deviceConfig = RoborockVacuumCleaner.initializeDeviceConfiguration(device, homeInFo, configManager, roborockService, log); super(deviceConfig.deviceName, device.sn ?? device.duid, deviceConfig.bridgeMode, deviceConfig.runModeConfigs[0].mode, deviceConfig.runModeConfigs, deviceConfig.cleanModes[0].mode, deviceConfig.cleanModes, undefined, undefined, RvcOperationalState.OperationalState.Docked, deviceConfig.operationalState, deviceConfig.supportedAreaAndRoutines, undefined, deviceConfig.supportedAreas[0].areaId, deviceConfig.supportedMaps); this.device = device; this.homeInFo = homeInFo; log.debug(`Creating RoborockVacuumCleaner for device: ${deviceConfig.deviceName}, model: ${device.specs.model}, forceRunAtDefault: ${configManager.forceRunAtDefault} bridgeMode: ${deviceConfig.bridgeMode}, Supported Clean Modes: ${debugStringify(deviceConfig.cleanModes)}, Supported Areas: ${debugStringify(deviceConfig.supportedAreas)}, Supported Maps: ${debugStringify(deviceConfig.supportedMaps)} Supported Areas and Routines: ${debugStringify(deviceConfig.supportedAreaAndRoutines)}, Supported Operational States: ${debugStringify(deviceConfig.operationalState)}`); } /** * Configure command handlers for the vacuum device. * Sets up handlers for identify, area selection, mode changes, and cleaning operations. */ configureHandler(behaviorHandler) { this.addCommandHandlerWithErrorHandling(CommandNames.IDENTIFY, async ({ request, cluster, attributes, endpoint }) => { this.log.info(`Identify command received for endpoint ${endpoint}, cluster ${cluster}, attributes ${debugStringify(attributes)}, request: ${JSON.stringify(request)}`); behaviorHandler.executeCommand(CommandNames.IDENTIFY, request.identifyTime ?? 5); }); this.addCommandHandlerWithErrorHandling(CommandNames.SELECT_AREAS, async ({ request }) => { const { newAreas } = request; if (!newAreas || newAreas.length === 0) { this.log.info('selectAreas called with empty or undefined areas, it means selecting no areas or all areas, ignoring.'); return; } this.log.info(`Selecting areas: ${newAreas.join(', ')}`); behaviorHandler.executeCommand(CommandNames.SELECT_AREAS, newAreas); }); this.addCommandHandlerWithErrorHandling(CommandNames.CHANGE_TO_MODE, async ({ request }) => { const { newMode } = request; this.log.info(`Changing to mode: ${newMode}`); behaviorHandler.executeCommand(CommandNames.CHANGE_TO_MODE, newMode); }); this.addCommandHandlerWithErrorHandling(CommandNames.PAUSE, async () => { this.log.info('Pause command received'); behaviorHandler.executeCommand(CommandNames.PAUSE); }); this.addCommandHandlerWithErrorHandling(CommandNames.RESUME, async () => { this.log.info('Resume command received'); behaviorHandler.executeCommand(CommandNames.RESUME); }); this.addCommandHandlerWithErrorHandling(CommandNames.GO_HOME, async () => { this.log.info('GoHome command received'); behaviorHandler.executeCommand(CommandNames.GO_HOME); }); this.addCommandHandlerWithErrorHandling(CommandNames.STOP, async () => { this.log.info('Stop command received'); behaviorHandler.executeCommand(CommandNames.STOP); }); } /** * Initialize device configuration including modes, areas, and maps. */ static initializeDeviceConfiguration(device, homeInFo, configManager, roborockService, log) { const cleanModes = getSupportedCleanModes(device.specs.model, configManager); const operationalState = getOperationalStates(); const result = getSupportedAreas(homeInFo, log); const supportedMaps = result.supportedMaps; let supportedAreas = result.supportedAreas; const runModeConfigs = getRunModeOptions(baseRunModeConfigs); const bridgeMode = configManager.isServerModeEnabled ? 'server' : 'matter'; const firstSupportedMap = supportedMaps.length > 0 ? supportedMaps[0] : undefined; if (!configManager.isMultipleMapEnabled) { supportedMaps.splice(1); // Keep only the first map supportedAreas = supportedAreas.filter((area) => area.mapId === firstSupportedMap?.mapId); } let routineAsRooms = []; if (configManager.showRoutinesAsRoom) { routineAsRooms = getSupportedRoutines(device.scenes ?? [], log); roborockService.setSupportedRoutines(device.duid, routineAsRooms); } // temporary use map id 999 for routine if (routineAsRooms.length > 0) { const mapForRoutine = { mapId: 999, name: 'Routine' }; supportedMaps.push(mapForRoutine); routineAsRooms.forEach((rt) => { rt.mapId = 999; }); } roborockService.setSupportedAreas(device.duid, result.supportedAreas); roborockService.setSupportedAreaIndexMap(device.duid, result.roomIndexMap); const supportedAreaAndRoutines = [...supportedAreas, ...routineAsRooms]; const deviceName = device.name; return { deviceName, bridgeMode, cleanModes, runModeConfigs, supportedAreas, supportedMaps, supportedAreaAndRoutines, operationalState, }; } /** * Helper method to add command handler with error handling. * Wraps handler logic in try-catch to avoid code duplication. */ addCommandHandlerWithErrorHandling(commandName, handler) { this.addCommandHandler(commandName, async (context) => { try { await handler(context); } catch (error) { this.log.error(`Error executing ${commandName} command: ${error}`); throw error; } }); } } //# sourceMappingURL=roborockVacuumCleaner.js.map