roborock.devices.traits.v1.home

Trait that represents a full view of the home layout.

This trait combines information about maps and rooms to provide a comprehensive view of the home layout, including room names and their corresponding segment on the map. It also makes it straight forward to fetch the map image and data.

This trait depends on the MapsTrait and RoomsTrait to gather the necessary information. It provides properties to access the current map, the list of rooms with names, and the map image and data.

Callers may first call discover_home() to populate the home layout cache by iterating through all available maps on the device. This will cache the map information and room names for all maps to minimize map switching and improve performance. After the initial discovery, callers can call refresh() to update the current map's information and room names as needed.

  1"""Trait that represents a full view of the home layout.
  2
  3This trait combines information about maps and rooms to provide a comprehensive
  4view of the home layout, including room names and their corresponding segment
  5on the map. It also makes it straight forward to fetch the map image and data.
  6
  7This trait depends on the MapsTrait and RoomsTrait to gather the necessary
  8information. It provides properties to access the current map, the list of
  9rooms with names, and the map image and data.
 10
 11Callers may first call `discover_home()` to populate the home layout cache by
 12iterating through all available maps on the device. This will cache the map
 13information and room names for all maps to minimize map switching and improve
 14performance. After the initial discovery, callers can call `refresh()` to update
 15the current map's information and room names as needed.
 16"""
 17
 18import asyncio
 19import base64
 20import logging
 21from typing import Self
 22
 23from roborock.data import CombinedMapInfo, RoborockBase
 24from roborock.data.v1.v1_code_mappings import RoborockStateCode
 25from roborock.devices.cache import DeviceCache
 26from roborock.devices.traits.v1 import common
 27from roborock.exceptions import RoborockDeviceBusy, RoborockException
 28from roborock.roborock_typing import RoborockCommand
 29
 30from .map_content import MapContent, MapContentTrait
 31from .maps import MapsTrait
 32from .rooms import RoomsTrait
 33from .status import StatusTrait
 34
 35_LOGGER = logging.getLogger(__name__)
 36
 37MAP_SLEEP = 3
 38
 39
 40class HomeTrait(RoborockBase, common.V1TraitMixin):
 41    """Trait that represents a full view of the home layout."""
 42
 43    command = RoborockCommand.GET_MAP_V1  # This is not used
 44
 45    def __init__(
 46        self,
 47        status_trait: StatusTrait,
 48        maps_trait: MapsTrait,
 49        map_content: MapContentTrait,
 50        rooms_trait: RoomsTrait,
 51        device_cache: DeviceCache,
 52    ) -> None:
 53        """Initialize the HomeTrait.
 54
 55        We keep track of the MapsTrait and RoomsTrait to provide a comprehensive
 56        view of the home layout. This also depends on the StatusTrait to determine
 57        the current map. See comments in MapsTrait for details on that dependency.
 58
 59        The cache is used to store discovered home data to minimize map switching
 60        and improve performance. The cache should be persisted by the caller to
 61        ensure data is retained across restarts.
 62
 63        After initial discovery, only information for the current map is refreshed
 64        to keep data up to date without excessive map switching. However, as
 65        users switch rooms, the current map's data will be updated to ensure
 66        accuracy.
 67        """
 68        super().__init__()
 69        self._status_trait = status_trait
 70        self._maps_trait = maps_trait
 71        self._map_content = map_content
 72        self._rooms_trait = rooms_trait
 73        self._device_cache = device_cache
 74        self._discovery_completed = False
 75        self._home_map_info: dict[int, CombinedMapInfo] | None = None
 76        self._home_map_content: dict[int, MapContent] | None = None
 77
 78    async def discover_home(self) -> None:
 79        """Iterate through all maps to discover rooms and cache them.
 80
 81        This will be a no-op if the home cache is already populated.
 82
 83        This cannot be called while the device is cleaning, as that would interrupt the
 84        cleaning process. This will raise `RoborockDeviceBusy` if the device is
 85        currently cleaning.
 86
 87        After discovery, the home cache will be populated and can be accessed via the `home_map_info` property.
 88        """
 89        device_cache_data = await self._device_cache.get()
 90        if device_cache_data and device_cache_data.home_map_info:
 91            _LOGGER.debug("Home cache already populated, skipping discovery")
 92            self._home_map_info = device_cache_data.home_map_info
 93            self._discovery_completed = True
 94            try:
 95                self._home_map_content = {
 96                    k: self._map_content.parse_map_content(base64.b64decode(v))
 97                    for k, v in (device_cache_data.home_map_content_base64 or {}).items()
 98                }
 99            except (ValueError, RoborockException) as ex:
