roborock.devices.traits.v1.status
1import logging 2from functools import cached_property 3from typing import Any 4 5from roborock import ( 6 CleaningMode, 7 CleanRoutes, 8 RoborockDockState, 9 StatusV2, 10 VacuumModes, 11 WaterModes, 12 get_clean_modes, 13 get_clean_routes, 14 get_cleaning_mode_options, 15 get_cleaning_mode_parameters, 16 get_current_cleaning_mode, 17 get_dock_state, 18 get_water_mode_mapping, 19 get_water_modes, 20 get_water_slide_mode_name, 21 resolve_cleaning_mode, 22) 23from roborock.devices.traits.common import DpsDataConverter, TraitUpdateListener 24from roborock.roborock_message import RoborockDataProtocol 25from roborock.roborock_typing import RoborockCommand 26 27from . import common 28from .device_features import DeviceFeaturesTrait 29 30_LOGGER = logging.getLogger(__name__) 31 32_DPS_CONVERTER = DpsDataConverter.from_dataclass(StatusV2) 33 34 35class StatusTrait(StatusV2, common.V1TraitMixin, TraitUpdateListener): 36 """Trait for managing the status of Roborock devices. 37 38 The StatusTrait gives you the access to the state of a Roborock vacuum. 39 The various attribute options on state change per each device. 40 Values like fan speed, mop mode, etc. have different options for every device 41 and are dynamically determined. 42 43 Usage: 44 Before accessing status properties, you should call `refresh()` to fetch 45 the latest data from the device. You must pass in the device feature trait 46 to this trait so that the dynamic attributes can be pre-determined. 47 48 The current dynamic attributes are: 49 - Fan Speed 50 - Water Mode 51 - Mop Route 52 53 You should use the _options version of the attribute to know which are 54 supported for your device (i.e. fan_speed_options) 55 Then you can use the _mapping to convert an int value to the actual Enum. 56 (i.e. fan_speed_mapping) 57 You can use the _name property to get the str value of the enum. (i.e. fan_speed_name) 58 59 """ 60 61 command = RoborockCommand.GET_STATUS 62 converter = common.DefaultConverter(StatusV2) 63 64 def __init__(self, device_feature_trait: DeviceFeaturesTrait, region: str | None = None) -> None: 65 """Initialize the StatusTrait.""" 66 super().__init__() 67 TraitUpdateListener.__init__(self, logger=_LOGGER) 68 self._device_features_trait = device_feature_trait 69 self._region = region 70 71 @property 72 def dock_state(self) -> RoborockDockState: 73 """Return the feature-aware dock state used by the Roborock app.""" 74 return get_dock_state( 75 state=self.state, 76 battery=self.battery, 77 charge_status=self.charge_status, 78 is_supported_valley_electricity=self._device_features_trait.is_supported_valley_electricity, 79 ) 80 81 @property 82 def is_battery_charging(self) -> bool: 83 """Return whether the battery is actively charging.""" 84 return self.dock_state == RoborockDockState.charging 85 86 @cached_property 87 def fan_speed_options(self) -> list[VacuumModes]: 88 return get_clean_modes(self._device_features_trait) 89 90 @cached_property 91 def fan_speed_mapping(self) -> dict[int, str]: 92 return {fan.code: fan.value for fan in self.fan_speed_options} 93 94 @cached_property 95 def water_mode_options(self) -> list[WaterModes]: 96 return get_water_modes(self._device_features_trait) 97 98 @cached_property 99 def water_mode_mapping(self) -> dict[int, str]: 100 return get_water_mode_mapping(self._device_features_trait) 101 102 @cached_property 103 def mop_route_options(self) -> list[CleanRoutes]: 104 return get_clean_routes(self._device_features_trait, self._region or "us") 105 106 @cached_property 107 def mop_route_mapping(self) -> dict[int, str]: 108 return {route.code: route.display_name for route in self.mop_route_options} 109 110 @cached_property 111 def cleaning_mode_options(self) -> list[CleaningMode]: 112 return get_cleaning_mode_options(self._device_features_trait) 113 114 @property 115 def fan_speed_name(self) -> str | None: 116 if self.fan_power is None: 117 return None 118 return self.fan_speed_mapping.get(self.fan_power) 119 120 @property 121 def water_mode_name(self) -> str | None: 122 if self.water_box_mode is None: 123 return None 124 if self._device_features_trait.is_water_slide_mode_supported: 125 return get_water_slide_mode_name(self.water_box_mode) 126 return self.water_mode_mapping.get(self.water_box_mode) 127 128 @property 129 def mop_route_name(self) -> str | None: 130 if self.mop_mode is None: 131 return None 132 return self.mop_route_mapping.get(self.mop_mode) 133 134 @property 135 def current_cleaning_mode(self) -> CleaningMode | None: 136 return get_current_cleaning_mode( 137 clean_mode=self.fan_power, 138 water_mode=self.water_box_mode, 139 mop_mode=self.mop_mode, 140 features=self._device_features_trait, 141 ) 142 143 @property 144 def current_cleaning_mode_name(self) -> str | None: 145 if (cleaning_mode := self.current_cleaning_mode) is None: 146 return None 147 return cleaning_mode.value 148 149 async def set_cleaning_mode(self, cleaning_mode: str | CleaningMode) -> None: 150 """Set the preferred high-level cleaning mode for the device.""" 151 await self.rpc_channel.send_command( 152 RoborockCommand.SET_CLEAN_MOTOR_MODE, 153 params=get_cleaning_mode_parameters(resolve_cleaning_mode(cleaning_mode), self._device_features_trait), 154 ) 155 156 async def resolve_error(self, error_code: int | None = None) -> None: 157 """Resolve an error, like tapping "Resolved" in the Roborock app. 158 159 Without an explicit code this resolves the current dock error if there is one, 160 otherwise the current robot error. A dock error such as water_empty stays latched 161 on the device until it is resolved, even after the cause has been fixed. 162 """ 163 if error_code is None: 164 if self.dock_error_status: 165 error_code = int(self.dock_error_status) 166 elif self.error_code: 167 error_code = int(self.error_code) 168 else: 169 return 170 await self.rpc_channel.send_command(RoborockCommand.RESOLVE_ERROR, params={"error_code": error_code}) 171 await self.refresh() 172 173 def update_from_dps(self, decoded_dps: dict[RoborockDataProtocol, Any]) -> None: 174 """Update the trait from data protocol push message data. 175 176 This handles unsolicited status updates pushed by the device 177 via RoborockDataProtocol codes (e.g. STATE=121, BATTERY=122). 178 """ 179 if _DPS_CONVERTER.update_from_dps(self, decoded_dps): 180 self._notify_update()
36class StatusTrait(StatusV2, common.V1TraitMixin, TraitUpdateListener): 37 """Trait for managing the status of Roborock devices. 38 39 The StatusTrait gives you the access to the state of a Roborock vacuum. 40 The various attribute options on state change per each device. 41 Values like fan speed, mop mode, etc. have different options for every device 42 and are dynamically determined. 43 44 Usage: 45 Before accessing status properties, you should call `refresh()` to fetch 46 the latest data from the device. You must pass in the device feature trait 47 to this trait so that the dynamic attributes can be pre-determined. 48 49 The current dynamic attributes are: 50 - Fan Speed 51 - Water Mode 52 - Mop Route 53 54 You should use the _options version of the attribute to know which are 55 supported for your device (i.e. fan_speed_options) 56 Then you can use the _mapping to convert an int value to the actual Enum. 57 (i.e. fan_speed_mapping) 58 You can use the _name property to get the str value of the enum. (i.e. fan_speed_name) 59 60 """ 61 62 command = RoborockCommand.GET_STATUS 63 converter = common.DefaultConverter(StatusV2) 64 65 def __init__(self, device_feature_trait: DeviceFeaturesTrait, region: str | None = None) -> None: 66 """Initialize the StatusTrait.""" 67 super().__init__() 68 TraitUpdateListener.__init__(self, logger=_LOGGER) 69 self._device_features_trait = device_feature_trait 70 self._region = region 71 72 @property 73 def dock_state(self) -> RoborockDockState: 74 """Return the feature-aware dock state used by the Roborock app.""" 75 return get_dock_state( 76 state=self.state, 77 battery=self.battery, 78 charge_status=self.charge_status, 79 is_supported_valley_electricity=self._device_features_trait.is_supported_valley_electricity, 80 ) 81 82 @property 83 def is_battery_charging(self) -> bool: 84 """Return whether the battery is actively charging.""" 85 return self.dock_state == RoborockDockState.charging 86 87 @cached_property 88 def fan_speed_options(self) -> list[VacuumModes]: 89 return get_clean_modes(self._device_features_trait) 90 91 @cached_property 92 def fan_speed_mapping(self) -> dict[int, str]: 93 return {fan.code: fan.value for fan in self.fan_speed_options} 94 95 @cached_property 96 def water_mode_options(self) -> list[WaterModes]: 97 return get_water_modes(self._device_features_trait) 98 99 @cached_property 100 def water_mode_mapping(self) -> dict[int, str]: 101 return get_water_mode_mapping(self._device_features_trait) 102 103 @cached_property 104 def mop_route_options(self) -> list[CleanRoutes]: 105 return get_clean_routes(self._device_features_trait, self._region or "us") 106 107 @cached_property 108 def mop_route_mapping(self) -> dict[int, str]: 109 return {route.code: route.display_name for route in self.mop_route_options} 110 111 @cached_property 112 def cleaning_mode_options(self) -> list[CleaningMode]: 113 return get_cleaning_mode_options(self._device_features_trait) 114 115 @property 116 def fan_speed_name(self) -> str | None: 117 if self.fan_power is None: 118 return None 119 return self.fan_speed_mapping.get(self.fan_power) 120 121 @property 122 def water_mode_name(self) -> str | None: 123 if self.water_box_mode is None: 124 return None 125 if self._device_features_trait.is_water_slide_mode_supported: 126 return get_water_slide_mode_name(self.water_box_mode) 127 return self.water_mode_mapping.get(self.water_box_mode) 128 129 @property 130 def mop_route_name(self) -> str | None: 131 if self.mop_mode is None: 132 return None 133 return self.mop_route_mapping.get(self.mop_mode) 134 135 @property 136 def current_cleaning_mode(self) -> CleaningMode | None: 137 return get_current_cleaning_mode( 138 clean_mode=self.fan_power, 139 water_mode=self.water_box_mode, 140 mop_mode=self.mop_mode, 141 features=self._device_features_trait, 142 ) 143 144 @property 145 def current_cleaning_mode_name(self) -> str | None: 146 if (cleaning_mode := self.current_cleaning_mode) is None: 147 return None 148 return cleaning_mode.value 149 150 async def set_cleaning_mode(self, cleaning_mode: str | CleaningMode) -> None: 151 """Set the preferred high-level cleaning mode for the device.""" 152 await self.rpc_channel.send_command( 153 RoborockCommand.SET_CLEAN_MOTOR_MODE, 154 params=get_cleaning_mode_parameters(resolve_cleaning_mode(cleaning_mode), self._device_features_trait), 155 ) 156 157 async def resolve_error(self, error_code: int | None = None) -> None: 158 """Resolve an error, like tapping "Resolved" in the Roborock app. 159 160 Without an explicit code this resolves the current dock error if there is one, 161 otherwise the current robot error. A dock error such as water_empty stays latched 162 on the device until it is resolved, even after the cause has been fixed. 163 """ 164 if error_code is None: 165 if self.dock_error_status: 166 error_code = int(self.dock_error_status) 167 elif self.error_code: 168 error_code = int(self.error_code) 169 else: 170 return 171 await self.rpc_channel.send_command(RoborockCommand.RESOLVE_ERROR, params={"error_code": error_code}) 172 await self.refresh() 173 174 def update_from_dps(self, decoded_dps: dict[RoborockDataProtocol, Any]) -> None: 175 """Update the trait from data protocol push message data. 176 177 This handles unsolicited status updates pushed by the device 178 via RoborockDataProtocol codes (e.g. STATE=121, BATTERY=122). 179 """ 180 if _DPS_CONVERTER.update_from_dps(self, decoded_dps): 181 self._notify_update()
Trait for managing the status of Roborock devices.
The StatusTrait gives you the access to the state of a Roborock vacuum. The various attribute options on state change per each device. Values like fan speed, mop mode, etc. have different options for every device and are dynamically determined.
Usage:
Before accessing status properties, you should call refresh() to fetch
the latest data from the device. You must pass in the device feature trait
to this trait so that the dynamic attributes can be pre-determined.
The current dynamic attributes are:
- Fan Speed
- Water Mode
- Mop Route
You should use the _options version of the attribute to know which are supported for your device (i.e. fan_speed_options) Then you can use the _mapping to convert an int value to the actual Enum. (i.e. fan_speed_mapping) You can use the _name property to get the str value of the enum. (i.e. fan_speed_name)
65 def __init__(self, device_feature_trait: DeviceFeaturesTrait, region: str | None = None) -> None: 66 """Initialize the StatusTrait.""" 67 super().__init__() 68 TraitUpdateListener.__init__(self, logger=_LOGGER) 69 self._device_features_trait = device_feature_trait 70 self._region = region
Initialize the StatusTrait.
The RoborockCommand used to fetch the trait data from the device (internal only).
The converter used to parse the response from the device (internal only).
72 @property 73 def dock_state(self) -> RoborockDockState: 74 """Return the feature-aware dock state used by the Roborock app.""" 75 return get_dock_state( 76 state=self.state, 77 battery=self.battery, 78 charge_status=self.charge_status, 79 is_supported_valley_electricity=self._device_features_trait.is_supported_valley_electricity, 80 )
Return the feature-aware dock state used by the Roborock app.
82 @property 83 def is_battery_charging(self) -> bool: 84 """Return whether the battery is actively charging.""" 85 return self.dock_state == RoborockDockState.charging
Return whether the battery is actively charging.
150 async def set_cleaning_mode(self, cleaning_mode: str | CleaningMode) -> None: 151 """Set the preferred high-level cleaning mode for the device.""" 152 await self.rpc_channel.send_command( 153 RoborockCommand.SET_CLEAN_MOTOR_MODE, 154 params=get_cleaning_mode_parameters(resolve_cleaning_mode(cleaning_mode), self._device_features_trait), 155 )
Set the preferred high-level cleaning mode for the device.
157 async def resolve_error(self, error_code: int | None = None) -> None: 158 """Resolve an error, like tapping "Resolved" in the Roborock app. 159 160 Without an explicit code this resolves the current dock error if there is one, 161 otherwise the current robot error. A dock error such as water_empty stays latched 162 on the device until it is resolved, even after the cause has been fixed. 163 """ 164 if error_code is None: 165 if self.dock_error_status: 166 error_code = int(self.dock_error_status) 167 elif self.error_code: 168 error_code = int(self.error_code) 169 else: 170 return 171 await self.rpc_channel.send_command(RoborockCommand.RESOLVE_ERROR, params={"error_code": error_code}) 172 await self.refresh()
Resolve an error, like tapping "Resolved" in the Roborock app.
Without an explicit code this resolves the current dock error if there is one, otherwise the current robot error. A dock error such as water_empty stays latched on the device until it is resolved, even after the cause has been fixed.
174 def update_from_dps(self, decoded_dps: dict[RoborockDataProtocol, Any]) -> None: 175 """Update the trait from data protocol push message data. 176 177 This handles unsolicited status updates pushed by the device 178 via RoborockDataProtocol codes (e.g. STATE=121, BATTERY=122). 179 """ 180 if _DPS_CONVERTER.update_from_dps(self, decoded_dps): 181 self._notify_update()
Update the trait from data protocol push message data.
This handles unsolicited status updates pushed by the device via RoborockDataProtocol codes (e.g. STATE=121, BATTERY=122).
Inherited Members
- roborock.data.v1.v1_containers.StatusV2
- msg_ver
- msg_seq
- state
- battery
- clean_time
- clean_area
- error_code
- map_present
- in_cleaning
- in_returning
- in_fresh_state
- lab_status
- water_box_status
- back_type
- wash_phase
- wash_ready
- fan_power
- dnd_enabled
- map_status
- is_locating
- lock_status
- water_box_mode
- water_box_carriage_status
- mop_forbidden_enable
- camera_status
- is_exploring
- home_sec_status
- home_sec_enable_password
- adbumper_status
- water_shortage_status
- dock_type
- dust_collection_status
- auto_dust_collection
- avoid_count
- mop_mode
- debug_mode
- collision_avoid_status
- switch_map_mode
- dock_error_status
- charge_status
- unsave_map_reason
- unsave_map_flag
- wash_status
- distance_off
- in_warmup
- dry_status
- rdt
- clean_percent
- rss
- dss
- common_status
- corner_clean_mode
- last_clean_t
- replenish_mode
- repeat
- kct
- subdivision_sets
- square_meter_clean_area
- error_code_name
- state_name
- current_map
- has_am
- clear_water_box_status
- dirty_water_box_status
- dust_bag_status
- water_box_filter_status
- clean_fluid_status
- hatch_door_status
- dock_cool_fan_status