From bbe082ccbe11b93a446ce740736e968fbeeb71a2 Mon Sep 17 00:00:00 2001 From: Allen Porter Date: Sun, 5 Apr 2026 07:51:06 -0700 Subject: [PATCH 1/6] feat: add support for Saros 10 (A147) device and update test snapshots --- .../__snapshots__/test_device_features.ambr | 18 +++ tests/mock_data.py | 6 +- tests/testdata/home_data_device_saros.json | 36 +++++ tests/testdata/home_data_product_a147.json | 143 ++++++++++++++++++ 4 files changed, 201 insertions(+), 2 deletions(-) create mode 100644 tests/testdata/home_data_device_saros.json create mode 100644 tests/testdata/home_data_product_a147.json diff --git a/tests/devices/traits/v1/__snapshots__/test_device_features.ambr b/tests/devices/traits/v1/__snapshots__/test_device_features.ambr index 71313f0a..0d3854d7 100644 --- a/tests/devices/traits/v1/__snapshots__/test_device_features.ambr +++ b/tests/devices/traits/v1/__snapshots__/test_device_features.ambr @@ -21,6 +21,17 @@ 'water_box_mode': True, }) # --- +# name: test_is_attribute_supported[home_data_device_saros.json] + dict({ + 'battery': True, + 'charge_status': True, + 'dry_status': True, + 'error_code': True, + 'fan_power': True, + 'state': True, + 'water_box_mode': True, + }) +# --- # name: test_is_attribute_supported[home_data_device_saros_10r.json] dict({ 'battery': True, @@ -46,6 +57,13 @@ 'side_brush_work_time': True, }) # --- +# name: test_is_consumable_field_supported[home_data_device_saros.json] + dict({ + 'filter_work_time': True, + 'main_brush_work_time': True, + 'side_brush_work_time': True, + }) +# --- # name: test_is_consumable_field_supported[home_data_device_saros_10r.json] dict({ 'filter_work_time': True, diff --git a/tests/mock_data.py b/tests/mock_data.py index 73292c3b..abb996c9 100644 --- a/tests/mock_data.py +++ b/tests/mock_data.py @@ -133,13 +133,15 @@ SS07_PRODUCT_DATA = PRODUCTS["home_data_product_ss07.json"] A102_PRODUCT_DATA = PRODUCTS["home_data_product_a102.json"] A114_PRODUCT_DATA = PRODUCTS["home_data_product_a114.json"] +A147_PRODUCT_DATA = PRODUCTS["home_data_product_a147.json"] # Devices -S7_DEVICE_DATA = DEVICES["home_data_device_s7_maxv.json"] +S7_MAXV_DEVICE_DATA = DEVICES["home_data_device_s7_maxv.json"] Q7_DEVICE_DATA = DEVICES["home_data_device_q7.json"] Q10_DEVICE_DATA = DEVICES["home_data_device_q10.json"] ZEO_ONE_DEVICE_DATA = DEVICES["home_data_device_zeo_one.json"] SAROS_10R_DEVICE_DATA = DEVICES["home_data_device_saros_10r.json"] +SAROS_10_DEVICE_DATA = DEVICES["home_data_device_saros.json"] HOME_DATA_RAW: dict[str, Any] = { @@ -152,7 +154,7 @@ A27_PRODUCT_DATA, ], "devices": [ - S7_DEVICE_DATA, + S7_MAXV_DEVICE_DATA, ], "receivedDevices": [], "rooms": [ diff --git a/tests/testdata/home_data_device_saros.json b/tests/testdata/home_data_device_saros.json new file mode 100644 index 00000000..76d41b5d --- /dev/null +++ b/tests/testdata/home_data_device_saros.json @@ -0,0 +1,36 @@ +{ + "duid": "device-id-saros-10", + "name": "Saros 10", + "localKey": "key123key123key1", + "productId": "product-saros-10", + "fv": "02.33.20", + "activeTime": 1672364449, + "timeZoneId": "Europe/Stockholm", + "iconUrl": "", + "share": false, + "online": true, + "pv": "1.0", + "tuyaMigrated": false, + "extra": "{}", + "sn": "device-saros-10-sn", + "featureSet": "4499195120484351", + "newFeatureSet": "0000000008EFBCDDDFFFAE7E7EFEFFFF", + "deviceStatus": { + "121": 8, + "122": 93, + "123": 102, + "124": 200, + "125": 100, + "126": 98, + "127": 100, + "128": 0, + "133": 1, + "135": 0, + "120": 0, + "134": 0 + }, + "silentOtaSwitch": false, + "f": false, + "createTime": 1766246477, + "cid": "" +} diff --git a/tests/testdata/home_data_product_a147.json b/tests/testdata/home_data_product_a147.json new file mode 100644 index 00000000..c190f854 --- /dev/null +++ b/tests/testdata/home_data_product_a147.json @@ -0,0 +1,143 @@ +{ + "id": "product-saros-10", + "name": "Saros 10", + "model": "roborock.vacuum.a147", + "category": "robot.vacuum.cleaner", + "capability": 0, + "schema": [ + { + "id": 101, + "name": "rpc_request", + "code": "rpc_request", + "mode": "rw", + "type": "RAW" + }, + { + "id": 102, + "name": "rpc_response", + "code": "rpc_response", + "mode": "rw", + "type": "RAW" + }, + { + "id": 120, + "name": "\u9519\u8bef\u4ee3\u7801", + "code": "error_code", + "mode": "ro", + "type": "ENUM", + "property": "{\"range\": [\"\"]}" + }, + { + "id": 121, + "name": "\u8bbe\u5907\u72b6\u6001", + "code": "state", + "mode": "ro", + "type": "ENUM", + "property": "{\"range\": [\"\"]}" + }, + { + "id": 122, + "name": "\u8bbe\u5907\u7535\u91cf", + "code": "battery", + "mode": "ro", + "type": "ENUM", + "property": "{\"range\": [\"\"]}" + }, + { + "id": 123, + "name": "\u6e05\u626b\u6a21\u5f0f", + "code": "fan_power", + "mode": "rw", + "type": "ENUM", + "property": "{\"range\": [\"\"]}" + }, + { + "id": 124, + "name": "\u62d6\u5730\u6a21\u5f0f", + "code": "water_box_mode", + "mode": "rw", + "type": "ENUM", + "property": "{\"range\": [\"\"]}" + }, + { + "id": 125, + "name": "\u4e3b\u5237\u5bff\u547d", + "code": "main_brush_life", + "mode": "rw", + "type": "VALUE", + "property": "{\"max\": 100, \"min\": 0, \"step\": 1, \"unit\": \"null\", \"scale\": 1}" + }, + { + "id": 126, + "name": "\u8fb9\u5237\u5bff\u547d", + "code": "side_brush_life", + "mode": "rw", + "type": "VALUE", + "property": "{\"max\": 100, \"min\": 0, \"step\": 1, \"unit\": \"null\", \"scale\": 1}" + }, + { + "id": 127, + "name": "\u6ee4\u7f51\u5bff\u547d", + "code": "filter_life", + "mode": "rw", + "type": "VALUE", + "property": "{\"max\": 100, \"min\": 0, \"step\": 1, \"unit\": \"null\", \"scale\": 1}" + }, + { + "id": 128, + "name": "\u989d\u5916\u72b6\u6001", + "code": "additional_props", + "mode": "ro", + "type": "RAW" + }, + { + "id": 130, + "name": "\u5b8c\u6210\u4e8b\u4ef6", + "code": "task_complete", + "mode": "ro", + "type": "RAW" + }, + { + "id": 131, + "name": "\u7535\u91cf\u4e0d\u8db3\u4efb\u52a1\u53d6\u6d88", + "code": "task_cancel_low_power", + "mode": "ro", + "type": "RAW" + }, + { + "id": 132, + "name": "\u8fd0\u52a8\u4e2d\u4efb\u52a1\u53d6\u6d88", + "code": "task_cancel_in_motion", + "mode": "ro", + "type": "RAW" + }, + { + "id": 133, + "name": "\u5145\u7535\u72b6\u6001", + "code": "charge_status", + "mode": "ro", + "type": "RAW" + }, + { + "id": 134, + "name": "\u70d8\u5e72\u72b6\u6001", + "code": "drying_status", + "mode": "ro", + "type": "RAW" + }, + { + "id": 135, + "name": "\u79bb\u7ebf\u539f\u56e0\u7ec6\u5206", + "code": "offline_status", + "mode": "ro", + "type": "RAW" + }, + { + "id": 139, + "name": "\u56de\u57fa\u7ad9\u76ee\u7684", + "code": "back_type", + "mode": "ro", + "type": "RAW" + } + ] +} From aa8de5ef60108e6f009706c21354468dbf356a25 Mon Sep 17 00:00:00 2001 From: Allen Porter Date: Sun, 5 Apr 2026 08:28:55 -0700 Subject: [PATCH 2/6] test: add property-based testing for device features using paired mock data --- .../test_supported_features.ambr | 1409 +++++++++++++++++ .../__snapshots__/test_device_features.ambr | 18 + tests/mock_data.py | 13 + tests/test_supported_features.py | 31 + tests/testdata/home_data_device_a123.json | 33 + tests/testdata/home_data_product_a123.json | 136 ++ 6 files changed, 1640 insertions(+) create mode 100644 tests/__snapshots__/test_supported_features.ambr create mode 100644 tests/testdata/home_data_device_a123.json create mode 100644 tests/testdata/home_data_product_a123.json diff --git a/tests/__snapshots__/test_supported_features.ambr b/tests/__snapshots__/test_supported_features.ambr new file mode 100644 index 00000000..acd4a661 --- /dev/null +++ b/tests/__snapshots__/test_supported_features.ambr @@ -0,0 +1,1409 @@ +# serializer version: 1 +# name: test_device_features_from_home_data[home_data_device_a123.json] + dict({ + 'is_activate_video_charging_and_standby_supported': False, + 'is_analysis_supported': False, + 'is_any_state_transit_goto_supported': True, + 'is_auto_collection_2_supported': True, + 'is_auto_delivery_field_in_global_status_supported': True, + 'is_auto_tear_down_mop_supported': False, + 'is_avoid_collision_mode_supported': True, + 'is_avoid_collision_supported': True, + 'is_back_charge_auto_wash_supported': True, + 'is_back_wash_new_smart_supported': False, + 'is_careful_slow_mop_supported': True, + 'is_carpet_custom_clean_supported': True, + 'is_carpet_deep_clean_supported': True, + 'is_carpet_long_haired_ex_supported': False, + 'is_carpet_long_haired_supported': False, + 'is_carpet_pressure_use_origin_paras_supported': False, + 'is_carpet_shape_type_supported': False, + 'is_carpet_show_on_map': True, + 'is_carpet_supported': True, + 'is_ces_2022_supported': False, + 'is_clean_count_setting_supported': True, + 'is_clean_direct_status_supported': False, + 'is_clean_efficiency_supported': False, + 'is_clean_fluid_delivery_supported': False, + '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': True, + 'is_clean_then_mop_mode_supported': False, + 'is_clean_time_line_supported': False, + 'is_collect_dust_count_show_supported': False, + 'is_collect_dust_mode_supported': True, + 'is_corner_clean_mode_supported': False, + 'is_corner_mop_stretch_supported': True, + 'is_ctm_with_repeat_supported': False, + 'is_current_map_restore_enabled': True, + 'is_custom_clean_mode_count_supported': True, + 'is_custom_mode_supported': True, + 'is_custom_water_box_distance_supported': True, + 'is_customized_clean_supported': True, + 'is_detect_wire_carpet_supported': False, + 'is_dirty_object_detect_supported': False, + 'is_dirty_replenish_clean_supported': False, + 'is_dry_interval_timer_supported': False, + 'is_dss_believable': True, + 'is_dual_band_wi_fi_supported': False, + 'is_dust_collection_setting_supported': True, + 'is_dynamically_add_clean_zones_supported': True, + 'is_dynamically_skip_clean_zone_supported': True, + 'is_egg_dance_mode_supported': False, + 'is_egg_mode_supported_from_new_features': False, + 'is_exact_custom_mode_supported': True, + 'is_exhibition_function_supported': False, + 'is_floor_dir_clean_any_time_supported': True, + 'is_flow_led_setting_supported': False, + 'is_follow_low_obs_supported': False, + 'is_full_duples_switch_supported': False, + 'is_fw_filter_obstacle_supported': True, + 'is_gap_deep_clean_supported': False, + 'is_goto_pure_clean_path_supported': True, + 'is_hot_wash_towel_supported': False, + 'is_identify_room_supported': False, + 'is_ignore_unknown_map_object_supported': True, + 'is_lds_lifting_supported': False, + 'is_led_status_switch_supported': False, + 'is_left_water_drain_supported': True, + 'is_low_area_access_supported': False, + 'is_main_brush_up_down_supported_from_str': False, + 'is_map_beautify_internal_debug_supported': True, + 'is_map_carpet_add_support': True, + 'is_map_eraser_supported': False, + 'is_matter_supported': False, + 'is_max_plus_mode_supported': True, + 'is_max_zone_opened_supported': False, + 'is_mechanical_arm_mode_supported': False, + 'is_midway_back_to_dock_supported': False, + 'is_min_battery_15_to_clean_task_supported': True, + 'is_mop_forbidden_supported': False, + 'is_mop_path_supported': True, + 'is_mop_shake_module_supported': False, + 'is_mop_shake_water_max_supported': False, + 'is_multi_floor_supported': False, + 'is_multi_map_segment_timer_supported': True, + 'is_new_ai_recognition_supported': True, + 'is_new_data_for_clean_history': True, + 'is_new_data_for_clean_history_detail': True, + 'is_new_endpoint_supported': True, + 'is_new_remote_view_supported': False, + 'is_no_need_carpet_press_set_supported': True, + 'is_none_pure_clean_mop_with_max_plus': False, + 'is_object_detect_check_supported': False, + 'is_offline_map_supported': True, + 'is_optimize_battery_supported': False, + 'is_order_clean_supported': False, + 'is_over_sea_ctm_supported': False, + 'is_pet_snapshot_supported': False, + 'is_pet_supplies_deep_clean_supported': True, + 'is_program_mode_supported': False, + 'is_pumping_water_supported': False, + 'is_pure_clean_mop_supported': True, + 'is_re_segment_supported': True, + 'is_record_allowed': True, + 'is_remote_supported': False, + 'is_right_brush_stretch_supported': False, + 'is_room_name_supported': True, + 'is_rpc_retry_supported': True, + 'is_rubber_brush_carpet_supported': False, + 'is_set_child_supported': True, + 'is_setting_carpet_first_supported': True, + 'is_shake_mop_set_supported': True, + 'is_should_show_arm_over_load_supported': False, + 'is_show_clean_finish_reason_supported': True, + 'is_show_general_obstacle_supported': False, + 'is_show_obstacle_photo_supported': False, + 'is_side_brush_lift_carpet_supported': False, + 'is_small_side_mop_supported': False, + 'is_smart_clean_mode_set_supported': True, + 'is_soak_and_wash_supported': False, + 'is_soft_clean_mode_supported': False, + 'is_sr_map_supported': False, + 'is_super_deep_wash_supported': True, + 'is_support_api_app_stop_grasp_supported': False, + 'is_support_backup_map': True, + 'is_support_clean_estimate': True, + 'is_support_cliff_zone': True, + 'is_support_custom_carpet': False, + 'is_support_custom_dnd': True, + 'is_support_custom_door_sill': True, + 'is_support_custom_mode_in_cleaning': True, + 'is_support_fetch_timer_summary': False, + 'is_support_floor_direction': True, + 'is_support_floor_edit': True, + 'is_support_furniture': True, + 'is_support_get_particular_status_supported': False, + 'is_support_incremental_map': True, + 'is_support_main_brush_up_down_supported': False, + 'is_support_mop_back_pwm_set': False, + 'is_support_quick_map_builder': True, + 'is_support_remote_control_in_call': False, + 'is_support_room_tag': True, + 'is_support_set_switch_map_mode': True, + 'is_support_set_volume_in_call': False, + 'is_support_side_brush_up_down_supported': False, + 'is_support_smart_door_sill': True, + 'is_support_smart_global_clean_with_custom_mode': True, + 'is_support_smart_scene': True, + 'is_support_stuck_zone': True, + 'is_support_voice_control_debug': False, + 'is_support_water_mode': True, + 'is_supported_download_test_voice': True, + 'is_supported_drying': True, + 'is_supported_valley_electricity': True, + 'is_sync_server_name_supported': False, + 'is_three_d_mapping_inner_test_supported': False, + 'is_tidyup_zones_supported': False, + 'is_two_gears_no_collision_supported': False, + 'is_two_key_real_time_video_supported': False, + 'is_two_key_rtv_in_charging_supported': False, + 'is_type_identify_supported': False, + 'is_unsave_map_reason_supported': True, + 'is_uvc_sterilize_supported': False, + 'is_video_monitor_supported': True, + 'is_video_patrol_supported': False, + 'is_video_setting_supported': True, + 'is_voice_control_led_supported': False, + 'is_voice_control_supported': False, + 'is_wash_then_charge_cmd_supported': True, + 'is_water_leak_check_supported': False, + 'is_water_slide_mode_supported': False, + 'is_water_up_down_drain_supported': True, + 'is_wifi_manage_supported': True, + 'is_workday_holiday_supported': False, + }) +# --- +# name: test_device_features_from_home_data[home_data_device_q10.json] + dict({ + 'is_activate_video_charging_and_standby_supported': False, + 'is_analysis_supported': False, + 'is_any_state_transit_goto_supported': False, + 'is_auto_collection_2_supported': False, + 'is_auto_delivery_field_in_global_status_supported': False, + 'is_auto_tear_down_mop_supported': False, + 'is_avoid_collision_mode_supported': False, + 'is_avoid_collision_supported': False, + 'is_back_charge_auto_wash_supported': False, + 'is_back_wash_new_smart_supported': False, + 'is_careful_slow_mop_supported': False, + 'is_carpet_custom_clean_supported': False, + 'is_carpet_deep_clean_supported': False, + 'is_carpet_long_haired_ex_supported': False, + 'is_carpet_long_haired_supported': False, + 'is_carpet_pressure_use_origin_paras_supported': False, + 'is_carpet_shape_type_supported': False, + 'is_carpet_show_on_map': False, + 'is_carpet_supported': False, + 'is_ces_2022_supported': False, + 'is_clean_count_setting_supported': False, + 'is_clean_direct_status_supported': False, + 'is_clean_efficiency_supported': False, + 'is_clean_fluid_delivery_supported': False, + 'is_clean_history_time_line_supported': False, + 'is_clean_route_deep_slow_plus_supported': False, + 'is_clean_route_fast_mode_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, + 'is_collect_dust_mode_supported': True, + 'is_corner_clean_mode_supported': False, + 'is_corner_mop_stretch_supported': False, + 'is_ctm_with_repeat_supported': False, + 'is_current_map_restore_enabled': False, + 'is_custom_clean_mode_count_supported': False, + 'is_custom_mode_supported': True, + 'is_custom_water_box_distance_supported': False, + 'is_customized_clean_supported': True, + 'is_detect_wire_carpet_supported': False, + 'is_dirty_object_detect_supported': False, + 'is_dirty_replenish_clean_supported': False, + 'is_dry_interval_timer_supported': False, + 'is_dss_believable': False, + 'is_dual_band_wi_fi_supported': False, + 'is_dust_collection_setting_supported': False, + 'is_dynamically_add_clean_zones_supported': False, + 'is_dynamically_skip_clean_zone_supported': False, + 'is_egg_dance_mode_supported': False, + 'is_egg_mode_supported_from_new_features': False, + 'is_exact_custom_mode_supported': False, + 'is_exhibition_function_supported': False, + 'is_floor_dir_clean_any_time_supported': False, + 'is_flow_led_setting_supported': False, + 'is_follow_low_obs_supported': False, + 'is_full_duples_switch_supported': False, + 'is_fw_filter_obstacle_supported': False, + 'is_gap_deep_clean_supported': False, + 'is_goto_pure_clean_path_supported': False, + 'is_hot_wash_towel_supported': False, + 'is_identify_room_supported': False, + 'is_ignore_unknown_map_object_supported': False, + 'is_lds_lifting_supported': False, + 'is_led_status_switch_supported': False, + 'is_left_water_drain_supported': False, + 'is_low_area_access_supported': False, + 'is_main_brush_up_down_supported_from_str': False, + 'is_map_beautify_internal_debug_supported': False, + 'is_map_carpet_add_support': False, + 'is_map_eraser_supported': False, + 'is_matter_supported': False, + 'is_max_plus_mode_supported': True, + 'is_max_zone_opened_supported': False, + 'is_mechanical_arm_mode_supported': False, + 'is_midway_back_to_dock_supported': False, + 'is_min_battery_15_to_clean_task_supported': False, + 'is_mop_forbidden_supported': False, + 'is_mop_path_supported': False, + 'is_mop_shake_module_supported': False, + 'is_mop_shake_water_max_supported': False, + 'is_multi_floor_supported': False, + 'is_multi_map_segment_timer_supported': False, + 'is_new_ai_recognition_supported': False, + 'is_new_data_for_clean_history': False, + 'is_new_data_for_clean_history_detail': False, + 'is_new_endpoint_supported': False, + 'is_new_remote_view_supported': True, + 'is_no_need_carpet_press_set_supported': False, + 'is_none_pure_clean_mop_with_max_plus': False, + 'is_object_detect_check_supported': False, + 'is_offline_map_supported': False, + 'is_optimize_battery_supported': False, + 'is_order_clean_supported': False, + 'is_over_sea_ctm_supported': False, + 'is_pet_snapshot_supported': False, + 'is_pet_supplies_deep_clean_supported': False, + 'is_program_mode_supported': False, + 'is_pumping_water_supported': False, + 'is_pure_clean_mop_supported': True, + 'is_re_segment_supported': False, + 'is_record_allowed': False, + 'is_remote_supported': False, + 'is_right_brush_stretch_supported': False, + 'is_room_name_supported': False, + 'is_rpc_retry_supported': False, + 'is_rubber_brush_carpet_supported': False, + 'is_set_child_supported': False, + 'is_setting_carpet_first_supported': False, + 'is_shake_mop_set_supported': False, + 'is_should_show_arm_over_load_supported': False, + 'is_show_clean_finish_reason_supported': False, + 'is_show_general_obstacle_supported': False, + 'is_show_obstacle_photo_supported': False, + 'is_side_brush_lift_carpet_supported': False, + 'is_small_side_mop_supported': False, + 'is_smart_clean_mode_set_supported': False, + 'is_soak_and_wash_supported': False, + 'is_soft_clean_mode_supported': False, + 'is_sr_map_supported': False, + 'is_super_deep_wash_supported': False, + 'is_support_api_app_stop_grasp_supported': False, + 'is_support_backup_map': False, + 'is_support_clean_estimate': False, + 'is_support_cliff_zone': False, + 'is_support_custom_carpet': False, + 'is_support_custom_dnd': False, + 'is_support_custom_door_sill': False, + 'is_support_custom_mode_in_cleaning': False, + 'is_support_fetch_timer_summary': False, + 'is_support_floor_direction': False, + 'is_support_floor_edit': False, + 'is_support_furniture': False, + 'is_support_get_particular_status_supported': False, + 'is_support_incremental_map': False, + 'is_support_main_brush_up_down_supported': False, + 'is_support_mop_back_pwm_set': False, + 'is_support_quick_map_builder': False, + 'is_support_remote_control_in_call': False, + 'is_support_room_tag': False, + 'is_support_set_switch_map_mode': False, + 'is_support_set_volume_in_call': False, + 'is_support_side_brush_up_down_supported': False, + 'is_support_smart_door_sill': False, + 'is_support_smart_global_clean_with_custom_mode': False, + 'is_support_smart_scene': False, + 'is_support_stuck_zone': False, + 'is_support_voice_control_debug': False, + 'is_support_water_mode': True, + 'is_supported_download_test_voice': False, + 'is_supported_drying': False, + 'is_supported_valley_electricity': False, + 'is_sync_server_name_supported': False, + 'is_three_d_mapping_inner_test_supported': False, + 'is_tidyup_zones_supported': False, + 'is_two_gears_no_collision_supported': False, + 'is_two_key_real_time_video_supported': False, + 'is_two_key_rtv_in_charging_supported': False, + 'is_type_identify_supported': False, + 'is_unsave_map_reason_supported': False, + 'is_uvc_sterilize_supported': False, + 'is_video_monitor_supported': False, + 'is_video_patrol_supported': False, + 'is_video_setting_supported': False, + 'is_voice_control_led_supported': False, + 'is_voice_control_supported': False, + 'is_wash_then_charge_cmd_supported': False, + 'is_water_leak_check_supported': False, + 'is_water_slide_mode_supported': False, + 'is_water_up_down_drain_supported': False, + 'is_wifi_manage_supported': False, + 'is_workday_holiday_supported': False, + }) +# --- +# name: test_device_features_from_home_data[home_data_device_q7.json] + dict({ + 'is_activate_video_charging_and_standby_supported': False, + 'is_analysis_supported': False, + 'is_any_state_transit_goto_supported': False, + 'is_auto_collection_2_supported': False, + 'is_auto_delivery_field_in_global_status_supported': False, + 'is_auto_tear_down_mop_supported': False, + 'is_avoid_collision_mode_supported': False, + 'is_avoid_collision_supported': False, + 'is_back_charge_auto_wash_supported': False, + 'is_back_wash_new_smart_supported': False, + 'is_careful_slow_mop_supported': False, + 'is_carpet_custom_clean_supported': False, + 'is_carpet_deep_clean_supported': False, + 'is_carpet_long_haired_ex_supported': False, + 'is_carpet_long_haired_supported': False, + 'is_carpet_pressure_use_origin_paras_supported': False, + 'is_carpet_shape_type_supported': False, + 'is_carpet_show_on_map': False, + 'is_carpet_supported': False, + 'is_ces_2022_supported': False, + 'is_clean_count_setting_supported': False, + 'is_clean_direct_status_supported': False, + 'is_clean_efficiency_supported': False, + 'is_clean_fluid_delivery_supported': False, + 'is_clean_history_time_line_supported': False, + 'is_clean_route_deep_slow_plus_supported': False, + 'is_clean_route_fast_mode_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, + 'is_collect_dust_mode_supported': True, + 'is_corner_clean_mode_supported': False, + 'is_corner_mop_stretch_supported': False, + 'is_ctm_with_repeat_supported': False, + 'is_current_map_restore_enabled': False, + 'is_custom_clean_mode_count_supported': False, + 'is_custom_mode_supported': True, + 'is_custom_water_box_distance_supported': False, + 'is_customized_clean_supported': True, + 'is_detect_wire_carpet_supported': False, + 'is_dirty_object_detect_supported': False, + 'is_dirty_replenish_clean_supported': False, + 'is_dry_interval_timer_supported': False, + 'is_dss_believable': False, + 'is_dual_band_wi_fi_supported': False, + 'is_dust_collection_setting_supported': False, + 'is_dynamically_add_clean_zones_supported': False, + 'is_dynamically_skip_clean_zone_supported': False, + 'is_egg_dance_mode_supported': False, + 'is_egg_mode_supported_from_new_features': False, + 'is_exact_custom_mode_supported': False, + 'is_exhibition_function_supported': False, + 'is_floor_dir_clean_any_time_supported': False, + 'is_flow_led_setting_supported': False, + 'is_follow_low_obs_supported': False, + 'is_full_duples_switch_supported': False, + 'is_fw_filter_obstacle_supported': False, + 'is_gap_deep_clean_supported': False, + 'is_goto_pure_clean_path_supported': False, + 'is_hot_wash_towel_supported': False, + 'is_identify_room_supported': False, + 'is_ignore_unknown_map_object_supported': False, + 'is_lds_lifting_supported': False, + 'is_led_status_switch_supported': False, + 'is_left_water_drain_supported': False, + 'is_low_area_access_supported': False, + 'is_main_brush_up_down_supported_from_str': False, + 'is_map_beautify_internal_debug_supported': False, + 'is_map_carpet_add_support': False, + 'is_map_eraser_supported': False, + 'is_matter_supported': False, + 'is_max_plus_mode_supported': True, + 'is_max_zone_opened_supported': False, + 'is_mechanical_arm_mode_supported': False, + 'is_midway_back_to_dock_supported': False, + 'is_min_battery_15_to_clean_task_supported': False, + 'is_mop_forbidden_supported': False, + 'is_mop_path_supported': False, + 'is_mop_shake_module_supported': False, + 'is_mop_shake_water_max_supported': False, + 'is_multi_floor_supported': False, + 'is_multi_map_segment_timer_supported': False, + 'is_new_ai_recognition_supported': False, + 'is_new_data_for_clean_history': False, + 'is_new_data_for_clean_history_detail': False, + 'is_new_endpoint_supported': False, + 'is_new_remote_view_supported': True, + 'is_no_need_carpet_press_set_supported': False, + 'is_none_pure_clean_mop_with_max_plus': False, + 'is_object_detect_check_supported': False, + 'is_offline_map_supported': False, + 'is_optimize_battery_supported': False, + 'is_order_clean_supported': False, + 'is_over_sea_ctm_supported': False, + 'is_pet_snapshot_supported': False, + 'is_pet_supplies_deep_clean_supported': False, + 'is_program_mode_supported': False, + 'is_pumping_water_supported': False, + 'is_pure_clean_mop_supported': True, + 'is_re_segment_supported': False, + 'is_record_allowed': False, + 'is_remote_supported': False, + 'is_right_brush_stretch_supported': False, + 'is_room_name_supported': False, + 'is_rpc_retry_supported': False, + 'is_rubber_brush_carpet_supported': False, + 'is_set_child_supported': False, + 'is_setting_carpet_first_supported': False, + 'is_shake_mop_set_supported': False, + 'is_should_show_arm_over_load_supported': False, + 'is_show_clean_finish_reason_supported': False, + 'is_show_general_obstacle_supported': False, + 'is_show_obstacle_photo_supported': False, + 'is_side_brush_lift_carpet_supported': False, + 'is_small_side_mop_supported': False, + 'is_smart_clean_mode_set_supported': False, + 'is_soak_and_wash_supported': False, + 'is_soft_clean_mode_supported': False, + 'is_sr_map_supported': False, + 'is_super_deep_wash_supported': False, + 'is_support_api_app_stop_grasp_supported': False, + 'is_support_backup_map': False, + 'is_support_clean_estimate': False, + 'is_support_cliff_zone': False, + 'is_support_custom_carpet': False, + 'is_support_custom_dnd': False, + 'is_support_custom_door_sill': False, + 'is_support_custom_mode_in_cleaning': False, + 'is_support_fetch_timer_summary': False, + 'is_support_floor_direction': False, + 'is_support_floor_edit': False, + 'is_support_furniture': False, + 'is_support_get_particular_status_supported': False, + 'is_support_incremental_map': False, + 'is_support_main_brush_up_down_supported': False, + 'is_support_mop_back_pwm_set': False, + 'is_support_quick_map_builder': False, + 'is_support_remote_control_in_call': False, + 'is_support_room_tag': False, + 'is_support_set_switch_map_mode': False, + 'is_support_set_volume_in_call': False, + 'is_support_side_brush_up_down_supported': False, + 'is_support_smart_door_sill': False, + 'is_support_smart_global_clean_with_custom_mode': False, + 'is_support_smart_scene': False, + 'is_support_stuck_zone': False, + 'is_support_voice_control_debug': False, + 'is_support_water_mode': True, + 'is_supported_download_test_voice': False, + 'is_supported_drying': False, + 'is_supported_valley_electricity': False, + 'is_sync_server_name_supported': False, + 'is_three_d_mapping_inner_test_supported': False, + 'is_tidyup_zones_supported': False, + 'is_two_gears_no_collision_supported': False, + 'is_two_key_real_time_video_supported': False, + 'is_two_key_rtv_in_charging_supported': False, + 'is_type_identify_supported': False, + 'is_unsave_map_reason_supported': False, + 'is_uvc_sterilize_supported': False, + 'is_video_monitor_supported': False, + 'is_video_patrol_supported': False, + 'is_video_setting_supported': False, + 'is_voice_control_led_supported': False, + 'is_voice_control_supported': False, + 'is_wash_then_charge_cmd_supported': False, + 'is_water_leak_check_supported': False, + 'is_water_slide_mode_supported': False, + 'is_water_up_down_drain_supported': False, + 'is_wifi_manage_supported': False, + 'is_workday_holiday_supported': False, + }) +# --- +# name: test_device_features_from_home_data[home_data_device_s5e.json] + dict({ + 'is_activate_video_charging_and_standby_supported': False, + 'is_analysis_supported': False, + 'is_any_state_transit_goto_supported': False, + 'is_auto_collection_2_supported': False, + 'is_auto_delivery_field_in_global_status_supported': False, + 'is_auto_tear_down_mop_supported': False, + 'is_avoid_collision_mode_supported': False, + 'is_avoid_collision_supported': False, + 'is_back_charge_auto_wash_supported': False, + 'is_back_wash_new_smart_supported': False, + 'is_careful_slow_mop_supported': False, + 'is_carpet_custom_clean_supported': False, + 'is_carpet_deep_clean_supported': False, + 'is_carpet_long_haired_ex_supported': False, + 'is_carpet_long_haired_supported': False, + 'is_carpet_pressure_use_origin_paras_supported': False, + 'is_carpet_shape_type_supported': False, + 'is_carpet_show_on_map': False, + 'is_carpet_supported': False, + 'is_ces_2022_supported': False, + 'is_clean_count_setting_supported': False, + 'is_clean_direct_status_supported': False, + 'is_clean_efficiency_supported': False, + 'is_clean_fluid_delivery_supported': False, + 'is_clean_history_time_line_supported': False, + 'is_clean_route_deep_slow_plus_supported': False, + 'is_clean_route_fast_mode_supported': False, + 'is_clean_route_setting_supported': False, + 'is_clean_then_mop_mode_supported': False, + 'is_clean_time_line_supported': False, + 'is_collect_dust_count_show_supported': False, + 'is_collect_dust_mode_supported': True, + 'is_corner_clean_mode_supported': False, + 'is_corner_mop_stretch_supported': False, + 'is_ctm_with_repeat_supported': False, + 'is_current_map_restore_enabled': False, + 'is_custom_clean_mode_count_supported': False, + 'is_custom_mode_supported': True, + 'is_custom_water_box_distance_supported': False, + 'is_customized_clean_supported': False, + 'is_detect_wire_carpet_supported': False, + 'is_dirty_object_detect_supported': False, + 'is_dirty_replenish_clean_supported': False, + 'is_dry_interval_timer_supported': False, + 'is_dss_believable': False, + 'is_dual_band_wi_fi_supported': False, + 'is_dust_collection_setting_supported': False, + 'is_dynamically_add_clean_zones_supported': False, + 'is_dynamically_skip_clean_zone_supported': False, + 'is_egg_dance_mode_supported': False, + 'is_egg_mode_supported_from_new_features': False, + 'is_exact_custom_mode_supported': False, + 'is_exhibition_function_supported': False, + 'is_floor_dir_clean_any_time_supported': False, + 'is_flow_led_setting_supported': False, + 'is_follow_low_obs_supported': False, + 'is_full_duples_switch_supported': False, + 'is_fw_filter_obstacle_supported': False, + 'is_gap_deep_clean_supported': False, + 'is_goto_pure_clean_path_supported': False, + 'is_hot_wash_towel_supported': False, + 'is_identify_room_supported': False, + 'is_ignore_unknown_map_object_supported': False, + 'is_lds_lifting_supported': False, + 'is_led_status_switch_supported': False, + 'is_left_water_drain_supported': False, + 'is_low_area_access_supported': False, + 'is_main_brush_up_down_supported_from_str': False, + 'is_map_beautify_internal_debug_supported': False, + 'is_map_carpet_add_support': False, + 'is_map_eraser_supported': False, + 'is_matter_supported': False, + 'is_max_plus_mode_supported': False, + 'is_max_zone_opened_supported': False, + 'is_mechanical_arm_mode_supported': False, + 'is_midway_back_to_dock_supported': False, + 'is_min_battery_15_to_clean_task_supported': False, + 'is_mop_forbidden_supported': True, + 'is_mop_path_supported': False, + 'is_mop_shake_module_supported': False, + 'is_mop_shake_water_max_supported': False, + 'is_multi_floor_supported': False, + 'is_multi_map_segment_timer_supported': False, + 'is_new_ai_recognition_supported': False, + 'is_new_data_for_clean_history': False, + 'is_new_data_for_clean_history_detail': False, + 'is_new_endpoint_supported': False, + 'is_new_remote_view_supported': False, + 'is_no_need_carpet_press_set_supported': False, + 'is_none_pure_clean_mop_with_max_plus': False, + 'is_object_detect_check_supported': False, + 'is_offline_map_supported': False, + 'is_optimize_battery_supported': False, + 'is_order_clean_supported': False, + 'is_over_sea_ctm_supported': False, + 'is_pet_snapshot_supported': False, + 'is_pet_supplies_deep_clean_supported': False, + 'is_program_mode_supported': False, + 'is_pumping_water_supported': False, + 'is_pure_clean_mop_supported': False, + 'is_re_segment_supported': False, + 'is_record_allowed': False, + 'is_remote_supported': False, + 'is_right_brush_stretch_supported': False, + 'is_room_name_supported': False, + 'is_rpc_retry_supported': False, + 'is_rubber_brush_carpet_supported': False, + 'is_set_child_supported': False, + 'is_setting_carpet_first_supported': False, + 'is_shake_mop_set_supported': False, + 'is_should_show_arm_over_load_supported': False, + 'is_show_clean_finish_reason_supported': False, + 'is_show_general_obstacle_supported': False, + 'is_show_obstacle_photo_supported': False, + 'is_side_brush_lift_carpet_supported': False, + 'is_small_side_mop_supported': False, + 'is_smart_clean_mode_set_supported': False, + 'is_soak_and_wash_supported': False, + 'is_soft_clean_mode_supported': False, + 'is_sr_map_supported': False, + 'is_super_deep_wash_supported': False, + 'is_support_api_app_stop_grasp_supported': False, + 'is_support_backup_map': False, + 'is_support_clean_estimate': False, + 'is_support_cliff_zone': False, + 'is_support_custom_carpet': False, + 'is_support_custom_dnd': False, + 'is_support_custom_door_sill': False, + 'is_support_custom_mode_in_cleaning': False, + 'is_support_fetch_timer_summary': False, + 'is_support_floor_direction': False, + 'is_support_floor_edit': False, + 'is_support_furniture': False, + 'is_support_get_particular_status_supported': False, + 'is_support_incremental_map': False, + 'is_support_main_brush_up_down_supported': False, + 'is_support_mop_back_pwm_set': False, + 'is_support_quick_map_builder': False, + 'is_support_remote_control_in_call': False, + 'is_support_room_tag': False, + 'is_support_set_switch_map_mode': False, + 'is_support_set_volume_in_call': False, + 'is_support_side_brush_up_down_supported': False, + 'is_support_smart_door_sill': False, + 'is_support_smart_global_clean_with_custom_mode': False, + 'is_support_smart_scene': False, + 'is_support_stuck_zone': False, + 'is_support_voice_control_debug': False, + 'is_support_water_mode': True, + 'is_supported_download_test_voice': False, + 'is_supported_drying': False, + 'is_supported_valley_electricity': False, + 'is_sync_server_name_supported': False, + 'is_three_d_mapping_inner_test_supported': False, + 'is_tidyup_zones_supported': False, + 'is_two_gears_no_collision_supported': False, + 'is_two_key_real_time_video_supported': False, + 'is_two_key_rtv_in_charging_supported': False, + 'is_type_identify_supported': False, + 'is_unsave_map_reason_supported': False, + 'is_uvc_sterilize_supported': False, + 'is_video_monitor_supported': False, + 'is_video_patrol_supported': False, + 'is_video_setting_supported': False, + 'is_voice_control_led_supported': False, + 'is_voice_control_supported': False, + 'is_wash_then_charge_cmd_supported': False, + 'is_water_leak_check_supported': False, + 'is_water_slide_mode_supported': False, + 'is_water_up_down_drain_supported': False, + 'is_wifi_manage_supported': False, + 'is_workday_holiday_supported': False, + }) +# --- +# name: test_device_features_from_home_data[home_data_device_s7_maxv.json] + dict({ + 'is_activate_video_charging_and_standby_supported': False, + 'is_analysis_supported': False, + 'is_any_state_transit_goto_supported': True, + 'is_auto_collection_2_supported': False, + 'is_auto_delivery_field_in_global_status_supported': False, + 'is_auto_tear_down_mop_supported': False, + 'is_avoid_collision_mode_supported': False, + 'is_avoid_collision_supported': True, + 'is_back_charge_auto_wash_supported': False, + 'is_back_wash_new_smart_supported': False, + 'is_careful_slow_mop_supported': True, + 'is_carpet_custom_clean_supported': False, + 'is_carpet_deep_clean_supported': False, + 'is_carpet_long_haired_ex_supported': False, + 'is_carpet_long_haired_supported': False, + 'is_carpet_pressure_use_origin_paras_supported': False, + 'is_carpet_shape_type_supported': False, + 'is_carpet_show_on_map': False, + 'is_carpet_supported': True, + 'is_ces_2022_supported': False, + 'is_clean_count_setting_supported': False, + 'is_clean_direct_status_supported': False, + 'is_clean_efficiency_supported': False, + 'is_clean_fluid_delivery_supported': False, + 'is_clean_history_time_line_supported': False, + 'is_clean_route_deep_slow_plus_supported': False, + 'is_clean_route_fast_mode_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, + 'is_collect_dust_mode_supported': True, + 'is_corner_clean_mode_supported': False, + 'is_corner_mop_stretch_supported': False, + 'is_ctm_with_repeat_supported': False, + 'is_current_map_restore_enabled': True, + 'is_custom_clean_mode_count_supported': False, + 'is_custom_mode_supported': True, + 'is_custom_water_box_distance_supported': False, + 'is_customized_clean_supported': True, + 'is_detect_wire_carpet_supported': False, + 'is_dirty_object_detect_supported': False, + 'is_dirty_replenish_clean_supported': False, + 'is_dry_interval_timer_supported': False, + 'is_dss_believable': False, + 'is_dual_band_wi_fi_supported': False, + 'is_dust_collection_setting_supported': True, + 'is_dynamically_add_clean_zones_supported': False, + 'is_dynamically_skip_clean_zone_supported': False, + 'is_egg_dance_mode_supported': False, + 'is_egg_mode_supported_from_new_features': True, + 'is_exact_custom_mode_supported': False, + 'is_exhibition_function_supported': False, + 'is_floor_dir_clean_any_time_supported': False, + 'is_flow_led_setting_supported': True, + 'is_follow_low_obs_supported': False, + 'is_full_duples_switch_supported': False, + 'is_fw_filter_obstacle_supported': True, + 'is_gap_deep_clean_supported': False, + 'is_goto_pure_clean_path_supported': False, + 'is_hot_wash_towel_supported': False, + 'is_identify_room_supported': False, + 'is_ignore_unknown_map_object_supported': True, + 'is_lds_lifting_supported': False, + 'is_led_status_switch_supported': False, + 'is_left_water_drain_supported': False, + 'is_low_area_access_supported': False, + 'is_main_brush_up_down_supported_from_str': False, + 'is_map_beautify_internal_debug_supported': True, + 'is_map_carpet_add_support': True, + 'is_map_eraser_supported': False, + 'is_matter_supported': False, + 'is_max_plus_mode_supported': True, + 'is_max_zone_opened_supported': False, + 'is_mechanical_arm_mode_supported': False, + 'is_midway_back_to_dock_supported': False, + 'is_min_battery_15_to_clean_task_supported': False, + 'is_mop_forbidden_supported': True, + 'is_mop_path_supported': True, + 'is_mop_shake_module_supported': True, + 'is_mop_shake_water_max_supported': False, + 'is_multi_floor_supported': False, + 'is_multi_map_segment_timer_supported': True, + 'is_new_ai_recognition_supported': False, + 'is_new_data_for_clean_history': True, + 'is_new_data_for_clean_history_detail': True, + 'is_new_endpoint_supported': False, + 'is_new_remote_view_supported': True, + 'is_no_need_carpet_press_set_supported': False, + 'is_none_pure_clean_mop_with_max_plus': False, + 'is_object_detect_check_supported': False, + 'is_offline_map_supported': False, + 'is_optimize_battery_supported': False, + 'is_order_clean_supported': False, + 'is_over_sea_ctm_supported': False, + 'is_pet_snapshot_supported': False, + 'is_pet_supplies_deep_clean_supported': False, + 'is_program_mode_supported': False, + 'is_pumping_water_supported': False, + 'is_pure_clean_mop_supported': True, + 'is_re_segment_supported': True, + 'is_record_allowed': True, + 'is_remote_supported': False, + 'is_right_brush_stretch_supported': False, + 'is_room_name_supported': True, + 'is_rpc_retry_supported': True, + 'is_rubber_brush_carpet_supported': False, + 'is_set_child_supported': True, + 'is_setting_carpet_first_supported': False, + 'is_shake_mop_set_supported': True, + 'is_should_show_arm_over_load_supported': False, + 'is_show_clean_finish_reason_supported': True, + 'is_show_general_obstacle_supported': False, + 'is_show_obstacle_photo_supported': False, + 'is_side_brush_lift_carpet_supported': False, + 'is_small_side_mop_supported': False, + 'is_smart_clean_mode_set_supported': False, + 'is_soak_and_wash_supported': False, + 'is_soft_clean_mode_supported': False, + 'is_sr_map_supported': False, + 'is_super_deep_wash_supported': False, + 'is_support_api_app_stop_grasp_supported': False, + 'is_support_backup_map': True, + 'is_support_clean_estimate': False, + 'is_support_cliff_zone': False, + 'is_support_custom_carpet': False, + 'is_support_custom_dnd': False, + 'is_support_custom_door_sill': False, + 'is_support_custom_mode_in_cleaning': True, + 'is_support_fetch_timer_summary': False, + 'is_support_floor_direction': False, + 'is_support_floor_edit': True, + 'is_support_furniture': True, + 'is_support_get_particular_status_supported': False, + 'is_support_incremental_map': False, + 'is_support_main_brush_up_down_supported': False, + 'is_support_mop_back_pwm_set': False, + 'is_support_quick_map_builder': True, + 'is_support_remote_control_in_call': False, + 'is_support_room_tag': True, + 'is_support_set_switch_map_mode': True, + 'is_support_set_volume_in_call': True, + 'is_support_side_brush_up_down_supported': False, + 'is_support_smart_door_sill': False, + 'is_support_smart_global_clean_with_custom_mode': True, + 'is_support_smart_scene': True, + 'is_support_stuck_zone': False, + 'is_support_voice_control_debug': False, + 'is_support_water_mode': True, + 'is_supported_download_test_voice': True, + 'is_supported_drying': True, + 'is_supported_valley_electricity': True, + 'is_sync_server_name_supported': False, + 'is_three_d_mapping_inner_test_supported': False, + 'is_tidyup_zones_supported': False, + 'is_two_gears_no_collision_supported': False, + 'is_two_key_real_time_video_supported': False, + 'is_two_key_rtv_in_charging_supported': False, + 'is_type_identify_supported': False, + 'is_unsave_map_reason_supported': True, + 'is_uvc_sterilize_supported': False, + 'is_video_monitor_supported': True, + 'is_video_patrol_supported': False, + 'is_video_setting_supported': True, + 'is_voice_control_led_supported': False, + 'is_voice_control_supported': False, + 'is_wash_then_charge_cmd_supported': True, + 'is_water_leak_check_supported': False, + 'is_water_slide_mode_supported': False, + 'is_water_up_down_drain_supported': False, + 'is_wifi_manage_supported': False, + 'is_workday_holiday_supported': False, + }) +# --- +# name: test_device_features_from_home_data[home_data_device_saros.json] + dict({ + 'is_activate_video_charging_and_standby_supported': False, + 'is_analysis_supported': False, + 'is_any_state_transit_goto_supported': True, + 'is_auto_collection_2_supported': True, + 'is_auto_delivery_field_in_global_status_supported': True, + 'is_auto_tear_down_mop_supported': True, + 'is_avoid_collision_mode_supported': True, + 'is_avoid_collision_supported': True, + 'is_back_charge_auto_wash_supported': True, + 'is_back_wash_new_smart_supported': False, + 'is_careful_slow_mop_supported': True, + 'is_carpet_custom_clean_supported': True, + 'is_carpet_deep_clean_supported': True, + 'is_carpet_long_haired_ex_supported': False, + 'is_carpet_long_haired_supported': True, + 'is_carpet_pressure_use_origin_paras_supported': False, + 'is_carpet_shape_type_supported': False, + 'is_carpet_show_on_map': True, + 'is_carpet_supported': True, + 'is_ces_2022_supported': False, + 'is_clean_count_setting_supported': True, + 'is_clean_direct_status_supported': True, + 'is_clean_efficiency_supported': False, + 'is_clean_fluid_delivery_supported': False, + 'is_clean_history_time_line_supported': True, + 'is_clean_route_deep_slow_plus_supported': False, + 'is_clean_route_fast_mode_supported': True, + 'is_clean_route_setting_supported': True, + 'is_clean_then_mop_mode_supported': False, + 'is_clean_time_line_supported': True, + 'is_collect_dust_count_show_supported': False, + 'is_collect_dust_mode_supported': True, + 'is_corner_clean_mode_supported': False, + 'is_corner_mop_stretch_supported': False, + 'is_ctm_with_repeat_supported': False, + 'is_current_map_restore_enabled': True, + 'is_custom_clean_mode_count_supported': True, + 'is_custom_mode_supported': True, + 'is_custom_water_box_distance_supported': False, + 'is_customized_clean_supported': True, + 'is_detect_wire_carpet_supported': False, + 'is_dirty_object_detect_supported': True, + 'is_dirty_replenish_clean_supported': True, + 'is_dry_interval_timer_supported': True, + 'is_dss_believable': True, + 'is_dual_band_wi_fi_supported': False, + 'is_dust_collection_setting_supported': True, + 'is_dynamically_add_clean_zones_supported': True, + 'is_dynamically_skip_clean_zone_supported': True, + 'is_egg_dance_mode_supported': True, + 'is_egg_mode_supported_from_new_features': False, + 'is_exact_custom_mode_supported': True, + 'is_exhibition_function_supported': False, + 'is_floor_dir_clean_any_time_supported': True, + 'is_flow_led_setting_supported': False, + 'is_follow_low_obs_supported': False, + 'is_full_duples_switch_supported': False, + 'is_fw_filter_obstacle_supported': True, + 'is_gap_deep_clean_supported': True, + 'is_goto_pure_clean_path_supported': True, + 'is_hot_wash_towel_supported': True, + 'is_identify_room_supported': True, + 'is_ignore_unknown_map_object_supported': True, + 'is_lds_lifting_supported': True, + 'is_led_status_switch_supported': False, + 'is_left_water_drain_supported': True, + 'is_low_area_access_supported': False, + 'is_main_brush_up_down_supported_from_str': True, + 'is_map_beautify_internal_debug_supported': True, + 'is_map_carpet_add_support': True, + 'is_map_eraser_supported': True, + 'is_matter_supported': True, + 'is_max_plus_mode_supported': True, + 'is_max_zone_opened_supported': True, + 'is_mechanical_arm_mode_supported': False, + 'is_midway_back_to_dock_supported': True, + 'is_min_battery_15_to_clean_task_supported': True, + 'is_mop_forbidden_supported': False, + 'is_mop_path_supported': True, + 'is_mop_shake_module_supported': True, + 'is_mop_shake_water_max_supported': True, + 'is_multi_floor_supported': False, + 'is_multi_map_segment_timer_supported': True, + 'is_new_ai_recognition_supported': True, + 'is_new_data_for_clean_history': True, + 'is_new_data_for_clean_history_detail': True, + 'is_new_endpoint_supported': True, + 'is_new_remote_view_supported': True, + 'is_no_need_carpet_press_set_supported': True, + 'is_none_pure_clean_mop_with_max_plus': False, + 'is_object_detect_check_supported': True, + 'is_offline_map_supported': True, + 'is_optimize_battery_supported': False, + 'is_order_clean_supported': False, + 'is_over_sea_ctm_supported': False, + 'is_pet_snapshot_supported': True, + 'is_pet_supplies_deep_clean_supported': True, + 'is_program_mode_supported': False, + 'is_pumping_water_supported': False, + 'is_pure_clean_mop_supported': True, + 'is_re_segment_supported': True, + 'is_record_allowed': True, + 'is_remote_supported': False, + 'is_right_brush_stretch_supported': True, + 'is_room_name_supported': True, + 'is_rpc_retry_supported': True, + 'is_rubber_brush_carpet_supported': False, + 'is_set_child_supported': True, + 'is_setting_carpet_first_supported': True, + 'is_shake_mop_set_supported': True, + 'is_should_show_arm_over_load_supported': False, + 'is_show_clean_finish_reason_supported': True, + 'is_show_general_obstacle_supported': False, + 'is_show_obstacle_photo_supported': False, + 'is_side_brush_lift_carpet_supported': False, + 'is_small_side_mop_supported': True, + 'is_smart_clean_mode_set_supported': True, + 'is_soak_and_wash_supported': False, + 'is_soft_clean_mode_supported': False, + 'is_sr_map_supported': False, + 'is_super_deep_wash_supported': True, + 'is_support_api_app_stop_grasp_supported': False, + 'is_support_backup_map': True, + 'is_support_clean_estimate': True, + 'is_support_cliff_zone': True, + 'is_support_custom_carpet': False, + 'is_support_custom_dnd': True, + 'is_support_custom_door_sill': True, + 'is_support_custom_mode_in_cleaning': True, + 'is_support_fetch_timer_summary': False, + 'is_support_floor_direction': True, + 'is_support_floor_edit': True, + 'is_support_furniture': True, + 'is_support_get_particular_status_supported': False, + 'is_support_incremental_map': True, + 'is_support_main_brush_up_down_supported': True, + 'is_support_mop_back_pwm_set': False, + 'is_support_quick_map_builder': True, + 'is_support_remote_control_in_call': True, + 'is_support_room_tag': True, + 'is_support_set_switch_map_mode': True, + 'is_support_set_volume_in_call': True, + 'is_support_side_brush_up_down_supported': True, + 'is_support_smart_door_sill': True, + 'is_support_smart_global_clean_with_custom_mode': True, + 'is_support_smart_scene': True, + 'is_support_stuck_zone': True, + 'is_support_voice_control_debug': False, + 'is_support_water_mode': True, + 'is_supported_download_test_voice': True, + 'is_supported_drying': True, + 'is_supported_valley_electricity': True, + 'is_sync_server_name_supported': False, + 'is_three_d_mapping_inner_test_supported': False, + 'is_tidyup_zones_supported': False, + 'is_two_gears_no_collision_supported': False, + 'is_two_key_real_time_video_supported': False, + 'is_two_key_rtv_in_charging_supported': True, + 'is_type_identify_supported': False, + 'is_unsave_map_reason_supported': True, + 'is_uvc_sterilize_supported': False, + 'is_video_monitor_supported': True, + 'is_video_patrol_supported': True, + 'is_video_setting_supported': True, + 'is_voice_control_led_supported': True, + 'is_voice_control_supported': True, + 'is_wash_then_charge_cmd_supported': True, + 'is_water_leak_check_supported': True, + 'is_water_slide_mode_supported': False, + 'is_water_up_down_drain_supported': True, + 'is_wifi_manage_supported': True, + 'is_workday_holiday_supported': False, + }) +# --- +# name: test_device_features_from_home_data[home_data_device_saros_10r.json] + dict({ + 'is_activate_video_charging_and_standby_supported': True, + 'is_analysis_supported': False, + 'is_any_state_transit_goto_supported': True, + 'is_auto_collection_2_supported': True, + 'is_auto_delivery_field_in_global_status_supported': True, + 'is_auto_tear_down_mop_supported': True, + 'is_avoid_collision_mode_supported': True, + 'is_avoid_collision_supported': True, + 'is_back_charge_auto_wash_supported': True, + 'is_back_wash_new_smart_supported': False, + 'is_careful_slow_mop_supported': True, + 'is_carpet_custom_clean_supported': True, + 'is_carpet_deep_clean_supported': True, + 'is_carpet_long_haired_ex_supported': False, + 'is_carpet_long_haired_supported': True, + 'is_carpet_pressure_use_origin_paras_supported': False, + 'is_carpet_shape_type_supported': False, + 'is_carpet_show_on_map': True, + 'is_carpet_supported': True, + 'is_ces_2022_supported': False, + 'is_clean_count_setting_supported': True, + 'is_clean_direct_status_supported': True, + 'is_clean_efficiency_supported': False, + 'is_clean_fluid_delivery_supported': True, + 'is_clean_history_time_line_supported': True, + 'is_clean_route_deep_slow_plus_supported': False, + 'is_clean_route_fast_mode_supported': True, + 'is_clean_route_setting_supported': True, + 'is_clean_then_mop_mode_supported': True, + 'is_clean_time_line_supported': True, + 'is_collect_dust_count_show_supported': True, + 'is_collect_dust_mode_supported': True, + 'is_corner_clean_mode_supported': False, + 'is_corner_mop_stretch_supported': True, + 'is_ctm_with_repeat_supported': True, + 'is_current_map_restore_enabled': True, + 'is_custom_clean_mode_count_supported': True, + 'is_custom_mode_supported': True, + 'is_custom_water_box_distance_supported': True, + 'is_customized_clean_supported': True, + 'is_detect_wire_carpet_supported': True, + 'is_dirty_object_detect_supported': True, + 'is_dirty_replenish_clean_supported': True, + 'is_dry_interval_timer_supported': True, + 'is_dss_believable': True, + 'is_dual_band_wi_fi_supported': False, + 'is_dust_collection_setting_supported': True, + 'is_dynamically_add_clean_zones_supported': True, + 'is_dynamically_skip_clean_zone_supported': True, + 'is_egg_dance_mode_supported': True, + 'is_egg_mode_supported_from_new_features': False, + 'is_exact_custom_mode_supported': True, + 'is_exhibition_function_supported': False, + 'is_floor_dir_clean_any_time_supported': True, + 'is_flow_led_setting_supported': False, + 'is_follow_low_obs_supported': False, + 'is_full_duples_switch_supported': False, + 'is_fw_filter_obstacle_supported': True, + 'is_gap_deep_clean_supported': True, + 'is_goto_pure_clean_path_supported': True, + 'is_hot_wash_towel_supported': True, + 'is_identify_room_supported': True, + 'is_ignore_unknown_map_object_supported': True, + 'is_lds_lifting_supported': False, + 'is_led_status_switch_supported': False, + 'is_left_water_drain_supported': True, + 'is_low_area_access_supported': False, + 'is_main_brush_up_down_supported_from_str': True, + 'is_map_beautify_internal_debug_supported': True, + 'is_map_carpet_add_support': True, + 'is_map_eraser_supported': True, + 'is_matter_supported': True, + 'is_max_plus_mode_supported': True, + 'is_max_zone_opened_supported': True, + 'is_mechanical_arm_mode_supported': False, + 'is_midway_back_to_dock_supported': True, + 'is_min_battery_15_to_clean_task_supported': True, + 'is_mop_forbidden_supported': False, + 'is_mop_path_supported': True, + 'is_mop_shake_module_supported': False, + 'is_mop_shake_water_max_supported': False, + 'is_multi_floor_supported': False, + 'is_multi_map_segment_timer_supported': True, + 'is_new_ai_recognition_supported': True, + 'is_new_data_for_clean_history': True, + 'is_new_data_for_clean_history_detail': True, + 'is_new_endpoint_supported': True, + 'is_new_remote_view_supported': True, + 'is_no_need_carpet_press_set_supported': True, + 'is_none_pure_clean_mop_with_max_plus': False, + 'is_object_detect_check_supported': True, + 'is_offline_map_supported': True, + 'is_optimize_battery_supported': False, + 'is_order_clean_supported': False, + 'is_over_sea_ctm_supported': True, + 'is_pet_snapshot_supported': True, + 'is_pet_supplies_deep_clean_supported': True, + 'is_program_mode_supported': False, + 'is_pumping_water_supported': False, + 'is_pure_clean_mop_supported': True, + 'is_re_segment_supported': True, + 'is_record_allowed': True, + 'is_remote_supported': False, + 'is_right_brush_stretch_supported': True, + 'is_room_name_supported': True, + 'is_rpc_retry_supported': True, + 'is_rubber_brush_carpet_supported': False, + 'is_set_child_supported': True, + 'is_setting_carpet_first_supported': True, + 'is_shake_mop_set_supported': True, + 'is_should_show_arm_over_load_supported': False, + 'is_show_clean_finish_reason_supported': True, + 'is_show_general_obstacle_supported': False, + 'is_show_obstacle_photo_supported': False, + 'is_side_brush_lift_carpet_supported': True, + 'is_small_side_mop_supported': False, + 'is_smart_clean_mode_set_supported': True, + 'is_soak_and_wash_supported': False, + 'is_soft_clean_mode_supported': False, + 'is_sr_map_supported': False, + 'is_super_deep_wash_supported': True, + 'is_support_api_app_stop_grasp_supported': False, + 'is_support_backup_map': True, + 'is_support_clean_estimate': True, + 'is_support_cliff_zone': True, + 'is_support_custom_carpet': False, + 'is_support_custom_dnd': True, + 'is_support_custom_door_sill': True, + 'is_support_custom_mode_in_cleaning': True, + 'is_support_fetch_timer_summary': False, + 'is_support_floor_direction': True, + 'is_support_floor_edit': True, + 'is_support_furniture': True, + 'is_support_get_particular_status_supported': False, + 'is_support_incremental_map': True, + 'is_support_main_brush_up_down_supported': True, + 'is_support_mop_back_pwm_set': False, + 'is_support_quick_map_builder': True, + 'is_support_remote_control_in_call': True, + 'is_support_room_tag': True, + 'is_support_set_switch_map_mode': True, + 'is_support_set_volume_in_call': True, + 'is_support_side_brush_up_down_supported': True, + 'is_support_smart_door_sill': True, + 'is_support_smart_global_clean_with_custom_mode': True, + 'is_support_smart_scene': True, + 'is_support_stuck_zone': True, + 'is_support_voice_control_debug': False, + 'is_support_water_mode': True, + 'is_supported_download_test_voice': True, + 'is_supported_drying': True, + 'is_supported_valley_electricity': True, + 'is_sync_server_name_supported': False, + 'is_three_d_mapping_inner_test_supported': False, + 'is_tidyup_zones_supported': False, + 'is_two_gears_no_collision_supported': False, + 'is_two_key_real_time_video_supported': True, + 'is_two_key_rtv_in_charging_supported': True, + 'is_type_identify_supported': False, + 'is_unsave_map_reason_supported': True, + 'is_uvc_sterilize_supported': False, + 'is_video_monitor_supported': True, + 'is_video_patrol_supported': True, + 'is_video_setting_supported': True, + 'is_voice_control_led_supported': True, + 'is_voice_control_supported': True, + 'is_wash_then_charge_cmd_supported': True, + 'is_water_leak_check_supported': False, + 'is_water_slide_mode_supported': True, + 'is_water_up_down_drain_supported': True, + 'is_wifi_manage_supported': True, + 'is_workday_holiday_supported': False, + }) +# --- +# name: test_device_features_from_home_data[home_data_device_zeo_one.json] + dict({ + 'is_activate_video_charging_and_standby_supported': False, + 'is_analysis_supported': False, + 'is_any_state_transit_goto_supported': False, + 'is_auto_collection_2_supported': False, + 'is_auto_delivery_field_in_global_status_supported': False, + 'is_auto_tear_down_mop_supported': False, + 'is_avoid_collision_mode_supported': False, + 'is_avoid_collision_supported': False, + 'is_back_charge_auto_wash_supported': False, + 'is_back_wash_new_smart_supported': False, + 'is_careful_slow_mop_supported': False, + 'is_carpet_custom_clean_supported': False, + 'is_carpet_deep_clean_supported': False, + 'is_carpet_long_haired_ex_supported': False, + 'is_carpet_long_haired_supported': False, + 'is_carpet_pressure_use_origin_paras_supported': False, + 'is_carpet_shape_type_supported': False, + 'is_carpet_show_on_map': False, + 'is_carpet_supported': False, + 'is_ces_2022_supported': False, + 'is_clean_count_setting_supported': False, + 'is_clean_direct_status_supported': False, + 'is_clean_efficiency_supported': False, + 'is_clean_fluid_delivery_supported': False, + 'is_clean_history_time_line_supported': False, + 'is_clean_route_deep_slow_plus_supported': False, + 'is_clean_route_fast_mode_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, + 'is_collect_dust_mode_supported': True, + 'is_corner_clean_mode_supported': False, + 'is_corner_mop_stretch_supported': False, + 'is_ctm_with_repeat_supported': False, + 'is_current_map_restore_enabled': False, + 'is_custom_clean_mode_count_supported': False, + 'is_custom_mode_supported': True, + 'is_custom_water_box_distance_supported': False, + 'is_customized_clean_supported': True, + 'is_detect_wire_carpet_supported': False, + 'is_dirty_object_detect_supported': False, + 'is_dirty_replenish_clean_supported': False, + 'is_dry_interval_timer_supported': False, + 'is_dss_believable': False, + 'is_dual_band_wi_fi_supported': False, + 'is_dust_collection_setting_supported': False, + 'is_dynamically_add_clean_zones_supported': False, + 'is_dynamically_skip_clean_zone_supported': False, + 'is_egg_dance_mode_supported': False, + 'is_egg_mode_supported_from_new_features': False, + 'is_exact_custom_mode_supported': False, + 'is_exhibition_function_supported': False, + 'is_floor_dir_clean_any_time_supported': False, + 'is_flow_led_setting_supported': False, + 'is_follow_low_obs_supported': False, + 'is_full_duples_switch_supported': False, + 'is_fw_filter_obstacle_supported': False, + 'is_gap_deep_clean_supported': False, + 'is_goto_pure_clean_path_supported': False, + 'is_hot_wash_towel_supported': False, + 'is_identify_room_supported': False, + 'is_ignore_unknown_map_object_supported': False, + 'is_lds_lifting_supported': False, + 'is_led_status_switch_supported': False, + 'is_left_water_drain_supported': False, + 'is_low_area_access_supported': False, + 'is_main_brush_up_down_supported_from_str': False, + 'is_map_beautify_internal_debug_supported': False, + 'is_map_carpet_add_support': False, + 'is_map_eraser_supported': False, + 'is_matter_supported': False, + 'is_max_plus_mode_supported': True, + 'is_max_zone_opened_supported': False, + 'is_mechanical_arm_mode_supported': False, + 'is_midway_back_to_dock_supported': False, + 'is_min_battery_15_to_clean_task_supported': False, + 'is_mop_forbidden_supported': False, + 'is_mop_path_supported': False, + 'is_mop_shake_module_supported': False, + 'is_mop_shake_water_max_supported': False, + 'is_multi_floor_supported': False, + 'is_multi_map_segment_timer_supported': False, + 'is_new_ai_recognition_supported': False, + 'is_new_data_for_clean_history': False, + 'is_new_data_for_clean_history_detail': False, + 'is_new_endpoint_supported': False, + 'is_new_remote_view_supported': True, + 'is_no_need_carpet_press_set_supported': False, + 'is_none_pure_clean_mop_with_max_plus': False, + 'is_object_detect_check_supported': False, + 'is_offline_map_supported': False, + 'is_optimize_battery_supported': False, + 'is_order_clean_supported': False, + 'is_over_sea_ctm_supported': False, + 'is_pet_snapshot_supported': False, + 'is_pet_supplies_deep_clean_supported': False, + 'is_program_mode_supported': False, + 'is_pumping_water_supported': False, + 'is_pure_clean_mop_supported': True, + 'is_re_segment_supported': False, + 'is_record_allowed': False, + 'is_remote_supported': False, + 'is_right_brush_stretch_supported': False, + 'is_room_name_supported': False, + 'is_rpc_retry_supported': False, + 'is_rubber_brush_carpet_supported': False, + 'is_set_child_supported': False, + 'is_setting_carpet_first_supported': False, + 'is_shake_mop_set_supported': False, + 'is_should_show_arm_over_load_supported': False, + 'is_show_clean_finish_reason_supported': False, + 'is_show_general_obstacle_supported': False, + 'is_show_obstacle_photo_supported': False, + 'is_side_brush_lift_carpet_supported': False, + 'is_small_side_mop_supported': False, + 'is_smart_clean_mode_set_supported': False, + 'is_soak_and_wash_supported': False, + 'is_soft_clean_mode_supported': False, + 'is_sr_map_supported': False, + 'is_super_deep_wash_supported': False, + 'is_support_api_app_stop_grasp_supported': False, + 'is_support_backup_map': False, + 'is_support_clean_estimate': False, + 'is_support_cliff_zone': False, + 'is_support_custom_carpet': False, + 'is_support_custom_dnd': False, + 'is_support_custom_door_sill': False, + 'is_support_custom_mode_in_cleaning': False, + 'is_support_fetch_timer_summary': False, + 'is_support_floor_direction': False, + 'is_support_floor_edit': False, + 'is_support_furniture': False, + 'is_support_get_particular_status_supported': False, + 'is_support_incremental_map': False, + 'is_support_main_brush_up_down_supported': False, + 'is_support_mop_back_pwm_set': False, + 'is_support_quick_map_builder': False, + 'is_support_remote_control_in_call': False, + 'is_support_room_tag': False, + 'is_support_set_switch_map_mode': False, + 'is_support_set_volume_in_call': False, + 'is_support_side_brush_up_down_supported': False, + 'is_support_smart_door_sill': False, + 'is_support_smart_global_clean_with_custom_mode': False, + 'is_support_smart_scene': False, + 'is_support_stuck_zone': False, + 'is_support_voice_control_debug': False, + 'is_support_water_mode': True, + 'is_supported_download_test_voice': False, + 'is_supported_drying': False, + 'is_supported_valley_electricity': False, + 'is_sync_server_name_supported': False, + 'is_three_d_mapping_inner_test_supported': False, + 'is_tidyup_zones_supported': False, + 'is_two_gears_no_collision_supported': False, + 'is_two_key_real_time_video_supported': False, + 'is_two_key_rtv_in_charging_supported': False, + 'is_type_identify_supported': False, + 'is_unsave_map_reason_supported': False, + 'is_uvc_sterilize_supported': False, + 'is_video_monitor_supported': False, + 'is_video_patrol_supported': False, + 'is_video_setting_supported': False, + 'is_voice_control_led_supported': False, + 'is_voice_control_supported': False, + 'is_wash_then_charge_cmd_supported': False, + 'is_water_leak_check_supported': False, + 'is_water_slide_mode_supported': False, + 'is_water_up_down_drain_supported': False, + 'is_wifi_manage_supported': False, + 'is_workday_holiday_supported': False, + }) +# --- diff --git a/tests/devices/traits/v1/__snapshots__/test_device_features.ambr b/tests/devices/traits/v1/__snapshots__/test_device_features.ambr index 0d3854d7..c87d70aa 100644 --- a/tests/devices/traits/v1/__snapshots__/test_device_features.ambr +++ b/tests/devices/traits/v1/__snapshots__/test_device_features.ambr @@ -1,4 +1,15 @@ # serializer version: 1 +# name: test_is_attribute_supported[home_data_device_a123.json] + dict({ + 'battery': True, + 'charge_status': True, + 'dry_status': True, + 'error_code': True, + 'fan_power': True, + 'state': True, + 'water_box_mode': True, + }) +# --- # name: test_is_attribute_supported[home_data_device_s5e.json] dict({ 'battery': True, @@ -43,6 +54,13 @@ 'water_box_mode': True, }) # --- +# name: test_is_consumable_field_supported[home_data_device_a123.json] + dict({ + 'filter_work_time': True, + 'main_brush_work_time': True, + 'side_brush_work_time': True, + }) +# --- # name: test_is_consumable_field_supported[home_data_device_s5e.json] dict({ 'filter_work_time': True, diff --git a/tests/mock_data.py b/tests/mock_data.py index abb996c9..dd1676c9 100644 --- a/tests/mock_data.py +++ b/tests/mock_data.py @@ -5,6 +5,8 @@ import pathlib from typing import Any +from roborock.data.containers import HomeDataDevice, HomeDataProduct + # All data is based on a U.S. customer with a Roborock S7 MaxV Ultra USER_EMAIL = "user@domain.com" @@ -143,6 +145,17 @@ SAROS_10R_DEVICE_DATA = DEVICES["home_data_device_saros_10r.json"] SAROS_10_DEVICE_DATA = DEVICES["home_data_device_saros.json"] +# All testdata devices joined with their matching product (keyed by device filename). +# Devices whose productId has no corresponding product file are omitted. +_PRODUCTS_BY_ID: dict[str, HomeDataProduct] = { + p.id: p for p in (HomeDataProduct.from_dict(v) for v in PRODUCTS.values()) +} +DEVICE_PRODUCT_PAIRS: dict[str, tuple[HomeDataDevice, HomeDataProduct]] = { + filename: (HomeDataDevice.from_dict(raw), product) + for filename, raw in DEVICES.items() + if (product := _PRODUCTS_BY_ID.get(HomeDataDevice.from_dict(raw).product_id)) is not None +} + HOME_DATA_RAW: dict[str, Any] = { "id": 123456, diff --git a/tests/test_supported_features.py b/tests/test_supported_features.py index 240856a1..a3fa4054 100644 --- a/tests/test_supported_features.py +++ b/tests/test_supported_features.py @@ -1,8 +1,12 @@ +from dataclasses import asdict + +import pytest from syrupy import SnapshotAssertion from roborock import SHORT_MODEL_TO_ENUM from roborock.data.code_mappings import RoborockProductNickname from roborock.device_features import DeviceFeatures +from tests import mock_data def test_supported_features_qrevo_maxv(): @@ -73,3 +77,30 @@ def test_new_feature_str_missing(): assert not device_features.is_dust_collection_setting_supported assert not device_features.is_hot_wash_towel_supported assert not device_features.is_show_clean_finish_reason_supported + + +@pytest.mark.parametrize( + ("device_filename"), + list(mock_data.DEVICE_PRODUCT_PAIRS.keys()), +) +def test_device_features_from_home_data( + device_filename: str, + snapshot: SnapshotAssertion, +) -> None: + """Test DeviceFeatures constructed from real testdata devices and products. + + For each paired device+product in testdata, construct DeviceFeatures from the + featureSet/newFeatureSet home data fields and assert the full feature dict + matches the snapshot. This catches regressions in feature-flag decoding + across all real device samples. + """ + device, product = mock_data.DEVICE_PRODUCT_PAIRS[device_filename] + device_features = DeviceFeatures.from_feature_flags( + new_feature_info=int(device.feature_set or "0"), + new_feature_info_str=device.new_feature_set or "", + feature_info=[], + product_nickname=product.product_nickname, + ) + # Snapshot all boolean features as a sorted dict for stable output + feature_dict = {k: v for k, v in asdict(device_features).items() if isinstance(v, bool)} + assert feature_dict == snapshot diff --git a/tests/testdata/home_data_device_a123.json b/tests/testdata/home_data_device_a123.json new file mode 100644 index 00000000..badf268a --- /dev/null +++ b/tests/testdata/home_data_device_a123.json @@ -0,0 +1,33 @@ +{ + "duid": "device-id-a123", + "name": "Roborock PearlS Lite", + "localKey": "key123key123key1", + "productId": "product-id-a123", + "fv": "02.03.28", + "activeTime": 1742574271, + "timeZoneId": "America/Los_Angeles", + "iconUrl": "", + "share": false, + "online": true, + "pv": "1.0", + "tuyaMigrated": false, + "extra": "{}", + "sn": "A123SAMPLESNTEST", + "featureSet": "2247397454282751", + "newFeatureSet": "42BA8D587EDAFFFE", + "deviceStatus": { + "121": 8, + "122": 100, + "123": 110, + "124": 209, + "125": 0, + "126": 22, + "127": 0, + "128": 0, + "133": 1, + "120": 0, + "134": 0 + }, + "silentOtaSwitch": true, + "f": false +} diff --git a/tests/testdata/home_data_product_a123.json b/tests/testdata/home_data_product_a123.json new file mode 100644 index 00000000..5186f4b0 --- /dev/null +++ b/tests/testdata/home_data_product_a123.json @@ -0,0 +1,136 @@ +{ + "id": "product-id-a123", + "name": "Roborock PearlS Lite", + "model": "roborock.vacuum.a123", + "category": "robot.vacuum.cleaner", + "capability": 0, + "schema": [ + { + "id": 101, + "name": "rpc_request", + "code": "rpc_request", + "mode": "rw", + "type": "RAW" + }, + { + "id": 102, + "name": "rpc_response", + "code": "rpc_response", + "mode": "rw", + "type": "RAW" + }, + { + "id": 120, + "name": "\u9519\u8bef\u4ee3\u7801", + "code": "error_code", + "mode": "ro", + "type": "ENUM", + "property": "{\"range\": [\"\"]}" + }, + { + "id": 121, + "name": "\u8bbe\u5907\u72b6\u6001", + "code": "state", + "mode": "ro", + "type": "ENUM", + "property": "{\"range\": [\"\"]}" + }, + { + "id": 122, + "name": "\u8bbe\u5907\u7535\u91cf", + "code": "battery", + "mode": "ro", + "type": "ENUM", + "property": "{\"range\": [\"\"]}" + }, + { + "id": 123, + "name": "\u6e05\u626b\u6a21\u5f0f", + "code": "fan_power", + "mode": "rw", + "type": "ENUM", + "property": "{\"range\": [\"\"]}" + }, + { + "id": 124, + "name": "\u62d6\u5730\u6a21\u5f0f", + "code": "water_box_mode", + "mode": "rw", + "type": "ENUM", + "property": "{\"range\": [\"\"]}" + }, + { + "id": 125, + "name": "\u4e3b\u5237\u5bff\u547d", + "code": "main_brush_life", + "mode": "rw", + "type": "VALUE", + "property": "{\"max\": 100, \"min\": 0, \"step\": 1, \"unit\": \"null\", \"scale\": 1}" + }, + { + "id": 126, + "name": "\u8fb9\u5237\u5bff\u547d", + "code": "side_brush_life", + "mode": "rw", + "type": "VALUE", + "property": "{\"max\": 100, \"min\": 0, \"step\": 1, \"unit\": \"null\", \"scale\": 1}" + }, + { + "id": 127, + "name": "\u6ee4\u7f51\u5bff\u547d", + "code": "filter_life", + "mode": "rw", + "type": "VALUE", + "property": "{\"max\": 100, \"min\": 0, \"step\": 1, \"unit\": \"null\", \"scale\": 1}" + }, + { + "id": 128, + "name": "\u989d\u5916\u72b6\u6001", + "code": "additional_props", + "mode": "ro", + "type": "RAW" + }, + { + "id": 130, + "name": "\u5b8c\u6210\u4e8b\u4ef6", + "code": "task_complete", + "mode": "ro", + "type": "RAW" + }, + { + "id": 131, + "name": "\u7535\u91cf\u4e0d\u8db3\u4efb\u52a1\u53d6\u6d88", + "code": "task_cancel_low_power", + "mode": "ro", + "type": "RAW" + }, + { + "id": 132, + "name": "\u8fd0\u52a8\u4e2d\u4efb\u52a1\u53d6\u6d88", + "code": "task_cancel_in_motion", + "mode": "ro", + "type": "RAW" + }, + { + "id": 133, + "name": "\u5145\u7535\u72b6\u6001", + "code": "charge_status", + "mode": "ro", + "type": "RAW" + }, + { + "id": 134, + "name": "\u70d8\u5e72\u72b6\u6001", + "code": "drying_status", + "mode": "ro", + "type": "RAW" + }, + { + "id": 135, + "name": "\u79bb\u7ebf\u539f\u56e0\u7ec6\u5206", + "code": "offline_status", + "mode": "ro", + "type": "RAW" + } + ] +} From 6b1f9b3dc93e9ffce09b8b0164b71a9742312634 Mon Sep 17 00:00:00 2001 From: Allen Porter Date: Sun, 5 Apr 2026 08:36:36 -0700 Subject: [PATCH 3/6] refactor: ensure deterministic test data loading by sorting file globs and remove redundant snapshot comment --- tests/mock_data.py | 8 ++++++-- tests/test_supported_features.py | 1 - 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/tests/mock_data.py b/tests/mock_data.py index dd1676c9..05784cf4 100644 --- a/tests/mock_data.py +++ b/tests/mock_data.py @@ -126,8 +126,12 @@ TESTDATA = pathlib.Path("tests/testdata") -PRODUCTS = {file.name: json.load(file.open(encoding="utf-8")) for file in TESTDATA.glob("home_data_product_*.json")} -DEVICES = {file.name: json.load(file.open(encoding="utf-8")) for file in TESTDATA.glob("home_data_device_*.json")} +PRODUCTS = { + file.name: json.load(file.open(encoding="utf-8")) for file in sorted(TESTDATA.glob("home_data_product_*.json")) +} +DEVICES = { + file.name: json.load(file.open(encoding="utf-8")) for file in sorted(TESTDATA.glob("home_data_device_*.json")) +} # Products A27_PRODUCT_DATA = PRODUCTS["home_data_product_a27.json"] diff --git a/tests/test_supported_features.py b/tests/test_supported_features.py index a3fa4054..8f3aa853 100644 --- a/tests/test_supported_features.py +++ b/tests/test_supported_features.py @@ -101,6 +101,5 @@ def test_device_features_from_home_data( feature_info=[], product_nickname=product.product_nickname, ) - # Snapshot all boolean features as a sorted dict for stable output feature_dict = {k: v for k, v in asdict(device_features).items() if isinstance(v, bool)} assert feature_dict == snapshot From ac6538028600987f43cb477cdd8c44ab1a0b974c Mon Sep 17 00:00:00 2001 From: Allen Porter Date: Sun, 5 Apr 2026 08:40:04 -0700 Subject: [PATCH 4/6] refactor: optimize device lookup in mock data by caching parsed device objects --- tests/mock_data.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tests/mock_data.py b/tests/mock_data.py index 05784cf4..9aaa65f0 100644 --- a/tests/mock_data.py +++ b/tests/mock_data.py @@ -154,10 +154,13 @@ _PRODUCTS_BY_ID: dict[str, HomeDataProduct] = { p.id: p for p in (HomeDataProduct.from_dict(v) for v in PRODUCTS.values()) } +_DEVICES_BY_FILENAME: dict[str, HomeDataDevice] = { + filename: HomeDataDevice.from_dict(device_data) for filename, device_data in DEVICES.items() +} DEVICE_PRODUCT_PAIRS: dict[str, tuple[HomeDataDevice, HomeDataProduct]] = { - filename: (HomeDataDevice.from_dict(raw), product) - for filename, raw in DEVICES.items() - if (product := _PRODUCTS_BY_ID.get(HomeDataDevice.from_dict(raw).product_id)) is not None + filename: (device, product) + for filename, device in _DEVICES_BY_FILENAME.items() + if (product := _PRODUCTS_BY_ID.get(device.product_id)) is not None } From e8816a3e94e96d23c5f16105ec2341a0f9704ad0 Mon Sep 17 00:00:00 2001 From: Allen Porter Date: Sun, 5 Apr 2026 11:03:36 -0700 Subject: [PATCH 5/6] feat: add support for Roborock Q5 Max+ and update test snapshots --- .../test_supported_features.ambr | 178 +++++++++++++++++- .../__snapshots__/test_device_features.ambr | 22 ++- tests/mock_data.py | 2 - ...a123.json => home_data_device_pearls.json} | 0 tests/testdata/home_data_device_q5_max.json | 32 ++++ tests/testdata/home_data_product_a125.json | 136 +++++++++++++ 6 files changed, 365 insertions(+), 5 deletions(-) rename tests/testdata/{home_data_device_a123.json => home_data_device_pearls.json} (100%) create mode 100644 tests/testdata/home_data_device_q5_max.json create mode 100644 tests/testdata/home_data_product_a125.json diff --git a/tests/__snapshots__/test_supported_features.ambr b/tests/__snapshots__/test_supported_features.ambr index acd4a661..196190d5 100644 --- a/tests/__snapshots__/test_supported_features.ambr +++ b/tests/__snapshots__/test_supported_features.ambr @@ -1,5 +1,5 @@ # serializer version: 1 -# name: test_device_features_from_home_data[home_data_device_a123.json] +# name: test_device_features_from_home_data[home_data_device_pearls.json] dict({ 'is_activate_video_charging_and_standby_supported': False, 'is_analysis_supported': False, @@ -351,6 +351,182 @@ 'is_workday_holiday_supported': False, }) # --- +# name: test_device_features_from_home_data[home_data_device_q5_max.json] + dict({ + 'is_activate_video_charging_and_standby_supported': False, + 'is_analysis_supported': False, + 'is_any_state_transit_goto_supported': True, + 'is_auto_collection_2_supported': False, + 'is_auto_delivery_field_in_global_status_supported': False, + 'is_auto_tear_down_mop_supported': False, + 'is_avoid_collision_mode_supported': False, + 'is_avoid_collision_supported': False, + 'is_back_charge_auto_wash_supported': True, + 'is_back_wash_new_smart_supported': False, + 'is_careful_slow_mop_supported': True, + 'is_carpet_custom_clean_supported': False, + 'is_carpet_deep_clean_supported': False, + 'is_carpet_long_haired_ex_supported': False, + 'is_carpet_long_haired_supported': False, + 'is_carpet_pressure_use_origin_paras_supported': False, + 'is_carpet_shape_type_supported': False, + 'is_carpet_show_on_map': True, + 'is_carpet_supported': False, + 'is_ces_2022_supported': False, + 'is_clean_count_setting_supported': False, + 'is_clean_direct_status_supported': False, + 'is_clean_efficiency_supported': False, + 'is_clean_fluid_delivery_supported': False, + '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_then_mop_mode_supported': False, + 'is_clean_time_line_supported': False, + 'is_collect_dust_count_show_supported': False, + 'is_collect_dust_mode_supported': True, + 'is_corner_clean_mode_supported': False, + 'is_corner_mop_stretch_supported': False, + 'is_ctm_with_repeat_supported': False, + 'is_current_map_restore_enabled': True, + 'is_custom_clean_mode_count_supported': False, + 'is_custom_mode_supported': True, + 'is_custom_water_box_distance_supported': False, + 'is_customized_clean_supported': False, + 'is_detect_wire_carpet_supported': False, + 'is_dirty_object_detect_supported': False, + 'is_dirty_replenish_clean_supported': False, + 'is_dry_interval_timer_supported': False, + 'is_dss_believable': True, + 'is_dual_band_wi_fi_supported': False, + 'is_dust_collection_setting_supported': True, + 'is_dynamically_add_clean_zones_supported': False, + 'is_dynamically_skip_clean_zone_supported': False, + 'is_egg_dance_mode_supported': False, + 'is_egg_mode_supported_from_new_features': False, + 'is_exact_custom_mode_supported': False, + 'is_exhibition_function_supported': False, + 'is_floor_dir_clean_any_time_supported': False, + 'is_flow_led_setting_supported': False, + 'is_follow_low_obs_supported': False, + 'is_full_duples_switch_supported': False, + 'is_fw_filter_obstacle_supported': True, + 'is_gap_deep_clean_supported': False, + 'is_goto_pure_clean_path_supported': True, + 'is_hot_wash_towel_supported': False, + 'is_identify_room_supported': False, + 'is_ignore_unknown_map_object_supported': True, + 'is_lds_lifting_supported': False, + 'is_led_status_switch_supported': False, + 'is_left_water_drain_supported': True, + 'is_low_area_access_supported': False, + 'is_main_brush_up_down_supported_from_str': False, + 'is_map_beautify_internal_debug_supported': True, + 'is_map_carpet_add_support': False, + 'is_map_eraser_supported': False, + 'is_matter_supported': False, + 'is_max_plus_mode_supported': False, + 'is_max_zone_opened_supported': False, + 'is_mechanical_arm_mode_supported': False, + 'is_midway_back_to_dock_supported': False, + 'is_min_battery_15_to_clean_task_supported': False, + 'is_mop_forbidden_supported': False, + 'is_mop_path_supported': False, + 'is_mop_shake_module_supported': False, + 'is_mop_shake_water_max_supported': False, + 'is_multi_floor_supported': False, + 'is_multi_map_segment_timer_supported': True, + 'is_new_ai_recognition_supported': False, + 'is_new_data_for_clean_history': True, + 'is_new_data_for_clean_history_detail': True, + 'is_new_endpoint_supported': True, + 'is_new_remote_view_supported': False, + 'is_no_need_carpet_press_set_supported': False, + 'is_none_pure_clean_mop_with_max_plus': True, + 'is_object_detect_check_supported': False, + 'is_offline_map_supported': True, + 'is_optimize_battery_supported': False, + 'is_order_clean_supported': False, + 'is_over_sea_ctm_supported': False, + 'is_pet_snapshot_supported': False, + 'is_pet_supplies_deep_clean_supported': False, + 'is_program_mode_supported': False, + 'is_pumping_water_supported': False, + 'is_pure_clean_mop_supported': True, + 'is_re_segment_supported': True, + 'is_record_allowed': True, + 'is_remote_supported': False, + 'is_right_brush_stretch_supported': False, + 'is_room_name_supported': True, + 'is_rpc_retry_supported': True, + 'is_rubber_brush_carpet_supported': False, + 'is_set_child_supported': True, + 'is_setting_carpet_first_supported': False, + 'is_shake_mop_set_supported': True, + 'is_should_show_arm_over_load_supported': False, + 'is_show_clean_finish_reason_supported': True, + 'is_show_general_obstacle_supported': False, + 'is_show_obstacle_photo_supported': False, + 'is_side_brush_lift_carpet_supported': False, + 'is_small_side_mop_supported': False, + 'is_smart_clean_mode_set_supported': False, + 'is_soak_and_wash_supported': False, + 'is_soft_clean_mode_supported': False, + 'is_sr_map_supported': False, + 'is_super_deep_wash_supported': True, + 'is_support_api_app_stop_grasp_supported': False, + 'is_support_backup_map': True, + 'is_support_clean_estimate': True, + 'is_support_cliff_zone': True, + 'is_support_custom_carpet': False, + 'is_support_custom_dnd': True, + 'is_support_custom_door_sill': True, + 'is_support_custom_mode_in_cleaning': True, + 'is_support_fetch_timer_summary': False, + 'is_support_floor_direction': True, + 'is_support_floor_edit': True, + 'is_support_furniture': True, + 'is_support_get_particular_status_supported': False, + 'is_support_incremental_map': True, + 'is_support_main_brush_up_down_supported': False, + 'is_support_mop_back_pwm_set': False, + 'is_support_quick_map_builder': True, + 'is_support_remote_control_in_call': False, + 'is_support_room_tag': True, + 'is_support_set_switch_map_mode': True, + 'is_support_set_volume_in_call': False, + 'is_support_side_brush_up_down_supported': False, + 'is_support_smart_door_sill': True, + 'is_support_smart_global_clean_with_custom_mode': True, + 'is_support_smart_scene': True, + 'is_support_stuck_zone': True, + 'is_support_voice_control_debug': False, + 'is_support_water_mode': True, + 'is_supported_download_test_voice': True, + 'is_supported_drying': False, + 'is_supported_valley_electricity': True, + 'is_sync_server_name_supported': False, + 'is_three_d_mapping_inner_test_supported': False, + 'is_tidyup_zones_supported': False, + 'is_two_gears_no_collision_supported': False, + 'is_two_key_real_time_video_supported': False, + 'is_two_key_rtv_in_charging_supported': False, + 'is_type_identify_supported': False, + 'is_unsave_map_reason_supported': True, + 'is_uvc_sterilize_supported': False, + 'is_video_monitor_supported': True, + 'is_video_patrol_supported': False, + 'is_video_setting_supported': True, + 'is_voice_control_led_supported': False, + 'is_voice_control_supported': False, + 'is_wash_then_charge_cmd_supported': True, + 'is_water_leak_check_supported': False, + 'is_water_slide_mode_supported': False, + 'is_water_up_down_drain_supported': True, + 'is_wifi_manage_supported': True, + 'is_workday_holiday_supported': False, + }) +# --- # name: test_device_features_from_home_data[home_data_device_q7.json] dict({ 'is_activate_video_charging_and_standby_supported': False, diff --git a/tests/devices/traits/v1/__snapshots__/test_device_features.ambr b/tests/devices/traits/v1/__snapshots__/test_device_features.ambr index c87d70aa..c803498d 100644 --- a/tests/devices/traits/v1/__snapshots__/test_device_features.ambr +++ b/tests/devices/traits/v1/__snapshots__/test_device_features.ambr @@ -1,5 +1,16 @@ # serializer version: 1 -# name: test_is_attribute_supported[home_data_device_a123.json] +# name: test_is_attribute_supported[home_data_device_pearls.json] + dict({ + 'battery': True, + 'charge_status': True, + 'dry_status': True, + 'error_code': True, + 'fan_power': True, + 'state': True, + 'water_box_mode': True, + }) +# --- +# name: test_is_attribute_supported[home_data_device_q5_max.json] dict({ 'battery': True, 'charge_status': True, @@ -54,7 +65,14 @@ 'water_box_mode': True, }) # --- -# name: test_is_consumable_field_supported[home_data_device_a123.json] +# name: test_is_consumable_field_supported[home_data_device_pearls.json] + dict({ + 'filter_work_time': True, + 'main_brush_work_time': True, + 'side_brush_work_time': True, + }) +# --- +# name: test_is_consumable_field_supported[home_data_device_q5_max.json] dict({ 'filter_work_time': True, 'main_brush_work_time': True, diff --git a/tests/mock_data.py b/tests/mock_data.py index 9aaa65f0..226a417a 100644 --- a/tests/mock_data.py +++ b/tests/mock_data.py @@ -139,7 +139,6 @@ SS07_PRODUCT_DATA = PRODUCTS["home_data_product_ss07.json"] A102_PRODUCT_DATA = PRODUCTS["home_data_product_a102.json"] A114_PRODUCT_DATA = PRODUCTS["home_data_product_a114.json"] -A147_PRODUCT_DATA = PRODUCTS["home_data_product_a147.json"] # Devices S7_MAXV_DEVICE_DATA = DEVICES["home_data_device_s7_maxv.json"] @@ -147,7 +146,6 @@ Q10_DEVICE_DATA = DEVICES["home_data_device_q10.json"] ZEO_ONE_DEVICE_DATA = DEVICES["home_data_device_zeo_one.json"] SAROS_10R_DEVICE_DATA = DEVICES["home_data_device_saros_10r.json"] -SAROS_10_DEVICE_DATA = DEVICES["home_data_device_saros.json"] # All testdata devices joined with their matching product (keyed by device filename). # Devices whose productId has no corresponding product file are omitted. diff --git a/tests/testdata/home_data_device_a123.json b/tests/testdata/home_data_device_pearls.json similarity index 100% rename from tests/testdata/home_data_device_a123.json rename to tests/testdata/home_data_device_pearls.json diff --git a/tests/testdata/home_data_device_q5_max.json b/tests/testdata/home_data_device_q5_max.json new file mode 100644 index 00000000..ea5f2574 --- /dev/null +++ b/tests/testdata/home_data_device_q5_max.json @@ -0,0 +1,32 @@ +{ + "duid": "device-id-a125", + "name": "Roborock Q5 Max+", + "localKey": "key123key123key1", + "productId": "product-id-a125", + "fv": "02.01.24", + "activeTime": 1765325043, + "timeZoneId": "America/Chicago", + "iconUrl": "", + "share": false, + "online": true, + "pv": "1.0", + "tuyaMigrated": false, + "extra": "{}", + "sn": "A125SAMPLESNTEST", + "featureSet": "2097860516935167", + "newFeatureSet": "00000040385AFFF6", + "deviceStatus": { + "121": 8, + "122": 100, + "123": 106, + "125": 11, + "126": 0, + "127": 0, + "128": 0, + "133": 1, + "120": 0, + "124": 204 + }, + "silentOtaSwitch": true, + "f": false +} diff --git a/tests/testdata/home_data_product_a125.json b/tests/testdata/home_data_product_a125.json new file mode 100644 index 00000000..b6114790 --- /dev/null +++ b/tests/testdata/home_data_product_a125.json @@ -0,0 +1,136 @@ +{ + "id": "product-id-a125", + "name": "Roborock Q5 Max+", + "model": "roborock.vacuum.a125", + "category": "robot.vacuum.cleaner", + "capability": 0, + "schema": [ + { + "id": 101, + "name": "rpc_request", + "code": "rpc_request", + "mode": "rw", + "type": "RAW" + }, + { + "id": 102, + "name": "rpc_response", + "code": "rpc_response", + "mode": "rw", + "type": "RAW" + }, + { + "id": 120, + "name": "\u9519\u8bef\u4ee3\u7801", + "code": "error_code", + "mode": "ro", + "type": "ENUM", + "property": "{\"range\": [\"\"]}" + }, + { + "id": 121, + "name": "\u8bbe\u5907\u72b6\u6001", + "code": "state", + "mode": "ro", + "type": "ENUM", + "property": "{\"range\": [\"\"]}" + }, + { + "id": 122, + "name": "\u8bbe\u5907\u7535\u91cf", + "code": "battery", + "mode": "ro", + "type": "ENUM", + "property": "{\"range\": [\"\"]}" + }, + { + "id": 123, + "name": "\u6e05\u626b\u6a21\u5f0f", + "code": "fan_power", + "mode": "rw", + "type": "ENUM", + "property": "{\"range\": [\"\"]}" + }, + { + "id": 124, + "name": "\u62d6\u5730\u6a21\u5f0f", + "code": "water_box_mode", + "mode": "rw", + "type": "ENUM", + "property": "{\"range\": [\"\"]}" + }, + { + "id": 125, + "name": "\u4e3b\u5237\u5bff\u547d", + "code": "main_brush_life", + "mode": "rw", + "type": "VALUE", + "property": "{\"max\": 100, \"min\": 0, \"step\": 1, \"unit\": \"null\", \"scale\": 1}" + }, + { + "id": 126, + "name": "\u8fb9\u5237\u5bff\u547d", + "code": "side_brush_life", + "mode": "rw", + "type": "VALUE", + "property": "{\"max\": 100, \"min\": 0, \"step\": 1, \"unit\": \"null\", \"scale\": 1}" + }, + { + "id": 127, + "name": "\u6ee4\u7f51\u5bff\u547d", + "code": "filter_life", + "mode": "rw", + "type": "VALUE", + "property": "{\"max\": 100, \"min\": 0, \"step\": 1, \"unit\": \"null\", \"scale\": 1}" + }, + { + "id": 128, + "name": "\u989d\u5916\u72b6\u6001", + "code": "additional_props", + "mode": "ro", + "type": "RAW" + }, + { + "id": 130, + "name": "\u5b8c\u6210\u4e8b\u4ef6", + "code": "task_complete", + "mode": "ro", + "type": "RAW" + }, + { + "id": 131, + "name": "\u7535\u91cf\u4e0d\u8db3\u4efb\u52a1\u53d6\u6d88", + "code": "task_cancel_low_power", + "mode": "ro", + "type": "RAW" + }, + { + "id": 132, + "name": "\u8fd0\u52a8\u4e2d\u4efb\u52a1\u53d6\u6d88", + "code": "task_cancel_in_motion", + "mode": "ro", + "type": "RAW" + }, + { + "id": 133, + "name": "\u5145\u7535\u72b6\u6001", + "code": "charge_status", + "mode": "ro", + "type": "RAW" + }, + { + "id": 134, + "name": "\u70d8\u5e72\u72b6\u6001", + "code": "drying_status", + "mode": "ro", + "type": "RAW" + }, + { + "id": 135, + "name": "\u79bb\u7ebf\u539f\u56e0\u7ec6\u5206", + "code": "offline_status", + "mode": "ro", + "type": "RAW" + } + ] +} From 0388bbed33b3d96d2659e41295d6ab490d9dd222 Mon Sep 17 00:00:00 2001 From: Allen Porter Date: Mon, 6 Apr 2026 08:38:31 -0700 Subject: [PATCH 6/6] chore: update supported features documentation, device definitions, and CLI model mapping --- SUPPORTED_FEATURES.md | 387 ++++++++++++------------ device_info.yaml | 682 ++++++++++++++++++++++++++++++++++++++++-- roborock/cli.py | 76 +++-- 3 files changed, 911 insertions(+), 234 deletions(-) diff --git a/SUPPORTED_FEATURES.md b/SUPPORTED_FEATURES.md index f0592a5b..752b73cf 100644 --- a/SUPPORTED_FEATURES.md +++ b/SUPPORTED_FEATURES.md @@ -1,193 +1,194 @@ -| Feature | roborock.vacuum.a15 | roborock.vacuum.a87 | roborock.vacuum.s5e | -|---|---|---|---| -| Product Nickname | TANOSS | PEARLPLUS | RUBYSLITE | -| Protocol Version | 1.0 | 1.0 | 1.0 | -| New Feature Info | 636084721975295 | 4499197267967999 | 633887780925447 | -| New Feature Info Str | 0000000000002000 | 508A977F7EFEFFFF | 0000000000002000 | -| `111` | X | X | X | -| `112` | X | X | X | -| `113` | X | X | X | -| `114` | X | X | X | -| `115` | X | X | X | -| `116` | X | X | X | -| `117` | X | X | X | -| `118` | X | X | X | -| `119` | X | X | X | -| `120` | X | X | X | -| `121` | | X | | -| `122` | X | X | X | -| `123` | X | X | X | -| `124` | X | X | X | -| `125` | X | X | X | -| `is_activate_video_charging_and_standby_supported` | | | | -| `is_analysis_supported` | X | X | X | -| `is_any_state_transit_goto_supported` | X | X | | -| `is_auto_collection_2_supported` | | | | -| `is_auto_delivery_field_in_global_status_supported` | | X | | -| `is_auto_tear_down_mop_supported` | | | | -| `is_avoid_collision_mode_supported` | | X | | -| `is_avoid_collision_supported` | | X | | -| `is_back_charge_auto_wash_supported` | | X | | -| `is_back_wash_new_smart_supported` | | | | -| `is_careful_slow_mop_supported` | X | X | | -| `is_carpet_custom_clean_supported` | | X | | -| `is_carpet_deep_clean_supported` | | X | | -| `is_carpet_long_haired_ex_supported` | | | | -| `is_carpet_long_haired_supported` | | | | -| `is_carpet_pressure_use_origin_paras_supported` | | | | -| `is_carpet_shape_type_supported` | | | | -| `is_carpet_show_on_map` | | X | | -| `is_carpet_supported` | X | X | | -| `is_ces_2022_supported` | | | | -| `is_clean_count_setting_supported` | | X | | -| `is_clean_direct_status_supported` | | | | -| `is_clean_efficiency_supported` | | | | -| `is_clean_fluid_delivery_supported` | | | | -| `is_clean_history_time_line_supported` | | | | -| `is_clean_route_deep_slow_plus_supported` | | | | -| `is_clean_route_fast_mode_supported` | | X | | -| `is_clean_route_setting_supported` | | | | -| `is_clean_then_mop_mode_supported` | | | | -| `is_clean_time_line_supported` | | | | -| `is_collect_dust_count_show_supported` | | | | -| `is_collect_dust_mode_supported` | X | X | X | -| `is_corner_clean_mode_supported` | | | | -| `is_corner_mop_stretch_supported` | | X | | -| `is_ctm_with_repeat_supported` | | | | -| `is_current_map_restore_enabled` | X | X | X | -| `is_custom_clean_mode_count_supported` | | X | | -| `is_custom_mode_supported` | X | X | X | -| `is_custom_water_box_distance_supported` | | X | X | -| `is_customized_clean_supported` | | | | -| `is_detect_wire_carpet_supported` | | | | -| `is_dirty_object_detect_supported` | | | | -| `is_dirty_replenish_clean_supported` | | X | | -| `is_dry_interval_timer_supported` | | | | -| `is_dss_believable` | | X | | -| `is_dual_band_wi_fi_supported` | | | | -| `is_dust_collection_setting_supported` | X | X | | -| `is_dynamically_add_clean_zones_supported` | | X | | -| `is_dynamically_skip_clean_zone_supported` | | X | | -| `is_egg_dance_mode_supported` | | | | -| `is_egg_mode_supported_from_new_features` | | | | -| `is_exact_custom_mode_supported` | | X | | -| `is_exhibition_function_supported` | | | | -| `is_floor_dir_clean_any_time_supported` | | X | | -| `is_flow_led_setting_supported` | X | | | -| `is_follow_low_obs_supported` | | | | -| `is_full_duples_switch_supported` | | | | -| `is_fw_filter_obstacle_supported` | X | X | | -| `is_gap_deep_clean_supported` | | | | -| `is_goto_pure_clean_path_supported` | | X | | -| `is_hot_wash_towel_supported` | | X | | -| `is_identify_room_supported` | | | | -| `is_ignore_unknown_map_object_supported` | X | X | | -| `is_lds_lifting_supported` | | | | -| `is_led_status_switch_supported` | X | X | X | -| `is_left_water_drain_supported` | | X | | -| `is_low_area_access_supported` | | | | -| `is_main_brush_up_down_supported_from_str` | | X | | -| `is_map_beautify_internal_debug_supported` | X | X | | -| `is_map_carpet_add_support` | | X | | -| `is_map_eraser_supported` | | | | -| `is_matter_supported` | | | | -| `is_max_plus_mode_supported` | | | | -| `is_max_zone_opened_supported` | | | | -| `is_mechanical_arm_mode_supported` | | | | -| `is_midway_back_to_dock_supported` | | | | -| `is_min_battery_15_to_clean_task_supported` | | X | | -| `is_mop_forbidden_supported` | | | | -| `is_mop_path_supported` | X | X | | -| `is_mop_shake_module_supported` | | | | -| `is_mop_shake_water_max_supported` | | | | -| `is_multi_floor_supported` | X | X | X | -| `is_multi_map_segment_timer_supported` | X | X | X | -| `is_new_ai_recognition_supported` | | | | -| `is_new_data_for_clean_history` | X | X | | -| `is_new_data_for_clean_history_detail` | X | X | | -| `is_new_endpoint_supported` | | X | | -| `is_new_remote_view_supported` | | | | -| `is_no_need_carpet_press_set_supported` | | | | -| `is_none_pure_clean_mop_with_max_plus` | | | | -| `is_object_detect_check_supported` | | | | -| `is_offline_map_supported` | | X | | -| `is_optimize_battery_supported` | | | | -| `is_order_clean_supported` | X | X | X | -| `is_over_sea_ctm_supported` | | | | -| `is_pet_snapshot_supported` | | | | -| `is_pet_supplies_deep_clean_supported` | | | | -| `is_program_mode_supported` | | | | -| `is_pumping_water_supported` | | | | -| `is_pure_clean_mop_supported` | | | | -| `is_re_segment_supported` | X | X | X | -| `is_record_allowed` | X | X | | -| `is_remote_supported` | X | X | X | -| `is_right_brush_stretch_supported` | | | | -| `is_room_name_supported` | X | X | X | -| `is_rpc_retry_supported` | | X | | -| `is_rubber_brush_carpet_supported` | | | | -| `is_set_child_supported` | X | X | | -| `is_setting_carpet_first_supported` | | X | | -| `is_shake_mop_set_supported` | X | X | | -| `is_should_show_arm_over_load_supported` | | | | -| `is_show_clean_finish_reason_supported` | X | X | X | -| `is_show_general_obstacle_supported` | | | | -| `is_show_obstacle_photo_supported` | | | | -| `is_side_brush_lift_carpet_supported` | | | | -| `is_small_side_mop_supported` | | | | -| `is_smart_clean_mode_set_supported` | | X | | -| `is_soak_and_wash_supported` | | | | -| `is_soft_clean_mode_supported` | | | | -| `is_sr_map_supported` | | | | -| `is_super_deep_wash_supported` | | X | | -| `is_support_api_app_stop_grasp_supported` | | | | -| `is_support_backup_map` | X | X | X | -| `is_support_clean_estimate` | | X | | -| `is_support_cliff_zone` | | X | | -| `is_support_custom_carpet` | | | | -| `is_support_custom_dnd` | | X | | -| `is_support_custom_door_sill` | | X | | -| `is_support_custom_mode_in_cleaning` | | X | | -| `is_support_fetch_timer_summary` | X | X | X | -| `is_support_floor_direction` | | X | | -| `is_support_floor_edit` | | X | | -| `is_support_furniture` | | X | | -| `is_support_get_particular_status_supported` | | | | -| `is_support_incremental_map` | | X | | -| `is_support_main_brush_up_down_supported` | | | | -| `is_support_mop_back_pwm_set` | | | | -| `is_support_quick_map_builder` | X | X | X | -| `is_support_remote_control_in_call` | | X | | -| `is_support_room_tag` | | X | | -| `is_support_set_switch_map_mode` | | X | | -| `is_support_set_volume_in_call` | | X | | -| `is_support_side_brush_up_down_supported` | | | | -| `is_support_smart_door_sill` | | X | | -| `is_support_smart_global_clean_with_custom_mode` | | X | | -| `is_support_smart_scene` | | X | | -| `is_support_stuck_zone` | | X | | -| `is_support_voice_control_debug` | | | | -| `is_support_water_mode` | | | | -| `is_supported_download_test_voice` | | X | | -| `is_supported_drying` | | X | | -| `is_supported_valley_electricity` | | X | | -| `is_sync_server_name_supported` | | | | -| `is_three_d_mapping_inner_test_supported` | | | | -| `is_tidyup_zones_supported` | | | | -| `is_two_gears_no_collision_supported` | | | | -| `is_two_key_real_time_video_supported` | | X | | -| `is_two_key_rtv_in_charging_supported` | | X | | -| `is_type_identify_supported` | | | | -| `is_unsave_map_reason_supported` | X | X | X | -| `is_uvc_sterilize_supported` | | | | -| `is_video_monitor_supported` | X | X | | -| `is_video_patrol_supported` | | | | -| `is_video_setting_supported` | X | X | | -| `is_voice_control_led_supported` | | | | -| `is_voice_control_supported` | | X | | -| `is_wash_then_charge_cmd_supported` | | X | | -| `is_water_leak_check_supported` | | X | | -| `is_water_slide_mode_supported` | | | | -| `is_water_up_down_drain_supported` | | X | | -| `is_wifi_manage_supported` | | X | | -| `is_workday_holiday_supported` | | | | +| Feature | roborock.vacuum.a10 | roborock.vacuum.a117 | roborock.vacuum.a123 | roborock.vacuum.a125 | roborock.vacuum.a144 | roborock.vacuum.a147 | roborock.vacuum.a15 | roborock.vacuum.a187 | roborock.vacuum.a27 | roborock.vacuum.a87 | roborock.vacuum.s5e | roborock.vacuum.sc01 | roborock.vacuum.sc05 | roborock.vacuum.ss07 | roborock.wm.a102 | +|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| +| product_nickname | TANOSV | PEARLPLUSS | PEARLSLITE | ULTRONSE | CORALPRO | VERDELITE | TANOSS | Unknown | TOPAZSV | PEARLPLUS | RUBYSLITE | Unknown | PEARLPLUS | Unknown | Unknown | +| protocol_version | 1.0 | 1.0 | 1.0 | 1.0 | 1.0 | 1.0 | 1.0 | 1.0 | 1.0 | 1.0 | 1.0 | B01 | B01 | B01 | A01 | +| new_feature_info | X | X | 0 | X | X | X | X | X | False | X | X | 0 | | 0 | 0 | +| new_feature_info_str | | X | X | X | X | X | X | X | | X | X | X | | X | X | +| `111` | | X | | | | | X | | | X | X | | | | | +| `112` | | X | | | | | X | | | X | X | | | | | +| `113` | | X | | | | | X | | | X | X | | | | | +| `114` | | X | | | | | X | | | X | X | | | | | +| `115` | | X | | | | | X | | | X | X | | | | | +| `116` | | X | | | | | X | | | X | X | | | | | +| `117` | | X | | | | | X | | | X | X | | | | | +| `118` | | X | | | | | X | | | X | X | | | | | +| `119` | | X | | | | | X | | | X | X | | | | | +| `120` | | X | | | | | X | | | X | X | | | | | +| `121` | | X | | | | | | | | X | | | | | | +| `122` | | X | | | | | X | | | X | X | | | | | +| `123` | | X | | | | | X | | | X | X | | | | | +| `124` | | X | | | | | X | | | X | X | | | | | +| `125` | | X | | | | | X | | | X | X | | | | | +| `feature_info` | | X | | | | | X | | | X | X | | | | | +| `is_activate_video_charging_and_standby_supported` | | | | | X | | | | | | | | | | | +| `is_analysis_supported` | | X | | | | | X | | | X | X | | | | | +| `is_any_state_transit_goto_supported` | X | X | | X | X | X | X | X | | X | | | | | | +| `is_auto_collection_2_supported` | | X | X | | X | X | | X | | | | | | | | +| `is_auto_delivery_field_in_global_status_supported` | | X | X | | X | X | | X | | X | | | | | | +| `is_auto_tear_down_mop_supported` | | | | | X | X | | | | | | | | | | +| `is_avoid_collision_mode_supported` | | X | X | | X | X | | X | | X | | | | | | +| `is_avoid_collision_supported` | | X | | | X | X | | X | | X | | | | | | +| `is_back_charge_auto_wash_supported` | | X | X | X | X | X | | X | | X | | | | | | +| `is_back_wash_new_smart_supported` | | | | | | | | | | | | | | | | +| `is_careful_slow_mop_supported` | | X | | X | X | X | X | X | | X | | | | | | +| `is_carpet_custom_clean_supported` | | X | X | | X | X | | X | | X | | | | | | +| `is_carpet_deep_clean_supported` | | X | X | | X | X | | X | | X | | | | | | +| `is_carpet_long_haired_ex_supported` | | | | | | | | | | | | | | | | +| `is_carpet_long_haired_supported` | | | | | X | X | | | | | | | | | | +| `is_carpet_pressure_use_origin_paras_supported` | | | | | | | | | | | | | | | | +| `is_carpet_shape_type_supported` | | | | | | | | | | | | | | | | +| `is_carpet_show_on_map` | | X | | X | X | X | | X | | X | | | | | | +| `is_carpet_supported` | | X | | | X | X | X | X | | X | | | | | | +| `is_ces_2022_supported` | | | | | | | | | | | | | | | | +| `is_clean_count_setting_supported` | | X | X | | X | X | | X | | X | | | | | | +| `is_clean_direct_status_supported` | | | | | X | X | | X | | | | | | | | +| `is_clean_efficiency_supported` | | | | | | | | | | | | | | | | +| `is_clean_fluid_delivery_supported` | | | | | X | | | | | | | | | | | +| `is_clean_history_time_line_supported` | | | | | X | X | | X | | | | | | | | +| `is_clean_route_deep_slow_plus_supported` | | | | | | | | | | | | | | | | +| `is_clean_route_fast_mode_supported` | | X | X | X | X | X | | X | | X | | | | | | +| `is_clean_route_setting_supported` | | | | | | | | | | | | | | | | +| `is_clean_then_mop_mode_supported` | | | | | X | | | X | | | | | | | | +| `is_clean_time_line_supported` | | | | | X | X | | X | | | | | | | | +| `is_collect_dust_count_show_supported` | | | | | X | | | | | | | | | | | +| `is_collect_dust_mode_supported` | X | X | X | X | X | X | X | X | X | X | X | X | X | X | X | +| `is_corner_clean_mode_supported` | | | | | | | | | | | | | | | | +| `is_corner_mop_stretch_supported` | | X | X | | X | | | X | | X | | | | | | +| `is_ctm_with_repeat_supported` | | | | | X | | | X | | | | | | | | +| `is_current_map_restore_enabled` | X | X | | X | X | X | X | X | | X | X | | | | | +| `is_custom_clean_mode_count_supported` | | X | X | | X | X | | X | | X | | | | | | +| `is_custom_mode_supported` | X | X | X | X | X | X | X | X | X | X | X | X | X | X | X | +| `is_custom_water_box_distance_supported` | X | X | | | X | | | X | | X | X | | | | | +| `is_customized_clean_supported` | | | | | | | | | | | | | | | | +| `is_detect_wire_carpet_supported` | | | | | X | | | | | | | | | | | +| `is_dirty_object_detect_supported` | | | | | X | X | | | | | | | | | | +| `is_dirty_replenish_clean_supported` | | X | | | X | X | | X | | X | | | | | | +| `is_dry_interval_timer_supported` | | | | | X | X | | X | | | | | | | | +| `is_dss_believable` | | X | X | X | X | X | | X | | X | | | | | | +| `is_dual_band_wi_fi_supported` | | | | | | | | | | | | | | | | +| `is_dust_collection_setting_supported` | | X | | X | X | X | X | X | | X | | | | | | +| `is_dynamically_add_clean_zones_supported` | | X | X | | X | X | | X | | X | | | | | | +| `is_dynamically_skip_clean_zone_supported` | | X | X | | X | X | | X | | X | | | | | | +| `is_egg_dance_mode_supported` | | | | | X | X | | | | | | | | | | +| `is_egg_mode_supported_from_new_features` | | | | | | | | | | | | | | | | +| `is_exact_custom_mode_supported` | | X | X | | X | X | | X | | X | | | | | | +| `is_exhibition_function_supported` | | | | | | | | | | | | | | | | +| `is_floor_dir_clean_any_time_supported` | | X | X | | X | X | | X | | X | | | | | | +| `is_flow_led_setting_supported` | | | | | | | X | | | | | | | | | +| `is_follow_low_obs_supported` | | | | | | | | | | | | | | | | +| `is_full_duples_switch_supported` | | | | | | | | | | | | | | | | +| `is_fw_filter_obstacle_supported` | X | X | | X | X | X | X | X | | X | | | | | | +| `is_gap_deep_clean_supported` | | X | | | X | X | | X | | | | | | | | +| `is_goto_pure_clean_path_supported` | | X | X | X | X | X | | X | | X | | | | | | +| `is_hot_wash_towel_supported` | | X | | | X | X | | X | | X | | | | | | +| `is_identify_room_supported` | | | | | X | X | | | | | | | | | | +| `is_ignore_unknown_map_object_supported` | X | X | | X | X | X | X | X | | X | | | | | | +| `is_lds_lifting_supported` | | | | | | X | | | | | | | | | | +| `is_led_status_switch_supported` | | X | | | | | X | | | X | X | | | | | +| `is_left_water_drain_supported` | | X | X | X | X | X | | X | | X | | | | | | +| `is_low_area_access_supported` | | | | | | | | | | | | | | | | +| `is_main_brush_up_down_supported_from_str` | | X | | | X | X | | X | | X | | | | | | +| `is_map_beautify_internal_debug_supported` | | X | | X | X | X | X | X | | X | | | | | | +| `is_map_carpet_add_support` | | X | | | X | X | | X | | X | | | | | | +| `is_map_eraser_supported` | | | | | X | X | | X | | | | | | | | +| `is_matter_supported` | | X | | | X | X | | X | | | | | | | | +| `is_max_plus_mode_supported` | | | | | | | | | | | | | | | | +| `is_max_zone_opened_supported` | | | | | X | X | | X | | | | | | | | +| `is_mechanical_arm_mode_supported` | | | | | | | | | | | | | | | | +| `is_midway_back_to_dock_supported` | | | | | X | X | | X | | | | | | | | +| `is_min_battery_15_to_clean_task_supported` | | X | X | | X | X | | X | | X | | | | | | +| `is_mop_forbidden_supported` | | | | | | | | | | | | | | | | +| `is_mop_path_supported` | | X | | | X | X | X | X | | X | | | | | | +| `is_mop_shake_module_supported` | | | | | | | | | | | | | | | | +| `is_mop_shake_water_max_supported` | | | | | | X | | | | | | | | | | +| `is_multi_floor_supported` | | X | | | | | X | | | X | X | | | | | +| `is_multi_map_segment_timer_supported` | X | X | | X | X | X | X | X | | X | X | | | | | +| `is_new_ai_recognition_supported` | | X | X | | X | X | | X | | | | | | | | +| `is_new_data_for_clean_history` | | X | | X | X | X | X | X | | X | | | | | | +| `is_new_data_for_clean_history_detail` | | X | | X | X | X | X | X | | X | | | | | | +| `is_new_endpoint_supported` | | X | X | X | X | X | | X | | X | | | | | | +| `is_new_remote_view_supported` | | | | | | | | | | | | | | | | +| `is_no_need_carpet_press_set_supported` | | X | X | | X | X | | X | | | | | | | | +| `is_none_pure_clean_mop_with_max_plus` | | | | | | | | | | | | | | | | +| `is_object_detect_check_supported` | | X | | | X | X | | X | | | | | | | | +| `is_offline_map_supported` | | X | X | X | X | X | | X | | X | | | | | | +| `is_optimize_battery_supported` | | | | | | | | | | | | | | | | +| `is_order_clean_supported` | | X | | | | | X | | | X | X | | | | | +| `is_over_sea_ctm_supported` | | | | | X | | | X | | | | | | | | +| `is_pet_snapshot_supported` | | X | | | X | X | | | | | | | | | | +| `is_pet_supplies_deep_clean_supported` | | X | X | | X | X | | X | | | | | | | | +| `is_program_mode_supported` | | | | | | | | | | | | | | | | +| `is_pumping_water_supported` | | | | | | | | | | | | | | | | +| `is_pure_clean_mop_supported` | | | | | | | | | | | | | | | | +| `is_re_segment_supported` | X | X | | X | X | X | X | X | | X | X | | | | | +| `is_record_allowed` | X | X | | X | X | X | X | X | | X | | | | | | +| `is_remote_supported` | | X | | | | | X | | | X | X | | | | | +| `is_right_brush_stretch_supported` | | X | | | X | X | | X | | | | | | | | +| `is_room_name_supported` | X | X | | X | X | X | X | X | | X | X | | | | | +| `is_rpc_retry_supported` | | X | | X | X | X | | X | | X | | | | | | +| `is_rubber_brush_carpet_supported` | | | | | | | | | | | | | | | | +| `is_set_child_supported` | X | X | | X | X | X | X | X | | X | | | | | | +| `is_setting_carpet_first_supported` | | X | X | | X | X | | X | | X | | | | | | +| `is_shake_mop_set_supported` | | X | | X | X | X | X | X | | X | | | | | | +| `is_should_show_arm_over_load_supported` | | | | | | | | | | | | | | | | +| `is_show_clean_finish_reason_supported` | X | X | | X | X | X | X | X | | X | X | | | | | +| `is_show_general_obstacle_supported` | | | | | | | | | | | | | | | | +| `is_show_obstacle_photo_supported` | | | | | | | | | | | | | | | | +| `is_side_brush_lift_carpet_supported` | | | | | X | | | | | | | | | | | +| `is_small_side_mop_supported` | | | | | | X | | | | | | | | | | +| `is_smart_clean_mode_set_supported` | | X | X | | X | X | | X | | X | | | | | | +| `is_soak_and_wash_supported` | | | | | | | | | | | | | | | | +| `is_soft_clean_mode_supported` | | | | | | | | | | | | | | | | +| `is_sr_map_supported` | | | | | | | | | | | | | | | | +| `is_super_deep_wash_supported` | | X | X | X | X | X | | X | | X | | | | | | +| `is_support_api_app_stop_grasp_supported` | | | | | | | | | | | | | | | | +| `is_support_backup_map` | | X | | X | X | X | X | X | | X | X | | | | | +| `is_support_clean_estimate` | | X | X | X | X | X | | X | | X | | | | | | +| `is_support_cliff_zone` | | X | X | X | X | X | | X | | X | | | | | | +| `is_support_custom_carpet` | | | | | | | | | | | | | | | | +| `is_support_custom_dnd` | | X | X | X | X | X | | X | | X | | | | | | +| `is_support_custom_door_sill` | | X | X | X | X | X | | X | | X | | | | | | +| `is_support_custom_mode_in_cleaning` | | X | | X | X | X | | X | | X | | | | | | +| `is_support_fetch_timer_summary` | | X | | | | | X | | | X | X | | | | | +| `is_support_floor_direction` | | X | X | X | X | X | | X | | X | | | | | | +| `is_support_floor_edit` | | X | | X | X | X | | X | | X | | | | | | +| `is_support_furniture` | | X | | X | X | X | | X | | X | | | | | | +| `is_support_get_particular_status_supported` | | | | | | | | | | | | | | | | +| `is_support_incremental_map` | | X | X | X | X | X | | X | | X | | | | | | +| `is_support_main_brush_up_down_supported` | | | | | X | X | | | | | | | | | | +| `is_support_mop_back_pwm_set` | | | | | | | | | | | | | | | | +| `is_support_quick_map_builder` | | X | | X | X | X | X | X | | X | X | | | | | +| `is_support_remote_control_in_call` | | X | | | X | X | | | | X | | | | | | +| `is_support_room_tag` | | X | | X | X | X | | X | | X | | | | | | +| `is_support_set_switch_map_mode` | | X | | X | X | X | | X | | X | | | | | | +| `is_support_set_volume_in_call` | | X | | | X | X | | | | X | | | | | | +| `is_support_side_brush_up_down_supported` | | | | | X | X | | | | | | | | | | +| `is_support_smart_door_sill` | | X | X | X | X | X | | X | | X | | | | | | +| `is_support_smart_global_clean_with_custom_mode` | | X | | X | X | X | | X | | X | | | | | | +| `is_support_smart_scene` | X | X | | X | X | X | | X | | X | | | | | | +| `is_support_stuck_zone` | | X | X | X | X | X | | X | | X | | | | | | +| `is_support_voice_control_debug` | | | | | | | | | | | | | | | | +| `is_support_water_mode` | | | | | | | | | | | | | | | | +| `is_supported_download_test_voice` | | X | | X | X | X | | X | | X | | | | | | +| `is_supported_drying` | | X | | | X | X | | X | | X | | | | | | +| `is_supported_valley_electricity` | | X | | X | X | X | | X | | X | | | | | | +| `is_sync_server_name_supported` | | | | | | | | | | | | | | | | +| `is_three_d_mapping_inner_test_supported` | | | | | | | | | | | | | | | | +| `is_tidyup_zones_supported` | | | | | | | | | | | | | | | | +| `is_two_gears_no_collision_supported` | | | | | | | | | | | | | | | | +| `is_two_key_real_time_video_supported` | | X | | | X | | | | | X | | | | | | +| `is_two_key_rtv_in_charging_supported` | | X | | | X | X | | | | X | | | | | | +| `is_type_identify_supported` | | | | | | | | | | | | | | | | +| `is_unsave_map_reason_supported` | | X | | X | X | X | X | X | | X | X | | | | | +| `is_uvc_sterilize_supported` | | | | | | | | | | | | | | | | +| `is_video_monitor_supported` | X | X | | X | X | X | X | X | | X | | | | | | +| `is_video_patrol_supported` | | X | | | X | X | | | | | | | | | | +| `is_video_setting_supported` | X | X | | X | X | X | X | X | | X | | | | | | +| `is_voice_control_led_supported` | | | | | X | X | | | | | | | | | | +| `is_voice_control_supported` | | X | | | X | X | | | | X | | | | | | +| `is_wash_then_charge_cmd_supported` | | X | | X | X | X | | X | | X | | | | | | +| `is_water_leak_check_supported` | | | | | | X | | | | X | | | | | | +| `is_water_slide_mode_supported` | | | | | X | | | | | | | | | | | +| `is_water_up_down_drain_supported` | | X | X | X | X | X | | X | | X | | | | | | +| `is_wifi_manage_supported` | | X | X | X | X | X | | X | | X | | | | | | +| `is_workday_holiday_supported` | | | | | | | | | | | | | | | | diff --git a/device_info.yaml b/device_info.yaml index 3125fcee..e2db9931 100644 --- a/device_info.yaml +++ b/device_info.yaml @@ -1,3 +1,107 @@ +roborock.vacuum.a10: + protocol_version: '1.0' + product_nickname: TANOSV + new_feature_info: 10738169343 + product: + id: 7ggJhlYqQs58zKFAOgBPc1 + name: S6 MaxV + model: roborock.vacuum.a10 + category: robot.vacuum.cleaner + capability: 2 + schema: + - id: 101 + name: rpc_request + code: rpc_request + mode: rw + type: RAW + - id: 102 + name: rpc_response + code: rpc_response + mode: rw + type: RAW + - id: 120 + name: "\u9519\u8BEF\u4EE3\u7801" + code: error_code + mode: ro + type: ENUM + property: '{"range": []}' + - id: 121 + name: "\u8BBE\u5907\u72B6\u6001" + code: state + mode: ro + type: ENUM + property: '{"range": []}' + - id: 122 + name: "\u8BBE\u5907\u7535\u91CF" + code: battery + mode: ro + type: ENUM + property: '{"range": []}' + - id: 123 + name: "\u6E05\u626B\u6A21\u5F0F" + code: fan_power + mode: rw + type: ENUM + property: '{"range": []}' + - id: 124 + name: "\u62D6\u5730\u6A21\u5F0F" + code: water_box_mode + mode: rw + type: ENUM + property: '{"range": []}' + - id: 125 + name: "\u4E3B\u5237\u5BFF\u547D" + code: main_brush_life + mode: rw + type: VALUE + property: '{"max": 100, "min": 0, "step": 1, "unit": null, "scale": 1}' + - id: 126 + name: "\u8FB9\u5237\u5BFF\u547D" + code: side_brush_life + mode: rw + type: VALUE + property: '{"max": 100, "min": 0, "step": 1, "unit": null, "scale": 1}' + - id: 127 + name: "\u6EE4\u7F51\u5BFF\u547D" + code: filter_life + mode: rw + type: VALUE + property: '{"max": 100, "min": 0, "step": 1, "unit": null, "scale": 1}' + - id: 128 + name: "\u989D\u5916\u72B6\u6001" + code: additional_props + mode: ro + type: RAW + - id: 130 + name: "\u5B8C\u6210\u4E8B\u4EF6" + code: task_complete + mode: ro + type: RAW + - id: 131 + name: "\u7535\u91CF\u4E0D\u8DB3\u4EFB\u52A1\u53D6\u6D88" + code: task_cancel_low_power + mode: ro + type: RAW + - id: 132 + name: "\u8FD0\u52A8\u4E2D\u4EFB\u52A1\u53D6\u6D88" + code: task_cancel_in_motion + mode: ro + type: RAW + - id: 133 + name: "\u5145\u7535\u72B6\u6001" + code: charge_status + mode: ro + type: RAW + - id: 134 + name: "\u70D8\u5E72\u72B6\u6001" + code: drying_status + mode: ro + type: RAW + - id: 135 + name: "\u79BB\u7EBF\u539F\u56E0\u7EC6\u5206" + code: offline_status + mode: ro + type: RAW roborock.vacuum.a117: protocol_version: '1.0' product_nickname: PEARLPLUSS @@ -119,30 +223,564 @@ roborock.vacuum.a117: code: offline_status mode: ro type: RAW -roborock.vacuum.a15: +roborock.vacuum.a123: protocol_version: '1.0' - product_nickname: TANOSS - 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: PEARLSLITE + new_feature_info: 0 + new_feature_info_str: 42BA8D587EDAFFFE product: - id: 1YYW18rpgyAJTISwb1NM91 - name: S7 - model: roborock.vacuum.a15 + id: 15zrEeDGib2Rn15gviBrvv + name: '**REDACTED**' + model: roborock.vacuum.a123 + category: robot.vacuum.cleaner + capability: 0 + schema: + - id: 101 + name: rpc_request + code: rpc_request + mode: rw + type: RAW + - id: 102 + name: rpc_response + code: rpc_response + mode: rw + type: RAW + - id: 120 + name: "\u9519\u8BEF\u4EE3\u7801" + code: error_code + mode: ro + type: ENUM + property: '{"range": [""]}' + - id: 121 + name: "\u8BBE\u5907\u72B6\u6001" + code: state + mode: ro + type: ENUM + property: '{"range": [""]}' + - id: 122 + name: "\u8BBE\u5907\u7535\u91CF" + code: battery + mode: ro + type: ENUM + property: '{"range": [""]}' + - id: 123 + name: "\u6E05\u626B\u6A21\u5F0F" + code: fan_power + mode: rw + type: ENUM + property: '{"range": [""]}' + - id: 124 + name: "\u62D6\u5730\u6A21\u5F0F" + code: water_box_mode + mode: rw + type: ENUM + property: '{"range": [""]}' + - id: 125 + name: "\u4E3B\u5237\u5BFF\u547D" + code: main_brush_life + mode: rw + type: VALUE + property: '{"max": 100, "min": 0, "step": 1, "unit": "null", "scale": 1}' + - id: 126 + name: "\u8FB9\u5237\u5BFF\u547D" + code: side_brush_life + mode: rw + type: VALUE + property: '{"max": 100, "min": 0, "step": 1, "unit": "null", "scale": 1}' + - id: 127 + name: "\u6EE4\u7F51\u5BFF\u547D" + code: filter_life + mode: rw + type: VALUE + property: '{"max": 100, "min": 0, "step": 1, "unit": "null", "scale": 1}' + - id: 128 + name: "\u989D\u5916\u72B6\u6001" + code: additional_props + mode: ro + type: RAW + - id: 130 + name: "\u5B8C\u6210\u4E8B\u4EF6" + code: task_complete + mode: ro + type: RAW + - id: 131 + name: "\u7535\u91CF\u4E0D\u8DB3\u4EFB\u52A1\u53D6\u6D88" + code: task_cancel_low_power + mode: ro + type: RAW + - id: 132 + name: "\u8FD0\u52A8\u4E2D\u4EFB\u52A1\u53D6\u6D88" + code: task_cancel_in_motion + mode: ro + type: RAW + - id: 133 + name: "\u5145\u7535\u72B6\u6001" + code: charge_status + mode: ro + type: RAW + - id: 134 + name: "\u70D8\u5E72\u72B6\u6001" + code: drying_status + mode: ro + type: RAW + - id: 135 + name: "\u79BB\u7EBF\u539F\u56E0\u7EC6\u5206" + code: offline_status + mode: ro + type: RAW +roborock.vacuum.a125: + protocol_version: '1.0' + product_nickname: ULTRONSE + new_feature_info: 2097860516935167 + new_feature_info_str: 00000040385AFFF6 + product: + id: 2BNKSSVJ0bsXHxTH3KLi6H + name: Q5 Max+ + model: roborock.vacuum.a125 + category: robot.vacuum.cleaner + capability: 0 + schema: + - id: 101 + name: rpc_request + code: rpc_request + mode: rw + type: RAW + - id: 102 + name: rpc_response + code: rpc_response + mode: rw + type: RAW + - id: 120 + name: "\u9519\u8BEF\u4EE3\u7801" + code: error_code + mode: ro + type: ENUM + property: '{"range": [""]}' + - id: 121 + name: "\u8BBE\u5907\u72B6\u6001" + code: state + mode: ro + type: ENUM + property: '{"range": [""]}' + - id: 122 + name: "\u8BBE\u5907\u7535\u91CF" + code: battery + mode: ro + type: ENUM + property: '{"range": [""]}' + - id: 123 + name: "\u6E05\u626B\u6A21\u5F0F" + code: fan_power + mode: rw + type: ENUM + property: '{"range": [""]}' + - id: 124 + name: "\u62D6\u5730\u6A21\u5F0F" + code: water_box_mode + mode: rw + type: ENUM + property: '{"range": [""]}' + - id: 125 + name: "\u4E3B\u5237\u5BFF\u547D" + code: main_brush_life + mode: rw + type: VALUE + property: '{"max": 100, "min": 0, "step": 1, "unit": "null", "scale": 1}' + - id: 126 + name: "\u8FB9\u5237\u5BFF\u547D" + code: side_brush_life + mode: rw + type: VALUE + property: '{"max": 100, "min": 0, "step": 1, "unit": "null", "scale": 1}' + - id: 127 + name: "\u6EE4\u7F51\u5BFF\u547D" + code: filter_life + mode: rw + type: VALUE + property: '{"max": 100, "min": 0, "step": 1, "unit": "null", "scale": 1}' + - id: 128 + name: "\u989D\u5916\u72B6\u6001" + code: additional_props + mode: ro + type: RAW + - id: 130 + name: "\u5B8C\u6210\u4E8B\u4EF6" + code: task_complete + mode: ro + type: RAW + - id: 131 + name: "\u7535\u91CF\u4E0D\u8DB3\u4EFB\u52A1\u53D6\u6D88" + code: task_cancel_low_power + mode: ro + type: RAW + - id: 132 + name: "\u8FD0\u52A8\u4E2D\u4EFB\u52A1\u53D6\u6D88" + code: task_cancel_in_motion + mode: ro + type: RAW + - id: 133 + name: "\u5145\u7535\u72B6\u6001" + code: charge_status + mode: ro + type: RAW + - id: 134 + name: "\u70D8\u5E72\u72B6\u6001" + code: drying_status + mode: ro + type: RAW + - id: 135 + name: "\u79BB\u7EBF\u539F\u56E0\u7EC6\u5206" + code: offline_status + mode: ro + type: RAW +roborock.vacuum.a147: + protocol_version: '1.0' + product_nickname: VERDELITE + new_feature_info: 4499195120484351 + new_feature_info_str: 0000000008EFBCDDDFFFAE7E7EFEFFFF + product: + id: 1KtYm84Say3qrqaqNAWebE + name: Saros 10 + model: roborock.vacuum.a147 + category: robot.vacuum.cleaner + capability: 0 + schema: + - id: 101 + name: rpc_request + code: rpc_request + mode: rw + type: RAW + - id: 102 + name: rpc_response + code: rpc_response + mode: rw + type: RAW + - id: 120 + name: "\u9519\u8BEF\u4EE3\u7801" + code: error_code + mode: ro + type: ENUM + property: '{"range": [""]}' + - id: 121 + name: "\u8BBE\u5907\u72B6\u6001" + code: state + mode: ro + type: ENUM + property: '{"range": [""]}' + - id: 122 + name: "\u8BBE\u5907\u7535\u91CF" + code: battery + mode: ro + type: ENUM + property: '{"range": [""]}' + - id: 123 + name: "\u6E05\u626B\u6A21\u5F0F" + code: fan_power + mode: rw + type: ENUM + property: '{"range": [""]}' + - id: 124 + name: "\u62D6\u5730\u6A21\u5F0F" + code: water_box_mode + mode: rw + type: ENUM + property: '{"range": [""]}' + - id: 125 + name: "\u4E3B\u5237\u5BFF\u547D" + code: main_brush_life + mode: rw + type: VALUE + property: '{"max": 100, "min": 0, "step": 1, "unit": "null", "scale": 1}' + - id: 126 + name: "\u8FB9\u5237\u5BFF\u547D" + code: side_brush_life + mode: rw + type: VALUE + property: '{"max": 100, "min": 0, "step": 1, "unit": "null", "scale": 1}' + - id: 127 + name: "\u6EE4\u7F51\u5BFF\u547D" + code: filter_life + mode: rw + type: VALUE + property: '{"max": 100, "min": 0, "step": 1, "unit": "null", "scale": 1}' + - id: 128 + name: "\u989D\u5916\u72B6\u6001" + code: additional_props + mode: ro + type: RAW + - id: 130 + name: "\u5B8C\u6210\u4E8B\u4EF6" + code: task_complete + mode: ro + type: RAW + - id: 131 + name: "\u7535\u91CF\u4E0D\u8DB3\u4EFB\u52A1\u53D6\u6D88" + code: task_cancel_low_power + mode: ro + type: RAW + - id: 132 + name: "\u8FD0\u52A8\u4E2D\u4EFB\u52A1\u53D6\u6D88" + code: task_cancel_in_motion + mode: ro + type: RAW + - id: 133 + name: "\u5145\u7535\u72B6\u6001" + code: charge_status + mode: ro + type: RAW + - id: 134 + name: "\u70D8\u5E72\u72B6\u6001" + code: drying_status + mode: ro + type: RAW + - id: 135 + name: "\u79BB\u7EBF\u539F\u56E0\u7EC6\u5206" + code: offline_status + mode: ro + type: RAW + - id: 139 + name: "\u56DE\u57FA\u7AD9\u76EE\u7684" + code: back_type + mode: ro + type: RAW +roborock.vacuum.a15: + protocol_version: '1.0' + product_nickname: TANOSS + 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: + id: 1YYW18rpgyAJTISwb1NM91 + name: S7 + model: roborock.vacuum.a15 + category: robot.vacuum.cleaner + capability: 0 + schema: + - id: 101 + name: rpc_request + code: rpc_request + mode: rw + type: RAW + - id: 102 + name: rpc_response + code: rpc_response + mode: rw + type: RAW + - id: 120 + name: "\u9519\u8BEF\u4EE3\u7801" + code: error_code + mode: ro + type: ENUM + property: '{"range": []}' + - id: 121 + name: "\u8BBE\u5907\u72B6\u6001" + code: state + mode: ro + type: ENUM + property: '{"range": []}' + - id: 122 + name: "\u8BBE\u5907\u7535\u91CF" + code: battery + mode: ro + type: ENUM + property: '{"range": []}' + - id: 123 + name: "\u6E05\u626B\u6A21\u5F0F" + code: fan_power + mode: rw + type: ENUM + property: '{"range": []}' + - id: 124 + name: "\u62D6\u5730\u6A21\u5F0F" + code: water_box_mode + mode: rw + type: ENUM + property: '{"range": []}' + - id: 125 + name: "\u4E3B\u5237\u5BFF\u547D" + code: main_brush_life + mode: rw + type: VALUE + property: '{"max": 100, "min": 0, "step": 1, "unit": null, "scale": 1}' + - id: 126 + name: "\u8FB9\u5237\u5BFF\u547D" + code: side_brush_life + mode: rw + type: VALUE + property: '{"max": 100, "min": 0, "step": 1, "unit": null, "scale": 1}' + - id: 127 + name: "\u6EE4\u7F51\u5BFF\u547D" + code: filter_life + mode: rw + type: VALUE + property: '{"max": 100, "min": 0, "step": 1, "unit": null, "scale": 1}' + - id: 128 + name: "\u989D\u5916\u72B6\u6001" + code: additional_props + mode: ro + type: RAW + - id: 130 + name: "\u5B8C\u6210\u4E8B\u4EF6" + code: task_complete + mode: ro + type: RAW + - id: 131 + name: "\u7535\u91CF\u4E0D\u8DB3\u4EFB\u52A1\u53D6\u6D88" + code: task_cancel_low_power + mode: ro + type: RAW + - id: 132 + name: "\u8FD0\u52A8\u4E2D\u4EFB\u52A1\u53D6\u6D88" + code: task_cancel_in_motion + mode: ro + type: RAW + - id: 133 + name: "\u5145\u7535\u72B6\u6001" + code: charge_status + mode: ro + type: RAW + - id: 134 + name: "\u70D8\u5E72\u72B6\u6001" + code: drying_status + mode: ro + type: RAW + - id: 135 + name: "\u79BB\u7EBF\u539F\u56E0\u7EC6\u5206" + code: offline_status + mode: ro + type: RAW +roborock.vacuum.a187: + protocol_version: '1.0' + product_nickname: Unknown + new_feature_info: 2247397454282751 + new_feature_info_str: 00040040282834C9C2FA8F5C7EDEFFFE + product: + id: 7gkjgsDwbTIwhqpDKoETBi + name: Roborock Qrevo Edge Series + model: roborock.vacuum.a187 + category: robot.vacuum.cleaner + capability: 0 + schema: + - id: 101 + name: rpc_request + code: rpc_request + mode: rw + type: RAW + - id: 102 + name: rpc_response + code: rpc_response + mode: rw + type: RAW + - id: 120 + name: "\u9519\u8BEF\u4EE3\u7801" + code: error_code + mode: ro + type: ENUM + property: '{"range": [""]}' + - id: 121 + name: "\u8BBE\u5907\u72B6\u6001" + code: state + mode: ro + type: ENUM + property: '{"range": [""]}' + - id: 122 + name: "\u8BBE\u5907\u7535\u91CF" + code: battery + mode: ro + type: ENUM + property: '{"range": [""]}' + - id: 123 + name: "\u6E05\u626B\u6A21\u5F0F" + code: fan_power + mode: rw + type: ENUM + property: '{"range": [""]}' + - id: 124 + name: "\u62D6\u5730\u6A21\u5F0F" + code: water_box_mode + mode: rw + type: ENUM + property: '{"range": [""]}' + - id: 125 + name: "\u4E3B\u5237\u5BFF\u547D" + code: main_brush_life + mode: rw + type: VALUE + property: '{"max": 100, "min": 0, "step": 1, "unit": "null", "scale": 1}' + - id: 126 + name: "\u8FB9\u5237\u5BFF\u547D" + code: side_brush_life + mode: rw + type: VALUE + property: '{"max": 100, "min": 0, "step": 1, "unit": "null", "scale": 1}' + - id: 127 + name: "\u6EE4\u7F51\u5BFF\u547D" + code: filter_life + mode: rw + type: VALUE + property: '{"max": 100, "min": 0, "step": 1, "unit": "null", "scale": 1}' + - id: 128 + name: "\u989D\u5916\u72B6\u6001" + code: additional_props + mode: ro + type: RAW + - id: 130 + name: "\u5B8C\u6210\u4E8B\u4EF6" + code: task_complete + mode: ro + type: RAW + - id: 131 + name: "\u7535\u91CF\u4E0D\u8DB3\u4EFB\u52A1\u53D6\u6D88" + code: task_cancel_low_power + mode: ro + type: RAW + - id: 132 + name: "\u8FD0\u52A8\u4E2D\u4EFB\u52A1\u53D6\u6D88" + code: task_cancel_in_motion + mode: ro + type: RAW + - id: 133 + name: "\u5145\u7535\u72B6\u6001" + code: charge_status + mode: ro + type: RAW + - id: 134 + name: "\u70D8\u5E72\u72B6\u6001" + code: drying_status + mode: ro + type: RAW + - id: 135 + name: "\u79BB\u7EBF\u539F\u56E0\u7EC6\u5206" + code: offline_status + mode: ro + type: RAW + - id: 139 + name: "\u56DE\u57FA\u7AD9\u76EE\u7684" + code: back_type + mode: ro + type: RAW +roborock.vacuum.a27: + protocol_version: '1.0' + product_nickname: TOPAZSV + new_feature_info: false + product: + id: 3FvTMilsXUPmxlqAeOsIrB + name: '**REDACTED**' + model: roborock.vacuum.a27 category: robot.vacuum.cleaner capability: 0 schema: diff --git a/roborock/cli.py b/roborock/cli.py index b2b208ff..c883604a 100644 --- a/roborock/cli.py +++ b/roborock/cli.py @@ -878,12 +878,12 @@ def _parse_diagnostic_file(diagnostic_path: Path) -> dict[str, dict[str, Any]]: device_features = traits_data.get("device_features", {}) # newFeatureInfo is the integer - new_feature_info = device_features.get("newFeatureInfo") + new_feature_info = device_features.get("newFeatureInfo", device_data.get("featureSet")) if new_feature_info is not None: - current_product_data["new_feature_info"] = new_feature_info + current_product_data["new_feature_info"] = int(new_feature_info) # newFeatureInfoStr is the hex string - new_feature_info_str = device_features.get("newFeatureInfoStr") + new_feature_info_str = device_data.get("newFeatureSet") if new_feature_info_str: current_product_data["new_feature_info_str"] = new_feature_info_str @@ -1048,29 +1048,67 @@ def update_docs(data_file: str, output_file: str): data_path = Path(data_file) output_path = Path(output_file) - if not data_path.exists(): - click.echo(f"Error: Data file not found at '{data_path}'", err=True) - return - - click.echo(f"Loading data from {data_path}...") - with open(data_path, encoding="utf-8") as f: - product_data_from_yaml = yaml.safe_load(f) - - if not product_data_from_yaml: - click.echo("No data found in YAML file. Exiting.", err=True) + product_data_from_yaml = {} + if data_path.exists(): + click.echo(f"Loading data from {data_path}...") + with open(data_path, encoding="utf-8") as f: + product_data_from_yaml = yaml.safe_load(f) or {} + else: + click.echo(f"Data file not found at '{data_path}', will try testdata.") + + combined_product_data = {} + + testdata_path = Path("tests/testdata") + if testdata_path.exists(): + products_by_id = {} + for f in testdata_path.glob("home_data_product_*.json"): + with open(f, encoding="utf-8") as file: + data = json.load(file) + products_by_id[data.get("id")] = data + + loaded_testdata = False + for f in testdata_path.glob("home_data_device_*.json"): + with open(f, encoding="utf-8") as file: + device_data = json.load(file) + product_id = device_data["productId"] + if product_id in products_by_id: + product_data = products_by_id[product_id] + model = product_data["model"] + short_model = model.split(".")[-1] + product_nickname = SHORT_MODEL_TO_ENUM.get(short_model) + feature_set = device_data.get("featureSet", "0") + new_feature_set = device_data.get("newFeatureSet", "0") + combined_product_data[model] = { + "product_nickname": product_nickname.name if product_nickname else "Unknown", + "protocol_version": device_data["pv"], + "new_feature_info": int(feature_set), + "new_feature_info_str": new_feature_set, + "feature_info": [], + } + print("Loaded %s", product_id) + loaded_testdata = True + if loaded_testdata: + click.echo("Loaded mock testdata from local repository.") + + if product_data_from_yaml: + for model, data in product_data_from_yaml.items(): + combined_product_data[model] = data + + if not combined_product_data: + click.echo("No data found from YAML or testdata. Exiting.", err=True) return product_features_map = {} all_feature_names = set() - # Process the raw data from YAML to build the feature map - for model, data in product_data_from_yaml.items(): + # Process the combined data to build the feature map + for model, data in combined_product_data.items(): # Reconstruct the DeviceFeatures object from the raw data in the YAML file device_features = DeviceFeatures.from_feature_flags( - new_feature_info=data.get("new_feature_info"), - new_feature_info_str=data.get("new_feature_info_str"), - feature_info=data.get("feature_info"), - product_nickname=data.get("product_nickname"), + new_feature_info=data.get("new_feature_info", 0), + new_feature_info_str=data.get("new_feature_info_str", ""), + feature_info=data.get("feature_info", []), + product_nickname=data.get("product_nickname", ""), ) features_dict = asdict(device_features)