100                _LOGGER.warning("Failed to parse cached home map content, will re-discover: %s", ex)
101                self._home_map_content = {}
102            else:
103                return
104
105        if self._status_trait.state == RoborockStateCode.cleaning:
106            raise RoborockDeviceBusy("Cannot perform home discovery while the device is cleaning")
107
108        await self._maps_trait.refresh()
109        if self._maps_trait.current_map_info is None:
110            raise RoborockException("Cannot perform home discovery without current map info")
111
112        home_map_info, home_map_content = await self._build_home_map_info()
113        _LOGGER.debug("Home discovery complete, caching data for %d maps", len(home_map_info))
114        self._discovery_completed = True
115        await self._update_home_cache(home_map_info, home_map_content)
116
117    async def _refresh_map_info(self, map_info) -> CombinedMapInfo:
118        """Collect room data for a specific map and return CombinedMapInfo."""
119        await self._rooms_trait.refresh()
120        return CombinedMapInfo(
121            map_flag=map_info.map_flag,
122            name=map_info.name,
123            rooms=self._rooms_trait.rooms or [],
124        )
125
126    async def _refresh_map_content(self) -> MapContent:
127        """Refresh the map content trait to get the latest map data."""
128        await self._map_content.refresh()
129        return MapContent(
130            image_content=self._map_content.image_content,
131            map_data=self._map_content.map_data,
132            raw_api_response=self._map_content.raw_api_response,
133        )
134
135    async def _build_home_map_info(self) -> tuple[dict[int, CombinedMapInfo], dict[int, MapContent]]:
136        """Perform the actual discovery and caching of home map info and content."""
137        home_map_info: dict[int, CombinedMapInfo] = {}
138        home_map_content: dict[int, MapContent] = {}
139
140        # Sort map_info to process the current map last, reducing map switching.
141        # False (non-original maps) sorts before True (original map). We ensure
142        # we load the original map last.
143        sorted_map_infos = sorted(
144            self._maps_trait.map_info or [],
145            key=lambda mi: mi.map_flag == self._maps_trait.current_map,
146            reverse=False,
147        )
148        _LOGGER.debug("Building home cache for maps: %s", [mi.map_flag for mi in sorted_map_infos])
149        for map_info in sorted_map_infos:
150            # We need to load each map to get its room data
151            if len(sorted_map_infos) > 1:
152                _LOGGER.debug("Loading map %s", map_info.map_flag)
153                await self._maps_trait.set_current_map(map_info.map_flag)
154                await asyncio.sleep(MAP_SLEEP)
155
156            map_content = await self._refresh_map_content()
157            home_map_content[map_info.map_flag] = map_content
158
159            combined_map_info = await self._refresh_map_info(map_info)
160            home_map_info[map_info.map_flag] = combined_map_info
161        return home_map_info, home_map_content
162
163    async def refresh(self) -> None:
164        """Refresh current map's underlying map and room data, updating cache as needed.
165
166        This will only refresh the current map's data and will not populate non
167        active maps or re-discover the home. It is expected that this will keep
168        information up to date for the current map as users switch to that map.
169        """
170        if not self._discovery_completed:
171            # Running initial discovery also populates all of the same information
172            # as below so we can just call that method. If the device is busy
173            # then we'll fall through below to refresh the current map only.
174            try:
175                await self.discover_home()
176                return
177            except RoborockDeviceBusy:
178                _LOGGER.debug("Cannot refresh home data while device is busy cleaning")
179
180        # Refresh the list of map names/info
181        await self._maps_trait.refresh()
182        if (current_map_info := self._maps_trait.current_map_info) is None or (
183            map_flag := self._maps_trait.current_map
184        ) is None:
185            raise RoborockException("Cannot refresh home data without current map info")
186
187        # Refresh the map content to ensure we have the latest image and object positions
188        new_map_content = await self._refresh_map_content()
189        # Refresh the current map's room data
190        combined_map_info = await self._refresh_map_info(current_map_info)
191        await self._update_current_map(
192            map_flag, combined_map_info, new_map_content, update_cache=self._discovery_completed
193        )
194
195    @property
196    def home_map_info(self) -> dict[int, CombinedMapInfo] | None:
197        """Returns the map information for all cached maps."""
198        return self._home_map_info
199
200    @property
201    def current_map_data(self) -> CombinedMapInfo | None:
202        """Returns the map data for the current map."""
203        current_map_flag = self._maps_trait.current_map
204        if current_map_flag is None or self._home_map_info is None:
205            return None
206        return self._home_map_info.get(current_map_flag)
207
208    @property
209    def home_map_content(self) -> dict[int, MapContent] | None:
210        """Returns the map content for all cached maps."""
211        return self._home_map_content
212
213    def _parse_response(self, response: common.V1ResponseData) -> Self:
214        """This trait does not parse responses directly."""
215        raise NotImplementedError("HomeTrait does not support direct command responses")
216
217    async def _update_home_cache(
218        self, home_map_info: dict[int, CombinedMapInfo], home_map_content: dict[int, MapContent]
219    ) -> None:
220        """Update the entire home cache with new map info and content."""
221        device_cache_data = await self._device_cache.get()
222        device_cache_data.home_map_info = home_map_info
223        device_cache_data.home_map_content_base64 = {
224            k: base64.b64encode(v.raw_api_response).decode("utf-8")
225            for k, v in home_map_content.items()
226            if v.raw_api_response
227        }
228        await self._device_cache.set(device_cache_data)
229        self._home_map_info = home_map_info
230        self._home_map_content = home_map_content
231
232    async def _update_current_map(
233        self,
234        map_flag: int,
235        map_info: CombinedMapInfo,
236        map_content: MapContent,
237        update_cache: bool,
238    ) -> None:
239        """Update the cache for the current map only."""
240        # Update the persistent cache if requested e.g. home discovery has
241        # completed and we want to keep it fresh. Otherwise just update the
242        # in memory map below.
243        if update_cache:
244            device_cache_data = await self._device_cache.get()
245            if device_cache_data.home_map_info is None:
246                device_cache_data.home_map_info = {}
247            device_cache_data.home_map_info[map_flag] = map_info
248            if map_content.raw_api_response:
249                if device_cache_data.home_map_content_base64 is None:
250                    device_cache_data.home_map_content_base64 = {}
251                device_cache_data.home_map_content_base64[map_flag] = base64.b64encode(
252                    map_content.raw_api_response
253                ).decode("utf-8")
254            await self._device_cache.set(device_cache_data)
255
256        if self._home_map_info is None:
257            self._home_map_info = {}
258        self._home_map_info[map_flag] = map_info
259
260        if self._home_map_content is None:
261            self._home_map_content = {}
262        self._home_map_content[map_flag] = map_content
MAP_SLEEP = 3
 41class HomeTrait(RoborockBase, common.V1TraitMixin):
 42    """Trait that represents a full view of the home layout."""
 43
 44    command = RoborockCommand.GET_MAP_V1  # This is not used
 45
 46    def __init__(
 47        self,
 48        status_trait: StatusTrait,
 49        maps_trait: MapsTrait,
 50        map_content: MapContentTrait,
 51        rooms_trait: RoomsTrait,
 52        device_cache: DeviceCache,
 53    ) -> None:
 54        """Initialize the HomeTrait.
 55
 56        We keep track of the MapsTrait and RoomsTrait to provide a comprehensive
 57        view of the home layout. This also depends on the StatusTrait to determine
 58        the current map. See comments in MapsTrait for details on that dependency.
 59
 60        The cache is used to store discovered home data to minimize map switching
 61        and improve performance. The cache should be persisted by the caller to
 62        ensure data is retained across restarts.
 63
 64        After initial discovery, only information for the current map is refreshed
 65        to keep data up to date without excessive map switching. However, as
 66        users switch rooms, the current map's data will be updated to ensure
 67        accuracy.
 68        """
 69        super().__init__()
 70        self._status_trait = status_trait
 71        self._maps_trait = maps_trait
 72        self._map_content = map_content
 73        self._rooms_trait = rooms_trait
 74        self._device_cache = device_cache
 75        self._discovery_completed = False
 76        self._home_map_info: dict[int, CombinedMapInfo] | None = None
 77        self._home_map_content: dict[int, MapContent] | None = None
 78
 79    async def discover_home(self) -> None:
 80        """Iterate through all maps to discover rooms and cache them.
 81
 82        This will be a no-op if the home cache is already populated.
 83
 84        This cannot be called while the device is cleaning, as that would interrupt the
 85        cleaning process. This will raise `RoborockDeviceBusy` if the device is
 86        currently cleaning.
 87
 88        After discovery, the home cache will be populated and can be accessed via the `home_map_info` property.
 89        """
 90        device_cache_data = await self._device_cache.get()
 91        if device_cache_data and device_cache_data.home_map_info:
 92            _LOGGER.debug("Home cache already populated, skipping discovery")
 93            self._home_map_info = device_cache_data.home_map_info
 94            self._discovery_completed = True
 95            try:
 96                self._home_map_content = {
 97                    k: self._map_content.parse_map_content(base64.b64decode(v))
 98                    for k, v in (device_cache_data.home_map_content_base64 or {}).items()
 99                }
