Repository: home-assistant/core
File: homeassistant/components/roborock/vacuum.py (Python)

Code before:
                    "flag": vacuum_map.map_flag,
                    "name": vacuum_map.name,
                    "rooms": {
                        # JsonValueType does not accept a int as a key - was not a
                        # issue with previous asdict() implementation.
                        room.segment_id: room.name  # type: ignore[misc]
                        for room in vacuum_map.rooms
                    },
                }
                for vacuum_map in (home_trait.home_map_info or {}).values()
            ]
        }

    async def get_vacuum_current_position(self) -> ServiceResponse:
        """Get the current position of the vacuum from the map."""
        map_content_trait = self.coordinator.properties_api.map_content
        try:
            await map_content_trait.refresh()
        except RoborockException as err:
            _LOGGER.debug("Failed to refresh map content: %s", err)
            raise HomeAssistantError(
                translation_domain=DOMAIN,
                translation_key="map_failure",
            ) from err
        if map_content_trait.map_data is None:
            raise HomeAssistantError(
                translation_domain=DOMAIN,
                translation_key="map_failure",
            )
        if (robot_position := map_content_trait.map_data.vacuum_position) is None:
            raise HomeAssistantError(
                translation_domain=DOMAIN, translation_key="position_not_found"
            )

        return {
            "x": robot_position.x,
            "y": robot_position.y,
        }


class RoborockQ7Vacuum(RoborockCoordinatedEntityB01, StateVacuumEntity):
    """General Representation of a Roborock vacuum."""

    _attr_icon = "mdi:robot-vacuum"
    _attr_supported_features = (
        VacuumEntityFeature.PAUSE
        | VacuumEntityFeature.STOP
        | VacuumEntityFeature.RETURN_HOME
        | VacuumEntityFeature.FAN_SPEED
        | VacuumEntityFeature.SEND_COMMAND
        | VacuumEntityFeature.LOCATE

Review comment (suggestion):
Error checking not needed, you are guaranteed to get only segment IDs from the ones that you provided.

Code after:
            )
            for map_flag, map_info in home_map_info.items()
            for room in map_info.rooms
        ]

    async def async_clean_segments(self, segment_ids: list[str], **kwargs: Any) -> None:
        """Clean the specified segments."""
        parsed: list[tuple[int, int]] = []
        for seg_id in segment_ids:
            # Segment id is mapflag:segment_id
            parts = seg_id.split(":")
            if len(parts) != 2:
                raise ServiceValidationError(
                    translation_domain=DOMAIN,
                    translation_key="segment_id_parse_error",
                    translation_placeholders={"segment_id": seg_id},
                )
            try:
                # We need to make sure both parts are ints.
                parsed.append((int(parts[0]), int(parts[1])))
            except ValueError as err:
                raise ServiceValidationError(
                    translation_domain=DOMAIN,
                    translation_key="segment_id_parse_error",
                    translation_placeholders={"segment_id": seg_id},
                ) from err

        # Because segment_ids can overlap for each map,
        # we need to make sure that only one map is passed in.
        unique_map_flags = {map_flag for map_flag, _ in parsed}
        if len(unique_map_flags) > 1:
            map_flags_str = ", ".join(str(flag) for flag in sorted(unique_map_flags))
            raise ServiceValidationError(
                translation_domain=DOMAIN,
                translation_key="multiple_maps_in_clean",
                translation_placeholders={"map_flags": map_flags_str},
            )
        target_map_flag = next(iter(unique_map_flags))
        if self._maps_trait.current_map != target_map_flag:
            # If the user is attempting to clean an area on a map that is not selected, we should try to change.
            try:
                await self._maps_trait.set_current_map(target_map_flag)
            except RoborockException as err:
                raise ServiceValidationError(
                    translation_domain=DOMAIN,
                    translation_key="command_failed",
                    translation_placeholders={"command": "load_multi_map"},
                ) from err
            await asyncio.sleep(MAP_SLEEP)

        # We can now confirm all segments are on our current map, so clean them all.