matterbridge-roborock-vacuum-plugin
Version:
Matterbridge Roborock Vacuum Plugin
117 lines • 4.62 kB
JavaScript
import { randomInt } from 'node:crypto';
import { debugStringify } from 'matterbridge/logger';
import { AreaNamespaceTag } from 'matterbridge/matter';
import { DEFAULT_AREA_ID_UNKNOWN, RANDOM_ROOM_MAX, RANDOM_ROOM_MIN } from '../constants/index.js';
import { RoomIndexMap } from '../core/application/models/index.js';
/**
* Create a fallback service area for error cases.
* @param areaId - Unique identifier for the area
* @param reason - Reason for the fallback area creation
* @returns Fallback service area configuration
*/
function createFallbackArea(areaId, reason) {
return {
areaId,
mapId: 0,
areaInfo: {
locationInfo: {
locationName: `Unknown - ${reason}`,
floorNumber: 0,
areaType: null,
},
landmarkInfo: null,
},
};
}
/**
* Convert vacuum rooms and room map to Matter ServiceArea areas.
* Handles single and multiple map configurations.
* @param homeInFo - Home entity containing room and map information
* @param logger - Logger for debugging and error reporting
* @returns Supported areas, maps, and room index mapping
*/
export function getSupportedAreas(homeInFo, logger) {
logger.debug('getSupportedAreas-vacuum room', debugStringify(homeInFo.rawRooms));
logger.debug('getSupportedAreas-roomMap', homeInFo.roomMap ? debugStringify(homeInFo.roomMap) : 'undefined');
const noVacuumRooms = !homeInFo.rawRooms || homeInFo.rawRooms.length === 0;
const noRoomMap = !homeInFo.roomMap?.rooms || homeInFo.roomMap.rooms.length === 0;
if (noVacuumRooms || noRoomMap) {
if (noVacuumRooms) {
logger.error('No rooms found');
}
if (noRoomMap) {
logger.error('No room map found');
}
return {
supportedAreas: [createFallbackArea(DEFAULT_AREA_ID_UNKNOWN, 'No Room')],
supportedMaps: [{ mapId: 0, name: 'Default Map' }],
roomIndexMap: new RoomIndexMap(new Map([[DEFAULT_AREA_ID_UNKNOWN, { roomId: DEFAULT_AREA_ID_UNKNOWN, mapId: 0, roomName: 'No Room' }]]), // areaInfo
new Map([[`${DEFAULT_AREA_ID_UNKNOWN}-0`, { areaId: DEFAULT_AREA_ID_UNKNOWN, mapId: 0, roomName: 'No Room' }]])),
};
}
const { supportedAreas, areaInfos, roomInfos } = processValidData(homeInFo);
const supportedMaps = homeInFo.mapInfo.maps.map((map) => ({
mapId: map.id,
name: map.name ?? `Map ${map.id}`,
}));
logger.debug('getSupportedAreas - supportedAreas', debugStringify(supportedAreas));
logger.debug('getSupportedAreas - supportedMaps', debugStringify(supportedMaps));
const roomIndexMap = new RoomIndexMap(areaInfos, roomInfos);
return {
supportedAreas,
supportedMaps,
roomIndexMap,
};
}
function processValidData(homeInFo) {
const areaInfos = new Map();
const roomInfos = new Map();
const supportedAreas = homeInFo.rawRooms.map((room, index) => {
const locationName = room.iot_name ??
homeInFo.rawRooms.find((r) => String(r.id) === room.iot_name_id || r.id === room.id)?.iot_name ??
`Unknown Room ${randomInt(RANDOM_ROOM_MIN, RANDOM_ROOM_MAX)}`;
const mapId = room.iot_map_id;
areaInfos.set(index, { roomId: room.id, mapId: mapId, roomName: locationName });
roomInfos.set(`${room.id}-${room.iot_map_id}`, { areaId: index, mapId: room.iot_map_id, roomName: locationName });
return {
areaId: index,
mapId: mapId,
areaInfo: {
locationInfo: {
locationName: locationName,
floorNumber: mapId,
areaType: populateAreaNamespaceTag(room),
},
landmarkInfo: null,
},
};
});
return {
supportedAreas,
areaInfos,
roomInfos,
};
}
function populateAreaNamespaceTag(room) {
if (room.tag && room.tag > 0) {
switch (room.tag) {
case 1:
case 2:
return AreaNamespaceTag.Bedroom.tag;
case 3:
return AreaNamespaceTag.GuestBedroom.tag;
case 6:
return AreaNamespaceTag.LivingRoom.tag;
case 7:
return AreaNamespaceTag.Balcony.tag;
case 9:
return AreaNamespaceTag.Study.tag;
case 14:
return AreaNamespaceTag.Kitchen.tag;
default:
return null;
}
}
return null;
}
//# sourceMappingURL=getSupportedAreas.js.map