100            except (ValueError, RoborockException) as ex:
101                _LOGGER.warning("Failed to parse cached home map content, will re-discover: %s", ex)
102                self._home_map_content = {}
103            else:
104                return
105
106        if self._status_trait.state == RoborockStateCode.cleaning:
107            raise RoborockDeviceBusy("Cannot perform home discovery while the device is cleaning")
108
109        await self._maps_trait.refresh()
110        if self._maps_trait.current_map_info is None:
111            raise RoborockException("Cannot perform home discovery without current map info")
112
113        home_map_info, home_map_content = await self._build_home_map_info()
114        _LOGGER.debug("Home discovery complete, caching data for %d maps", len(home_map_info))
115        self._discovery_completed = True
116        await self._update_home_cache(home_map_info, home_map_content)
117
118    async def _refresh_map_info(self, map_info) -> CombinedMapInfo:
119        """Collect room data for a specific map and return CombinedMapInfo."""
120        await self._rooms_trait.refresh()
121        return CombinedMapInfo(
122            map_flag=map_info.map_flag,
123            name=map_info.name,
124            rooms=self._rooms_trait.rooms or [],
125        )
126
127    async def _refresh_map_content(self) -> MapContent:
128        """Refresh the map content trait to get the latest map data."""
129        await self._map_content.refresh()
130        return MapContent(
131            image_content=self._map_content.image_content,
132            map_data=self._map_content.map_data,
133            raw_api_response=self._map_content.raw_api_response,
134        )
135
136    async def _build_home_map_info(self) -> tuple[dict[int, CombinedMapInfo], dict[int, MapContent]]:
137        """Perform the actual discovery and caching of home map info and content."""
138        home_map_info: dict[int, CombinedMapInfo] = {}
139        home_map_content: dict[int, MapContent] = {}
140
141        # Sort map_info to process the current map last, reducing map switching.
142        # False (non-original maps) sorts before True (original map). We ensure
143        # we load the original map last.
144        sorted_map_infos = sorted(
145            self._maps_trait.map_info or [],
146            key=lambda mi: mi.map_flag == self._maps_trait.current_map,
147            reverse=False,
148        )
149        _LOGGER.debug("Building home cache for maps: %s", [mi.map_flag for mi in sorted_map_infos])
150        for map_info in sorted_map_infos:
151            # We need to load each map to get its room data
152            if len(sorted_map_infos) > 1:
153                _LOGGER.debug("Loading map %s", map_info.map_flag)
154                await self._maps_trait.set_current_map(map_info.map_flag)
155                await asyncio.sleep(MAP_SLEEP)
156
157            map_content = await self._refresh_map_content()
158            home_map_content[map_info.map_flag] = map_content
159
160            combined_map_info = await self._refresh_map_info(map_info)
161            home_map_info[map_info.map_flag] = combined_map_info
162        return home_map_info, home_map_content
163
164    async def refresh(self) -> None:
165        """Refresh current map's underlying map and room data, updating cache as needed.
166
167        This will only refresh the current map's data and will not populate non
168        active maps or re-discover the home. It is expected that this will keep
169        information up to date for the current map as users switch to that map.
170        """
171        if not self._discovery_completed:
172            # Running initial discovery also populates all of the same information
173            # as below so we can just call that method. If the device is busy
174            # then we'll fall through below to refresh the current map only.
175            try:
176                await self.discover_home()
177                return
178            except RoborockDeviceBusy:
179                _LOGGER.debug("Cannot refresh home data while device is busy cleaning")
180
181        # Refresh the list of map names/info
182        await self._maps_trait.refresh()
183        if (current_map_info := self._maps_trait.current_map_info) is None or (
184            map_flag := self._maps_trait.current_map
185        ) is None:
186            raise RoborockException("Cannot refresh home data without current map info")
187
188        # Refresh the map content to ensure we have the latest image and object positions
189        new_map_content = await self._refresh_map_content()
190        # Refresh the current map's room data
191        combined_map_info = await self._refresh_map_info(current_map_info)
192        await self._update_current_map(
193            map_flag, combined_map_info, new_map_content, update_cache=self._discovery_completed
194        )
195
196    @property
197    def home_map_info(self) -> dict[int, CombinedMapInfo] | None:
198        """Returns the map information for all cached maps."""
199        return self._home_map_info
200
201    @property
202    def current_map_data(self) -> CombinedMapInfo | None:
203        """Returns the map data for the current map."""
204        current_map_flag = self._maps_trait.current_map
205        if current_map_flag is None or self._home_map_info is None:
206            return None
207        return self._home_map_info.get(current_map_flag)
208
209    @property
210    def home_map_content(self) -> dict[int, MapContent] | None:
211        """Returns the map content for all cached maps."""
212        return self._home_map_content
213
214    def _parse_response(self, response: common.V1ResponseData) -> Self:
215        """This trait does not parse responses directly."""
216        raise NotImplementedError("HomeTrait does not support direct command responses")
217
218    async def _update_home_cache(
219        self, home_map_info: dict[int, CombinedMapInfo], home_map_content: dict[int, MapContent]
220    ) -> None:
221        """Update the entire home cache with new map info and content."""
222        device_cache_data = await self._device_cache.get()
223        device_cache_data.home_map_info = home_map_info
224        device_cache_data.home_map_content_base64 = {
225            k: base64.b64encode(v.raw_api_response).decode("utf-8")
226            for k, v in home_map_content.items()
227            if v.raw_api_response
228        }
229        await self._device_cache.set(device_cache_data)
230        self._home_map_info = home_map_info
231        self._home_map_content = home_map_content
232
233    async def _update_current_map(
234        self,
235        map_flag: int,
236        map_info: CombinedMapInfo,
237        map_content: MapContent,
238        update_cache: bool,
239    ) -> None:
240        """Update the cache for the current map only."""
241        # Update the persistent cache if requested e.g. home discovery has
242        # completed and we want to keep it fresh. Otherwise just update the
243        # in memory map below.
244        if update_cache:
245            device_cache_data = await self._device_cache.get()
246            if device_cache_data.home_map_info is None:
247                device_cache_data.home_map_info = {}
248            device_cache_data.home_map_info[map_flag] = map_info
249            if map_content.raw_api_response:
250                if device_cache_data.home_map_content_base64 is None:
251                    device_cache_data.home_map_content_base64 = {}
252                device_cache_data.home_map_content_base64[map_flag] = base64.b64encode(
253                    map_content.raw_api_response
254                ).decode("utf-8")
255            await self._device_cache.set(device_cache_data)
256
257        if self._home_map_info is None:
258            self._home_map_info = {}
259        self._home_map_info[map_flag] = map_info
260
261        if self._home_map_content is None:
262            self._home_map_content = {}
263        self._home_map_content[map_flag] = map_content

