Skip to content

Commit dcf4df9

Browse files
committed
feat: Allow rooms trait to unconditionally override map info rooms during merging.
1 parent bbb6cda commit dcf4df9

File tree

4 files changed

+19
-24
lines changed

4 files changed

+19
-24
lines changed

roborock/data/v1/v1_containers.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -722,9 +722,9 @@ def mapFlag(self) -> int:
722722
def rooms_map(self) -> dict[int, NamedRoomMapping]:
723723
"""Returns a dictionary of room mappings by segment id."""
724724
return {
725-
room.id: room.named_room_mapping
725+
room.id: mapping
726726
for room in self.rooms or ()
727-
if room.id is not None and room.named_room_mapping is not None
727+
if room.id is not None and (mapping := room.named_room_mapping) is not None
728728
}
729729

730730

roborock/devices/traits/v1/home.py

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -119,25 +119,20 @@ async def _refresh_map_info(self, map_info: MultiMapsListMapInfo) -> CombinedMap
119119
"""Collect room data for a specific map and return CombinedMapInfo."""
120120
await self._rooms_trait.refresh()
121121

122-
# We have room names from two sources. The map_info.rooms which we just
123-
# received from the MultiMapsList or the self._rooms_trait.rooms which
124-
# comes from the GET_ROOM_MAPPING command. We merge them, giving priority
125-
# to map_info rooms, and excluding unset rooms from the trait.
126-
rooms: list[NamedRoomMapping] = list(
127-
{
128-
**map_info.rooms_map,
129-
**{
130-
room.segment_id: room
131-
for room in self._rooms_trait.rooms or ()
132-
if (existing := map_info.rooms_map.get(room.segment_id)) is None
133-
or (room.raw_name and existing.raw_name is None)
134-
},
135-
}.values()
136-
)
122+
# We have room names from multiple sources:
123+
# - The map_info.rooms which we just received from the MultiMapsList
124+
# - RoomsTrait rooms come from the GET_ROOM_MAPPING command for the current device (only)
125+
# - RoomsTrait rooms that are pulled from the cloud API
126+
# We always prefer the RoomsTrait room names since they are always newer and
127+
# just refreshed above.
128+
rooms_map: dict[str, NamedRoomMapping] = {
129+
**map_info.rooms_map,
130+
**{room.segment_id: room for room in self._rooms_trait.rooms or ()},
131+
}
137132
return CombinedMapInfo(
138133
map_flag=map_info.map_flag,
139134
name=map_info.name,
140-
rooms=rooms,
135+
rooms=list(rooms_map.values()),
141136
)
142137

143138
async def _refresh_map_content(self) -> MapContent:

roborock/devices/traits/v1/rooms.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ def _parse_rooms(
7272
)
7373

7474
async def _refresh_rooms(self) -> list[HomeDataRoom]:
75-
"""Merge the existing rooms with new rooms returned from the API."""
75+
"""Fetch the latest rooms from the web API."""
7676
try:
7777
return await self._web_api.get_rooms()
7878
except Exception:

tests/devices/traits/v1/test_home.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ async def test_discover_home_empty_cache(
244244
assert map_123_data.rooms[0].iot_id == "2362041"
245245
assert map_123_data.rooms[0].name == "Example room 3"
246246
assert map_123_data.rooms[1].segment_id == 19
247-
assert map_123_data.rooms[0].iot_id == "2362041"
247+
assert map_123_data.rooms[1].iot_id == "2362042"
248248
assert map_123_data.rooms[1].name == "Room 19" # Not in mock home data
249249

250250
map_123_content = home_trait.home_map_content[123]
@@ -675,7 +675,7 @@ async def test_refresh_map_info_prefers_map_info_names_and_adds_missing_rooms(
675675
# - segment_id 18 with valid name: not in map_info, should be added
676676
# - segment_id 20 with valid name: overrides map_info fallback "Room 20"
677677
rooms_trait.rooms = [
678-
NamedRoomMapping(segment_id=16, iot_id="2362048"), # Exists in map_info, should not override
678+
NamedRoomMapping(segment_id=16, iot_id="2362048"), # Will override even with no name
679679
NamedRoomMapping(
680680
segment_id=19, iot_id="2362042", raw_name="Updated Bedroom Name"
681681
), # Exists in map_info, should not override
@@ -697,9 +697,9 @@ async def test_refresh_map_info_prefers_map_info_names_and_adds_missing_rooms(
697697
# Sort rooms by segment_id for consistent assertions
698698
sorted_rooms = sorted(result.rooms, key=lambda r: r.segment_id)
699699

700-
# Room 16: from map_info, kept (not overridden by rooms_trait fallback)
700+
# Room 16: from map_info is overridden by rooms_trait
701701
assert sorted_rooms[0].segment_id == 16
702-
assert sorted_rooms[0].name == "Kitchen from map_info"
702+
assert sorted_rooms[0].name == "Room 16"
703703
assert sorted_rooms[0].iot_id == "2362048"
704704

705705
# Room 17: from rooms_trait with fallback name, added because not in map_info
@@ -714,7 +714,7 @@ async def test_refresh_map_info_prefers_map_info_names_and_adds_missing_rooms(
714714

715715
# Room 19: from map_info, kept (not overridden by rooms_trait)
716716
assert sorted_rooms[3].segment_id == 19
717-
assert sorted_rooms[3].name == "Bedroom from map_info"
717+
assert sorted_rooms[3].name == "Updated Bedroom Name"
718718
assert sorted_rooms[3].iot_id == "2362042"
719719

720720
# Room 20: map_info fallback name replaced by rooms_trait name

0 commit comments

Comments
 (0)