11"""Push-driven map traits for B01 Q10 devices.
22
3- Map-related state arrives on three independent streams:
3+ Map-related state arrives on four independent streams:
44
55* map packets are decoded from map-protocol responses;
66* trace packets are decoded from trace-protocol responses;
77* restricted zones and virtual walls arrive as ordinary DPS values.
8+ * the device status indicates when an idle robot is charging at the saved dock.
89
910``MapDpsTrait`` owns the low-level DPS read model. ``MapContentTrait`` depends
10- on it and combines that state with the latest map/trace packets through the pure
11- functions in :mod:`roborock.map.b01_q10_render`. The high-level trait keeps only
12- the latest value from each source and one replace-whole rendered image;
11+ on it and the status trait, then combines that state with the latest map/trace
12+ packets through the pure functions in :mod:`roborock.map.b01_q10_render`. The
13+ high-level trait keeps only the latest value from each source and one
14+ replace-whole rendered image;
1315calibration, path placement and overlay placement remain inside the renderer.
1416"""
1517
1820from typing import Any
1921
2022from roborock .data import RoborockBase
21- from roborock .data .b01_q10 .b01_q10_code_mappings import B01_Q10_DP
23+ from roborock .data .b01_q10 .b01_q10_code_mappings import B01_Q10_DP , YXDeviceState
2224from roborock .devices .traits .common import DpsDataConverter , TraitUpdateListener
2325from roborock .exceptions import RoborockException
2426from roborock .map .b01_q10_map_parser import (
3234from roborock .map .b01_q10_render import Q10MapOverlays , render_q10_map
3335
3436from .common import UpdatableTrait
37+ from .status import StatusTrait
3538
3639_LOGGER = logging .getLogger (__name__ )
3740
@@ -73,23 +76,27 @@ def update_from_dps(self, decoded_dps: dict[B01_Q10_DP, Any]) -> None:
7376class MapContentTrait (TraitUpdateListener ):
7477 """High-level composed Q10 map view.
7578
76- The latest map and trace packets are combined with the injected
77- :class:`MapDpsTrait` whenever any of those three sources changes.
79+ The latest map and trace packets are combined with the injected map DPS and
80+ status traits whenever any source changes.
7881 """
7982
8083 def __init__ (
8184 self ,
8285 map_dps : MapDpsTrait ,
86+ status : StatusTrait | None = None ,
8387 * ,
8488 map_parser_config : B01Q10MapParserConfig | None = None ,
8589 ) -> None :
8690 TraitUpdateListener .__init__ (self , logger = _LOGGER )
8791 self ._config = map_parser_config or B01Q10MapParserConfig ()
8892 self ._map_dps = map_dps
93+ self ._status = status or StatusTrait ()
94+ self ._robot_at_dock = self ._status .status == YXDeviceState .CHARGING
8995 self ._map_packet : Q10MapPacket | None = None
9096 self ._trace_packet : Q10TracePacket | None = None
9197 self ._image_content : bytes | None = None
9298 self ._map_dps .add_update_listener (self ._map_dps_updated )
99+ self ._status .add_update_listener (self ._status_updated )
93100
94101 @property
95102 def image_content (self ) -> bytes | None :
@@ -129,7 +136,18 @@ def update_from_trace_packet(self, packet: Q10TracePacket) -> None:
129136 self ._notify_update ()
130137
131138 def _map_dps_updated (self ) -> None :
132- """Render after the low-level DPS source changes."""
139+ """Render after the low-level map DPS source changes."""
140+ if self ._map_packet is None :
141+ return
142+ self ._render ()
143+ self ._notify_update ()
144+
145+ def _status_updated (self ) -> None :
146+ """Render only when the status changes whether the robot is docked."""
147+ robot_at_dock = self ._status .status == YXDeviceState .CHARGING
148+ if robot_at_dock == self ._robot_at_dock :
149+ return
150+ self ._robot_at_dock = robot_at_dock
133151 if self ._map_packet is None :
134152 return
135153 self ._render ()
@@ -145,6 +163,7 @@ def _render(self) -> None:
145163 self ._trace_packet ,
146164 self ._map_dps .overlays ,
147165 config = self ._config ,
166+ robot_at_dock = self ._robot_at_dock ,
148167 )
149168 except RoborockException as ex :
150169 _LOGGER .debug ("Failed to render Q10 map packet: %s" , ex )
0 commit comments