Trait that represents a full view of the home layout.

HomeTrait( status_trait: roborock.devices.traits.v1.status.StatusTrait, maps_trait: <function mqtt_rpc_channel.<locals>.wrapper>, map_content: <function map_rpc_channel.<locals>.wrapper>, rooms_trait: roborock.devices.traits.v1.rooms.RoomsTrait, device_cache: roborock.devices.cache.DeviceCache)
46    def __init__(
47        self,
48        status_trait: StatusTrait,
49        maps_trait: MapsTrait,
50        map_content: MapContentTrait,
51        rooms_trait: RoomsTrait,
52        device_cache: DeviceCache,
53    ) -> None:
54        """Initialize the HomeTrait.
55
56        We keep track of the MapsTrait and RoomsTrait to provide a comprehensive
57        view of the home layout. This also depends on the StatusTrait to determine
58        the current map. See comments in MapsTrait for details on that dependency.
59
60        The cache is used to store discovered home data to minimize map switching
61        and improve performance. The cache should be persisted by the caller to
62        ensure data is retained across restarts.
63
64        After initial discovery, only information for the current map is refreshed
65        to keep data up to date without excessive map switching. However, as
66        users switch rooms, the current map's data will be updated to ensure
67        accuracy.
68        """
69        super().__init__()
70        self._status_trait = status_trait
71        self._maps_trait = maps_trait
72        self._map_content = map_content
73        self._rooms_trait = rooms_trait
74        self._device_cache = device_cache
75        self._discovery_completed = False
76        self._home_map_info: dict[int, CombinedMapInfo] | None = None
77        self._home_map_content: dict[int, MapContent] | None = None

