1515
1616import logging
1717from dataclasses import dataclass , field
18+ from typing import Any
1819
1920from roborock .data import RoborockBase
2021from roborock .data .b01_q10 .b01_q10_code_mappings import B01_Q10_DP
2728 Q10Room ,
2829 Q10TracePacket ,
2930)
30- from roborock .map .b01_q10_overlays import Q10Zone , parse_virtual_wall_blob , parse_zone_blob
31+ from roborock .map .b01_q10_overlays import parse_virtual_wall_blob , parse_zone_blob
3132from roborock .map .b01_q10_render import Q10MapOverlays , render_q10_map
3233
3334from .common import UpdatableTrait
@@ -44,23 +45,29 @@ class MapDps(RoborockBase):
4445
4546
4647class MapDpsTrait (MapDps , UpdatableTrait ):
47- """Converter-backed read model for map-related DPS values."""
48+ """Private read model for map-related DPS values and decoded overlays ."""
4849
4950 _CONVERTER = DpsDataConverter .from_dataclass (MapDps )
5051
5152 def __init__ (self ) -> None :
5253 MapDps .__init__ (self )
5354 UpdatableTrait .__init__ (self , command = None , logger = _LOGGER )
55+ self ._overlays = Q10MapOverlays ()
5456
5557 @property
56- def zones (self ) -> list [ Q10Zone ] :
57- """Restricted zones decoded from the latest DPS value ."""
58- return parse_zone_blob ( self .restricted_zone_up )
58+ def overlays (self ) -> Q10MapOverlays :
59+ """Overlays decoded once from the latest relevant DPS update ."""
60+ return self ._overlays
5961
60- @property
61- def virtual_walls (self ) -> list [Q10Zone ]:
62- """Virtual walls decoded from the latest DPS value."""
63- return parse_virtual_wall_blob (self .virtual_wall_up )
62+ def update_from_dps (self , decoded_dps : dict [B01_Q10_DP , Any ]) -> None :
63+ """Decode overlay blobs when they arrive, then notify dependents."""
64+ if not self ._CONVERTER .update_from_dps (self , decoded_dps ):
65+ return
66+ self ._overlays = Q10MapOverlays (
67+ zones = tuple (parse_zone_blob (self .restricted_zone_up )),
68+ virtual_walls = tuple (parse_virtual_wall_blob (self .virtual_wall_up )),
69+ )
70+ self ._notify_update ()
6471
6572
6673class MapContentTrait (TraitUpdateListener ):
@@ -96,17 +103,17 @@ def rooms(self) -> list[Q10Room]:
96103
97104 @property
98105 def path (self ) -> list [Q10Point ]:
99- """Full path from the latest trace packet ."""
106+ """Full path for live status and callers drawing their own map overlay ."""
100107 return self ._trace_packet .points if self ._trace_packet else []
101108
102109 @property
103110 def robot_position (self ) -> Q10Point | None :
104- """Current robot position from the latest trace packet ."""
111+ """Current position for live status and caller-rendered map overlays ."""
105112 return self ._trace_packet .robot_position if self ._trace_packet else None
106113
107114 @property
108115 def robot_heading (self ) -> int | None :
109- """Current robot heading from the latest trace packet ."""
116+ """Current heading for orienting a robot marker on a caller-rendered map ."""
110117 return self ._trace_packet .heading if self ._trace_packet else None
111118
112119 def update_from_map_packet (self , packet : Q10MapPacket ) -> None :
@@ -129,17 +136,14 @@ def _map_dps_updated(self) -> None:
129136 self ._notify_update ()
130137
131138 def _render (self ) -> None :
132- """Render the latest map, trace and DPS sources, if a map is available ."""
139+ """Render the required map with the latest optional trace and overlays ."""
133140 if self ._map_packet is None :
134141 return
135142 try :
136143 self ._image_content = render_q10_map (
137144 self ._map_packet ,
138145 self ._trace_packet ,
139- Q10MapOverlays (
140- zones = tuple (self ._map_dps .zones ),
141- virtual_walls = tuple (self ._map_dps .virtual_walls ),
142- ),
146+ self ._map_dps .overlays ,
143147 config = self ._config ,
144148 )
145149 except RoborockException as ex :
0 commit comments