UNPKG

matterbridge-roborock-vacuum-plugin

Version:
170 lines (169 loc) 8.35 kB
import { PowerSource, RvcCleanMode, RvcOperationalState, RvcRunMode, ServiceArea } from 'matterbridge/matter/clusters'; import { getRunningMode } from '../initialData/getSupportedRunModes.js'; import { state_to_matter_state } from '../share/function.js'; import { OperationStatusCode } from '../roborockCommunication/Zenum/operationStatusCode.js'; import { getRoomMap } from '../helper.js'; import { debugStringify } from 'matterbridge/logger'; import { getBatteryState, getBatteryStatus } from '../initialData/index.js'; import { getCurrentCleanModeFunc } from '../share/runtimeHelper.js'; import { hasDockingStationError, parseDockingStationStatus } from '../model/DockingStationStatus.js'; export async function handleLocalMessage(data, platform, duid = '') { const robot = platform.robots.get(duid); if (!robot) { platform.log.error(`Robot with DUID ${duid} not found.`); return; } const currentMappedAreas = platform.roborockService?.getSupportedAreas(duid); const roomIndexMap = platform.roborockService?.getSupportedAreasIndexMap(duid); const roomMap = await getRoomMap(duid, platform); platform.log.debug(`RoomMap: ${roomMap ? debugStringify(roomMap) : 'undefined'}`); platform.log.debug(`Current mapped areas: ${currentMappedAreas ? debugStringify(currentMappedAreas) : 'undefined'}`); platform.log.debug(`RoomIndexMap: `, roomIndexMap); const deviceData = robot.device.data; const state = state_to_matter_state(data.state); if (state) { robot.updateAttribute(RvcRunMode.Cluster.id, 'currentMode', getRunningMode(state), platform.log); } if (data.state === OperationStatusCode.Idle) { const selectedAreas = platform.roborockService?.getSelectedAreas(duid) ?? []; robot.updateAttribute(ServiceArea.Cluster.id, 'selectedAreas', selectedAreas, platform.log); } if (state === RvcRunMode.ModeTag.Cleaning && !data.cleaning_info) { platform.log.debug('No cleaning_info, setting currentArea to null'); robot.updateAttribute(ServiceArea.Cluster.id, 'currentArea', null, platform.log); robot.updateAttribute(ServiceArea.Cluster.id, 'selectedAreas', [], platform.log); } else { const isMultipleMapEnable = platform.enableExperimentalFeature?.enableExperimentalFeature && platform.enableExperimentalFeature?.advancedFeature?.enableMultipleMap; if (isMultipleMapEnable) { await mapRoomsToAreasFeatureOn(platform, duid, data); } else { await mapRoomsToAreasFeatureOff(platform, duid, data); } } if (data.battery) { const batteryLevel = data.battery; robot.updateAttribute(PowerSource.Cluster.id, 'batPercentRemaining', batteryLevel * 2, platform.log); robot.updateAttribute(PowerSource.Cluster.id, 'batChargeState', getBatteryState(data.state, data.battery), platform.log); robot.updateAttribute(PowerSource.Cluster.id, 'batChargeLevel', getBatteryStatus(batteryLevel), platform.log); } const currentCleanModeSetting = { suctionPower: data.cleaning_info?.fan_power ?? data.fan_power, waterFlow: data.cleaning_info?.water_box_status ?? data.water_box_mode, distance_off: data.distance_off, mopRoute: data.cleaning_info?.mop_mode ?? data.mop_mode, segment_id: data.cleaning_info?.segment_id, target_segment_id: data.cleaning_info?.target_segment_id, }; platform.log.debug(`data: ${debugStringify(data)}`); platform.log.notice(`currentCleanModeSetting: ${debugStringify(currentCleanModeSetting)}`); if (currentCleanModeSetting.mopRoute && currentCleanModeSetting.suctionPower && currentCleanModeSetting.waterFlow) { const currentCleanMode = getCurrentCleanModeFunc(deviceData.model, platform.enableExperimentalFeature?.advancedFeature?.forceRunAtDefault ?? false)(currentCleanModeSetting); platform.log.debug(`Current clean mode: ${currentCleanMode}`); if (currentCleanMode) { robot.updateAttribute(RvcCleanMode.Cluster.id, 'currentMode', currentCleanMode, platform.log); } } processAdditionalProps(robot, data, duid, platform); } export function triggerDssError(robot, platform) { const currentOperationState = robot.getAttribute(RvcOperationalState.Cluster.id, 'operationalState'); if (currentOperationState === RvcOperationalState.OperationalState.Error) { return true; } if (currentOperationState === RvcOperationalState.OperationalState.Docked) { robot.updateAttribute(RvcOperationalState.Cluster.id, 'operationalState', RvcOperationalState.OperationalState.Error, platform.log); return true; } return false; } async function processAdditionalProps(robot, message, duid, platform) { const dssStatus = getDssStatus(message, duid, platform); if (dssStatus) { triggerDssError(robot, platform); } } function getDssStatus(message, duid, platform) { const robot = platform.robots.get(duid); if (robot === undefined) { platform.log.error(`Error4: Robot with DUID ${duid} not found`); return undefined; } if (platform.enableExperimentalFeature && platform.enableExperimentalFeature.enableExperimentalFeature && platform.enableExperimentalFeature.advancedFeature.includeDockStationStatus && message.dss !== undefined) { const dss = parseDockingStationStatus(message.dss); if (dss && robot) { robot.dockStationStatus = dss; } if (dss && hasDockingStationError(dss)) { return RvcOperationalState.OperationalState.Error; } } return undefined; } async function mapRoomsToAreasFeatureOff(platform, duid, data) { const currentMappedAreas = platform.roborockService?.getSupportedAreas(duid); const robot = platform.robots.get(duid); if (!robot) { platform.log.error(`Robot with DUID ${duid} not found.`); return; } if (!data.cleaning_info) { return; } const source_segment_id = data.cleaning_info.segment_id ?? -1; const source_target_segment_id = data.cleaning_info.target_segment_id ?? -1; const segment_id = source_segment_id !== -1 ? source_segment_id : source_target_segment_id; const mappedArea = currentMappedAreas?.find((x) => x.areaId == segment_id); platform.log.debug(`mappedArea: source_segment_id: ${source_segment_id}, source_target_segment_id: ${source_target_segment_id}, segment_id: ${segment_id}, result: ${mappedArea ? debugStringify(mappedArea) : 'undefined'} `); if (segment_id !== -1 && mappedArea) { robot.updateAttribute(ServiceArea.Cluster.id, 'currentArea', segment_id, platform.log); } if (segment_id == -1) { robot.updateAttribute(ServiceArea.Cluster.id, 'currentArea', null, platform.log); } } async function mapRoomsToAreasFeatureOn(platform, duid, data) { const robot = platform.robots.get(duid); if (!robot) { platform.log.error(`Robot with DUID ${duid} not found.`); return; } if (!data.cleaning_info) { return; } const currentMappedAreas = platform.roborockService?.getSupportedAreas(duid); const roomIndexMap = platform.roborockService?.getSupportedAreasIndexMap(duid); const source_segment_id = data.cleaning_info.segment_id ?? -1; const source_target_segment_id = data.cleaning_info.target_segment_id ?? -1; const segment_id = source_segment_id !== -1 ? source_segment_id : source_target_segment_id; const areaId = roomIndexMap?.getAreaId(segment_id, 0); if (!areaId) { platform.log.debug(` source_segment_id: ${source_segment_id}, source_target_segment_id: ${source_target_segment_id}, segment_id: ${segment_id}, areaId: ${areaId}`); return; } const mappedArea = currentMappedAreas?.find((x) => x.areaId == areaId); platform.log.debug(`mappedArea: source_segment_id: ${source_segment_id}, source_target_segment_id: ${source_target_segment_id}, segment_id: ${segment_id}, areaId: ${areaId}, result: ${mappedArea ? debugStringify(mappedArea) : 'undefined'} `); if (areaId !== -1 && mappedArea) { robot.updateAttribute(ServiceArea.Cluster.id, 'currentArea', areaId, platform.log); } }