Initialize the HomeTrait.

We keep track of the MapsTrait and RoomsTrait to provide a comprehensive view of the home layout. This also depends on the StatusTrait to determine the current map. See comments in MapsTrait for details on that dependency.

The cache is used to store discovered home data to minimize map switching and improve performance. The cache should be persisted by the caller to ensure data is retained across restarts.

After initial discovery, only information for the current map is refreshed to keep data up to date without excessive map switching. However, as users switch rooms, the current map's data will be updated to ensure accuracy.

command = <RoborockCommand.GET_MAP_V1: 'get_map_v1'>
async def discover_home(self) -> None:
 79    async def discover_home(self) -> None:
 80        """Iterate through all maps to discover rooms and cache them.
 81
 82        This will be a no-op if the home cache is already populated.
 83
 84        This cannot be called while the device is cleaning, as that would interrupt the
 85        cleaning process. This will raise `RoborockDeviceBusy` if the device is
 86        currently cleaning.
 87
 88        After discovery, the home cache will be populated and can be accessed via the `home_map_info` property.
 89        """
 90        device_cache_data = await self._device_cache.get()
 91        if device_cache_data and device_cache_data.home_map_info:
 92            _LOGGER.debug("Home cache already populated, skipping discovery")
 93            self._home_map_info = device_cache_data.home_map_info
 94            self._discovery_completed = True
 95            try:
 96                self._home_map_content = {
 97                    k: self._map_content.parse_map_content(base64.b64decode(v))
 98                    for k, v in (device_cache_data.home_map_content_base64 or {}).items()
 99                }
