From 3a2baeaea242d32c9ba68cacef4c7e15b53ca469 Mon Sep 17 00:00:00 2001 From: Luke Date: Wed, 12 Aug 2026 10:12:51 -0400 Subject: [PATCH 1/2] fix: fix support gap for the clean route logic --- roborock/data/v1/v1_clean_modes.py | 6 ++- roborock/device_features.py | 4 ++ .../test_supported_features.ambr | 2 +- .../devices/__snapshots__/test_v1_device.ambr | 2 +- tests/devices/traits/v1/test_status.py | 46 +++++++++++++++++++ tests/test_supported_features.py | 40 ++++++++++++++++ 6 files changed, 97 insertions(+), 3 deletions(-) diff --git a/roborock/data/v1/v1_clean_modes.py b/roborock/data/v1/v1_clean_modes.py index 258307b3..3b7d4517 100644 --- a/roborock/data/v1/v1_clean_modes.py +++ b/roborock/data/v1/v1_clean_modes.py @@ -131,6 +131,10 @@ def get_clean_modes(features: DeviceFeatures) -> list[VacuumModes]: def get_clean_routes(features: DeviceFeatures, region: str) -> list[CleanRoutes]: """The routes that the vacuum will take while mopping""" + # Mop routes are only configurable when the device advertises support for + # setting the shake-mop route. + if not features.is_shake_mop_set_supported: + return [] if features.is_none_pure_clean_mop_with_max_plus: return [CleanRoutes.FAST, CleanRoutes.STANDARD] supported = [CleanRoutes.STANDARD, CleanRoutes.DEEP] @@ -271,7 +275,7 @@ def get_cleaning_mode_parameters(cleaning_mode: CleaningMode, features: DeviceFe fan_power, water_box_mode, mop_mode = _get_clean_motor_mode_params(cleaning_mode, features) params: dict[str, int] = {"fan_power": fan_power.code, "water_box_mode": water_box_mode.code} - if features.is_clean_route_setting_supported: + if features.is_shake_mop_set_supported: params["mop_mode"] = mop_mode.code return [params] diff --git a/roborock/device_features.py b/roborock/device_features.py index 767c519a..23af4c9c 100644 --- a/roborock/device_features.py +++ b/roborock/device_features.py @@ -644,6 +644,10 @@ def from_feature_flags( if any(feat in available_features for feat in product_features): # type: ignore kwargs[f.name] = True + # Clean-route setting support is provided by either the runtime + # shake-mop flag or the model's shake/spin mop capability. + kwargs["is_clean_route_setting_supported"] |= kwargs["is_shake_mop_set_supported"] + return cls(**kwargs) def get_supported_features(self) -> list[str]: diff --git a/tests/__snapshots__/test_supported_features.ambr b/tests/__snapshots__/test_supported_features.ambr index 447a6822..5f8d9bd7 100644 --- a/tests/__snapshots__/test_supported_features.ambr +++ b/tests/__snapshots__/test_supported_features.ambr @@ -386,7 +386,7 @@ 'is_clean_history_time_line_supported': False, 'is_clean_route_deep_slow_plus_supported': False, 'is_clean_route_fast_mode_supported': True, - 'is_clean_route_setting_supported': False, + 'is_clean_route_setting_supported': True, 'is_clean_then_mop_mode_supported': False, 'is_clean_time_line_supported': False, 'is_collect_dust_count_show_supported': False, diff --git a/tests/devices/__snapshots__/test_v1_device.ambr b/tests/devices/__snapshots__/test_v1_device.ambr index f33f2490..3cd44496 100644 --- a/tests/devices/__snapshots__/test_v1_device.ambr +++ b/tests/devices/__snapshots__/test_v1_device.ambr @@ -874,7 +874,7 @@ }) # --- # name: test_device_trait_command_parsing[status] - StatusTrait(adbumper_status=None, auto_dust_collection=None, avoid_count=None, back_type=None, battery=100, camera_status=None, charge_status=None, clean_area=91287500, clean_fluid_status=None, clean_percent=None, clean_time=5405, cleaning_mode_options=[, , , ], clear_water_box_status=None, collision_avoid_status=None, command=, common_status=None, converter=DefaultConverter, corner_clean_mode=None, current_cleaning_mode=, current_cleaning_mode_name='custom', current_map=0, debug_mode=None, dirty_water_box_status=None, distance_off=0, dnd_enabled=1, dock_cool_fan_status=None, dock_error_status=None, dock_state=, dock_type=None, dry_status=None, dss=None, dust_bag_status=None, dust_collection_status=None, error_code=, error_code_name='none', fan_power=106, fan_speed_mapping={101: 'quiet', 102: 'balanced', 103: 'turbo', 104: 'max', 108: 'max_plus', 105: 'off', 106: 'custom'}, fan_speed_name='custom', fan_speed_options=[, , , , , , ], has_am=None, hatch_door_status=None, home_sec_enable_password=None, home_sec_status=None, in_cleaning=, in_fresh_state=1, in_returning=0, in_warmup=None, is_exploring=None, is_locating=0, kct=None, lab_status=1, last_clean_t=None, lock_status=0, map_present=1, map_status=3, mop_forbidden_enable=0, mop_mode=None, mop_route_mapping={300: 'standard', 301: 'deep', 302: 'custom'}, mop_route_name=None, mop_route_options=[, , ], msg_seq=515, msg_ver=2, rdt=None, repeat=None, replenish_mode=None, rss=None, square_meter_clean_area=91.3, state=, state_name='charging', subdivision_sets=None, switch_map_mode=None, unsave_map_flag=0, unsave_map_reason=4, wash_phase=None, wash_ready=None, wash_status=None, water_box_carriage_status=0, water_box_filter_status=None, water_box_mode=204, water_box_status=0, water_mode_mapping={200: 'off', 201: 'mild', 202: 'standard', 203: 'intense', 207: 'custom_water_flow', 204: 'custom'}, water_mode_name='custom', water_mode_options=[, , , , , ], water_shortage_status=None) + StatusTrait(adbumper_status=None, auto_dust_collection=None, avoid_count=None, back_type=None, battery=100, camera_status=None, charge_status=None, clean_area=91287500, clean_fluid_status=None, clean_percent=None, clean_time=5405, cleaning_mode_options=[, , , ], clear_water_box_status=None, collision_avoid_status=None, command=, common_status=None, converter=DefaultConverter, corner_clean_mode=None, current_cleaning_mode=, current_cleaning_mode_name='custom', current_map=0, debug_mode=None, dirty_water_box_status=None, distance_off=0, dnd_enabled=1, dock_cool_fan_status=None, dock_error_status=None, dock_state=, dock_type=None, dry_status=None, dss=None, dust_bag_status=None, dust_collection_status=None, error_code=, error_code_name='none', fan_power=106, fan_speed_mapping={101: 'quiet', 102: 'balanced', 103: 'turbo', 104: 'max', 108: 'max_plus', 105: 'off', 106: 'custom'}, fan_speed_name='custom', fan_speed_options=[, , , , , , ], has_am=None, hatch_door_status=None, home_sec_enable_password=None, home_sec_status=None, in_cleaning=, in_fresh_state=1, in_returning=0, in_warmup=None, is_exploring=None, is_locating=0, kct=None, lab_status=1, last_clean_t=None, lock_status=0, map_present=1, map_status=3, mop_forbidden_enable=0, mop_mode=None, mop_route_mapping={}, mop_route_name=None, mop_route_options=[], msg_seq=515, msg_ver=2, rdt=None, repeat=None, replenish_mode=None, rss=None, square_meter_clean_area=91.3, state=, state_name='charging', subdivision_sets=None, switch_map_mode=None, unsave_map_flag=0, unsave_map_reason=4, wash_phase=None, wash_ready=None, wash_status=None, water_box_carriage_status=0, water_box_filter_status=None, water_box_mode=204, water_box_status=0, water_mode_mapping={200: 'off', 201: 'mild', 202: 'standard', 203: 'intense', 207: 'custom_water_flow', 204: 'custom'}, water_mode_name='custom', water_mode_options=[, , , , , ], water_shortage_status=None) # --- # name: test_device_trait_command_parsing[status].1 dict({ diff --git a/tests/devices/traits/v1/test_status.py b/tests/devices/traits/v1/test_status.py index 0c397faf..6f2b7c65 100644 --- a/tests/devices/traits/v1/test_status.py +++ b/tests/devices/traits/v1/test_status.py @@ -50,6 +50,7 @@ def _create_cleaning_mode_status_trait(**feature_overrides: bool) -> StatusTrait features.is_pure_clean_mop_supported = True features.is_customized_clean_supported = True features.is_clean_route_setting_supported = True + features.is_shake_mop_set_supported = True for feature_name, value in feature_overrides.items(): if not hasattr(features, feature_name): raise AttributeError(f"Unknown DeviceFeatures override: {feature_name}") @@ -110,6 +111,7 @@ def test_none_values(status_trait: StatusTrait) -> None: def test_options(status_trait: StatusTrait) -> None: """Test that fan_speed_options returns a list of options.""" + status_trait._device_features_trait.is_shake_mop_set_supported = True assert isinstance(status_trait.fan_speed_options, list) assert len(status_trait.fan_speed_options) > 0 assert isinstance(status_trait.water_mode_options, list) @@ -118,6 +120,49 @@ def test_options(status_trait: StatusTrait) -> None: assert len(status_trait.mop_route_options) > 0 +def test_s6_maxv_has_no_mop_route_options() -> None: + """Test S6 MaxV does not expose the unsupported mop-route selector.""" + features = DeviceFeatures.from_feature_flags( + new_feature_info=10738169343, + new_feature_info_str="", + feature_info=[], + product_nickname=SHORT_MODEL_TO_ENUM["a10"], + ) + status_trait = StatusTrait(cast(DeviceFeaturesTrait, features), region="us") + + assert not features.is_shake_mop_set_supported + assert status_trait.mop_route_options == [] + assert status_trait.mop_route_mapping == {} + assert get_cleaning_mode_parameters(CleaningMode.VAC_AND_MOP, features) == [ + { + "fan_power": VacuumModes.BALANCED.code, + "water_box_mode": WaterModes.STANDARD.code, + } + ] + + +def test_s7_has_mop_route_options() -> None: + """Test S7 exposes its supported mop routes.""" + features = DeviceFeatures.from_feature_flags( + new_feature_info=636084721975295, + new_feature_info_str="0000000000002000", + feature_info=[111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 122, 123, 124, 125], + product_nickname=SHORT_MODEL_TO_ENUM["a15"], + ) + status_trait = StatusTrait(cast(DeviceFeaturesTrait, features), region="us") + + assert features.is_shake_mop_set_supported + assert CleanRoutes.STANDARD in status_trait.mop_route_options + assert CleanRoutes.DEEP in status_trait.mop_route_options + assert get_cleaning_mode_parameters(CleaningMode.VAC_AND_MOP, features) == [ + { + "fan_power": VacuumModes.BALANCED.code, + "water_box_mode": WaterModes.STANDARD.code, + "mop_mode": CleanRoutes.STANDARD.code, + } + ] + + def test_cleaning_mode_options() -> None: """Test the high-level cleaning mode options for the device.""" status_trait = _create_cleaning_mode_status_trait() @@ -316,6 +361,7 @@ def test_get_cleaning_mode_parameters_without_clean_route_setting() -> None: """Test older V1 devices use the 2-field clean motor payload.""" status_trait = _create_cleaning_mode_status_trait( is_clean_route_setting_supported=False, + is_shake_mop_set_supported=False, is_customized_clean_supported=False, ) diff --git a/tests/test_supported_features.py b/tests/test_supported_features.py index 8144fc53..09ecf745 100644 --- a/tests/test_supported_features.py +++ b/tests/test_supported_features.py @@ -75,6 +75,8 @@ def test_supported_features_qrevo_maxv(): assert num_true != 0 assert device_features.is_dust_collection_setting_supported assert device_features.is_led_status_switch_supported + assert device_features.is_shake_mop_set_supported + assert device_features.is_clean_route_setting_supported assert not device_features.is_matter_supported print(device_features) @@ -95,6 +97,8 @@ def test_supported_features_s7(): assert device_features assert device_features.is_custom_mode_supported assert device_features.is_led_status_switch_supported + assert device_features.is_shake_mop_set_supported + assert device_features.is_clean_route_setting_supported assert not device_features.is_hot_wash_towel_supported num_true = sum(v for v in vars(device_features).values() if isinstance(v, bool)) assert num_true != 0 @@ -127,6 +131,42 @@ def test_new_feature_str_missing(): assert not device_features.is_show_clean_finish_reason_supported +def test_clean_route_setting_support_from_shake_mop_flag() -> None: + """Test clean-route capability includes the runtime shake-mop flag.""" + device_features = DeviceFeatures.from_feature_flags( + new_feature_info=262144, + new_feature_info_str="", + feature_info=[], + product_nickname=None, + ) + + assert device_features.is_shake_mop_set_supported + assert device_features.is_clean_route_setting_supported + + +@pytest.mark.parametrize( + ("new_feature_info", "expected"), + [ + (0, False), + (262143, False), + (262144, True), + (262145, True), + (1 << 60, False), + ], +) +def test_shake_mop_feature_bit_boundary(new_feature_info: int, expected: bool) -> None: + """Test only feature values containing the shake-mop bit enable it.""" + device_features = DeviceFeatures.from_feature_flags( + new_feature_info=new_feature_info, + new_feature_info_str="", + feature_info=[], + product_nickname=None, + ) + + assert device_features.is_shake_mop_set_supported is expected + assert device_features.is_clean_route_setting_supported is expected + + @pytest.mark.parametrize( ("dock_type", "is_collectable", "is_washable"), [ From 8b057e53d964f0ae447d1618948f08b503d67eb0 Mon Sep 17 00:00:00 2001 From: Luke Date: Thu, 13 Aug 2026 10:20:11 -0400 Subject: [PATCH 2/2] fix: align mop routes with device capabilities --- roborock/data/code_mappings.py | 13 +++- roborock/data/v1/v1_clean_modes.py | 17 +++-- roborock/device_features.py | 10 ++- roborock/devices/traits/v1/status.py | 2 +- .../test_supported_features.ambr | 9 +++ tests/data/test_code_mappings.py | 12 +++- .../__snapshots__/test_device_manager.ambr | 1 + .../__snapshots__/test_file_cache.ambr | 6 +- .../devices/__snapshots__/test_v1_device.ambr | 6 +- tests/devices/traits/v1/test_status.py | 72 +++++++++++++++++-- tests/test_supported_features.py | 35 +++++++++ 11 files changed, 158 insertions(+), 25 deletions(-) diff --git a/roborock/data/code_mappings.py b/roborock/data/code_mappings.py index 6c066193..ff03e0e4 100644 --- a/roborock/data/code_mappings.py +++ b/roborock/data/code_mappings.py @@ -72,14 +72,21 @@ class RoborockModeEnum(StrEnum): code: int """The integer code associated with the enum member.""" + _display_name_: str | None - def __new__(cls, value: str, code: int) -> Self: + def __new__(cls, value: str, code: int, display_name: str | None = None) -> Self: """Creates a new enum member.""" member = str.__new__(cls, value) member._value_ = value member.code = code + member._display_name_ = display_name return member + @property + def display_name(self) -> str: + """Return the canonical user-facing name for the mode.""" + return self._display_name_ or self.value + @classmethod def from_code(cls, code: int) -> Self: for member in cls: @@ -149,8 +156,8 @@ def from_any_optional(cls, value: str | int) -> Self | None: @classmethod def keys(cls) -> list[str]: - """Returns a list of all member values.""" - return [member.value for member in cls] + """Returns a de-duplicated list of canonical member names.""" + return list(dict.fromkeys(member.display_name for member in cls)) def __eq__(self, other: Any) -> bool: if isinstance(other, str): diff --git a/roborock/data/v1/v1_clean_modes.py b/roborock/data/v1/v1_clean_modes.py index 3b7d4517..0b1e6f27 100644 --- a/roborock/data/v1/v1_clean_modes.py +++ b/roborock/data/v1/v1_clean_modes.py @@ -29,7 +29,7 @@ class CleanRoutes(RoborockModeEnum): DEEP = ("deep", 301) DEEP_PLUS = ("deep_plus", 303) FAST = ("fast", 304) - DEEP_PLUS_CN = ("deep_plus", 305) + DEEP_PLUS_CN = ("deep_plus_cn", 305, "deep_plus") SMART_MODE = ("smart_mode", 306) CUSTOMIZED = ("custom", 302) @@ -131,20 +131,19 @@ def get_clean_modes(features: DeviceFeatures) -> list[VacuumModes]: def get_clean_routes(features: DeviceFeatures, region: str) -> list[CleanRoutes]: """The routes that the vacuum will take while mopping""" - # Mop routes are only configurable when the device advertises support for - # setting the shake-mop route. - if not features.is_shake_mop_set_supported: + if not features.is_clean_route_setting_supported: return [] if features.is_none_pure_clean_mop_with_max_plus: return [CleanRoutes.FAST, CleanRoutes.STANDARD] - supported = [CleanRoutes.STANDARD, CleanRoutes.DEEP] + supported = [CleanRoutes.STANDARD] + if not features.is_clean_efficiency_supported: + supported.append(CleanRoutes.DEEP) if features.is_careful_slow_mop_supported: - if not ( - features.is_corner_clean_mode_supported + if ( + not features.is_corner_clean_mode_supported and features.is_clean_route_deep_slow_plus_supported and region == "cn" ): - # for some reason there is a china specific deep plus mode supported.append(CleanRoutes.DEEP_PLUS_CN) else: supported.append(CleanRoutes.DEEP_PLUS) @@ -275,7 +274,7 @@ def get_cleaning_mode_parameters(cleaning_mode: CleaningMode, features: DeviceFe fan_power, water_box_mode, mop_mode = _get_clean_motor_mode_params(cleaning_mode, features) params: dict[str, int] = {"fan_power": fan_power.code, "water_box_mode": water_box_mode.code} - if features.is_shake_mop_set_supported: + if features.is_clean_route_setting_supported: params["mop_mode"] = mop_mode.code return [params] diff --git a/roborock/device_features.py b/roborock/device_features.py index 23af4c9c..e61a119d 100644 --- a/roborock/device_features.py +++ b/roborock/device_features.py @@ -87,6 +87,7 @@ class NewFeatureStrBit(IntEnum): TWO_GEARS_NO_COLLISION = 118 CARPET_SHAPE_TYPE = 119 SR_MAP = 120 + ROLLER_MOP = 128 class ProductFeatures(StrEnum): @@ -474,6 +475,7 @@ class DeviceFeatures(RoborockBase): ) is_carpet_shape_type_supported: bool = field(metadata={"new_feature_str_bit": NewFeatureStrBit.CARPET_SHAPE_TYPE}) is_sr_map_supported: bool = field(metadata={"new_feature_str_bit": NewFeatureStrBit.SR_MAP}) + is_roller_mop_supported: bool = field(metadata={"new_feature_str_bit": NewFeatureStrBit.ROLLER_MOP}) # Features from feature_info list is_led_status_switch_supported: bool = field(metadata={"robot_features": 119}) @@ -644,9 +646,11 @@ def from_feature_flags( if any(feat in available_features for feat in product_features): # type: ignore kwargs[f.name] = True - # Clean-route setting support is provided by either the runtime - # shake-mop flag or the model's shake/spin mop capability. - kwargs["is_clean_route_setting_supported"] |= kwargs["is_shake_mop_set_supported"] + # The app combines runtime shake-mop, model shake/spin, and roller-mop + # capabilities when deciding whether mop routes can be configured. + kwargs["is_clean_route_setting_supported"] |= ( + kwargs["is_shake_mop_set_supported"] or kwargs["is_roller_mop_supported"] + ) return cls(**kwargs) diff --git a/roborock/devices/traits/v1/status.py b/roborock/devices/traits/v1/status.py index 3bdc19c6..9bed4e41 100644 --- a/roborock/devices/traits/v1/status.py +++ b/roborock/devices/traits/v1/status.py @@ -87,7 +87,7 @@ def mop_route_options(self) -> list[CleanRoutes]: @cached_property def mop_route_mapping(self) -> dict[int, str]: - return {route.code: route.value for route in self.mop_route_options} + return {route.code: route.display_name for route in self.mop_route_options} @cached_property def cleaning_mode_options(self) -> list[CleaningMode]: diff --git a/tests/__snapshots__/test_supported_features.ambr b/tests/__snapshots__/test_supported_features.ambr index 5f8d9bd7..eac70c3d 100644 --- a/tests/__snapshots__/test_supported_features.ambr +++ b/tests/__snapshots__/test_supported_features.ambr @@ -107,6 +107,7 @@ 'is_record_allowed': True, 'is_remote_supported': False, 'is_right_brush_stretch_supported': False, + 'is_roller_mop_supported': False, 'is_room_name_supported': True, 'is_rpc_retry_supported': True, 'is_rubber_brush_carpet_supported': False, @@ -285,6 +286,7 @@ 'is_record_allowed': False, 'is_remote_supported': False, 'is_right_brush_stretch_supported': False, + 'is_roller_mop_supported': False, 'is_room_name_supported': False, 'is_rpc_retry_supported': False, 'is_rubber_brush_carpet_supported': False, @@ -463,6 +465,7 @@ 'is_record_allowed': True, 'is_remote_supported': False, 'is_right_brush_stretch_supported': False, + 'is_roller_mop_supported': False, 'is_room_name_supported': True, 'is_rpc_retry_supported': True, 'is_rubber_brush_carpet_supported': False, @@ -641,6 +644,7 @@ 'is_record_allowed': False, 'is_remote_supported': False, 'is_right_brush_stretch_supported': False, + 'is_roller_mop_supported': False, 'is_room_name_supported': False, 'is_rpc_retry_supported': False, 'is_rubber_brush_carpet_supported': False, @@ -819,6 +823,7 @@ 'is_record_allowed': False, 'is_remote_supported': False, 'is_right_brush_stretch_supported': False, + 'is_roller_mop_supported': False, 'is_room_name_supported': False, 'is_rpc_retry_supported': False, 'is_rubber_brush_carpet_supported': False, @@ -997,6 +1002,7 @@ 'is_record_allowed': True, 'is_remote_supported': False, 'is_right_brush_stretch_supported': False, + 'is_roller_mop_supported': False, 'is_room_name_supported': True, 'is_rpc_retry_supported': True, 'is_rubber_brush_carpet_supported': False, @@ -1175,6 +1181,7 @@ 'is_record_allowed': True, 'is_remote_supported': False, 'is_right_brush_stretch_supported': True, + 'is_roller_mop_supported': False, 'is_room_name_supported': True, 'is_rpc_retry_supported': True, 'is_rubber_brush_carpet_supported': False, @@ -1353,6 +1360,7 @@ 'is_record_allowed': True, 'is_remote_supported': False, 'is_right_brush_stretch_supported': True, + 'is_roller_mop_supported': False, 'is_room_name_supported': True, 'is_rpc_retry_supported': True, 'is_rubber_brush_carpet_supported': False, @@ -1531,6 +1539,7 @@ 'is_record_allowed': False, 'is_remote_supported': False, 'is_right_brush_stretch_supported': False, + 'is_roller_mop_supported': False, 'is_room_name_supported': False, 'is_rpc_retry_supported': False, 'is_rubber_brush_carpet_supported': False, diff --git a/tests/data/test_code_mappings.py b/tests/data/test_code_mappings.py index b93f296b..735d87ac 100644 --- a/tests/data/test_code_mappings.py +++ b/tests/data/test_code_mappings.py @@ -6,7 +6,7 @@ import pytest -from roborock import HomeDataProduct, RoborockCategory +from roborock import CleanRoutes, HomeDataProduct, RoborockCategory from roborock.data.b01_q10.b01_q10_code_mappings import B01_Q10_DP, YXCleanType from roborock.data.code_mappings import completed_warnings from roborock.data.dyad.dyad_code_mappings import DyadError @@ -160,3 +160,13 @@ def test_roborock_enum_display_names_group_duplicate_protocol_codes() -> None: assert DyadError(20008).display_name == "battery_temperature_protection" assert "battery_temperature_protection_2" not in DyadError.keys() + + +def test_roborock_mode_enum_display_names_group_duplicate_protocol_codes() -> None: + """Mode variants keep distinct codes but expose one translation key.""" + assert CleanRoutes.DEEP_PLUS.code == 303 + assert CleanRoutes.DEEP_PLUS_CN.code == 305 + assert CleanRoutes.DEEP_PLUS_CN.value == "deep_plus_cn" + assert CleanRoutes.DEEP_PLUS_CN.display_name == "deep_plus" + assert CleanRoutes.keys().count("deep_plus") == 1 + assert "deep_plus_cn" not in CleanRoutes.keys() diff --git a/tests/devices/__snapshots__/test_device_manager.ambr b/tests/devices/__snapshots__/test_device_manager.ambr index 43a91d1a..dadae598 100644 --- a/tests/devices/__snapshots__/test_device_manager.ambr +++ b/tests/devices/__snapshots__/test_device_manager.ambr @@ -289,6 +289,7 @@ 'isRecordAllowed': False, 'isRemoteSupported': True, 'isRightBrushStretchSupported': False, + 'isRollerMopSupported': False, 'isRoomNameSupported': True, 'isRpcRetrySupported': False, 'isRubberBrushCarpetSupported': False, diff --git a/tests/devices/__snapshots__/test_file_cache.ambr b/tests/devices/__snapshots__/test_file_cache.ambr index 85f15dd6..b2025e5c 100644 --- a/tests/devices/__snapshots__/test_file_cache.ambr +++ b/tests/devices/__snapshots__/test_file_cache.ambr @@ -1,6 +1,6 @@ # serializer version: 1 # name: test_set_and_flush_and_get[default-all_fields_cache] - CacheData(home_data=HomeData(id=123456, name='My Home', products=[HomeDataProduct(id='product-id-s7-maxv', name='Roborock S7 MaxV', model='roborock.vacuum.a27', category=, code='a27', icon_url=None, attribute=None, capability=0, schema=[HomeDataProductSchema(id='101', name='rpc_request', code='rpc_request_code', mode='rw', type='RAW', product_property=None, property=None, desc=None), HomeDataProductSchema(id='102', name='rpc_response', code='rpc_response', mode='rw', type='RAW', product_property=None, property=None, desc=None), HomeDataProductSchema(id='120', name='错误代码', code='error_code', mode='ro', type='ENUM', product_property=None, property='{"range": []}', desc=None), HomeDataProductSchema(id='121', name='设备状态', code='state', mode='ro', type='ENUM', product_property=None, property='{"range": []}', desc=None), HomeDataProductSchema(id='122', name='设备电量', code='battery', mode='ro', type='ENUM', product_property=None, property='{"range": []}', desc=None), HomeDataProductSchema(id='123', name='清扫模式', code='fan_power', mode='rw', type='ENUM', product_property=None, property='{"range": []}', desc=None), HomeDataProductSchema(id='124', name='拖地模式', code='water_box_mode', mode='rw', type='ENUM', product_property=None, property='{"range": []}', desc=None), HomeDataProductSchema(id='125', name='主刷寿命', code='main_brush_life', mode='rw', type='VALUE', product_property=None, property='{"max": 100, "min": 0, "step": 1, "unit": null, "scale": 1}', desc=None), HomeDataProductSchema(id='126', name='边刷寿命', code='side_brush_life', mode='rw', type='VALUE', product_property=None, property='{"max": 100, "min": 0, "step": 1, "unit": null, "scale": 1}', desc=None), HomeDataProductSchema(id='127', name='滤网寿命', code='filter_life', mode='rw', type='VALUE', product_property=None, property='{"max": 100, "min": 0, "step": 1, "unit": null, "scale": 1}', desc=None), HomeDataProductSchema(id='128', name='额外状态', code='additional_props', mode='ro', type='RAW', product_property=None, property=None, desc=None), HomeDataProductSchema(id='130', name='完成事件', code='task_complete', mode='ro', type='RAW', product_property=None, property=None, desc=None), HomeDataProductSchema(id='131', name='电量不足任务取消', code='task_cancel_low_power', mode='ro', type='RAW', product_property=None, property=None, desc=None), HomeDataProductSchema(id='132', name='运动中任务取消', code='task_cancel_in_motion', mode='ro', type='RAW', product_property=None, property=None, desc=None), HomeDataProductSchema(id='133', name='充电状态', code='charge_status', mode='ro', type='RAW', product_property=None, property=None, desc=None), HomeDataProductSchema(id='134', name='烘干状态', code='drying_status', mode='ro', type='RAW', product_property=None, property=None, desc=None)])], devices=[HomeDataDevice(duid='abc123', name='Roborock S7 MaxV', local_key='key123key123key1', product_id='product-id-s7-maxv', fv='02.56.02', attribute=None, active_time=1672364449, runtime_env=None, time_zone_id='America/Los_Angeles', icon_url='no_url', lon=None, lat=None, share=False, share_time=None, online=True, pv='1.0', room_id=2362003, tuya_uuid=None, tuya_migrated=False, extra='{"RRPhotoPrivacyVersion": "1"}', sn='abc123', feature_set='2234201184108543', new_feature_set='0000000000002041', device_status={'121': 8, '122': 100, '123': 102, '124': 203, '125': 94, '126': 90, '127': 87, '128': 0, '133': 1, '120': 0}, silent_ota_switch=True, setting=None, f=None, create_time=None, cid=None, share_type=None, share_expired_time=None)], received_devices=[], lon=None, lat=None, geo_name=None, rooms=[HomeDataRoom(id=2362048, name='Example room 1'), HomeDataRoom(id=2362044, name='Example room 2'), HomeDataRoom(id=2362041, name='Example room 3')]), device_info={'device1': DeviceCacheData(network_info=NetworkInfo(ip='1.1.1.1', ssid='test_wifi', mac='aa:bb:cc:dd:ee:ff', bssid='aa:bb:cc:dd:ee:ff', rssi=-50), home_map_info={1: CombinedMapInfo(map_flag=1, name='Test Map 1', rooms=[NamedRoomMapping(segment_id=1023, iot_id='4321', raw_name='Living Room'), NamedRoomMapping(segment_id=1024, iot_id='4322', raw_name='Starship')]), 2: CombinedMapInfo(map_flag=2, name='Test Map 2', rooms=[NamedRoomMapping(segment_id=2047, iot_id='5432', raw_name='Bedroom')])}, home_map_content_base64={1: 'ZHVtbXlfbWFwX2NvbnRlbnQ=', 2: 'bW9yZV9kdW1teV9jb250ZW50'}, device_features=DeviceFeatures(is_show_clean_finish_reason_supported=True, is_re_segment_supported=False, is_video_monitor_supported=False, is_any_state_transit_goto_supported=False, is_fw_filter_obstacle_supported=False, is_video_setting_supported=False, is_ignore_unknown_map_object_supported=False, is_set_child_supported=False, is_carpet_supported=False, is_record_allowed=False, is_mop_path_supported=False, is_multi_map_segment_timer_supported=False, is_current_map_restore_enabled=False, is_room_name_supported=False, is_shake_mop_set_supported=False, is_map_beautify_internal_debug_supported=False, is_new_data_for_clean_history=False, is_new_data_for_clean_history_detail=False, is_flow_led_setting_supported=False, is_dust_collection_setting_supported=False, is_rpc_retry_supported=False, is_avoid_collision_supported=False, is_support_set_switch_map_mode=False, is_map_carpet_add_support=False, is_custom_water_box_distance_supported=False, is_support_smart_scene=False, is_support_floor_edit=False, is_support_furniture=False, is_wash_then_charge_cmd_supported=False, is_support_room_tag=False, is_support_quick_map_builder=False, is_support_smart_global_clean_with_custom_mode=False, is_careful_slow_mop_supported=False, is_egg_mode_supported_from_new_features=False, is_carpet_show_on_map=False, is_supported_valley_electricity=False, is_unsave_map_reason_supported=False, is_supported_drying=False, is_supported_download_test_voice=False, is_support_backup_map=False, is_support_custom_mode_in_cleaning=False, is_support_remote_control_in_call=False, is_support_set_volume_in_call=True, is_support_clean_estimate=False, is_support_custom_dnd=False, is_carpet_deep_clean_supported=False, is_support_stuck_zone=False, is_support_custom_door_sill=False, is_wifi_manage_supported=False, is_clean_route_fast_mode_supported=False, is_support_cliff_zone=False, is_support_smart_door_sill=False, is_support_floor_direction=False, is_back_charge_auto_wash_supported=False, is_support_incremental_map=False, is_offline_map_supported=False, is_super_deep_wash_supported=False, is_ces_2022_supported=False, is_dss_believable=False, is_main_brush_up_down_supported_from_str=False, is_goto_pure_clean_path_supported=False, is_water_up_down_drain_supported=False, is_setting_carpet_first_supported=False, is_clean_route_deep_slow_plus_supported=False, is_dynamically_skip_clean_zone_supported=False, is_dynamically_add_clean_zones_supported=False, is_left_water_drain_supported=False, is_clean_count_setting_supported=False, is_corner_clean_mode_supported=False, is_two_key_real_time_video_supported=False, is_two_key_rtv_in_charging_supported=False, is_dirty_replenish_clean_supported=False, is_auto_delivery_field_in_global_status_supported=False, is_avoid_collision_mode_supported=False, is_voice_control_supported=False, is_new_endpoint_supported=False, is_pumping_water_supported=False, is_corner_mop_stretch_supported=False, is_hot_wash_towel_supported=False, is_floor_dir_clean_any_time_supported=False, is_pet_supplies_deep_clean_supported=False, is_mop_shake_water_max_supported=False, is_exact_custom_mode_supported=False, is_video_patrol_supported=False, is_carpet_custom_clean_supported=False, is_pet_snapshot_supported=False, is_custom_clean_mode_count_supported=False, is_new_ai_recognition_supported=False, is_auto_collection_2_supported=False, is_right_brush_stretch_supported=False, is_smart_clean_mode_set_supported=False, is_dirty_object_detect_supported=False, is_no_need_carpet_press_set_supported=False, is_voice_control_led_supported=False, is_water_leak_check_supported=False, is_min_battery_15_to_clean_task_supported=False, is_gap_deep_clean_supported=False, is_object_detect_check_supported=False, is_identify_room_supported=False, is_matter_supported=False, is_workday_holiday_supported=False, is_clean_direct_status_supported=False, is_map_eraser_supported=False, is_optimize_battery_supported=False, is_activate_video_charging_and_standby_supported=False, is_carpet_long_haired_supported=False, is_clean_history_time_line_supported=False, is_max_zone_opened_supported=False, is_exhibition_function_supported=False, is_lds_lifting_supported=False, is_auto_tear_down_mop_supported=False, is_small_side_mop_supported=False, is_support_side_brush_up_down_supported=False, is_dry_interval_timer_supported=False, is_uvc_sterilize_supported=False, is_midway_back_to_dock_supported=False, is_support_main_brush_up_down_supported=False, is_egg_dance_mode_supported=False, is_mechanical_arm_mode_supported=False, is_tidyup_zones_supported=False, is_clean_time_line_supported=False, is_clean_then_mop_mode_supported=False, is_type_identify_supported=False, is_support_get_particular_status_supported=False, is_three_d_mapping_inner_test_supported=False, is_sync_server_name_supported=False, is_should_show_arm_over_load_supported=False, is_collect_dust_count_show_supported=False, is_support_api_app_stop_grasp_supported=False, is_ctm_with_repeat_supported=False, is_side_brush_lift_carpet_supported=False, is_detect_wire_carpet_supported=False, is_water_slide_mode_supported=False, is_soak_and_wash_supported=False, is_clean_efficiency_supported=False, is_back_wash_new_smart_supported=False, is_dual_band_wi_fi_supported=False, is_program_mode_supported=False, is_clean_fluid_delivery_supported=False, is_carpet_long_haired_ex_supported=False, is_over_sea_ctm_supported=False, is_full_duples_switch_supported=False, is_low_area_access_supported=False, is_follow_low_obs_supported=False, is_two_gears_no_collision_supported=False, is_carpet_shape_type_supported=False, is_sr_map_supported=False, is_led_status_switch_supported=False, is_multi_floor_supported=False, is_support_fetch_timer_summary=False, is_order_clean_supported=False, is_analysis_supported=False, is_remote_supported=False, is_support_voice_control_debug=False, is_mop_forbidden_supported=True, is_soft_clean_mode_supported=True, is_custom_mode_supported=True, is_support_custom_carpet=True, is_show_general_obstacle_supported=True, is_show_obstacle_photo_supported=True, is_rubber_brush_carpet_supported=True, is_carpet_pressure_use_origin_paras_supported=True, is_support_mop_back_pwm_set=True, is_collect_dust_mode_supported=True, is_support_water_mode=False, is_ai_recognition_setting_supported=False, is_ai_recognition_obstacle_supported=False, is_pure_clean_mop_supported=False, is_new_remote_view_supported=False, is_max_plus_mode_supported=False, is_none_pure_clean_mop_with_max_plus=False, is_clean_route_setting_supported=False, is_mop_shake_module_supported=False, is_customized_clean_supported=False), trait_data={'test_trait': {'key': 'value', 'number': 42}}), 'device2': DeviceCacheData(network_info=None, home_map_info=None, home_map_content_base64=None, device_features=None, trait_data=None)}, network_info={}, home_map_info={}, home_map_content={}, home_map_content_base64={}, device_features=None, trait_data=None) + CacheData(home_data=HomeData(id=123456, name='My Home', products=[HomeDataProduct(id='product-id-s7-maxv', name='Roborock S7 MaxV', model='roborock.vacuum.a27', category=, code='a27', icon_url=None, attribute=None, capability=0, schema=[HomeDataProductSchema(id='101', name='rpc_request', code='rpc_request_code', mode='rw', type='RAW', product_property=None, property=None, desc=None), HomeDataProductSchema(id='102', name='rpc_response', code='rpc_response', mode='rw', type='RAW', product_property=None, property=None, desc=None), HomeDataProductSchema(id='120', name='错误代码', code='error_code', mode='ro', type='ENUM', product_property=None, property='{"range": []}', desc=None), HomeDataProductSchema(id='121', name='设备状态', code='state', mode='ro', type='ENUM', product_property=None, property='{"range": []}', desc=None), HomeDataProductSchema(id='122', name='设备电量', code='battery', mode='ro', type='ENUM', product_property=None, property='{"range": []}', desc=None), HomeDataProductSchema(id='123', name='清扫模式', code='fan_power', mode='rw', type='ENUM', product_property=None, property='{"range": []}', desc=None), HomeDataProductSchema(id='124', name='拖地模式', code='water_box_mode', mode='rw', type='ENUM', product_property=None, property='{"range": []}', desc=None), HomeDataProductSchema(id='125', name='主刷寿命', code='main_brush_life', mode='rw', type='VALUE', product_property=None, property='{"max": 100, "min": 0, "step": 1, "unit": null, "scale": 1}', desc=None), HomeDataProductSchema(id='126', name='边刷寿命', code='side_brush_life', mode='rw', type='VALUE', product_property=None, property='{"max": 100, "min": 0, "step": 1, "unit": null, "scale": 1}', desc=None), HomeDataProductSchema(id='127', name='滤网寿命', code='filter_life', mode='rw', type='VALUE', product_property=None, property='{"max": 100, "min": 0, "step": 1, "unit": null, "scale": 1}', desc=None), HomeDataProductSchema(id='128', name='额外状态', code='additional_props', mode='ro', type='RAW', product_property=None, property=None, desc=None), HomeDataProductSchema(id='130', name='完成事件', code='task_complete', mode='ro', type='RAW', product_property=None, property=None, desc=None), HomeDataProductSchema(id='131', name='电量不足任务取消', code='task_cancel_low_power', mode='ro', type='RAW', product_property=None, property=None, desc=None), HomeDataProductSchema(id='132', name='运动中任务取消', code='task_cancel_in_motion', mode='ro', type='RAW', product_property=None, property=None, desc=None), HomeDataProductSchema(id='133', name='充电状态', code='charge_status', mode='ro', type='RAW', product_property=None, property=None, desc=None), HomeDataProductSchema(id='134', name='烘干状态', code='drying_status', mode='ro', type='RAW', product_property=None, property=None, desc=None)])], devices=[HomeDataDevice(duid='abc123', name='Roborock S7 MaxV', local_key='key123key123key1', product_id='product-id-s7-maxv', fv='02.56.02', attribute=None, active_time=1672364449, runtime_env=None, time_zone_id='America/Los_Angeles', icon_url='no_url', lon=None, lat=None, share=False, share_time=None, online=True, pv='1.0', room_id=2362003, tuya_uuid=None, tuya_migrated=False, extra='{"RRPhotoPrivacyVersion": "1"}', sn='abc123', feature_set='2234201184108543', new_feature_set='0000000000002041', device_status={'121': 8, '122': 100, '123': 102, '124': 203, '125': 94, '126': 90, '127': 87, '128': 0, '133': 1, '120': 0}, silent_ota_switch=True, setting=None, f=None, create_time=None, cid=None, share_type=None, share_expired_time=None)], received_devices=[], lon=None, lat=None, geo_name=None, rooms=[HomeDataRoom(id=2362048, name='Example room 1'), HomeDataRoom(id=2362044, name='Example room 2'), HomeDataRoom(id=2362041, name='Example room 3')]), device_info={'device1': DeviceCacheData(network_info=NetworkInfo(ip='1.1.1.1', ssid='test_wifi', mac='aa:bb:cc:dd:ee:ff', bssid='aa:bb:cc:dd:ee:ff', rssi=-50), home_map_info={1: CombinedMapInfo(map_flag=1, name='Test Map 1', rooms=[NamedRoomMapping(segment_id=1023, iot_id='4321', raw_name='Living Room'), NamedRoomMapping(segment_id=1024, iot_id='4322', raw_name='Starship')]), 2: CombinedMapInfo(map_flag=2, name='Test Map 2', rooms=[NamedRoomMapping(segment_id=2047, iot_id='5432', raw_name='Bedroom')])}, home_map_content_base64={1: 'ZHVtbXlfbWFwX2NvbnRlbnQ=', 2: 'bW9yZV9kdW1teV9jb250ZW50'}, device_features=DeviceFeatures(is_show_clean_finish_reason_supported=True, is_re_segment_supported=False, is_video_monitor_supported=False, is_any_state_transit_goto_supported=False, is_fw_filter_obstacle_supported=False, is_video_setting_supported=False, is_ignore_unknown_map_object_supported=False, is_set_child_supported=False, is_carpet_supported=False, is_record_allowed=False, is_mop_path_supported=False, is_multi_map_segment_timer_supported=False, is_current_map_restore_enabled=False, is_room_name_supported=False, is_shake_mop_set_supported=False, is_map_beautify_internal_debug_supported=False, is_new_data_for_clean_history=False, is_new_data_for_clean_history_detail=False, is_flow_led_setting_supported=False, is_dust_collection_setting_supported=False, is_rpc_retry_supported=False, is_avoid_collision_supported=False, is_support_set_switch_map_mode=False, is_map_carpet_add_support=False, is_custom_water_box_distance_supported=False, is_support_smart_scene=False, is_support_floor_edit=False, is_support_furniture=False, is_wash_then_charge_cmd_supported=False, is_support_room_tag=False, is_support_quick_map_builder=False, is_support_smart_global_clean_with_custom_mode=False, is_careful_slow_mop_supported=False, is_egg_mode_supported_from_new_features=False, is_carpet_show_on_map=False, is_supported_valley_electricity=False, is_unsave_map_reason_supported=False, is_supported_drying=False, is_supported_download_test_voice=False, is_support_backup_map=False, is_support_custom_mode_in_cleaning=False, is_support_remote_control_in_call=False, is_support_set_volume_in_call=True, is_support_clean_estimate=False, is_support_custom_dnd=False, is_carpet_deep_clean_supported=False, is_support_stuck_zone=False, is_support_custom_door_sill=False, is_wifi_manage_supported=False, is_clean_route_fast_mode_supported=False, is_support_cliff_zone=False, is_support_smart_door_sill=False, is_support_floor_direction=False, is_back_charge_auto_wash_supported=False, is_support_incremental_map=False, is_offline_map_supported=False, is_super_deep_wash_supported=False, is_ces_2022_supported=False, is_dss_believable=False, is_main_brush_up_down_supported_from_str=False, is_goto_pure_clean_path_supported=False, is_water_up_down_drain_supported=False, is_setting_carpet_first_supported=False, is_clean_route_deep_slow_plus_supported=False, is_dynamically_skip_clean_zone_supported=False, is_dynamically_add_clean_zones_supported=False, is_left_water_drain_supported=False, is_clean_count_setting_supported=False, is_corner_clean_mode_supported=False, is_two_key_real_time_video_supported=False, is_two_key_rtv_in_charging_supported=False, is_dirty_replenish_clean_supported=False, is_auto_delivery_field_in_global_status_supported=False, is_avoid_collision_mode_supported=False, is_voice_control_supported=False, is_new_endpoint_supported=False, is_pumping_water_supported=False, is_corner_mop_stretch_supported=False, is_hot_wash_towel_supported=False, is_floor_dir_clean_any_time_supported=False, is_pet_supplies_deep_clean_supported=False, is_mop_shake_water_max_supported=False, is_exact_custom_mode_supported=False, is_video_patrol_supported=False, is_carpet_custom_clean_supported=False, is_pet_snapshot_supported=False, is_custom_clean_mode_count_supported=False, is_new_ai_recognition_supported=False, is_auto_collection_2_supported=False, is_right_brush_stretch_supported=False, is_smart_clean_mode_set_supported=False, is_dirty_object_detect_supported=False, is_no_need_carpet_press_set_supported=False, is_voice_control_led_supported=False, is_water_leak_check_supported=False, is_min_battery_15_to_clean_task_supported=False, is_gap_deep_clean_supported=False, is_object_detect_check_supported=False, is_identify_room_supported=False, is_matter_supported=False, is_workday_holiday_supported=False, is_clean_direct_status_supported=False, is_map_eraser_supported=False, is_optimize_battery_supported=False, is_activate_video_charging_and_standby_supported=False, is_carpet_long_haired_supported=False, is_clean_history_time_line_supported=False, is_max_zone_opened_supported=False, is_exhibition_function_supported=False, is_lds_lifting_supported=False, is_auto_tear_down_mop_supported=False, is_small_side_mop_supported=False, is_support_side_brush_up_down_supported=False, is_dry_interval_timer_supported=False, is_uvc_sterilize_supported=False, is_midway_back_to_dock_supported=False, is_support_main_brush_up_down_supported=False, is_egg_dance_mode_supported=False, is_mechanical_arm_mode_supported=False, is_tidyup_zones_supported=False, is_clean_time_line_supported=False, is_clean_then_mop_mode_supported=False, is_type_identify_supported=False, is_support_get_particular_status_supported=False, is_three_d_mapping_inner_test_supported=False, is_sync_server_name_supported=False, is_should_show_arm_over_load_supported=False, is_collect_dust_count_show_supported=False, is_support_api_app_stop_grasp_supported=False, is_ctm_with_repeat_supported=False, is_side_brush_lift_carpet_supported=False, is_detect_wire_carpet_supported=False, is_water_slide_mode_supported=False, is_soak_and_wash_supported=False, is_clean_efficiency_supported=False, is_back_wash_new_smart_supported=False, is_dual_band_wi_fi_supported=False, is_program_mode_supported=False, is_clean_fluid_delivery_supported=False, is_carpet_long_haired_ex_supported=False, is_over_sea_ctm_supported=False, is_full_duples_switch_supported=False, is_low_area_access_supported=False, is_follow_low_obs_supported=False, is_two_gears_no_collision_supported=False, is_carpet_shape_type_supported=False, is_sr_map_supported=False, is_roller_mop_supported=False, is_led_status_switch_supported=False, is_multi_floor_supported=False, is_support_fetch_timer_summary=False, is_order_clean_supported=False, is_analysis_supported=False, is_remote_supported=False, is_support_voice_control_debug=False, is_mop_forbidden_supported=True, is_soft_clean_mode_supported=True, is_custom_mode_supported=True, is_support_custom_carpet=True, is_show_general_obstacle_supported=True, is_show_obstacle_photo_supported=True, is_rubber_brush_carpet_supported=True, is_carpet_pressure_use_origin_paras_supported=True, is_support_mop_back_pwm_set=True, is_collect_dust_mode_supported=True, is_support_water_mode=False, is_ai_recognition_setting_supported=False, is_ai_recognition_obstacle_supported=False, is_pure_clean_mop_supported=False, is_new_remote_view_supported=False, is_max_plus_mode_supported=False, is_none_pure_clean_mop_with_max_plus=False, is_clean_route_setting_supported=False, is_mop_shake_module_supported=False, is_customized_clean_supported=False), trait_data={'test_trait': {'key': 'value', 'number': 42}}), 'device2': DeviceCacheData(network_info=None, home_map_info=None, home_map_content_base64=None, device_features=None, trait_data=None)}, network_info={}, home_map_info={}, home_map_content={}, home_map_content_base64={}, device_features=None, trait_data=None) # --- # name: test_set_and_flush_and_get[default-empty_cache] CacheData(home_data=None, device_info={}, network_info={}, home_map_info={}, home_map_content={}, home_map_content_base64={}, device_features=None, trait_data=None) @@ -12,7 +12,7 @@ CacheData(home_data=HomeData(id=123456, name='My Home', products=[HomeDataProduct(id='product-id-s7-maxv', name='Roborock S7 MaxV', model='roborock.vacuum.a27', category=, code='a27', icon_url=None, attribute=None, capability=0, schema=[HomeDataProductSchema(id='101', name='rpc_request', code='rpc_request_code', mode='rw', type='RAW', product_property=None, property=None, desc=None), HomeDataProductSchema(id='102', name='rpc_response', code='rpc_response', mode='rw', type='RAW', product_property=None, property=None, desc=None), HomeDataProductSchema(id='120', name='错误代码', code='error_code', mode='ro', type='ENUM', product_property=None, property='{"range": []}', desc=None), HomeDataProductSchema(id='121', name='设备状态', code='state', mode='ro', type='ENUM', product_property=None, property='{"range": []}', desc=None), HomeDataProductSchema(id='122', name='设备电量', code='battery', mode='ro', type='ENUM', product_property=None, property='{"range": []}', desc=None), HomeDataProductSchema(id='123', name='清扫模式', code='fan_power', mode='rw', type='ENUM', product_property=None, property='{"range": []}', desc=None), HomeDataProductSchema(id='124', name='拖地模式', code='water_box_mode', mode='rw', type='ENUM', product_property=None, property='{"range": []}', desc=None), HomeDataProductSchema(id='125', name='主刷寿命', code='main_brush_life', mode='rw', type='VALUE', product_property=None, property='{"max": 100, "min": 0, "step": 1, "unit": null, "scale": 1}', desc=None), HomeDataProductSchema(id='126', name='边刷寿命', code='side_brush_life', mode='rw', type='VALUE', product_property=None, property='{"max": 100, "min": 0, "step": 1, "unit": null, "scale": 1}', desc=None), HomeDataProductSchema(id='127', name='滤网寿命', code='filter_life', mode='rw', type='VALUE', product_property=None, property='{"max": 100, "min": 0, "step": 1, "unit": null, "scale": 1}', desc=None), HomeDataProductSchema(id='128', name='额外状态', code='additional_props', mode='ro', type='RAW', product_property=None, property=None, desc=None), HomeDataProductSchema(id='130', name='完成事件', code='task_complete', mode='ro', type='RAW', product_property=None, property=None, desc=None), HomeDataProductSchema(id='131', name='电量不足任务取消', code='task_cancel_low_power', mode='ro', type='RAW', product_property=None, property=None, desc=None), HomeDataProductSchema(id='132', name='运动中任务取消', code='task_cancel_in_motion', mode='ro', type='RAW', product_property=None, property=None, desc=None), HomeDataProductSchema(id='133', name='充电状态', code='charge_status', mode='ro', type='RAW', product_property=None, property=None, desc=None), HomeDataProductSchema(id='134', name='烘干状态', code='drying_status', mode='ro', type='RAW', product_property=None, property=None, desc=None)])], devices=[HomeDataDevice(duid='abc123', name='Roborock S7 MaxV', local_key='key123key123key1', product_id='product-id-s7-maxv', fv='02.56.02', attribute=None, active_time=1672364449, runtime_env=None, time_zone_id='America/Los_Angeles', icon_url='no_url', lon=None, lat=None, share=False, share_time=None, online=True, pv='1.0', room_id=2362003, tuya_uuid=None, tuya_migrated=False, extra='{"RRPhotoPrivacyVersion": "1"}', sn='abc123', feature_set='2234201184108543', new_feature_set='0000000000002041', device_status={'121': 8, '122': 100, '123': 102, '124': 203, '125': 94, '126': 90, '127': 87, '128': 0, '133': 1, '120': 0}, silent_ota_switch=True, setting=None, f=None, create_time=None, cid=None, share_type=None, share_expired_time=None)], received_devices=[], lon=None, lat=None, geo_name=None, rooms=[HomeDataRoom(id=2362048, name='Example room 1'), HomeDataRoom(id=2362044, name='Example room 2'), HomeDataRoom(id=2362041, name='Example room 3')]), device_info={}, network_info={}, home_map_info={}, home_map_content={}, home_map_content_base64={}, device_features=None, trait_data=None) # --- # name: test_set_and_flush_and_get[json-all_fields_cache] - CacheData(home_data=HomeData(id=123456, name='My Home', products=[HomeDataProduct(id='product-id-s7-maxv', name='Roborock S7 MaxV', model='roborock.vacuum.a27', category=, code='a27', icon_url=None, attribute=None, capability=0, schema=[HomeDataProductSchema(id='101', name='rpc_request', code='rpc_request_code', mode='rw', type='RAW', product_property=None, property=None, desc=None), HomeDataProductSchema(id='102', name='rpc_response', code='rpc_response', mode='rw', type='RAW', product_property=None, property=None, desc=None), HomeDataProductSchema(id='120', name='错误代码', code='error_code', mode='ro', type='ENUM', product_property=None, property='{"range": []}', desc=None), HomeDataProductSchema(id='121', name='设备状态', code='state', mode='ro', type='ENUM', product_property=None, property='{"range": []}', desc=None), HomeDataProductSchema(id='122', name='设备电量', code='battery', mode='ro', type='ENUM', product_property=None, property='{"range": []}', desc=None), HomeDataProductSchema(id='123', name='清扫模式', code='fan_power', mode='rw', type='ENUM', product_property=None, property='{"range": []}', desc=None), HomeDataProductSchema(id='124', name='拖地模式', code='water_box_mode', mode='rw', type='ENUM', product_property=None, property='{"range": []}', desc=None), HomeDataProductSchema(id='125', name='主刷寿命', code='main_brush_life', mode='rw', type='VALUE', product_property=None, property='{"max": 100, "min": 0, "step": 1, "unit": null, "scale": 1}', desc=None), HomeDataProductSchema(id='126', name='边刷寿命', code='side_brush_life', mode='rw', type='VALUE', product_property=None, property='{"max": 100, "min": 0, "step": 1, "unit": null, "scale": 1}', desc=None), HomeDataProductSchema(id='127', name='滤网寿命', code='filter_life', mode='rw', type='VALUE', product_property=None, property='{"max": 100, "min": 0, "step": 1, "unit": null, "scale": 1}', desc=None), HomeDataProductSchema(id='128', name='额外状态', code='additional_props', mode='ro', type='RAW', product_property=None, property=None, desc=None), HomeDataProductSchema(id='130', name='完成事件', code='task_complete', mode='ro', type='RAW', product_property=None, property=None, desc=None), HomeDataProductSchema(id='131', name='电量不足任务取消', code='task_cancel_low_power', mode='ro', type='RAW', product_property=None, property=None, desc=None), HomeDataProductSchema(id='132', name='运动中任务取消', code='task_cancel_in_motion', mode='ro', type='RAW', product_property=None, property=None, desc=None), HomeDataProductSchema(id='133', name='充电状态', code='charge_status', mode='ro', type='RAW', product_property=None, property=None, desc=None), HomeDataProductSchema(id='134', name='烘干状态', code='drying_status', mode='ro', type='RAW', product_property=None, property=None, desc=None)])], devices=[HomeDataDevice(duid='abc123', name='Roborock S7 MaxV', local_key='key123key123key1', product_id='product-id-s7-maxv', fv='02.56.02', attribute=None, active_time=1672364449, runtime_env=None, time_zone_id='America/Los_Angeles', icon_url='no_url', lon=None, lat=None, share=False, share_time=None, online=True, pv='1.0', room_id=2362003, tuya_uuid=None, tuya_migrated=False, extra='{"RRPhotoPrivacyVersion": "1"}', sn='abc123', feature_set='2234201184108543', new_feature_set='0000000000002041', device_status={'121': 8, '122': 100, '123': 102, '124': 203, '125': 94, '126': 90, '127': 87, '128': 0, '133': 1, '120': 0}, silent_ota_switch=True, setting=None, f=None, create_time=None, cid=None, share_type=None, share_expired_time=None)], received_devices=[], lon=None, lat=None, geo_name=None, rooms=[HomeDataRoom(id=2362048, name='Example room 1'), HomeDataRoom(id=2362044, name='Example room 2'), HomeDataRoom(id=2362041, name='Example room 3')]), device_info={'device1': DeviceCacheData(network_info=NetworkInfo(ip='1.1.1.1', ssid='test_wifi', mac='aa:bb:cc:dd:ee:ff', bssid='aa:bb:cc:dd:ee:ff', rssi=-50), home_map_info={1: CombinedMapInfo(map_flag=1, name='Test Map 1', rooms=[NamedRoomMapping(segment_id=1023, iot_id='4321', raw_name='Living Room'), NamedRoomMapping(segment_id=1024, iot_id='4322', raw_name='Starship')]), 2: CombinedMapInfo(map_flag=2, name='Test Map 2', rooms=[NamedRoomMapping(segment_id=2047, iot_id='5432', raw_name='Bedroom')])}, home_map_content_base64={1: 'ZHVtbXlfbWFwX2NvbnRlbnQ=', 2: 'bW9yZV9kdW1teV9jb250ZW50'}, device_features=DeviceFeatures(is_show_clean_finish_reason_supported=True, is_re_segment_supported=False, is_video_monitor_supported=False, is_any_state_transit_goto_supported=False, is_fw_filter_obstacle_supported=False, is_video_setting_supported=False, is_ignore_unknown_map_object_supported=False, is_set_child_supported=False, is_carpet_supported=False, is_record_allowed=False, is_mop_path_supported=False, is_multi_map_segment_timer_supported=False, is_current_map_restore_enabled=False, is_room_name_supported=False, is_shake_mop_set_supported=False, is_map_beautify_internal_debug_supported=False, is_new_data_for_clean_history=False, is_new_data_for_clean_history_detail=False, is_flow_led_setting_supported=False, is_dust_collection_setting_supported=False, is_rpc_retry_supported=False, is_avoid_collision_supported=False, is_support_set_switch_map_mode=False, is_map_carpet_add_support=False, is_custom_water_box_distance_supported=False, is_support_smart_scene=False, is_support_floor_edit=False, is_support_furniture=False, is_wash_then_charge_cmd_supported=False, is_support_room_tag=False, is_support_quick_map_builder=False, is_support_smart_global_clean_with_custom_mode=False, is_careful_slow_mop_supported=False, is_egg_mode_supported_from_new_features=False, is_carpet_show_on_map=False, is_supported_valley_electricity=False, is_unsave_map_reason_supported=False, is_supported_drying=False, is_supported_download_test_voice=False, is_support_backup_map=False, is_support_custom_mode_in_cleaning=False, is_support_remote_control_in_call=False, is_support_set_volume_in_call=True, is_support_clean_estimate=False, is_support_custom_dnd=False, is_carpet_deep_clean_supported=False, is_support_stuck_zone=False, is_support_custom_door_sill=False, is_wifi_manage_supported=False, is_clean_route_fast_mode_supported=False, is_support_cliff_zone=False, is_support_smart_door_sill=False, is_support_floor_direction=False, is_back_charge_auto_wash_supported=False, is_support_incremental_map=False, is_offline_map_supported=False, is_super_deep_wash_supported=False, is_ces_2022_supported=False, is_dss_believable=False, is_main_brush_up_down_supported_from_str=False, is_goto_pure_clean_path_supported=False, is_water_up_down_drain_supported=False, is_setting_carpet_first_supported=False, is_clean_route_deep_slow_plus_supported=False, is_dynamically_skip_clean_zone_supported=False, is_dynamically_add_clean_zones_supported=False, is_left_water_drain_supported=False, is_clean_count_setting_supported=False, is_corner_clean_mode_supported=False, is_two_key_real_time_video_supported=False, is_two_key_rtv_in_charging_supported=False, is_dirty_replenish_clean_supported=False, is_auto_delivery_field_in_global_status_supported=False, is_avoid_collision_mode_supported=False, is_voice_control_supported=False, is_new_endpoint_supported=False, is_pumping_water_supported=False, is_corner_mop_stretch_supported=False, is_hot_wash_towel_supported=False, is_floor_dir_clean_any_time_supported=False, is_pet_supplies_deep_clean_supported=False, is_mop_shake_water_max_supported=False, is_exact_custom_mode_supported=False, is_video_patrol_supported=False, is_carpet_custom_clean_supported=False, is_pet_snapshot_supported=False, is_custom_clean_mode_count_supported=False, is_new_ai_recognition_supported=False, is_auto_collection_2_supported=False, is_right_brush_stretch_supported=False, is_smart_clean_mode_set_supported=False, is_dirty_object_detect_supported=False, is_no_need_carpet_press_set_supported=False, is_voice_control_led_supported=False, is_water_leak_check_supported=False, is_min_battery_15_to_clean_task_supported=False, is_gap_deep_clean_supported=False, is_object_detect_check_supported=False, is_identify_room_supported=False, is_matter_supported=False, is_workday_holiday_supported=False, is_clean_direct_status_supported=False, is_map_eraser_supported=False, is_optimize_battery_supported=False, is_activate_video_charging_and_standby_supported=False, is_carpet_long_haired_supported=False, is_clean_history_time_line_supported=False, is_max_zone_opened_supported=False, is_exhibition_function_supported=False, is_lds_lifting_supported=False, is_auto_tear_down_mop_supported=False, is_small_side_mop_supported=False, is_support_side_brush_up_down_supported=False, is_dry_interval_timer_supported=False, is_uvc_sterilize_supported=False, is_midway_back_to_dock_supported=False, is_support_main_brush_up_down_supported=False, is_egg_dance_mode_supported=False, is_mechanical_arm_mode_supported=False, is_tidyup_zones_supported=False, is_clean_time_line_supported=False, is_clean_then_mop_mode_supported=False, is_type_identify_supported=False, is_support_get_particular_status_supported=False, is_three_d_mapping_inner_test_supported=False, is_sync_server_name_supported=False, is_should_show_arm_over_load_supported=False, is_collect_dust_count_show_supported=False, is_support_api_app_stop_grasp_supported=False, is_ctm_with_repeat_supported=False, is_side_brush_lift_carpet_supported=False, is_detect_wire_carpet_supported=False, is_water_slide_mode_supported=False, is_soak_and_wash_supported=False, is_clean_efficiency_supported=False, is_back_wash_new_smart_supported=False, is_dual_band_wi_fi_supported=False, is_program_mode_supported=False, is_clean_fluid_delivery_supported=False, is_carpet_long_haired_ex_supported=False, is_over_sea_ctm_supported=False, is_full_duples_switch_supported=False, is_low_area_access_supported=False, is_follow_low_obs_supported=False, is_two_gears_no_collision_supported=False, is_carpet_shape_type_supported=False, is_sr_map_supported=False, is_led_status_switch_supported=False, is_multi_floor_supported=False, is_support_fetch_timer_summary=False, is_order_clean_supported=False, is_analysis_supported=False, is_remote_supported=False, is_support_voice_control_debug=False, is_mop_forbidden_supported=True, is_soft_clean_mode_supported=True, is_custom_mode_supported=True, is_support_custom_carpet=True, is_show_general_obstacle_supported=True, is_show_obstacle_photo_supported=True, is_rubber_brush_carpet_supported=True, is_carpet_pressure_use_origin_paras_supported=True, is_support_mop_back_pwm_set=True, is_collect_dust_mode_supported=True, is_support_water_mode=False, is_ai_recognition_setting_supported=False, is_ai_recognition_obstacle_supported=False, is_pure_clean_mop_supported=False, is_new_remote_view_supported=False, is_max_plus_mode_supported=False, is_none_pure_clean_mop_with_max_plus=False, is_clean_route_setting_supported=False, is_mop_shake_module_supported=False, is_customized_clean_supported=False), trait_data={'test_trait': {'key': 'value', 'number': 42}}), 'device2': DeviceCacheData(network_info=None, home_map_info=None, home_map_content_base64=None, device_features=None, trait_data=None)}, network_info={}, home_map_info={}, home_map_content={}, home_map_content_base64={}, device_features=None, trait_data=None) + CacheData(home_data=HomeData(id=123456, name='My Home', products=[HomeDataProduct(id='product-id-s7-maxv', name='Roborock S7 MaxV', model='roborock.vacuum.a27', category=, code='a27', icon_url=None, attribute=None, capability=0, schema=[HomeDataProductSchema(id='101', name='rpc_request', code='rpc_request_code', mode='rw', type='RAW', product_property=None, property=None, desc=None), HomeDataProductSchema(id='102', name='rpc_response', code='rpc_response', mode='rw', type='RAW', product_property=None, property=None, desc=None), HomeDataProductSchema(id='120', name='错误代码', code='error_code', mode='ro', type='ENUM', product_property=None, property='{"range": []}', desc=None), HomeDataProductSchema(id='121', name='设备状态', code='state', mode='ro', type='ENUM', product_property=None, property='{"range": []}', desc=None), HomeDataProductSchema(id='122', name='设备电量', code='battery', mode='ro', type='ENUM', product_property=None, property='{"range": []}', desc=None), HomeDataProductSchema(id='123', name='清扫模式', code='fan_power', mode='rw', type='ENUM', product_property=None, property='{"range": []}', desc=None), HomeDataProductSchema(id='124', name='拖地模式', code='water_box_mode', mode='rw', type='ENUM', product_property=None, property='{"range": []}', desc=None), HomeDataProductSchema(id='125', name='主刷寿命', code='main_brush_life', mode='rw', type='VALUE', product_property=None, property='{"max": 100, "min": 0, "step": 1, "unit": null, "scale": 1}', desc=None), HomeDataProductSchema(id='126', name='边刷寿命', code='side_brush_life', mode='rw', type='VALUE', product_property=None, property='{"max": 100, "min": 0, "step": 1, "unit": null, "scale": 1}', desc=None), HomeDataProductSchema(id='127', name='滤网寿命', code='filter_life', mode='rw', type='VALUE', product_property=None, property='{"max": 100, "min": 0, "step": 1, "unit": null, "scale": 1}', desc=None), HomeDataProductSchema(id='128', name='额外状态', code='additional_props', mode='ro', type='RAW', product_property=None, property=None, desc=None), HomeDataProductSchema(id='130', name='完成事件', code='task_complete', mode='ro', type='RAW', product_property=None, property=None, desc=None), HomeDataProductSchema(id='131', name='电量不足任务取消', code='task_cancel_low_power', mode='ro', type='RAW', product_property=None, property=None, desc=None), HomeDataProductSchema(id='132', name='运动中任务取消', code='task_cancel_in_motion', mode='ro', type='RAW', product_property=None, property=None, desc=None), HomeDataProductSchema(id='133', name='充电状态', code='charge_status', mode='ro', type='RAW', product_property=None, property=None, desc=None), HomeDataProductSchema(id='134', name='烘干状态', code='drying_status', mode='ro', type='RAW', product_property=None, property=None, desc=None)])], devices=[HomeDataDevice(duid='abc123', name='Roborock S7 MaxV', local_key='key123key123key1', product_id='product-id-s7-maxv', fv='02.56.02', attribute=None, active_time=1672364449, runtime_env=None, time_zone_id='America/Los_Angeles', icon_url='no_url', lon=None, lat=None, share=False, share_time=None, online=True, pv='1.0', room_id=2362003, tuya_uuid=None, tuya_migrated=False, extra='{"RRPhotoPrivacyVersion": "1"}', sn='abc123', feature_set='2234201184108543', new_feature_set='0000000000002041', device_status={'121': 8, '122': 100, '123': 102, '124': 203, '125': 94, '126': 90, '127': 87, '128': 0, '133': 1, '120': 0}, silent_ota_switch=True, setting=None, f=None, create_time=None, cid=None, share_type=None, share_expired_time=None)], received_devices=[], lon=None, lat=None, geo_name=None, rooms=[HomeDataRoom(id=2362048, name='Example room 1'), HomeDataRoom(id=2362044, name='Example room 2'), HomeDataRoom(id=2362041, name='Example room 3')]), device_info={'device1': DeviceCacheData(network_info=NetworkInfo(ip='1.1.1.1', ssid='test_wifi', mac='aa:bb:cc:dd:ee:ff', bssid='aa:bb:cc:dd:ee:ff', rssi=-50), home_map_info={1: CombinedMapInfo(map_flag=1, name='Test Map 1', rooms=[NamedRoomMapping(segment_id=1023, iot_id='4321', raw_name='Living Room'), NamedRoomMapping(segment_id=1024, iot_id='4322', raw_name='Starship')]), 2: CombinedMapInfo(map_flag=2, name='Test Map 2', rooms=[NamedRoomMapping(segment_id=2047, iot_id='5432', raw_name='Bedroom')])}, home_map_content_base64={1: 'ZHVtbXlfbWFwX2NvbnRlbnQ=', 2: 'bW9yZV9kdW1teV9jb250ZW50'}, device_features=DeviceFeatures(is_show_clean_finish_reason_supported=True, is_re_segment_supported=False, is_video_monitor_supported=False, is_any_state_transit_goto_supported=False, is_fw_filter_obstacle_supported=False, is_video_setting_supported=False, is_ignore_unknown_map_object_supported=False, is_set_child_supported=False, is_carpet_supported=False, is_record_allowed=False, is_mop_path_supported=False, is_multi_map_segment_timer_supported=False, is_current_map_restore_enabled=False, is_room_name_supported=False, is_shake_mop_set_supported=False, is_map_beautify_internal_debug_supported=False, is_new_data_for_clean_history=False, is_new_data_for_clean_history_detail=False, is_flow_led_setting_supported=False, is_dust_collection_setting_supported=False, is_rpc_retry_supported=False, is_avoid_collision_supported=False, is_support_set_switch_map_mode=False, is_map_carpet_add_support=False, is_custom_water_box_distance_supported=False, is_support_smart_scene=False, is_support_floor_edit=False, is_support_furniture=False, is_wash_then_charge_cmd_supported=False, is_support_room_tag=False, is_support_quick_map_builder=False, is_support_smart_global_clean_with_custom_mode=False, is_careful_slow_mop_supported=False, is_egg_mode_supported_from_new_features=False, is_carpet_show_on_map=False, is_supported_valley_electricity=False, is_unsave_map_reason_supported=False, is_supported_drying=False, is_supported_download_test_voice=False, is_support_backup_map=False, is_support_custom_mode_in_cleaning=False, is_support_remote_control_in_call=False, is_support_set_volume_in_call=True, is_support_clean_estimate=False, is_support_custom_dnd=False, is_carpet_deep_clean_supported=False, is_support_stuck_zone=False, is_support_custom_door_sill=False, is_wifi_manage_supported=False, is_clean_route_fast_mode_supported=False, is_support_cliff_zone=False, is_support_smart_door_sill=False, is_support_floor_direction=False, is_back_charge_auto_wash_supported=False, is_support_incremental_map=False, is_offline_map_supported=False, is_super_deep_wash_supported=False, is_ces_2022_supported=False, is_dss_believable=False, is_main_brush_up_down_supported_from_str=False, is_goto_pure_clean_path_supported=False, is_water_up_down_drain_supported=False, is_setting_carpet_first_supported=False, is_clean_route_deep_slow_plus_supported=False, is_dynamically_skip_clean_zone_supported=False, is_dynamically_add_clean_zones_supported=False, is_left_water_drain_supported=False, is_clean_count_setting_supported=False, is_corner_clean_mode_supported=False, is_two_key_real_time_video_supported=False, is_two_key_rtv_in_charging_supported=False, is_dirty_replenish_clean_supported=False, is_auto_delivery_field_in_global_status_supported=False, is_avoid_collision_mode_supported=False, is_voice_control_supported=False, is_new_endpoint_supported=False, is_pumping_water_supported=False, is_corner_mop_stretch_supported=False, is_hot_wash_towel_supported=False, is_floor_dir_clean_any_time_supported=False, is_pet_supplies_deep_clean_supported=False, is_mop_shake_water_max_supported=False, is_exact_custom_mode_supported=False, is_video_patrol_supported=False, is_carpet_custom_clean_supported=False, is_pet_snapshot_supported=False, is_custom_clean_mode_count_supported=False, is_new_ai_recognition_supported=False, is_auto_collection_2_supported=False, is_right_brush_stretch_supported=False, is_smart_clean_mode_set_supported=False, is_dirty_object_detect_supported=False, is_no_need_carpet_press_set_supported=False, is_voice_control_led_supported=False, is_water_leak_check_supported=False, is_min_battery_15_to_clean_task_supported=False, is_gap_deep_clean_supported=False, is_object_detect_check_supported=False, is_identify_room_supported=False, is_matter_supported=False, is_workday_holiday_supported=False, is_clean_direct_status_supported=False, is_map_eraser_supported=False, is_optimize_battery_supported=False, is_activate_video_charging_and_standby_supported=False, is_carpet_long_haired_supported=False, is_clean_history_time_line_supported=False, is_max_zone_opened_supported=False, is_exhibition_function_supported=False, is_lds_lifting_supported=False, is_auto_tear_down_mop_supported=False, is_small_side_mop_supported=False, is_support_side_brush_up_down_supported=False, is_dry_interval_timer_supported=False, is_uvc_sterilize_supported=False, is_midway_back_to_dock_supported=False, is_support_main_brush_up_down_supported=False, is_egg_dance_mode_supported=False, is_mechanical_arm_mode_supported=False, is_tidyup_zones_supported=False, is_clean_time_line_supported=False, is_clean_then_mop_mode_supported=False, is_type_identify_supported=False, is_support_get_particular_status_supported=False, is_three_d_mapping_inner_test_supported=False, is_sync_server_name_supported=False, is_should_show_arm_over_load_supported=False, is_collect_dust_count_show_supported=False, is_support_api_app_stop_grasp_supported=False, is_ctm_with_repeat_supported=False, is_side_brush_lift_carpet_supported=False, is_detect_wire_carpet_supported=False, is_water_slide_mode_supported=False, is_soak_and_wash_supported=False, is_clean_efficiency_supported=False, is_back_wash_new_smart_supported=False, is_dual_band_wi_fi_supported=False, is_program_mode_supported=False, is_clean_fluid_delivery_supported=False, is_carpet_long_haired_ex_supported=False, is_over_sea_ctm_supported=False, is_full_duples_switch_supported=False, is_low_area_access_supported=False, is_follow_low_obs_supported=False, is_two_gears_no_collision_supported=False, is_carpet_shape_type_supported=False, is_sr_map_supported=False, is_roller_mop_supported=False, is_led_status_switch_supported=False, is_multi_floor_supported=False, is_support_fetch_timer_summary=False, is_order_clean_supported=False, is_analysis_supported=False, is_remote_supported=False, is_support_voice_control_debug=False, is_mop_forbidden_supported=True, is_soft_clean_mode_supported=True, is_custom_mode_supported=True, is_support_custom_carpet=True, is_show_general_obstacle_supported=True, is_show_obstacle_photo_supported=True, is_rubber_brush_carpet_supported=True, is_carpet_pressure_use_origin_paras_supported=True, is_support_mop_back_pwm_set=True, is_collect_dust_mode_supported=True, is_support_water_mode=False, is_ai_recognition_setting_supported=False, is_ai_recognition_obstacle_supported=False, is_pure_clean_mop_supported=False, is_new_remote_view_supported=False, is_max_plus_mode_supported=False, is_none_pure_clean_mop_with_max_plus=False, is_clean_route_setting_supported=False, is_mop_shake_module_supported=False, is_customized_clean_supported=False), trait_data={'test_trait': {'key': 'value', 'number': 42}}), 'device2': DeviceCacheData(network_info=None, home_map_info=None, home_map_content_base64=None, device_features=None, trait_data=None)}, network_info={}, home_map_info={}, home_map_content={}, home_map_content_base64={}, device_features=None, trait_data=None) # --- # name: test_set_and_flush_and_get[json-empty_cache] CacheData(home_data=None, device_info={}, network_info={}, home_map_info={}, home_map_content={}, home_map_content_base64={}, device_features=None, trait_data=None) @@ -24,7 +24,7 @@ CacheData(home_data=HomeData(id=123456, name='My Home', products=[HomeDataProduct(id='product-id-s7-maxv', name='Roborock S7 MaxV', model='roborock.vacuum.a27', category=, code='a27', icon_url=None, attribute=None, capability=0, schema=[HomeDataProductSchema(id='101', name='rpc_request', code='rpc_request_code', mode='rw', type='RAW', product_property=None, property=None, desc=None), HomeDataProductSchema(id='102', name='rpc_response', code='rpc_response', mode='rw', type='RAW', product_property=None, property=None, desc=None), HomeDataProductSchema(id='120', name='错误代码', code='error_code', mode='ro', type='ENUM', product_property=None, property='{"range": []}', desc=None), HomeDataProductSchema(id='121', name='设备状态', code='state', mode='ro', type='ENUM', product_property=None, property='{"range": []}', desc=None), HomeDataProductSchema(id='122', name='设备电量', code='battery', mode='ro', type='ENUM', product_property=None, property='{"range": []}', desc=None), HomeDataProductSchema(id='123', name='清扫模式', code='fan_power', mode='rw', type='ENUM', product_property=None, property='{"range": []}', desc=None), HomeDataProductSchema(id='124', name='拖地模式', code='water_box_mode', mode='rw', type='ENUM', product_property=None, property='{"range": []}', desc=None), HomeDataProductSchema(id='125', name='主刷寿命', code='main_brush_life', mode='rw', type='VALUE', product_property=None, property='{"max": 100, "min": 0, "step": 1, "unit": null, "scale": 1}', desc=None), HomeDataProductSchema(id='126', name='边刷寿命', code='side_brush_life', mode='rw', type='VALUE', product_property=None, property='{"max": 100, "min": 0, "step": 1, "unit": null, "scale": 1}', desc=None), HomeDataProductSchema(id='127', name='滤网寿命', code='filter_life', mode='rw', type='VALUE', product_property=None, property='{"max": 100, "min": 0, "step": 1, "unit": null, "scale": 1}', desc=None), HomeDataProductSchema(id='128', name='额外状态', code='additional_props', mode='ro', type='RAW', product_property=None, property=None, desc=None), HomeDataProductSchema(id='130', name='完成事件', code='task_complete', mode='ro', type='RAW', product_property=None, property=None, desc=None), HomeDataProductSchema(id='131', name='电量不足任务取消', code='task_cancel_low_power', mode='ro', type='RAW', product_property=None, property=None, desc=None), HomeDataProductSchema(id='132', name='运动中任务取消', code='task_cancel_in_motion', mode='ro', type='RAW', product_property=None, property=None, desc=None), HomeDataProductSchema(id='133', name='充电状态', code='charge_status', mode='ro', type='RAW', product_property=None, property=None, desc=None), HomeDataProductSchema(id='134', name='烘干状态', code='drying_status', mode='ro', type='RAW', product_property=None, property=None, desc=None)])], devices=[HomeDataDevice(duid='abc123', name='Roborock S7 MaxV', local_key='key123key123key1', product_id='product-id-s7-maxv', fv='02.56.02', attribute=None, active_time=1672364449, runtime_env=None, time_zone_id='America/Los_Angeles', icon_url='no_url', lon=None, lat=None, share=False, share_time=None, online=True, pv='1.0', room_id=2362003, tuya_uuid=None, tuya_migrated=False, extra='{"RRPhotoPrivacyVersion": "1"}', sn='abc123', feature_set='2234201184108543', new_feature_set='0000000000002041', device_status={'121': 8, '122': 100, '123': 102, '124': 203, '125': 94, '126': 90, '127': 87, '128': 0, '133': 1, '120': 0}, silent_ota_switch=True, setting=None, f=None, create_time=None, cid=None, share_type=None, share_expired_time=None)], received_devices=[], lon=None, lat=None, geo_name=None, rooms=[HomeDataRoom(id=2362048, name='Example room 1'), HomeDataRoom(id=2362044, name='Example room 2'), HomeDataRoom(id=2362041, name='Example room 3')]), device_info={}, network_info={}, home_map_info={}, home_map_content={}, home_map_content_base64={}, device_features=None, trait_data=None) # --- # name: test_set_and_flush_and_get[pickle-all_fields_cache] - CacheData(home_data=HomeData(id=123456, name='My Home', products=[HomeDataProduct(id='product-id-s7-maxv', name='Roborock S7 MaxV', model='roborock.vacuum.a27', category=, code='a27', icon_url=None, attribute=None, capability=0, schema=[HomeDataProductSchema(id='101', name='rpc_request', code='rpc_request_code', mode='rw', type='RAW', product_property=None, property=None, desc=None), HomeDataProductSchema(id='102', name='rpc_response', code='rpc_response', mode='rw', type='RAW', product_property=None, property=None, desc=None), HomeDataProductSchema(id='120', name='错误代码', code='error_code', mode='ro', type='ENUM', product_property=None, property='{"range": []}', desc=None), HomeDataProductSchema(id='121', name='设备状态', code='state', mode='ro', type='ENUM', product_property=None, property='{"range": []}', desc=None), HomeDataProductSchema(id='122', name='设备电量', code='battery', mode='ro', type='ENUM', product_property=None, property='{"range": []}', desc=None), HomeDataProductSchema(id='123', name='清扫模式', code='fan_power', mode='rw', type='ENUM', product_property=None, property='{"range": []}', desc=None), HomeDataProductSchema(id='124', name='拖地模式', code='water_box_mode', mode='rw', type='ENUM', product_property=None, property='{"range": []}', desc=None), HomeDataProductSchema(id='125', name='主刷寿命', code='main_brush_life', mode='rw', type='VALUE', product_property=None, property='{"max": 100, "min": 0, "step": 1, "unit": null, "scale": 1}', desc=None), HomeDataProductSchema(id='126', name='边刷寿命', code='side_brush_life', mode='rw', type='VALUE', product_property=None, property='{"max": 100, "min": 0, "step": 1, "unit": null, "scale": 1}', desc=None), HomeDataProductSchema(id='127', name='滤网寿命', code='filter_life', mode='rw', type='VALUE', product_property=None, property='{"max": 100, "min": 0, "step": 1, "unit": null, "scale": 1}', desc=None), HomeDataProductSchema(id='128', name='额外状态', code='additional_props', mode='ro', type='RAW', product_property=None, property=None, desc=None), HomeDataProductSchema(id='130', name='完成事件', code='task_complete', mode='ro', type='RAW', product_property=None, property=None, desc=None), HomeDataProductSchema(id='131', name='电量不足任务取消', code='task_cancel_low_power', mode='ro', type='RAW', product_property=None, property=None, desc=None), HomeDataProductSchema(id='132', name='运动中任务取消', code='task_cancel_in_motion', mode='ro', type='RAW', product_property=None, property=None, desc=None), HomeDataProductSchema(id='133', name='充电状态', code='charge_status', mode='ro', type='RAW', product_property=None, property=None, desc=None), HomeDataProductSchema(id='134', name='烘干状态', code='drying_status', mode='ro', type='RAW', product_property=None, property=None, desc=None)])], devices=[HomeDataDevice(duid='abc123', name='Roborock S7 MaxV', local_key='key123key123key1', product_id='product-id-s7-maxv', fv='02.56.02', attribute=None, active_time=1672364449, runtime_env=None, time_zone_id='America/Los_Angeles', icon_url='no_url', lon=None, lat=None, share=False, share_time=None, online=True, pv='1.0', room_id=2362003, tuya_uuid=None, tuya_migrated=False, extra='{"RRPhotoPrivacyVersion": "1"}', sn='abc123', feature_set='2234201184108543', new_feature_set='0000000000002041', device_status={'121': 8, '122': 100, '123': 102, '124': 203, '125': 94, '126': 90, '127': 87, '128': 0, '133': 1, '120': 0}, silent_ota_switch=True, setting=None, f=None, create_time=None, cid=None, share_type=None, share_expired_time=None)], received_devices=[], lon=None, lat=None, geo_name=None, rooms=[HomeDataRoom(id=2362048, name='Example room 1'), HomeDataRoom(id=2362044, name='Example room 2'), HomeDataRoom(id=2362041, name='Example room 3')]), device_info={'device1': DeviceCacheData(network_info=NetworkInfo(ip='1.1.1.1', ssid='test_wifi', mac='aa:bb:cc:dd:ee:ff', bssid='aa:bb:cc:dd:ee:ff', rssi=-50), home_map_info={1: CombinedMapInfo(map_flag=1, name='Test Map 1', rooms=[NamedRoomMapping(segment_id=1023, iot_id='4321', raw_name='Living Room'), NamedRoomMapping(segment_id=1024, iot_id='4322', raw_name='Starship')]), 2: CombinedMapInfo(map_flag=2, name='Test Map 2', rooms=[NamedRoomMapping(segment_id=2047, iot_id='5432', raw_name='Bedroom')])}, home_map_content_base64={1: 'ZHVtbXlfbWFwX2NvbnRlbnQ=', 2: 'bW9yZV9kdW1teV9jb250ZW50'}, device_features=DeviceFeatures(is_show_clean_finish_reason_supported=True, is_re_segment_supported=False, is_video_monitor_supported=False, is_any_state_transit_goto_supported=False, is_fw_filter_obstacle_supported=False, is_video_setting_supported=False, is_ignore_unknown_map_object_supported=False, is_set_child_supported=False, is_carpet_supported=False, is_record_allowed=False, is_mop_path_supported=False, is_multi_map_segment_timer_supported=False, is_current_map_restore_enabled=False, is_room_name_supported=False, is_shake_mop_set_supported=False, is_map_beautify_internal_debug_supported=False, is_new_data_for_clean_history=False, is_new_data_for_clean_history_detail=False, is_flow_led_setting_supported=False, is_dust_collection_setting_supported=False, is_rpc_retry_supported=False, is_avoid_collision_supported=False, is_support_set_switch_map_mode=False, is_map_carpet_add_support=False, is_custom_water_box_distance_supported=False, is_support_smart_scene=False, is_support_floor_edit=False, is_support_furniture=False, is_wash_then_charge_cmd_supported=False, is_support_room_tag=False, is_support_quick_map_builder=False, is_support_smart_global_clean_with_custom_mode=False, is_careful_slow_mop_supported=False, is_egg_mode_supported_from_new_features=False, is_carpet_show_on_map=False, is_supported_valley_electricity=False, is_unsave_map_reason_supported=False, is_supported_drying=False, is_supported_download_test_voice=False, is_support_backup_map=False, is_support_custom_mode_in_cleaning=False, is_support_remote_control_in_call=False, is_support_set_volume_in_call=True, is_support_clean_estimate=False, is_support_custom_dnd=False, is_carpet_deep_clean_supported=False, is_support_stuck_zone=False, is_support_custom_door_sill=False, is_wifi_manage_supported=False, is_clean_route_fast_mode_supported=False, is_support_cliff_zone=False, is_support_smart_door_sill=False, is_support_floor_direction=False, is_back_charge_auto_wash_supported=False, is_support_incremental_map=False, is_offline_map_supported=False, is_super_deep_wash_supported=False, is_ces_2022_supported=False, is_dss_believable=False, is_main_brush_up_down_supported_from_str=False, is_goto_pure_clean_path_supported=False, is_water_up_down_drain_supported=False, is_setting_carpet_first_supported=False, is_clean_route_deep_slow_plus_supported=False, is_dynamically_skip_clean_zone_supported=False, is_dynamically_add_clean_zones_supported=False, is_left_water_drain_supported=False, is_clean_count_setting_supported=False, is_corner_clean_mode_supported=False, is_two_key_real_time_video_supported=False, is_two_key_rtv_in_charging_supported=False, is_dirty_replenish_clean_supported=False, is_auto_delivery_field_in_global_status_supported=False, is_avoid_collision_mode_supported=False, is_voice_control_supported=False, is_new_endpoint_supported=False, is_pumping_water_supported=False, is_corner_mop_stretch_supported=False, is_hot_wash_towel_supported=False, is_floor_dir_clean_any_time_supported=False, is_pet_supplies_deep_clean_supported=False, is_mop_shake_water_max_supported=False, is_exact_custom_mode_supported=False, is_video_patrol_supported=False, is_carpet_custom_clean_supported=False, is_pet_snapshot_supported=False, is_custom_clean_mode_count_supported=False, is_new_ai_recognition_supported=False, is_auto_collection_2_supported=False, is_right_brush_stretch_supported=False, is_smart_clean_mode_set_supported=False, is_dirty_object_detect_supported=False, is_no_need_carpet_press_set_supported=False, is_voice_control_led_supported=False, is_water_leak_check_supported=False, is_min_battery_15_to_clean_task_supported=False, is_gap_deep_clean_supported=False, is_object_detect_check_supported=False, is_identify_room_supported=False, is_matter_supported=False, is_workday_holiday_supported=False, is_clean_direct_status_supported=False, is_map_eraser_supported=False, is_optimize_battery_supported=False, is_activate_video_charging_and_standby_supported=False, is_carpet_long_haired_supported=False, is_clean_history_time_line_supported=False, is_max_zone_opened_supported=False, is_exhibition_function_supported=False, is_lds_lifting_supported=False, is_auto_tear_down_mop_supported=False, is_small_side_mop_supported=False, is_support_side_brush_up_down_supported=False, is_dry_interval_timer_supported=False, is_uvc_sterilize_supported=False, is_midway_back_to_dock_supported=False, is_support_main_brush_up_down_supported=False, is_egg_dance_mode_supported=False, is_mechanical_arm_mode_supported=False, is_tidyup_zones_supported=False, is_clean_time_line_supported=False, is_clean_then_mop_mode_supported=False, is_type_identify_supported=False, is_support_get_particular_status_supported=False, is_three_d_mapping_inner_test_supported=False, is_sync_server_name_supported=False, is_should_show_arm_over_load_supported=False, is_collect_dust_count_show_supported=False, is_support_api_app_stop_grasp_supported=False, is_ctm_with_repeat_supported=False, is_side_brush_lift_carpet_supported=False, is_detect_wire_carpet_supported=False, is_water_slide_mode_supported=False, is_soak_and_wash_supported=False, is_clean_efficiency_supported=False, is_back_wash_new_smart_supported=False, is_dual_band_wi_fi_supported=False, is_program_mode_supported=False, is_clean_fluid_delivery_supported=False, is_carpet_long_haired_ex_supported=False, is_over_sea_ctm_supported=False, is_full_duples_switch_supported=False, is_low_area_access_supported=False, is_follow_low_obs_supported=False, is_two_gears_no_collision_supported=False, is_carpet_shape_type_supported=False, is_sr_map_supported=False, is_led_status_switch_supported=False, is_multi_floor_supported=False, is_support_fetch_timer_summary=False, is_order_clean_supported=False, is_analysis_supported=False, is_remote_supported=False, is_support_voice_control_debug=False, is_mop_forbidden_supported=True, is_soft_clean_mode_supported=True, is_custom_mode_supported=True, is_support_custom_carpet=True, is_show_general_obstacle_supported=True, is_show_obstacle_photo_supported=True, is_rubber_brush_carpet_supported=True, is_carpet_pressure_use_origin_paras_supported=True, is_support_mop_back_pwm_set=True, is_collect_dust_mode_supported=True, is_support_water_mode=False, is_ai_recognition_setting_supported=False, is_ai_recognition_obstacle_supported=False, is_pure_clean_mop_supported=False, is_new_remote_view_supported=False, is_max_plus_mode_supported=False, is_none_pure_clean_mop_with_max_plus=False, is_clean_route_setting_supported=False, is_mop_shake_module_supported=False, is_customized_clean_supported=False), trait_data={'test_trait': {'key': 'value', 'number': 42}}), 'device2': DeviceCacheData(network_info=None, home_map_info=None, home_map_content_base64=None, device_features=None, trait_data=None)}, network_info={}, home_map_info={}, home_map_content={}, home_map_content_base64={}, device_features=None, trait_data=None) + CacheData(home_data=HomeData(id=123456, name='My Home', products=[HomeDataProduct(id='product-id-s7-maxv', name='Roborock S7 MaxV', model='roborock.vacuum.a27', category=, code='a27', icon_url=None, attribute=None, capability=0, schema=[HomeDataProductSchema(id='101', name='rpc_request', code='rpc_request_code', mode='rw', type='RAW', product_property=None, property=None, desc=None), HomeDataProductSchema(id='102', name='rpc_response', code='rpc_response', mode='rw', type='RAW', product_property=None, property=None, desc=None), HomeDataProductSchema(id='120', name='错误代码', code='error_code', mode='ro', type='ENUM', product_property=None, property='{"range": []}', desc=None), HomeDataProductSchema(id='121', name='设备状态', code='state', mode='ro', type='ENUM', product_property=None, property='{"range": []}', desc=None), HomeDataProductSchema(id='122', name='设备电量', code='battery', mode='ro', type='ENUM', product_property=None, property='{"range": []}', desc=None), HomeDataProductSchema(id='123', name='清扫模式', code='fan_power', mode='rw', type='ENUM', product_property=None, property='{"range": []}', desc=None), HomeDataProductSchema(id='124', name='拖地模式', code='water_box_mode', mode='rw', type='ENUM', product_property=None, property='{"range": []}', desc=None), HomeDataProductSchema(id='125', name='主刷寿命', code='main_brush_life', mode='rw', type='VALUE', product_property=None, property='{"max": 100, "min": 0, "step": 1, "unit": null, "scale": 1}', desc=None), HomeDataProductSchema(id='126', name='边刷寿命', code='side_brush_life', mode='rw', type='VALUE', product_property=None, property='{"max": 100, "min": 0, "step": 1, "unit": null, "scale": 1}', desc=None), HomeDataProductSchema(id='127', name='滤网寿命', code='filter_life', mode='rw', type='VALUE', product_property=None, property='{"max": 100, "min": 0, "step": 1, "unit": null, "scale": 1}', desc=None), HomeDataProductSchema(id='128', name='额外状态', code='additional_props', mode='ro', type='RAW', product_property=None, property=None, desc=None), HomeDataProductSchema(id='130', name='完成事件', code='task_complete', mode='ro', type='RAW', product_property=None, property=None, desc=None), HomeDataProductSchema(id='131', name='电量不足任务取消', code='task_cancel_low_power', mode='ro', type='RAW', product_property=None, property=None, desc=None), HomeDataProductSchema(id='132', name='运动中任务取消', code='task_cancel_in_motion', mode='ro', type='RAW', product_property=None, property=None, desc=None), HomeDataProductSchema(id='133', name='充电状态', code='charge_status', mode='ro', type='RAW', product_property=None, property=None, desc=None), HomeDataProductSchema(id='134', name='烘干状态', code='drying_status', mode='ro', type='RAW', product_property=None, property=None, desc=None)])], devices=[HomeDataDevice(duid='abc123', name='Roborock S7 MaxV', local_key='key123key123key1', product_id='product-id-s7-maxv', fv='02.56.02', attribute=None, active_time=1672364449, runtime_env=None, time_zone_id='America/Los_Angeles', icon_url='no_url', lon=None, lat=None, share=False, share_time=None, online=True, pv='1.0', room_id=2362003, tuya_uuid=None, tuya_migrated=False, extra='{"RRPhotoPrivacyVersion": "1"}', sn='abc123', feature_set='2234201184108543', new_feature_set='0000000000002041', device_status={'121': 8, '122': 100, '123': 102, '124': 203, '125': 94, '126': 90, '127': 87, '128': 0, '133': 1, '120': 0}, silent_ota_switch=True, setting=None, f=None, create_time=None, cid=None, share_type=None, share_expired_time=None)], received_devices=[], lon=None, lat=None, geo_name=None, rooms=[HomeDataRoom(id=2362048, name='Example room 1'), HomeDataRoom(id=2362044, name='Example room 2'), HomeDataRoom(id=2362041, name='Example room 3')]), device_info={'device1': DeviceCacheData(network_info=NetworkInfo(ip='1.1.1.1', ssid='test_wifi', mac='aa:bb:cc:dd:ee:ff', bssid='aa:bb:cc:dd:ee:ff', rssi=-50), home_map_info={1: CombinedMapInfo(map_flag=1, name='Test Map 1', rooms=[NamedRoomMapping(segment_id=1023, iot_id='4321', raw_name='Living Room'), NamedRoomMapping(segment_id=1024, iot_id='4322', raw_name='Starship')]), 2: CombinedMapInfo(map_flag=2, name='Test Map 2', rooms=[NamedRoomMapping(segment_id=2047, iot_id='5432', raw_name='Bedroom')])}, home_map_content_base64={1: 'ZHVtbXlfbWFwX2NvbnRlbnQ=', 2: 'bW9yZV9kdW1teV9jb250ZW50'}, device_features=DeviceFeatures(is_show_clean_finish_reason_supported=True, is_re_segment_supported=False, is_video_monitor_supported=False, is_any_state_transit_goto_supported=False, is_fw_filter_obstacle_supported=False, is_video_setting_supported=False, is_ignore_unknown_map_object_supported=False, is_set_child_supported=False, is_carpet_supported=False, is_record_allowed=False, is_mop_path_supported=False, is_multi_map_segment_timer_supported=False, is_current_map_restore_enabled=False, is_room_name_supported=False, is_shake_mop_set_supported=False, is_map_beautify_internal_debug_supported=False, is_new_data_for_clean_history=False, is_new_data_for_clean_history_detail=False, is_flow_led_setting_supported=False, is_dust_collection_setting_supported=False, is_rpc_retry_supported=False, is_avoid_collision_supported=False, is_support_set_switch_map_mode=False, is_map_carpet_add_support=False, is_custom_water_box_distance_supported=False, is_support_smart_scene=False, is_support_floor_edit=False, is_support_furniture=False, is_wash_then_charge_cmd_supported=False, is_support_room_tag=False, is_support_quick_map_builder=False, is_support_smart_global_clean_with_custom_mode=False, is_careful_slow_mop_supported=False, is_egg_mode_supported_from_new_features=False, is_carpet_show_on_map=False, is_supported_valley_electricity=False, is_unsave_map_reason_supported=False, is_supported_drying=False, is_supported_download_test_voice=False, is_support_backup_map=False, is_support_custom_mode_in_cleaning=False, is_support_remote_control_in_call=False, is_support_set_volume_in_call=True, is_support_clean_estimate=False, is_support_custom_dnd=False, is_carpet_deep_clean_supported=False, is_support_stuck_zone=False, is_support_custom_door_sill=False, is_wifi_manage_supported=False, is_clean_route_fast_mode_supported=False, is_support_cliff_zone=False, is_support_smart_door_sill=False, is_support_floor_direction=False, is_back_charge_auto_wash_supported=False, is_support_incremental_map=False, is_offline_map_supported=False, is_super_deep_wash_supported=False, is_ces_2022_supported=False, is_dss_believable=False, is_main_brush_up_down_supported_from_str=False, is_goto_pure_clean_path_supported=False, is_water_up_down_drain_supported=False, is_setting_carpet_first_supported=False, is_clean_route_deep_slow_plus_supported=False, is_dynamically_skip_clean_zone_supported=False, is_dynamically_add_clean_zones_supported=False, is_left_water_drain_supported=False, is_clean_count_setting_supported=False, is_corner_clean_mode_supported=False, is_two_key_real_time_video_supported=False, is_two_key_rtv_in_charging_supported=False, is_dirty_replenish_clean_supported=False, is_auto_delivery_field_in_global_status_supported=False, is_avoid_collision_mode_supported=False, is_voice_control_supported=False, is_new_endpoint_supported=False, is_pumping_water_supported=False, is_corner_mop_stretch_supported=False, is_hot_wash_towel_supported=False, is_floor_dir_clean_any_time_supported=False, is_pet_supplies_deep_clean_supported=False, is_mop_shake_water_max_supported=False, is_exact_custom_mode_supported=False, is_video_patrol_supported=False, is_carpet_custom_clean_supported=False, is_pet_snapshot_supported=False, is_custom_clean_mode_count_supported=False, is_new_ai_recognition_supported=False, is_auto_collection_2_supported=False, is_right_brush_stretch_supported=False, is_smart_clean_mode_set_supported=False, is_dirty_object_detect_supported=False, is_no_need_carpet_press_set_supported=False, is_voice_control_led_supported=False, is_water_leak_check_supported=False, is_min_battery_15_to_clean_task_supported=False, is_gap_deep_clean_supported=False, is_object_detect_check_supported=False, is_identify_room_supported=False, is_matter_supported=False, is_workday_holiday_supported=False, is_clean_direct_status_supported=False, is_map_eraser_supported=False, is_optimize_battery_supported=False, is_activate_video_charging_and_standby_supported=False, is_carpet_long_haired_supported=False, is_clean_history_time_line_supported=False, is_max_zone_opened_supported=False, is_exhibition_function_supported=False, is_lds_lifting_supported=False, is_auto_tear_down_mop_supported=False, is_small_side_mop_supported=False, is_support_side_brush_up_down_supported=False, is_dry_interval_timer_supported=False, is_uvc_sterilize_supported=False, is_midway_back_to_dock_supported=False, is_support_main_brush_up_down_supported=False, is_egg_dance_mode_supported=False, is_mechanical_arm_mode_supported=False, is_tidyup_zones_supported=False, is_clean_time_line_supported=False, is_clean_then_mop_mode_supported=False, is_type_identify_supported=False, is_support_get_particular_status_supported=False, is_three_d_mapping_inner_test_supported=False, is_sync_server_name_supported=False, is_should_show_arm_over_load_supported=False, is_collect_dust_count_show_supported=False, is_support_api_app_stop_grasp_supported=False, is_ctm_with_repeat_supported=False, is_side_brush_lift_carpet_supported=False, is_detect_wire_carpet_supported=False, is_water_slide_mode_supported=False, is_soak_and_wash_supported=False, is_clean_efficiency_supported=False, is_back_wash_new_smart_supported=False, is_dual_band_wi_fi_supported=False, is_program_mode_supported=False, is_clean_fluid_delivery_supported=False, is_carpet_long_haired_ex_supported=False, is_over_sea_ctm_supported=False, is_full_duples_switch_supported=False, is_low_area_access_supported=False, is_follow_low_obs_supported=False, is_two_gears_no_collision_supported=False, is_carpet_shape_type_supported=False, is_sr_map_supported=False, is_roller_mop_supported=False, is_led_status_switch_supported=False, is_multi_floor_supported=False, is_support_fetch_timer_summary=False, is_order_clean_supported=False, is_analysis_supported=False, is_remote_supported=False, is_support_voice_control_debug=False, is_mop_forbidden_supported=True, is_soft_clean_mode_supported=True, is_custom_mode_supported=True, is_support_custom_carpet=True, is_show_general_obstacle_supported=True, is_show_obstacle_photo_supported=True, is_rubber_brush_carpet_supported=True, is_carpet_pressure_use_origin_paras_supported=True, is_support_mop_back_pwm_set=True, is_collect_dust_mode_supported=True, is_support_water_mode=False, is_ai_recognition_setting_supported=False, is_ai_recognition_obstacle_supported=False, is_pure_clean_mop_supported=False, is_new_remote_view_supported=False, is_max_plus_mode_supported=False, is_none_pure_clean_mop_with_max_plus=False, is_clean_route_setting_supported=False, is_mop_shake_module_supported=False, is_customized_clean_supported=False), trait_data={'test_trait': {'key': 'value', 'number': 42}}), 'device2': DeviceCacheData(network_info=None, home_map_info=None, home_map_content_base64=None, device_features=None, trait_data=None)}, network_info={}, home_map_info={}, home_map_content={}, home_map_content_base64={}, device_features=None, trait_data=None) # --- # name: test_set_and_flush_and_get[pickle-empty_cache] CacheData(home_data=None, device_info={}, network_info={}, home_map_info={}, home_map_content={}, home_map_content_base64={}, device_features=None, trait_data=None) diff --git a/tests/devices/__snapshots__/test_v1_device.ambr b/tests/devices/__snapshots__/test_v1_device.ambr index 3cd44496..0e5c3f5c 100644 --- a/tests/devices/__snapshots__/test_v1_device.ambr +++ b/tests/devices/__snapshots__/test_v1_device.ambr @@ -317,6 +317,7 @@ 'isRecordAllowed': False, 'isRemoteSupported': True, 'isRightBrushStretchSupported': False, + 'isRollerMopSupported': False, 'isRoomNameSupported': True, 'isRpcRetrySupported': False, 'isRubberBrushCarpetSupported': False, @@ -737,6 +738,7 @@ 'isRecordAllowed': False, 'isRemoteSupported': True, 'isRightBrushStretchSupported': False, + 'isRollerMopSupported': False, 'isRoomNameSupported': True, 'isRpcRetrySupported': False, 'isRubberBrushCarpetSupported': False, @@ -874,7 +876,7 @@ }) # --- # name: test_device_trait_command_parsing[status] - StatusTrait(adbumper_status=None, auto_dust_collection=None, avoid_count=None, back_type=None, battery=100, camera_status=None, charge_status=None, clean_area=91287500, clean_fluid_status=None, clean_percent=None, clean_time=5405, cleaning_mode_options=[, , , ], clear_water_box_status=None, collision_avoid_status=None, command=, common_status=None, converter=DefaultConverter, corner_clean_mode=None, current_cleaning_mode=, current_cleaning_mode_name='custom', current_map=0, debug_mode=None, dirty_water_box_status=None, distance_off=0, dnd_enabled=1, dock_cool_fan_status=None, dock_error_status=None, dock_state=, dock_type=None, dry_status=None, dss=None, dust_bag_status=None, dust_collection_status=None, error_code=, error_code_name='none', fan_power=106, fan_speed_mapping={101: 'quiet', 102: 'balanced', 103: 'turbo', 104: 'max', 108: 'max_plus', 105: 'off', 106: 'custom'}, fan_speed_name='custom', fan_speed_options=[, , , , , , ], has_am=None, hatch_door_status=None, home_sec_enable_password=None, home_sec_status=None, in_cleaning=, in_fresh_state=1, in_returning=0, in_warmup=None, is_exploring=None, is_locating=0, kct=None, lab_status=1, last_clean_t=None, lock_status=0, map_present=1, map_status=3, mop_forbidden_enable=0, mop_mode=None, mop_route_mapping={}, mop_route_name=None, mop_route_options=[], msg_seq=515, msg_ver=2, rdt=None, repeat=None, replenish_mode=None, rss=None, square_meter_clean_area=91.3, state=, state_name='charging', subdivision_sets=None, switch_map_mode=None, unsave_map_flag=0, unsave_map_reason=4, wash_phase=None, wash_ready=None, wash_status=None, water_box_carriage_status=0, water_box_filter_status=None, water_box_mode=204, water_box_status=0, water_mode_mapping={200: 'off', 201: 'mild', 202: 'standard', 203: 'intense', 207: 'custom_water_flow', 204: 'custom'}, water_mode_name='custom', water_mode_options=[, , , , , ], water_shortage_status=None) + StatusTrait(adbumper_status=None, auto_dust_collection=None, avoid_count=None, back_type=None, battery=100, camera_status=None, charge_status=None, clean_area=91287500, clean_fluid_status=None, clean_percent=None, clean_time=5405, cleaning_mode_options=[, , , ], clear_water_box_status=None, collision_avoid_status=None, command=, common_status=None, converter=DefaultConverter, corner_clean_mode=None, current_cleaning_mode=, current_cleaning_mode_name='custom', current_map=0, debug_mode=None, dirty_water_box_status=None, distance_off=0, dnd_enabled=1, dock_cool_fan_status=None, dock_error_status=None, dock_state=, dock_type=None, dry_status=None, dss=None, dust_bag_status=None, dust_collection_status=None, error_code=, error_code_name='none', fan_power=106, fan_speed_mapping={101: 'quiet', 102: 'balanced', 103: 'turbo', 104: 'max', 108: 'max_plus', 105: 'off', 106: 'custom'}, fan_speed_name='custom', fan_speed_options=[, , , , , , ], has_am=None, hatch_door_status=None, home_sec_enable_password=None, home_sec_status=None, in_cleaning=, in_fresh_state=1, in_returning=0, in_warmup=None, is_exploring=None, is_locating=0, kct=None, lab_status=1, last_clean_t=None, lock_status=0, map_present=1, map_status=3, mop_forbidden_enable=0, mop_mode=None, mop_route_mapping={300: 'standard', 301: 'deep', 302: 'custom'}, mop_route_name=None, mop_route_options=[, , ], msg_seq=515, msg_ver=2, rdt=None, repeat=None, replenish_mode=None, rss=None, square_meter_clean_area=91.3, state=, state_name='charging', subdivision_sets=None, switch_map_mode=None, unsave_map_flag=0, unsave_map_reason=4, wash_phase=None, wash_ready=None, wash_status=None, water_box_carriage_status=0, water_box_filter_status=None, water_box_mode=204, water_box_status=0, water_mode_mapping={200: 'off', 201: 'mild', 202: 'standard', 203: 'intense', 207: 'custom_water_flow', 204: 'custom'}, water_mode_name='custom', water_mode_options=[, , , , , ], water_shortage_status=None) # --- # name: test_device_trait_command_parsing[status].1 dict({ @@ -1164,6 +1166,7 @@ 'isRecordAllowed': False, 'isRemoteSupported': True, 'isRightBrushStretchSupported': False, + 'isRollerMopSupported': False, 'isRoomNameSupported': True, 'isRpcRetrySupported': False, 'isRubberBrushCarpetSupported': False, @@ -1561,6 +1564,7 @@ 'isRecordAllowed': False, 'isRemoteSupported': True, 'isRightBrushStretchSupported': False, + 'isRollerMopSupported': False, 'isRoomNameSupported': True, 'isRpcRetrySupported': False, 'isRubberBrushCarpetSupported': False, diff --git a/tests/devices/traits/v1/test_status.py b/tests/devices/traits/v1/test_status.py index 6f2b7c65..6fb0284c 100644 --- a/tests/devices/traits/v1/test_status.py +++ b/tests/devices/traits/v1/test_status.py @@ -15,7 +15,7 @@ get_current_cleaning_mode, resolve_cleaning_mode, ) -from roborock.data import SHORT_MODEL_TO_ENUM +from roborock.data import SHORT_MODEL_TO_ENUM, RoborockProductNickname from roborock.data.v1 import ( RoborockStateCode, ) @@ -50,7 +50,6 @@ def _create_cleaning_mode_status_trait(**feature_overrides: bool) -> StatusTrait features.is_pure_clean_mop_supported = True features.is_customized_clean_supported = True features.is_clean_route_setting_supported = True - features.is_shake_mop_set_supported = True for feature_name, value in feature_overrides.items(): if not hasattr(features, feature_name): raise AttributeError(f"Unknown DeviceFeatures override: {feature_name}") @@ -111,7 +110,7 @@ def test_none_values(status_trait: StatusTrait) -> None: def test_options(status_trait: StatusTrait) -> None: """Test that fan_speed_options returns a list of options.""" - status_trait._device_features_trait.is_shake_mop_set_supported = True + status_trait._device_features_trait.is_clean_route_setting_supported = True assert isinstance(status_trait.fan_speed_options, list) assert len(status_trait.fan_speed_options) > 0 assert isinstance(status_trait.water_mode_options, list) @@ -163,6 +162,72 @@ def test_s7_has_mop_route_options() -> None: ] +def test_spin_mop_without_runtime_shake_has_mop_route_options() -> None: + """Test spin-mop models retain routes without the runtime shake bit.""" + features = DeviceFeatures.from_feature_flags( + new_feature_info=0, + new_feature_info_str="42BA8D587EDAFFFE", + feature_info=[], + product_nickname=SHORT_MODEL_TO_ENUM["a123"], + ) + status_trait = StatusTrait(cast(DeviceFeaturesTrait, features), region="us") + + assert not features.is_shake_mop_set_supported + assert features.is_clean_route_setting_supported + assert CleanRoutes.STANDARD in status_trait.mop_route_options + assert CleanRoutes.DEEP in status_trait.mop_route_options + assert get_cleaning_mode_parameters(CleaningMode.VAC_AND_MOP, features)[0]["mop_mode"] == 300 + + +def test_clean_efficiency_device_omits_deep_route() -> None: + """Test Saros 20-style clean-efficiency devices do not expose route 301.""" + features = DeviceFeatures.from_feature_flags( + new_feature_info=4499197267967999, + new_feature_info_str="0000000000099518CCFF7EFDA8E93EDDDBFF8F7F7EFEFFFF", + feature_info=[111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125], + product_nickname=RoborockProductNickname.PEARLPLUS, + ) + status_trait = StatusTrait(cast(DeviceFeaturesTrait, features), region="us") + + assert features.is_clean_efficiency_supported + assert features.is_clean_route_setting_supported + assert CleanRoutes.STANDARD in status_trait.mop_route_options + assert CleanRoutes.DEEP not in status_trait.mop_route_options + assert CleanRoutes.DEEP_PLUS in status_trait.mop_route_options + assert CleanRoutes.FAST in status_trait.mop_route_options + + +@pytest.mark.parametrize( + ("is_corner_clean_mode_supported", "is_clean_route_deep_slow_plus_supported", "region", "expected_code"), + [ + (False, False, "us", 303), + (False, True, "us", 303), + (True, True, "us", 303), + (False, False, "cn", 303), + (True, True, "cn", 303), + (False, True, "cn", 305), + ], +) +def test_deep_plus_route_matches_rr_api( + is_corner_clean_mode_supported: bool, + is_clean_route_deep_slow_plus_supported: bool, + region: str, + expected_code: int, +) -> None: + """Test route 305 is limited to its RR_API China-only feature combination.""" + status_trait = _create_cleaning_mode_status_trait( + is_careful_slow_mop_supported=True, + is_corner_clean_mode_supported=is_corner_clean_mode_supported, + is_clean_route_deep_slow_plus_supported=is_clean_route_deep_slow_plus_supported, + ) + status_trait._region = region + + route_codes = [route.code for route in status_trait.mop_route_options] + assert expected_code in route_codes + assert ({303, 305} - {expected_code}).isdisjoint(route_codes) + assert status_trait.mop_route_mapping[expected_code] == "deep_plus" + + def test_cleaning_mode_options() -> None: """Test the high-level cleaning mode options for the device.""" status_trait = _create_cleaning_mode_status_trait() @@ -361,7 +426,6 @@ def test_get_cleaning_mode_parameters_without_clean_route_setting() -> None: """Test older V1 devices use the 2-field clean motor payload.""" status_trait = _create_cleaning_mode_status_trait( is_clean_route_setting_supported=False, - is_shake_mop_set_supported=False, is_customized_clean_supported=False, ) diff --git a/tests/test_supported_features.py b/tests/test_supported_features.py index 09ecf745..5a19f5b1 100644 --- a/tests/test_supported_features.py +++ b/tests/test_supported_features.py @@ -144,6 +144,41 @@ def test_clean_route_setting_support_from_shake_mop_flag() -> None: assert device_features.is_clean_route_setting_supported +def test_clean_route_setting_support_from_spin_mop_model() -> None: + """Test clean-route capability includes model-level spin-mop support.""" + device_features = DeviceFeatures.from_feature_flags( + new_feature_info=0, + new_feature_info_str="", + feature_info=[], + product_nickname=RoborockProductNickname.PEARLSLITE, + ) + + assert not device_features.is_shake_mop_set_supported + assert not device_features.is_roller_mop_supported + assert device_features.is_clean_route_setting_supported + + +@pytest.mark.parametrize( + ("feature_bit", "expected"), + [ + (127, False), + (128, True), + (129, False), + ], +) +def test_clean_route_setting_support_from_roller_mop_bit(feature_bit: int, expected: bool) -> None: + """Test only the RR_API roller-mop bit adds roller route support.""" + device_features = DeviceFeatures.from_feature_flags( + new_feature_info=0, + new_feature_info_str=f"{1 << feature_bit:X}", + feature_info=[], + product_nickname=None, + ) + + assert device_features.is_roller_mop_supported is expected + assert device_features.is_clean_route_setting_supported is expected + + @pytest.mark.parametrize( ("new_feature_info", "expected"), [