100            except (ValueError, RoborockException) as ex:
101                _LOGGER.warning("Failed to parse cached home map content, will re-discover: %s", ex)
102                self._home_map_content = {}
103            else:
104                return
105
106        if self._status_trait.state == RoborockStateCode.cleaning:
107            raise RoborockDeviceBusy("Cannot perform home discovery while the device is cleaning")
108
109        await self._maps_trait.refresh()
110        if self._maps_trait.current_map_info is None:
111            raise RoborockException("Cannot perform home discovery without current map info")
112
113        home_map_info, home_map_content = await self._build_home_map_info()
114        _LOGGER.debug("Home discovery complete, caching data for %d maps", len(home_map_info))
115        self._discovery_completed = True
116        await self._update_home_cache(home_map_info, home_map_content)

Iterate through all maps to discover rooms and cache them.

This will be a no-op if the home cache is already populated.

This cannot be called while the device is cleaning, as that would interrupt the cleaning process. This will raise RoborockDeviceBusy if the device is currently cleaning.

After discovery, the home cache will be populated and can be accessed via the home_map_info property.

async def refresh(self) -> None:
164    async def refresh(self) -> None:
165        """Refresh current map's underlying map and room data, updating cache as needed.
166
167        This will only refresh the current map's data and will not populate non
168        active maps or re-discover the home. It is expected that this will keep
169        information up to date for the current map as users switch to that map.
170        """
171        if not self._discovery_completed:
172            # Running initial discovery also populates all of the same information
173            # as below so we can just call that method. If the device is busy
174            # then we'll fall through below to refresh the current map only.
175            try:
176                await self.discover_home()
177                return
178            except RoborockDeviceBusy:
179                _LOGGER.debug("Cannot refresh home data while device is busy cleaning")
180
181        # Refresh the list of map names/info
182        await self._maps_trait.refresh()
183        if (current_map_info := self._maps_trait.current_map_info) is None or (
184            map_flag := self._maps_trait.current_map
185        ) is None:
186            raise RoborockException("Cannot refresh home data without current map info")
187
188        # Refresh the map content to ensure we have the latest image and object positions
189        new_map_content = await self._refresh_map_content()
190        # Refresh the current map's room data
191        combined_map_info = await self._refresh_map_info(current_map_info)
192        await self._update_current_map(
193            map_flag, combined_map_info, new_map_content, update_cache=self._discovery_completed
194        )

Refresh current map's underlying map and room data, updating cache as needed.

This will only refresh the current map's data and will not populate non active maps or re-discover the home. It is expected that this will keep information up to date for the current map as users switch to that map.

home_map_info: dict[int, roborock.data.containers.CombinedMapInfo] | None
196    @property
197    def home_map_info(self) -> dict[int, CombinedMapInfo] | None:
198        """Returns the map information for all cached maps."""
199        return self._home_map_info

Returns the map information for all cached maps.

current_map_data: roborock.data.containers.CombinedMapInfo | None
201    @property
202    def current_map_data(self) -> CombinedMapInfo | None:
203        """Returns the map data for the current map."""
204        current_map_flag = self._maps_trait.current_map
205        if current_map_flag is None or self._home_map_info is None:
206            return None
207        return self._home_map_info.get(current_map_flag)

Returns the map data for the current map.

home_map_content: dict[int, roborock.devices.traits.v1.map_content.MapContent] | None
209    @property
210    def home_map_content(self) -> dict[int, MapContent] | None:
211        """Returns the map content for all cached maps."""
212        return self._home_map_content

Returns the map content for all cached maps.