From 4607eab433949c9308e5b299b768735eba28fe79 Mon Sep 17 00:00:00 2001 From: Paulo Ruberto Date: Fri, 16 Jan 2026 22:38:31 -0500 Subject: [PATCH 1/6] Implement Roborock dock cleaning fluid status --- homeassistant/components/roborock/binary_sensor.py | 14 +++++++++++++- homeassistant/components/roborock/icons.json | 3 +++ homeassistant/components/roborock/strings.json | 3 +++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/roborock/binary_sensor.py b/homeassistant/components/roborock/binary_sensor.py index 687d3a1f72532d..b9a59e50333292 100644 --- a/homeassistant/components/roborock/binary_sensor.py +++ b/homeassistant/components/roborock/binary_sensor.py @@ -5,7 +5,7 @@ from collections.abc import Callable from dataclasses import dataclass -from roborock.data import RoborockStateCode +from roborock.data import CleanFluidStatus, RoborockStateCode from homeassistant.components.binary_sensor import ( BinarySensorDeviceClass, @@ -64,6 +64,18 @@ class RoborockBinarySensorDescription(BinarySensorEntityDescription): entity_category=EntityCategory.DIAGNOSTIC, value_fn=lambda data: data.status.water_shortage_status, ), + RoborockBinarySensorDescription( + key="clean_fluid_empty", + translation_key="clean_fluid_empty", + device_class=BinarySensorDeviceClass.PROBLEM, + entity_category=EntityCategory.DIAGNOSTIC, + value_fn=lambda data: ( + data.status.clean_fluid_status == CleanFluidStatus.empty_not_installed + if data.status.clean_fluid_status is not None + else None + ), + is_dock_entity=True, + ), RoborockBinarySensorDescription( key="in_cleaning", translation_key="in_cleaning", diff --git a/homeassistant/components/roborock/icons.json b/homeassistant/components/roborock/icons.json index b077362cac414e..ab82988358e61a 100644 --- a/homeassistant/components/roborock/icons.json +++ b/homeassistant/components/roborock/icons.json @@ -15,6 +15,9 @@ }, "water_shortage": { "default": "mdi:water" + }, + "clean_fluid_empty": { + "default": "mdi:spray-bottle" } }, "button": { diff --git a/homeassistant/components/roborock/strings.json b/homeassistant/components/roborock/strings.json index 14013131f27100..5545c63ec3c73d 100644 --- a/homeassistant/components/roborock/strings.json +++ b/homeassistant/components/roborock/strings.json @@ -55,6 +55,9 @@ }, "water_shortage": { "name": "Water shortage" + }, + "clean_fluid_empty": { + "name": "Cleaning fluid" } }, "button": { From d10a090346e7db2cf7c48a197b3b63c63ea8f799 Mon Sep 17 00:00:00 2001 From: Paulo Ruberto Date: Fri, 16 Jan 2026 23:23:14 -0500 Subject: [PATCH 2/6] Update test --- tests/components/roborock/mock_data.py | 1 + .../snapshots/test_binary_sensor.ambr | 236 +++++++++--------- 2 files changed, 119 insertions(+), 118 deletions(-) diff --git a/tests/components/roborock/mock_data.py b/tests/components/roborock/mock_data.py index 80a51dff45d6a1..1c02aba12810fb 100644 --- a/tests/components/roborock/mock_data.py +++ b/tests/components/roborock/mock_data.py @@ -1389,6 +1389,7 @@ "home_sec_enable_password": 0, "adbumper_status": [0, 0, 0], "water_shortage_status": 0, + "clean_fluid_status": 0, "dock_type": 3, "dust_collection_status": 0, "auto_dust_collection": 1, diff --git a/tests/components/roborock/snapshots/test_binary_sensor.ambr b/tests/components/roborock/snapshots/test_binary_sensor.ambr index 2213453d00c944..ac5db368f1ee5d 100644 --- a/tests/components/roborock/snapshots/test_binary_sensor.ambr +++ b/tests/components/roborock/snapshots/test_binary_sensor.ambr @@ -1,5 +1,5 @@ # serializer version: 1 -# name: test_binary_sensors[binary_sensor.roborock_s7_2_charging-entry] +# name: test_binary_sensors[binary_sensor.roborock_s7_2-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -12,7 +12,7 @@ 'disabled_by': None, 'domain': 'binary_sensor', 'entity_category': , - 'entity_id': 'binary_sensor.roborock_s7_2_charging', + 'entity_id': 'binary_sensor.roborock_s7_2', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -20,36 +20,36 @@ 'labels': set({ }), 'name': None, - 'object_id_base': 'Charging', + 'object_id_base': None, 'options': dict({ }), - 'original_device_class': , + 'original_device_class': , 'original_icon': None, - 'original_name': 'Charging', + 'original_name': None, 'platform': 'roborock', 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': 0, - 'translation_key': None, - 'unique_id': 'battery_charging_device_2', + 'translation_key': 'mop_attached', + 'unique_id': 'water_box_carriage_status_device_2', 'unit_of_measurement': None, }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_2_charging-state] +# name: test_binary_sensors[binary_sensor.roborock_s7_2-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - 'device_class': 'battery_charging', - 'friendly_name': 'Roborock S7 2 Charging', + 'device_class': 'connectivity', + 'friendly_name': 'Roborock S7 2 None', }), 'context': , - 'entity_id': 'binary_sensor.roborock_s7_2_charging', + 'entity_id': 'binary_sensor.roborock_s7_2', 'last_changed': , 'last_reported': , 'last_updated': , 'state': 'on', }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_2_cleaning-entry] +# name: test_binary_sensors[binary_sensor.roborock_s7_2_2-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -62,7 +62,7 @@ 'disabled_by': None, 'domain': 'binary_sensor', 'entity_category': , - 'entity_id': 'binary_sensor.roborock_s7_2_cleaning', + 'entity_id': 'binary_sensor.roborock_s7_2_2', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -70,36 +70,36 @@ 'labels': set({ }), 'name': None, - 'object_id_base': 'Cleaning', + 'object_id_base': None, 'options': dict({ }), - 'original_device_class': , + 'original_device_class': , 'original_icon': None, - 'original_name': 'Cleaning', + 'original_name': None, 'platform': 'roborock', 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': 0, - 'translation_key': 'in_cleaning', - 'unique_id': 'in_cleaning_device_2', + 'translation_key': 'water_box_attached', + 'unique_id': 'water_box_status_device_2', 'unit_of_measurement': None, }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_2_cleaning-state] +# name: test_binary_sensors[binary_sensor.roborock_s7_2_2-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - 'device_class': 'running', - 'friendly_name': 'Roborock S7 2 Cleaning', + 'device_class': 'connectivity', + 'friendly_name': 'Roborock S7 2 None', }), 'context': , - 'entity_id': 'binary_sensor.roborock_s7_2_cleaning', + 'entity_id': 'binary_sensor.roborock_s7_2_2', 'last_changed': , 'last_reported': , 'last_updated': , - 'state': 'off', + 'state': 'on', }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_2_mop_attached-entry] +# name: test_binary_sensors[binary_sensor.roborock_s7_2_3-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -112,7 +112,7 @@ 'disabled_by': None, 'domain': 'binary_sensor', 'entity_category': , - 'entity_id': 'binary_sensor.roborock_s7_2_mop_attached', + 'entity_id': 'binary_sensor.roborock_s7_2_3', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -120,36 +120,36 @@ 'labels': set({ }), 'name': None, - 'object_id_base': 'Mop attached', + 'object_id_base': None, 'options': dict({ }), - 'original_device_class': , + 'original_device_class': , 'original_icon': None, - 'original_name': 'Mop attached', + 'original_name': None, 'platform': 'roborock', 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': 0, - 'translation_key': 'mop_attached', - 'unique_id': 'water_box_carriage_status_device_2', + 'translation_key': 'water_shortage', + 'unique_id': 'water_shortage_device_2', 'unit_of_measurement': None, }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_2_mop_attached-state] +# name: test_binary_sensors[binary_sensor.roborock_s7_2_3-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - 'device_class': 'connectivity', - 'friendly_name': 'Roborock S7 2 Mop attached', + 'device_class': 'problem', + 'friendly_name': 'Roborock S7 2 None', }), 'context': , - 'entity_id': 'binary_sensor.roborock_s7_2_mop_attached', + 'entity_id': 'binary_sensor.roborock_s7_2_3', 'last_changed': , 'last_reported': , 'last_updated': , - 'state': 'on', + 'state': 'off', }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_2_water_box_attached-entry] +# name: test_binary_sensors[binary_sensor.roborock_s7_2_4-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -162,7 +162,7 @@ 'disabled_by': None, 'domain': 'binary_sensor', 'entity_category': , - 'entity_id': 'binary_sensor.roborock_s7_2_water_box_attached', + 'entity_id': 'binary_sensor.roborock_s7_2_4', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -170,36 +170,36 @@ 'labels': set({ }), 'name': None, - 'object_id_base': 'Water box attached', + 'object_id_base': None, 'options': dict({ }), - 'original_device_class': , + 'original_device_class': , 'original_icon': None, - 'original_name': 'Water box attached', + 'original_name': None, 'platform': 'roborock', 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': 0, - 'translation_key': 'water_box_attached', - 'unique_id': 'water_box_status_device_2', + 'translation_key': 'in_cleaning', + 'unique_id': 'in_cleaning_device_2', 'unit_of_measurement': None, }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_2_water_box_attached-state] +# name: test_binary_sensors[binary_sensor.roborock_s7_2_4-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - 'device_class': 'connectivity', - 'friendly_name': 'Roborock S7 2 Water box attached', + 'device_class': 'running', + 'friendly_name': 'Roborock S7 2 None', }), 'context': , - 'entity_id': 'binary_sensor.roborock_s7_2_water_box_attached', + 'entity_id': 'binary_sensor.roborock_s7_2_4', 'last_changed': , 'last_reported': , 'last_updated': , - 'state': 'on', + 'state': 'off', }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_2_water_shortage-entry] +# name: test_binary_sensors[binary_sensor.roborock_s7_2_5-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -212,7 +212,7 @@ 'disabled_by': None, 'domain': 'binary_sensor', 'entity_category': , - 'entity_id': 'binary_sensor.roborock_s7_2_water_shortage', + 'entity_id': 'binary_sensor.roborock_s7_2_5', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -220,36 +220,36 @@ 'labels': set({ }), 'name': None, - 'object_id_base': 'Water shortage', + 'object_id_base': None, 'options': dict({ }), - 'original_device_class': , + 'original_device_class': , 'original_icon': None, - 'original_name': 'Water shortage', + 'original_name': None, 'platform': 'roborock', 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': 0, - 'translation_key': 'water_shortage', - 'unique_id': 'water_shortage_device_2', + 'translation_key': None, + 'unique_id': 'battery_charging_device_2', 'unit_of_measurement': None, }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_2_water_shortage-state] +# name: test_binary_sensors[binary_sensor.roborock_s7_2_5-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - 'device_class': 'problem', - 'friendly_name': 'Roborock S7 2 Water shortage', + 'device_class': 'battery_charging', + 'friendly_name': 'Roborock S7 2 None', }), 'context': , - 'entity_id': 'binary_sensor.roborock_s7_2_water_shortage', + 'entity_id': 'binary_sensor.roborock_s7_2_5', 'last_changed': , 'last_reported': , 'last_updated': , - 'state': 'off', + 'state': 'on', }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_charging-entry] +# name: test_binary_sensors[binary_sensor.roborock_s7_maxv-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -262,7 +262,7 @@ 'disabled_by': None, 'domain': 'binary_sensor', 'entity_category': , - 'entity_id': 'binary_sensor.roborock_s7_maxv_charging', + 'entity_id': 'binary_sensor.roborock_s7_maxv', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -270,36 +270,36 @@ 'labels': set({ }), 'name': None, - 'object_id_base': 'Charging', + 'object_id_base': None, 'options': dict({ }), - 'original_device_class': , + 'original_device_class': , 'original_icon': None, - 'original_name': 'Charging', + 'original_name': None, 'platform': 'roborock', 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': 0, - 'translation_key': None, - 'unique_id': 'battery_charging_abc123', + 'translation_key': 'mop_attached', + 'unique_id': 'water_box_carriage_status_abc123', 'unit_of_measurement': None, }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_charging-state] +# name: test_binary_sensors[binary_sensor.roborock_s7_maxv-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - 'device_class': 'battery_charging', - 'friendly_name': 'Roborock S7 MaxV Charging', + 'device_class': 'connectivity', + 'friendly_name': 'Roborock S7 MaxV None', }), 'context': , - 'entity_id': 'binary_sensor.roborock_s7_maxv_charging', + 'entity_id': 'binary_sensor.roborock_s7_maxv', 'last_changed': , 'last_reported': , 'last_updated': , 'state': 'on', }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_cleaning-entry] +# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_2-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -312,7 +312,7 @@ 'disabled_by': None, 'domain': 'binary_sensor', 'entity_category': , - 'entity_id': 'binary_sensor.roborock_s7_maxv_cleaning', + 'entity_id': 'binary_sensor.roborock_s7_maxv_2', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -320,36 +320,36 @@ 'labels': set({ }), 'name': None, - 'object_id_base': 'Cleaning', + 'object_id_base': None, 'options': dict({ }), - 'original_device_class': , + 'original_device_class': , 'original_icon': None, - 'original_name': 'Cleaning', + 'original_name': None, 'platform': 'roborock', 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': 0, - 'translation_key': 'in_cleaning', - 'unique_id': 'in_cleaning_abc123', + 'translation_key': 'water_box_attached', + 'unique_id': 'water_box_status_abc123', 'unit_of_measurement': None, }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_cleaning-state] +# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_2-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - 'device_class': 'running', - 'friendly_name': 'Roborock S7 MaxV Cleaning', + 'device_class': 'connectivity', + 'friendly_name': 'Roborock S7 MaxV None', }), 'context': , - 'entity_id': 'binary_sensor.roborock_s7_maxv_cleaning', + 'entity_id': 'binary_sensor.roborock_s7_maxv_2', 'last_changed': , 'last_reported': , 'last_updated': , - 'state': 'off', + 'state': 'on', }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_mop_attached-entry] +# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_3-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -362,7 +362,7 @@ 'disabled_by': None, 'domain': 'binary_sensor', 'entity_category': , - 'entity_id': 'binary_sensor.roborock_s7_maxv_mop_attached', + 'entity_id': 'binary_sensor.roborock_s7_maxv_3', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -370,36 +370,36 @@ 'labels': set({ }), 'name': None, - 'object_id_base': 'Mop attached', + 'object_id_base': None, 'options': dict({ }), - 'original_device_class': , + 'original_device_class': , 'original_icon': None, - 'original_name': 'Mop attached', + 'original_name': None, 'platform': 'roborock', 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': 0, - 'translation_key': 'mop_attached', - 'unique_id': 'water_box_carriage_status_abc123', + 'translation_key': 'water_shortage', + 'unique_id': 'water_shortage_abc123', 'unit_of_measurement': None, }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_mop_attached-state] +# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_3-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - 'device_class': 'connectivity', - 'friendly_name': 'Roborock S7 MaxV Mop attached', + 'device_class': 'problem', + 'friendly_name': 'Roborock S7 MaxV None', }), 'context': , - 'entity_id': 'binary_sensor.roborock_s7_maxv_mop_attached', + 'entity_id': 'binary_sensor.roborock_s7_maxv_3', 'last_changed': , 'last_reported': , 'last_updated': , - 'state': 'on', + 'state': 'off', }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_water_box_attached-entry] +# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_4-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -412,7 +412,7 @@ 'disabled_by': None, 'domain': 'binary_sensor', 'entity_category': , - 'entity_id': 'binary_sensor.roborock_s7_maxv_water_box_attached', + 'entity_id': 'binary_sensor.roborock_s7_maxv_4', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -420,36 +420,36 @@ 'labels': set({ }), 'name': None, - 'object_id_base': 'Water box attached', + 'object_id_base': None, 'options': dict({ }), - 'original_device_class': , + 'original_device_class': , 'original_icon': None, - 'original_name': 'Water box attached', + 'original_name': None, 'platform': 'roborock', 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': 0, - 'translation_key': 'water_box_attached', - 'unique_id': 'water_box_status_abc123', + 'translation_key': 'in_cleaning', + 'unique_id': 'in_cleaning_abc123', 'unit_of_measurement': None, }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_water_box_attached-state] +# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_4-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - 'device_class': 'connectivity', - 'friendly_name': 'Roborock S7 MaxV Water box attached', + 'device_class': 'running', + 'friendly_name': 'Roborock S7 MaxV None', }), 'context': , - 'entity_id': 'binary_sensor.roborock_s7_maxv_water_box_attached', + 'entity_id': 'binary_sensor.roborock_s7_maxv_4', 'last_changed': , 'last_reported': , 'last_updated': , - 'state': 'on', + 'state': 'off', }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_water_shortage-entry] +# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_5-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -462,7 +462,7 @@ 'disabled_by': None, 'domain': 'binary_sensor', 'entity_category': , - 'entity_id': 'binary_sensor.roborock_s7_maxv_water_shortage', + 'entity_id': 'binary_sensor.roborock_s7_maxv_5', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -470,32 +470,32 @@ 'labels': set({ }), 'name': None, - 'object_id_base': 'Water shortage', + 'object_id_base': None, 'options': dict({ }), - 'original_device_class': , + 'original_device_class': , 'original_icon': None, - 'original_name': 'Water shortage', + 'original_name': None, 'platform': 'roborock', 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': 0, - 'translation_key': 'water_shortage', - 'unique_id': 'water_shortage_abc123', + 'translation_key': None, + 'unique_id': 'battery_charging_abc123', 'unit_of_measurement': None, }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_water_shortage-state] +# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_5-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - 'device_class': 'problem', - 'friendly_name': 'Roborock S7 MaxV Water shortage', + 'device_class': 'battery_charging', + 'friendly_name': 'Roborock S7 MaxV None', }), 'context': , - 'entity_id': 'binary_sensor.roborock_s7_maxv_water_shortage', + 'entity_id': 'binary_sensor.roborock_s7_maxv_5', 'last_changed': , 'last_reported': , 'last_updated': , - 'state': 'off', + 'state': 'on', }) # --- From 53d0e1f00ba50fabf33ee54325e8038150e5bb07 Mon Sep 17 00:00:00 2001 From: Paulo Ruberto Date: Mon, 19 Jan 2026 20:24:14 -0500 Subject: [PATCH 3/6] Use is_clean_fluid_delivery_supported --- .../components/roborock/binary_sensor.py | 18 +- tests/components/roborock/conftest.py | 3 + .../snapshots/test_binary_sensor.ambr | 236 +++++++++--------- .../components/roborock/test_binary_sensor.py | 29 +++ 4 files changed, 162 insertions(+), 124 deletions(-) diff --git a/homeassistant/components/roborock/binary_sensor.py b/homeassistant/components/roborock/binary_sensor.py index b9a59e50333292..7d50494e2496ee 100644 --- a/homeassistant/components/roborock/binary_sensor.py +++ b/homeassistant/components/roborock/binary_sensor.py @@ -6,6 +6,7 @@ from dataclasses import dataclass from roborock.data import CleanFluidStatus, RoborockStateCode +from roborock.devices.traits.v1 import PropertiesApi from homeassistant.components.binary_sensor import ( BinarySensorDeviceClass, @@ -33,6 +34,9 @@ class RoborockBinarySensorDescription(BinarySensorEntityDescription): is_dock_entity: bool = False """Whether this sensor is for the dock.""" + feature_supported: Callable[[PropertiesApi], bool] | None = None + """Function to check if the sensor is supported by the device.""" + BINARY_SENSOR_DESCRIPTIONS = [ RoborockBinarySensorDescription( @@ -69,12 +73,10 @@ class RoborockBinarySensorDescription(BinarySensorEntityDescription): translation_key="clean_fluid_empty", device_class=BinarySensorDeviceClass.PROBLEM, entity_category=EntityCategory.DIAGNOSTIC, - value_fn=lambda data: ( - data.status.clean_fluid_status == CleanFluidStatus.empty_not_installed - if data.status.clean_fluid_status is not None - else None - ), + value_fn=lambda data: data.status.clean_fluid_status + == CleanFluidStatus.empty_not_installed, is_dock_entity=True, + feature_supported=lambda api: api.device_features.is_clean_fluid_delivery_supported, ), RoborockBinarySensorDescription( key="in_cleaning", @@ -106,7 +108,11 @@ async def async_setup_entry( ) for coordinator in config_entry.runtime_data.v1 for description in BINARY_SENSOR_DESCRIPTIONS - if description.value_fn(coordinator.data) is not None + if ( + description.feature_supported is None + or description.feature_supported(coordinator.properties_api) + ) + and description.value_fn(coordinator.data) is not None ) diff --git a/tests/components/roborock/conftest.py b/tests/components/roborock/conftest.py index 70f7ab0ad7a6c2..0cd4f88d4a04e5 100644 --- a/tests/components/roborock/conftest.py +++ b/tests/components/roborock/conftest.py @@ -33,6 +33,7 @@ from roborock.devices.traits.v1.command import CommandTrait from roborock.devices.traits.v1.common import V1TraitMixin from roborock.devices.traits.v1.consumeable import ConsumableTrait +from roborock.devices.traits.v1.device_features import DeviceFeaturesTrait from roborock.devices.traits.v1.do_not_disturb import DoNotDisturbTrait from roborock.devices.traits.v1.dust_collection_mode import DustCollectionModeTrait from roborock.devices.traits.v1.home import HomeTrait @@ -353,6 +354,8 @@ def create_v1_properties(network_info: NetworkInfo) -> AsyncMock: v1_properties.routines = make_mock_trait(trait_spec=RoutinesTrait) v1_properties.routines.get_routines = AsyncMock(return_value=SCENES) v1_properties.routines.execute_routine = AsyncMock() + v1_properties.device_features = make_mock_trait(trait_spec=DeviceFeaturesTrait) + v1_properties.device_features.is_clean_fluid_delivery_supported = False # Mock diagnostics for a subset of properties v1_properties.as_dict.return_value = { "status": STATUS.as_dict(), diff --git a/tests/components/roborock/snapshots/test_binary_sensor.ambr b/tests/components/roborock/snapshots/test_binary_sensor.ambr index ac5db368f1ee5d..2213453d00c944 100644 --- a/tests/components/roborock/snapshots/test_binary_sensor.ambr +++ b/tests/components/roborock/snapshots/test_binary_sensor.ambr @@ -1,5 +1,5 @@ # serializer version: 1 -# name: test_binary_sensors[binary_sensor.roborock_s7_2-entry] +# name: test_binary_sensors[binary_sensor.roborock_s7_2_charging-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -12,7 +12,7 @@ 'disabled_by': None, 'domain': 'binary_sensor', 'entity_category': , - 'entity_id': 'binary_sensor.roborock_s7_2', + 'entity_id': 'binary_sensor.roborock_s7_2_charging', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -20,36 +20,36 @@ 'labels': set({ }), 'name': None, - 'object_id_base': None, + 'object_id_base': 'Charging', 'options': dict({ }), - 'original_device_class': , + 'original_device_class': , 'original_icon': None, - 'original_name': None, + 'original_name': 'Charging', 'platform': 'roborock', 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': 0, - 'translation_key': 'mop_attached', - 'unique_id': 'water_box_carriage_status_device_2', + 'translation_key': None, + 'unique_id': 'battery_charging_device_2', 'unit_of_measurement': None, }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_2-state] +# name: test_binary_sensors[binary_sensor.roborock_s7_2_charging-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - 'device_class': 'connectivity', - 'friendly_name': 'Roborock S7 2 None', + 'device_class': 'battery_charging', + 'friendly_name': 'Roborock S7 2 Charging', }), 'context': , - 'entity_id': 'binary_sensor.roborock_s7_2', + 'entity_id': 'binary_sensor.roborock_s7_2_charging', 'last_changed': , 'last_reported': , 'last_updated': , 'state': 'on', }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_2_2-entry] +# name: test_binary_sensors[binary_sensor.roborock_s7_2_cleaning-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -62,7 +62,7 @@ 'disabled_by': None, 'domain': 'binary_sensor', 'entity_category': , - 'entity_id': 'binary_sensor.roborock_s7_2_2', + 'entity_id': 'binary_sensor.roborock_s7_2_cleaning', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -70,36 +70,36 @@ 'labels': set({ }), 'name': None, - 'object_id_base': None, + 'object_id_base': 'Cleaning', 'options': dict({ }), - 'original_device_class': , + 'original_device_class': , 'original_icon': None, - 'original_name': None, + 'original_name': 'Cleaning', 'platform': 'roborock', 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': 0, - 'translation_key': 'water_box_attached', - 'unique_id': 'water_box_status_device_2', + 'translation_key': 'in_cleaning', + 'unique_id': 'in_cleaning_device_2', 'unit_of_measurement': None, }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_2_2-state] +# name: test_binary_sensors[binary_sensor.roborock_s7_2_cleaning-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - 'device_class': 'connectivity', - 'friendly_name': 'Roborock S7 2 None', + 'device_class': 'running', + 'friendly_name': 'Roborock S7 2 Cleaning', }), 'context': , - 'entity_id': 'binary_sensor.roborock_s7_2_2', + 'entity_id': 'binary_sensor.roborock_s7_2_cleaning', 'last_changed': , 'last_reported': , 'last_updated': , - 'state': 'on', + 'state': 'off', }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_2_3-entry] +# name: test_binary_sensors[binary_sensor.roborock_s7_2_mop_attached-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -112,7 +112,7 @@ 'disabled_by': None, 'domain': 'binary_sensor', 'entity_category': , - 'entity_id': 'binary_sensor.roborock_s7_2_3', + 'entity_id': 'binary_sensor.roborock_s7_2_mop_attached', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -120,36 +120,36 @@ 'labels': set({ }), 'name': None, - 'object_id_base': None, + 'object_id_base': 'Mop attached', 'options': dict({ }), - 'original_device_class': , + 'original_device_class': , 'original_icon': None, - 'original_name': None, + 'original_name': 'Mop attached', 'platform': 'roborock', 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': 0, - 'translation_key': 'water_shortage', - 'unique_id': 'water_shortage_device_2', + 'translation_key': 'mop_attached', + 'unique_id': 'water_box_carriage_status_device_2', 'unit_of_measurement': None, }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_2_3-state] +# name: test_binary_sensors[binary_sensor.roborock_s7_2_mop_attached-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - 'device_class': 'problem', - 'friendly_name': 'Roborock S7 2 None', + 'device_class': 'connectivity', + 'friendly_name': 'Roborock S7 2 Mop attached', }), 'context': , - 'entity_id': 'binary_sensor.roborock_s7_2_3', + 'entity_id': 'binary_sensor.roborock_s7_2_mop_attached', 'last_changed': , 'last_reported': , 'last_updated': , - 'state': 'off', + 'state': 'on', }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_2_4-entry] +# name: test_binary_sensors[binary_sensor.roborock_s7_2_water_box_attached-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -162,7 +162,7 @@ 'disabled_by': None, 'domain': 'binary_sensor', 'entity_category': , - 'entity_id': 'binary_sensor.roborock_s7_2_4', + 'entity_id': 'binary_sensor.roborock_s7_2_water_box_attached', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -170,36 +170,36 @@ 'labels': set({ }), 'name': None, - 'object_id_base': None, + 'object_id_base': 'Water box attached', 'options': dict({ }), - 'original_device_class': , + 'original_device_class': , 'original_icon': None, - 'original_name': None, + 'original_name': 'Water box attached', 'platform': 'roborock', 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': 0, - 'translation_key': 'in_cleaning', - 'unique_id': 'in_cleaning_device_2', + 'translation_key': 'water_box_attached', + 'unique_id': 'water_box_status_device_2', 'unit_of_measurement': None, }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_2_4-state] +# name: test_binary_sensors[binary_sensor.roborock_s7_2_water_box_attached-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - 'device_class': 'running', - 'friendly_name': 'Roborock S7 2 None', + 'device_class': 'connectivity', + 'friendly_name': 'Roborock S7 2 Water box attached', }), 'context': , - 'entity_id': 'binary_sensor.roborock_s7_2_4', + 'entity_id': 'binary_sensor.roborock_s7_2_water_box_attached', 'last_changed': , 'last_reported': , 'last_updated': , - 'state': 'off', + 'state': 'on', }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_2_5-entry] +# name: test_binary_sensors[binary_sensor.roborock_s7_2_water_shortage-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -212,7 +212,7 @@ 'disabled_by': None, 'domain': 'binary_sensor', 'entity_category': , - 'entity_id': 'binary_sensor.roborock_s7_2_5', + 'entity_id': 'binary_sensor.roborock_s7_2_water_shortage', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -220,36 +220,36 @@ 'labels': set({ }), 'name': None, - 'object_id_base': None, + 'object_id_base': 'Water shortage', 'options': dict({ }), - 'original_device_class': , + 'original_device_class': , 'original_icon': None, - 'original_name': None, + 'original_name': 'Water shortage', 'platform': 'roborock', 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': 0, - 'translation_key': None, - 'unique_id': 'battery_charging_device_2', + 'translation_key': 'water_shortage', + 'unique_id': 'water_shortage_device_2', 'unit_of_measurement': None, }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_2_5-state] +# name: test_binary_sensors[binary_sensor.roborock_s7_2_water_shortage-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - 'device_class': 'battery_charging', - 'friendly_name': 'Roborock S7 2 None', + 'device_class': 'problem', + 'friendly_name': 'Roborock S7 2 Water shortage', }), 'context': , - 'entity_id': 'binary_sensor.roborock_s7_2_5', + 'entity_id': 'binary_sensor.roborock_s7_2_water_shortage', 'last_changed': , 'last_reported': , 'last_updated': , - 'state': 'on', + 'state': 'off', }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_maxv-entry] +# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_charging-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -262,7 +262,7 @@ 'disabled_by': None, 'domain': 'binary_sensor', 'entity_category': , - 'entity_id': 'binary_sensor.roborock_s7_maxv', + 'entity_id': 'binary_sensor.roborock_s7_maxv_charging', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -270,36 +270,36 @@ 'labels': set({ }), 'name': None, - 'object_id_base': None, + 'object_id_base': 'Charging', 'options': dict({ }), - 'original_device_class': , + 'original_device_class': , 'original_icon': None, - 'original_name': None, + 'original_name': 'Charging', 'platform': 'roborock', 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': 0, - 'translation_key': 'mop_attached', - 'unique_id': 'water_box_carriage_status_abc123', + 'translation_key': None, + 'unique_id': 'battery_charging_abc123', 'unit_of_measurement': None, }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_maxv-state] +# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_charging-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - 'device_class': 'connectivity', - 'friendly_name': 'Roborock S7 MaxV None', + 'device_class': 'battery_charging', + 'friendly_name': 'Roborock S7 MaxV Charging', }), 'context': , - 'entity_id': 'binary_sensor.roborock_s7_maxv', + 'entity_id': 'binary_sensor.roborock_s7_maxv_charging', 'last_changed': , 'last_reported': , 'last_updated': , 'state': 'on', }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_2-entry] +# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_cleaning-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -312,7 +312,7 @@ 'disabled_by': None, 'domain': 'binary_sensor', 'entity_category': , - 'entity_id': 'binary_sensor.roborock_s7_maxv_2', + 'entity_id': 'binary_sensor.roborock_s7_maxv_cleaning', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -320,36 +320,36 @@ 'labels': set({ }), 'name': None, - 'object_id_base': None, + 'object_id_base': 'Cleaning', 'options': dict({ }), - 'original_device_class': , + 'original_device_class': , 'original_icon': None, - 'original_name': None, + 'original_name': 'Cleaning', 'platform': 'roborock', 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': 0, - 'translation_key': 'water_box_attached', - 'unique_id': 'water_box_status_abc123', + 'translation_key': 'in_cleaning', + 'unique_id': 'in_cleaning_abc123', 'unit_of_measurement': None, }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_2-state] +# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_cleaning-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - 'device_class': 'connectivity', - 'friendly_name': 'Roborock S7 MaxV None', + 'device_class': 'running', + 'friendly_name': 'Roborock S7 MaxV Cleaning', }), 'context': , - 'entity_id': 'binary_sensor.roborock_s7_maxv_2', + 'entity_id': 'binary_sensor.roborock_s7_maxv_cleaning', 'last_changed': , 'last_reported': , 'last_updated': , - 'state': 'on', + 'state': 'off', }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_3-entry] +# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_mop_attached-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -362,7 +362,7 @@ 'disabled_by': None, 'domain': 'binary_sensor', 'entity_category': , - 'entity_id': 'binary_sensor.roborock_s7_maxv_3', + 'entity_id': 'binary_sensor.roborock_s7_maxv_mop_attached', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -370,36 +370,36 @@ 'labels': set({ }), 'name': None, - 'object_id_base': None, + 'object_id_base': 'Mop attached', 'options': dict({ }), - 'original_device_class': , + 'original_device_class': , 'original_icon': None, - 'original_name': None, + 'original_name': 'Mop attached', 'platform': 'roborock', 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': 0, - 'translation_key': 'water_shortage', - 'unique_id': 'water_shortage_abc123', + 'translation_key': 'mop_attached', + 'unique_id': 'water_box_carriage_status_abc123', 'unit_of_measurement': None, }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_3-state] +# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_mop_attached-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - 'device_class': 'problem', - 'friendly_name': 'Roborock S7 MaxV None', + 'device_class': 'connectivity', + 'friendly_name': 'Roborock S7 MaxV Mop attached', }), 'context': , - 'entity_id': 'binary_sensor.roborock_s7_maxv_3', + 'entity_id': 'binary_sensor.roborock_s7_maxv_mop_attached', 'last_changed': , 'last_reported': , 'last_updated': , - 'state': 'off', + 'state': 'on', }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_4-entry] +# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_water_box_attached-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -412,7 +412,7 @@ 'disabled_by': None, 'domain': 'binary_sensor', 'entity_category': , - 'entity_id': 'binary_sensor.roborock_s7_maxv_4', + 'entity_id': 'binary_sensor.roborock_s7_maxv_water_box_attached', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -420,36 +420,36 @@ 'labels': set({ }), 'name': None, - 'object_id_base': None, + 'object_id_base': 'Water box attached', 'options': dict({ }), - 'original_device_class': , + 'original_device_class': , 'original_icon': None, - 'original_name': None, + 'original_name': 'Water box attached', 'platform': 'roborock', 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': 0, - 'translation_key': 'in_cleaning', - 'unique_id': 'in_cleaning_abc123', + 'translation_key': 'water_box_attached', + 'unique_id': 'water_box_status_abc123', 'unit_of_measurement': None, }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_4-state] +# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_water_box_attached-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - 'device_class': 'running', - 'friendly_name': 'Roborock S7 MaxV None', + 'device_class': 'connectivity', + 'friendly_name': 'Roborock S7 MaxV Water box attached', }), 'context': , - 'entity_id': 'binary_sensor.roborock_s7_maxv_4', + 'entity_id': 'binary_sensor.roborock_s7_maxv_water_box_attached', 'last_changed': , 'last_reported': , 'last_updated': , - 'state': 'off', + 'state': 'on', }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_5-entry] +# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_water_shortage-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -462,7 +462,7 @@ 'disabled_by': None, 'domain': 'binary_sensor', 'entity_category': , - 'entity_id': 'binary_sensor.roborock_s7_maxv_5', + 'entity_id': 'binary_sensor.roborock_s7_maxv_water_shortage', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -470,32 +470,32 @@ 'labels': set({ }), 'name': None, - 'object_id_base': None, + 'object_id_base': 'Water shortage', 'options': dict({ }), - 'original_device_class': , + 'original_device_class': , 'original_icon': None, - 'original_name': None, + 'original_name': 'Water shortage', 'platform': 'roborock', 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': 0, - 'translation_key': None, - 'unique_id': 'battery_charging_abc123', + 'translation_key': 'water_shortage', + 'unique_id': 'water_shortage_abc123', 'unit_of_measurement': None, }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_5-state] +# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_water_shortage-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - 'device_class': 'battery_charging', - 'friendly_name': 'Roborock S7 MaxV None', + 'device_class': 'problem', + 'friendly_name': 'Roborock S7 MaxV Water shortage', }), 'context': , - 'entity_id': 'binary_sensor.roborock_s7_maxv_5', + 'entity_id': 'binary_sensor.roborock_s7_maxv_water_shortage', 'last_changed': , 'last_reported': , 'last_updated': , - 'state': 'on', + 'state': 'off', }) # --- diff --git a/tests/components/roborock/test_binary_sensor.py b/tests/components/roborock/test_binary_sensor.py index d1c2ba039b515d..a89e13d91d2af0 100644 --- a/tests/components/roborock/test_binary_sensor.py +++ b/tests/components/roborock/test_binary_sensor.py @@ -7,6 +7,8 @@ from homeassistant.core import HomeAssistant from homeassistant.helpers import entity_registry as er +from .conftest import FakeDevice + from tests.common import MockConfigEntry, snapshot_platform @@ -24,3 +26,30 @@ async def test_binary_sensors( ) -> None: """Test binary sensors and check test values are correctly set.""" await snapshot_platform(hass, entity_registry, snapshot, setup_entry.entry_id) + + +@pytest.mark.usefixtures("entity_registry_enabled_by_default") +async def test_clean_fluid_empty_with_feature_supported( + hass: HomeAssistant, + fake_vacuum: FakeDevice, + setup_entry: MockConfigEntry, +) -> None: + """Test that clean_fluid_empty entity appears when feature is supported.""" + # Enable the feature + fake_vacuum.v1_properties.device_features.is_clean_fluid_delivery_supported = True + + # Reload to pick up changes + await hass.config_entries.async_unload(setup_entry.entry_id) + await hass.async_block_till_done() + await hass.config_entries.async_setup(setup_entry.entry_id) + await hass.async_block_till_done() + + # Verify entity exists + entity_registry = er.async_get(hass) + entities = er.async_entries_for_config_entry(entity_registry, setup_entry.entry_id) + clean_fluid_entities = [ + e for e in entities if e.unique_id and "clean_fluid_empty" in e.unique_id + ] + assert len(clean_fluid_entities) > 0, ( + "clean_fluid_empty entity should be created when feature is supported" + ) From 97b2ccd9bc797d33fe099f5d0b192f7617572055 Mon Sep 17 00:00:00 2001 From: Paulo Ruberto Date: Sun, 25 Jan 2026 09:16:27 -0500 Subject: [PATCH 4/6] Revert "Use is_clean_fluid_delivery_supported" This reverts commit 53d0e1f00ba50fabf33ee54325e8038150e5bb07. --- .../components/roborock/binary_sensor.py | 18 +- tests/components/roborock/conftest.py | 3 - .../snapshots/test_binary_sensor.ambr | 236 +++++++++--------- .../components/roborock/test_binary_sensor.py | 29 --- 4 files changed, 124 insertions(+), 162 deletions(-) diff --git a/homeassistant/components/roborock/binary_sensor.py b/homeassistant/components/roborock/binary_sensor.py index 7d50494e2496ee..b9a59e50333292 100644 --- a/homeassistant/components/roborock/binary_sensor.py +++ b/homeassistant/components/roborock/binary_sensor.py @@ -6,7 +6,6 @@ from dataclasses import dataclass from roborock.data import CleanFluidStatus, RoborockStateCode -from roborock.devices.traits.v1 import PropertiesApi from homeassistant.components.binary_sensor import ( BinarySensorDeviceClass, @@ -34,9 +33,6 @@ class RoborockBinarySensorDescription(BinarySensorEntityDescription): is_dock_entity: bool = False """Whether this sensor is for the dock.""" - feature_supported: Callable[[PropertiesApi], bool] | None = None - """Function to check if the sensor is supported by the device.""" - BINARY_SENSOR_DESCRIPTIONS = [ RoborockBinarySensorDescription( @@ -73,10 +69,12 @@ class RoborockBinarySensorDescription(BinarySensorEntityDescription): translation_key="clean_fluid_empty", device_class=BinarySensorDeviceClass.PROBLEM, entity_category=EntityCategory.DIAGNOSTIC, - value_fn=lambda data: data.status.clean_fluid_status - == CleanFluidStatus.empty_not_installed, + value_fn=lambda data: ( + data.status.clean_fluid_status == CleanFluidStatus.empty_not_installed + if data.status.clean_fluid_status is not None + else None + ), is_dock_entity=True, - feature_supported=lambda api: api.device_features.is_clean_fluid_delivery_supported, ), RoborockBinarySensorDescription( key="in_cleaning", @@ -108,11 +106,7 @@ async def async_setup_entry( ) for coordinator in config_entry.runtime_data.v1 for description in BINARY_SENSOR_DESCRIPTIONS - if ( - description.feature_supported is None - or description.feature_supported(coordinator.properties_api) - ) - and description.value_fn(coordinator.data) is not None + if description.value_fn(coordinator.data) is not None ) diff --git a/tests/components/roborock/conftest.py b/tests/components/roborock/conftest.py index 0cd4f88d4a04e5..70f7ab0ad7a6c2 100644 --- a/tests/components/roborock/conftest.py +++ b/tests/components/roborock/conftest.py @@ -33,7 +33,6 @@ from roborock.devices.traits.v1.command import CommandTrait from roborock.devices.traits.v1.common import V1TraitMixin from roborock.devices.traits.v1.consumeable import ConsumableTrait -from roborock.devices.traits.v1.device_features import DeviceFeaturesTrait from roborock.devices.traits.v1.do_not_disturb import DoNotDisturbTrait from roborock.devices.traits.v1.dust_collection_mode import DustCollectionModeTrait from roborock.devices.traits.v1.home import HomeTrait @@ -354,8 +353,6 @@ def create_v1_properties(network_info: NetworkInfo) -> AsyncMock: v1_properties.routines = make_mock_trait(trait_spec=RoutinesTrait) v1_properties.routines.get_routines = AsyncMock(return_value=SCENES) v1_properties.routines.execute_routine = AsyncMock() - v1_properties.device_features = make_mock_trait(trait_spec=DeviceFeaturesTrait) - v1_properties.device_features.is_clean_fluid_delivery_supported = False # Mock diagnostics for a subset of properties v1_properties.as_dict.return_value = { "status": STATUS.as_dict(), diff --git a/tests/components/roborock/snapshots/test_binary_sensor.ambr b/tests/components/roborock/snapshots/test_binary_sensor.ambr index 2213453d00c944..ac5db368f1ee5d 100644 --- a/tests/components/roborock/snapshots/test_binary_sensor.ambr +++ b/tests/components/roborock/snapshots/test_binary_sensor.ambr @@ -1,5 +1,5 @@ # serializer version: 1 -# name: test_binary_sensors[binary_sensor.roborock_s7_2_charging-entry] +# name: test_binary_sensors[binary_sensor.roborock_s7_2-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -12,7 +12,7 @@ 'disabled_by': None, 'domain': 'binary_sensor', 'entity_category': , - 'entity_id': 'binary_sensor.roborock_s7_2_charging', + 'entity_id': 'binary_sensor.roborock_s7_2', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -20,36 +20,36 @@ 'labels': set({ }), 'name': None, - 'object_id_base': 'Charging', + 'object_id_base': None, 'options': dict({ }), - 'original_device_class': , + 'original_device_class': , 'original_icon': None, - 'original_name': 'Charging', + 'original_name': None, 'platform': 'roborock', 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': 0, - 'translation_key': None, - 'unique_id': 'battery_charging_device_2', + 'translation_key': 'mop_attached', + 'unique_id': 'water_box_carriage_status_device_2', 'unit_of_measurement': None, }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_2_charging-state] +# name: test_binary_sensors[binary_sensor.roborock_s7_2-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - 'device_class': 'battery_charging', - 'friendly_name': 'Roborock S7 2 Charging', + 'device_class': 'connectivity', + 'friendly_name': 'Roborock S7 2 None', }), 'context': , - 'entity_id': 'binary_sensor.roborock_s7_2_charging', + 'entity_id': 'binary_sensor.roborock_s7_2', 'last_changed': , 'last_reported': , 'last_updated': , 'state': 'on', }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_2_cleaning-entry] +# name: test_binary_sensors[binary_sensor.roborock_s7_2_2-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -62,7 +62,7 @@ 'disabled_by': None, 'domain': 'binary_sensor', 'entity_category': , - 'entity_id': 'binary_sensor.roborock_s7_2_cleaning', + 'entity_id': 'binary_sensor.roborock_s7_2_2', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -70,36 +70,36 @@ 'labels': set({ }), 'name': None, - 'object_id_base': 'Cleaning', + 'object_id_base': None, 'options': dict({ }), - 'original_device_class': , + 'original_device_class': , 'original_icon': None, - 'original_name': 'Cleaning', + 'original_name': None, 'platform': 'roborock', 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': 0, - 'translation_key': 'in_cleaning', - 'unique_id': 'in_cleaning_device_2', + 'translation_key': 'water_box_attached', + 'unique_id': 'water_box_status_device_2', 'unit_of_measurement': None, }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_2_cleaning-state] +# name: test_binary_sensors[binary_sensor.roborock_s7_2_2-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - 'device_class': 'running', - 'friendly_name': 'Roborock S7 2 Cleaning', + 'device_class': 'connectivity', + 'friendly_name': 'Roborock S7 2 None', }), 'context': , - 'entity_id': 'binary_sensor.roborock_s7_2_cleaning', + 'entity_id': 'binary_sensor.roborock_s7_2_2', 'last_changed': , 'last_reported': , 'last_updated': , - 'state': 'off', + 'state': 'on', }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_2_mop_attached-entry] +# name: test_binary_sensors[binary_sensor.roborock_s7_2_3-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -112,7 +112,7 @@ 'disabled_by': None, 'domain': 'binary_sensor', 'entity_category': , - 'entity_id': 'binary_sensor.roborock_s7_2_mop_attached', + 'entity_id': 'binary_sensor.roborock_s7_2_3', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -120,36 +120,36 @@ 'labels': set({ }), 'name': None, - 'object_id_base': 'Mop attached', + 'object_id_base': None, 'options': dict({ }), - 'original_device_class': , + 'original_device_class': , 'original_icon': None, - 'original_name': 'Mop attached', + 'original_name': None, 'platform': 'roborock', 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': 0, - 'translation_key': 'mop_attached', - 'unique_id': 'water_box_carriage_status_device_2', + 'translation_key': 'water_shortage', + 'unique_id': 'water_shortage_device_2', 'unit_of_measurement': None, }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_2_mop_attached-state] +# name: test_binary_sensors[binary_sensor.roborock_s7_2_3-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - 'device_class': 'connectivity', - 'friendly_name': 'Roborock S7 2 Mop attached', + 'device_class': 'problem', + 'friendly_name': 'Roborock S7 2 None', }), 'context': , - 'entity_id': 'binary_sensor.roborock_s7_2_mop_attached', + 'entity_id': 'binary_sensor.roborock_s7_2_3', 'last_changed': , 'last_reported': , 'last_updated': , - 'state': 'on', + 'state': 'off', }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_2_water_box_attached-entry] +# name: test_binary_sensors[binary_sensor.roborock_s7_2_4-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -162,7 +162,7 @@ 'disabled_by': None, 'domain': 'binary_sensor', 'entity_category': , - 'entity_id': 'binary_sensor.roborock_s7_2_water_box_attached', + 'entity_id': 'binary_sensor.roborock_s7_2_4', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -170,36 +170,36 @@ 'labels': set({ }), 'name': None, - 'object_id_base': 'Water box attached', + 'object_id_base': None, 'options': dict({ }), - 'original_device_class': , + 'original_device_class': , 'original_icon': None, - 'original_name': 'Water box attached', + 'original_name': None, 'platform': 'roborock', 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': 0, - 'translation_key': 'water_box_attached', - 'unique_id': 'water_box_status_device_2', + 'translation_key': 'in_cleaning', + 'unique_id': 'in_cleaning_device_2', 'unit_of_measurement': None, }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_2_water_box_attached-state] +# name: test_binary_sensors[binary_sensor.roborock_s7_2_4-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - 'device_class': 'connectivity', - 'friendly_name': 'Roborock S7 2 Water box attached', + 'device_class': 'running', + 'friendly_name': 'Roborock S7 2 None', }), 'context': , - 'entity_id': 'binary_sensor.roborock_s7_2_water_box_attached', + 'entity_id': 'binary_sensor.roborock_s7_2_4', 'last_changed': , 'last_reported': , 'last_updated': , - 'state': 'on', + 'state': 'off', }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_2_water_shortage-entry] +# name: test_binary_sensors[binary_sensor.roborock_s7_2_5-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -212,7 +212,7 @@ 'disabled_by': None, 'domain': 'binary_sensor', 'entity_category': , - 'entity_id': 'binary_sensor.roborock_s7_2_water_shortage', + 'entity_id': 'binary_sensor.roborock_s7_2_5', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -220,36 +220,36 @@ 'labels': set({ }), 'name': None, - 'object_id_base': 'Water shortage', + 'object_id_base': None, 'options': dict({ }), - 'original_device_class': , + 'original_device_class': , 'original_icon': None, - 'original_name': 'Water shortage', + 'original_name': None, 'platform': 'roborock', 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': 0, - 'translation_key': 'water_shortage', - 'unique_id': 'water_shortage_device_2', + 'translation_key': None, + 'unique_id': 'battery_charging_device_2', 'unit_of_measurement': None, }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_2_water_shortage-state] +# name: test_binary_sensors[binary_sensor.roborock_s7_2_5-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - 'device_class': 'problem', - 'friendly_name': 'Roborock S7 2 Water shortage', + 'device_class': 'battery_charging', + 'friendly_name': 'Roborock S7 2 None', }), 'context': , - 'entity_id': 'binary_sensor.roborock_s7_2_water_shortage', + 'entity_id': 'binary_sensor.roborock_s7_2_5', 'last_changed': , 'last_reported': , 'last_updated': , - 'state': 'off', + 'state': 'on', }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_charging-entry] +# name: test_binary_sensors[binary_sensor.roborock_s7_maxv-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -262,7 +262,7 @@ 'disabled_by': None, 'domain': 'binary_sensor', 'entity_category': , - 'entity_id': 'binary_sensor.roborock_s7_maxv_charging', + 'entity_id': 'binary_sensor.roborock_s7_maxv', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -270,36 +270,36 @@ 'labels': set({ }), 'name': None, - 'object_id_base': 'Charging', + 'object_id_base': None, 'options': dict({ }), - 'original_device_class': , + 'original_device_class': , 'original_icon': None, - 'original_name': 'Charging', + 'original_name': None, 'platform': 'roborock', 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': 0, - 'translation_key': None, - 'unique_id': 'battery_charging_abc123', + 'translation_key': 'mop_attached', + 'unique_id': 'water_box_carriage_status_abc123', 'unit_of_measurement': None, }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_charging-state] +# name: test_binary_sensors[binary_sensor.roborock_s7_maxv-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - 'device_class': 'battery_charging', - 'friendly_name': 'Roborock S7 MaxV Charging', + 'device_class': 'connectivity', + 'friendly_name': 'Roborock S7 MaxV None', }), 'context': , - 'entity_id': 'binary_sensor.roborock_s7_maxv_charging', + 'entity_id': 'binary_sensor.roborock_s7_maxv', 'last_changed': , 'last_reported': , 'last_updated': , 'state': 'on', }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_cleaning-entry] +# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_2-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -312,7 +312,7 @@ 'disabled_by': None, 'domain': 'binary_sensor', 'entity_category': , - 'entity_id': 'binary_sensor.roborock_s7_maxv_cleaning', + 'entity_id': 'binary_sensor.roborock_s7_maxv_2', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -320,36 +320,36 @@ 'labels': set({ }), 'name': None, - 'object_id_base': 'Cleaning', + 'object_id_base': None, 'options': dict({ }), - 'original_device_class': , + 'original_device_class': , 'original_icon': None, - 'original_name': 'Cleaning', + 'original_name': None, 'platform': 'roborock', 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': 0, - 'translation_key': 'in_cleaning', - 'unique_id': 'in_cleaning_abc123', + 'translation_key': 'water_box_attached', + 'unique_id': 'water_box_status_abc123', 'unit_of_measurement': None, }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_cleaning-state] +# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_2-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - 'device_class': 'running', - 'friendly_name': 'Roborock S7 MaxV Cleaning', + 'device_class': 'connectivity', + 'friendly_name': 'Roborock S7 MaxV None', }), 'context': , - 'entity_id': 'binary_sensor.roborock_s7_maxv_cleaning', + 'entity_id': 'binary_sensor.roborock_s7_maxv_2', 'last_changed': , 'last_reported': , 'last_updated': , - 'state': 'off', + 'state': 'on', }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_mop_attached-entry] +# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_3-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -362,7 +362,7 @@ 'disabled_by': None, 'domain': 'binary_sensor', 'entity_category': , - 'entity_id': 'binary_sensor.roborock_s7_maxv_mop_attached', + 'entity_id': 'binary_sensor.roborock_s7_maxv_3', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -370,36 +370,36 @@ 'labels': set({ }), 'name': None, - 'object_id_base': 'Mop attached', + 'object_id_base': None, 'options': dict({ }), - 'original_device_class': , + 'original_device_class': , 'original_icon': None, - 'original_name': 'Mop attached', + 'original_name': None, 'platform': 'roborock', 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': 0, - 'translation_key': 'mop_attached', - 'unique_id': 'water_box_carriage_status_abc123', + 'translation_key': 'water_shortage', + 'unique_id': 'water_shortage_abc123', 'unit_of_measurement': None, }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_mop_attached-state] +# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_3-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - 'device_class': 'connectivity', - 'friendly_name': 'Roborock S7 MaxV Mop attached', + 'device_class': 'problem', + 'friendly_name': 'Roborock S7 MaxV None', }), 'context': , - 'entity_id': 'binary_sensor.roborock_s7_maxv_mop_attached', + 'entity_id': 'binary_sensor.roborock_s7_maxv_3', 'last_changed': , 'last_reported': , 'last_updated': , - 'state': 'on', + 'state': 'off', }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_water_box_attached-entry] +# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_4-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -412,7 +412,7 @@ 'disabled_by': None, 'domain': 'binary_sensor', 'entity_category': , - 'entity_id': 'binary_sensor.roborock_s7_maxv_water_box_attached', + 'entity_id': 'binary_sensor.roborock_s7_maxv_4', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -420,36 +420,36 @@ 'labels': set({ }), 'name': None, - 'object_id_base': 'Water box attached', + 'object_id_base': None, 'options': dict({ }), - 'original_device_class': , + 'original_device_class': , 'original_icon': None, - 'original_name': 'Water box attached', + 'original_name': None, 'platform': 'roborock', 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': 0, - 'translation_key': 'water_box_attached', - 'unique_id': 'water_box_status_abc123', + 'translation_key': 'in_cleaning', + 'unique_id': 'in_cleaning_abc123', 'unit_of_measurement': None, }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_water_box_attached-state] +# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_4-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - 'device_class': 'connectivity', - 'friendly_name': 'Roborock S7 MaxV Water box attached', + 'device_class': 'running', + 'friendly_name': 'Roborock S7 MaxV None', }), 'context': , - 'entity_id': 'binary_sensor.roborock_s7_maxv_water_box_attached', + 'entity_id': 'binary_sensor.roborock_s7_maxv_4', 'last_changed': , 'last_reported': , 'last_updated': , - 'state': 'on', + 'state': 'off', }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_water_shortage-entry] +# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_5-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -462,7 +462,7 @@ 'disabled_by': None, 'domain': 'binary_sensor', 'entity_category': , - 'entity_id': 'binary_sensor.roborock_s7_maxv_water_shortage', + 'entity_id': 'binary_sensor.roborock_s7_maxv_5', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -470,32 +470,32 @@ 'labels': set({ }), 'name': None, - 'object_id_base': 'Water shortage', + 'object_id_base': None, 'options': dict({ }), - 'original_device_class': , + 'original_device_class': , 'original_icon': None, - 'original_name': 'Water shortage', + 'original_name': None, 'platform': 'roborock', 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': 0, - 'translation_key': 'water_shortage', - 'unique_id': 'water_shortage_abc123', + 'translation_key': None, + 'unique_id': 'battery_charging_abc123', 'unit_of_measurement': None, }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_water_shortage-state] +# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_5-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - 'device_class': 'problem', - 'friendly_name': 'Roborock S7 MaxV Water shortage', + 'device_class': 'battery_charging', + 'friendly_name': 'Roborock S7 MaxV None', }), 'context': , - 'entity_id': 'binary_sensor.roborock_s7_maxv_water_shortage', + 'entity_id': 'binary_sensor.roborock_s7_maxv_5', 'last_changed': , 'last_reported': , 'last_updated': , - 'state': 'off', + 'state': 'on', }) # --- diff --git a/tests/components/roborock/test_binary_sensor.py b/tests/components/roborock/test_binary_sensor.py index a89e13d91d2af0..d1c2ba039b515d 100644 --- a/tests/components/roborock/test_binary_sensor.py +++ b/tests/components/roborock/test_binary_sensor.py @@ -7,8 +7,6 @@ from homeassistant.core import HomeAssistant from homeassistant.helpers import entity_registry as er -from .conftest import FakeDevice - from tests.common import MockConfigEntry, snapshot_platform @@ -26,30 +24,3 @@ async def test_binary_sensors( ) -> None: """Test binary sensors and check test values are correctly set.""" await snapshot_platform(hass, entity_registry, snapshot, setup_entry.entry_id) - - -@pytest.mark.usefixtures("entity_registry_enabled_by_default") -async def test_clean_fluid_empty_with_feature_supported( - hass: HomeAssistant, - fake_vacuum: FakeDevice, - setup_entry: MockConfigEntry, -) -> None: - """Test that clean_fluid_empty entity appears when feature is supported.""" - # Enable the feature - fake_vacuum.v1_properties.device_features.is_clean_fluid_delivery_supported = True - - # Reload to pick up changes - await hass.config_entries.async_unload(setup_entry.entry_id) - await hass.async_block_till_done() - await hass.config_entries.async_setup(setup_entry.entry_id) - await hass.async_block_till_done() - - # Verify entity exists - entity_registry = er.async_get(hass) - entities = er.async_entries_for_config_entry(entity_registry, setup_entry.entry_id) - clean_fluid_entities = [ - e for e in entities if e.unique_id and "clean_fluid_empty" in e.unique_id - ] - assert len(clean_fluid_entities) > 0, ( - "clean_fluid_empty entity should be created when feature is supported" - ) From 6cbee167d23826dfc2cfd3a17ac73e13e29bd86b Mon Sep 17 00:00:00 2001 From: Paulo Ruberto Date: Sun, 25 Jan 2026 09:17:46 -0500 Subject: [PATCH 5/6] Update snapshot --- .../snapshots/test_binary_sensor.ambr | 236 +++++++++--------- 1 file changed, 118 insertions(+), 118 deletions(-) diff --git a/tests/components/roborock/snapshots/test_binary_sensor.ambr b/tests/components/roborock/snapshots/test_binary_sensor.ambr index ac5db368f1ee5d..2213453d00c944 100644 --- a/tests/components/roborock/snapshots/test_binary_sensor.ambr +++ b/tests/components/roborock/snapshots/test_binary_sensor.ambr @@ -1,5 +1,5 @@ # serializer version: 1 -# name: test_binary_sensors[binary_sensor.roborock_s7_2-entry] +# name: test_binary_sensors[binary_sensor.roborock_s7_2_charging-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -12,7 +12,7 @@ 'disabled_by': None, 'domain': 'binary_sensor', 'entity_category': , - 'entity_id': 'binary_sensor.roborock_s7_2', + 'entity_id': 'binary_sensor.roborock_s7_2_charging', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -20,36 +20,36 @@ 'labels': set({ }), 'name': None, - 'object_id_base': None, + 'object_id_base': 'Charging', 'options': dict({ }), - 'original_device_class': , + 'original_device_class': , 'original_icon': None, - 'original_name': None, + 'original_name': 'Charging', 'platform': 'roborock', 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': 0, - 'translation_key': 'mop_attached', - 'unique_id': 'water_box_carriage_status_device_2', + 'translation_key': None, + 'unique_id': 'battery_charging_device_2', 'unit_of_measurement': None, }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_2-state] +# name: test_binary_sensors[binary_sensor.roborock_s7_2_charging-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - 'device_class': 'connectivity', - 'friendly_name': 'Roborock S7 2 None', + 'device_class': 'battery_charging', + 'friendly_name': 'Roborock S7 2 Charging', }), 'context': , - 'entity_id': 'binary_sensor.roborock_s7_2', + 'entity_id': 'binary_sensor.roborock_s7_2_charging', 'last_changed': , 'last_reported': , 'last_updated': , 'state': 'on', }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_2_2-entry] +# name: test_binary_sensors[binary_sensor.roborock_s7_2_cleaning-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -62,7 +62,7 @@ 'disabled_by': None, 'domain': 'binary_sensor', 'entity_category': , - 'entity_id': 'binary_sensor.roborock_s7_2_2', + 'entity_id': 'binary_sensor.roborock_s7_2_cleaning', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -70,36 +70,36 @@ 'labels': set({ }), 'name': None, - 'object_id_base': None, + 'object_id_base': 'Cleaning', 'options': dict({ }), - 'original_device_class': , + 'original_device_class': , 'original_icon': None, - 'original_name': None, + 'original_name': 'Cleaning', 'platform': 'roborock', 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': 0, - 'translation_key': 'water_box_attached', - 'unique_id': 'water_box_status_device_2', + 'translation_key': 'in_cleaning', + 'unique_id': 'in_cleaning_device_2', 'unit_of_measurement': None, }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_2_2-state] +# name: test_binary_sensors[binary_sensor.roborock_s7_2_cleaning-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - 'device_class': 'connectivity', - 'friendly_name': 'Roborock S7 2 None', + 'device_class': 'running', + 'friendly_name': 'Roborock S7 2 Cleaning', }), 'context': , - 'entity_id': 'binary_sensor.roborock_s7_2_2', + 'entity_id': 'binary_sensor.roborock_s7_2_cleaning', 'last_changed': , 'last_reported': , 'last_updated': , - 'state': 'on', + 'state': 'off', }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_2_3-entry] +# name: test_binary_sensors[binary_sensor.roborock_s7_2_mop_attached-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -112,7 +112,7 @@ 'disabled_by': None, 'domain': 'binary_sensor', 'entity_category': , - 'entity_id': 'binary_sensor.roborock_s7_2_3', + 'entity_id': 'binary_sensor.roborock_s7_2_mop_attached', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -120,36 +120,36 @@ 'labels': set({ }), 'name': None, - 'object_id_base': None, + 'object_id_base': 'Mop attached', 'options': dict({ }), - 'original_device_class': , + 'original_device_class': , 'original_icon': None, - 'original_name': None, + 'original_name': 'Mop attached', 'platform': 'roborock', 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': 0, - 'translation_key': 'water_shortage', - 'unique_id': 'water_shortage_device_2', + 'translation_key': 'mop_attached', + 'unique_id': 'water_box_carriage_status_device_2', 'unit_of_measurement': None, }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_2_3-state] +# name: test_binary_sensors[binary_sensor.roborock_s7_2_mop_attached-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - 'device_class': 'problem', - 'friendly_name': 'Roborock S7 2 None', + 'device_class': 'connectivity', + 'friendly_name': 'Roborock S7 2 Mop attached', }), 'context': , - 'entity_id': 'binary_sensor.roborock_s7_2_3', + 'entity_id': 'binary_sensor.roborock_s7_2_mop_attached', 'last_changed': , 'last_reported': , 'last_updated': , - 'state': 'off', + 'state': 'on', }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_2_4-entry] +# name: test_binary_sensors[binary_sensor.roborock_s7_2_water_box_attached-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -162,7 +162,7 @@ 'disabled_by': None, 'domain': 'binary_sensor', 'entity_category': , - 'entity_id': 'binary_sensor.roborock_s7_2_4', + 'entity_id': 'binary_sensor.roborock_s7_2_water_box_attached', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -170,36 +170,36 @@ 'labels': set({ }), 'name': None, - 'object_id_base': None, + 'object_id_base': 'Water box attached', 'options': dict({ }), - 'original_device_class': , + 'original_device_class': , 'original_icon': None, - 'original_name': None, + 'original_name': 'Water box attached', 'platform': 'roborock', 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': 0, - 'translation_key': 'in_cleaning', - 'unique_id': 'in_cleaning_device_2', + 'translation_key': 'water_box_attached', + 'unique_id': 'water_box_status_device_2', 'unit_of_measurement': None, }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_2_4-state] +# name: test_binary_sensors[binary_sensor.roborock_s7_2_water_box_attached-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - 'device_class': 'running', - 'friendly_name': 'Roborock S7 2 None', + 'device_class': 'connectivity', + 'friendly_name': 'Roborock S7 2 Water box attached', }), 'context': , - 'entity_id': 'binary_sensor.roborock_s7_2_4', + 'entity_id': 'binary_sensor.roborock_s7_2_water_box_attached', 'last_changed': , 'last_reported': , 'last_updated': , - 'state': 'off', + 'state': 'on', }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_2_5-entry] +# name: test_binary_sensors[binary_sensor.roborock_s7_2_water_shortage-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -212,7 +212,7 @@ 'disabled_by': None, 'domain': 'binary_sensor', 'entity_category': , - 'entity_id': 'binary_sensor.roborock_s7_2_5', + 'entity_id': 'binary_sensor.roborock_s7_2_water_shortage', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -220,36 +220,36 @@ 'labels': set({ }), 'name': None, - 'object_id_base': None, + 'object_id_base': 'Water shortage', 'options': dict({ }), - 'original_device_class': , + 'original_device_class': , 'original_icon': None, - 'original_name': None, + 'original_name': 'Water shortage', 'platform': 'roborock', 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': 0, - 'translation_key': None, - 'unique_id': 'battery_charging_device_2', + 'translation_key': 'water_shortage', + 'unique_id': 'water_shortage_device_2', 'unit_of_measurement': None, }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_2_5-state] +# name: test_binary_sensors[binary_sensor.roborock_s7_2_water_shortage-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - 'device_class': 'battery_charging', - 'friendly_name': 'Roborock S7 2 None', + 'device_class': 'problem', + 'friendly_name': 'Roborock S7 2 Water shortage', }), 'context': , - 'entity_id': 'binary_sensor.roborock_s7_2_5', + 'entity_id': 'binary_sensor.roborock_s7_2_water_shortage', 'last_changed': , 'last_reported': , 'last_updated': , - 'state': 'on', + 'state': 'off', }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_maxv-entry] +# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_charging-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -262,7 +262,7 @@ 'disabled_by': None, 'domain': 'binary_sensor', 'entity_category': , - 'entity_id': 'binary_sensor.roborock_s7_maxv', + 'entity_id': 'binary_sensor.roborock_s7_maxv_charging', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -270,36 +270,36 @@ 'labels': set({ }), 'name': None, - 'object_id_base': None, + 'object_id_base': 'Charging', 'options': dict({ }), - 'original_device_class': , + 'original_device_class': , 'original_icon': None, - 'original_name': None, + 'original_name': 'Charging', 'platform': 'roborock', 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': 0, - 'translation_key': 'mop_attached', - 'unique_id': 'water_box_carriage_status_abc123', + 'translation_key': None, + 'unique_id': 'battery_charging_abc123', 'unit_of_measurement': None, }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_maxv-state] +# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_charging-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - 'device_class': 'connectivity', - 'friendly_name': 'Roborock S7 MaxV None', + 'device_class': 'battery_charging', + 'friendly_name': 'Roborock S7 MaxV Charging', }), 'context': , - 'entity_id': 'binary_sensor.roborock_s7_maxv', + 'entity_id': 'binary_sensor.roborock_s7_maxv_charging', 'last_changed': , 'last_reported': , 'last_updated': , 'state': 'on', }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_2-entry] +# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_cleaning-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -312,7 +312,7 @@ 'disabled_by': None, 'domain': 'binary_sensor', 'entity_category': , - 'entity_id': 'binary_sensor.roborock_s7_maxv_2', + 'entity_id': 'binary_sensor.roborock_s7_maxv_cleaning', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -320,36 +320,36 @@ 'labels': set({ }), 'name': None, - 'object_id_base': None, + 'object_id_base': 'Cleaning', 'options': dict({ }), - 'original_device_class': , + 'original_device_class': , 'original_icon': None, - 'original_name': None, + 'original_name': 'Cleaning', 'platform': 'roborock', 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': 0, - 'translation_key': 'water_box_attached', - 'unique_id': 'water_box_status_abc123', + 'translation_key': 'in_cleaning', + 'unique_id': 'in_cleaning_abc123', 'unit_of_measurement': None, }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_2-state] +# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_cleaning-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - 'device_class': 'connectivity', - 'friendly_name': 'Roborock S7 MaxV None', + 'device_class': 'running', + 'friendly_name': 'Roborock S7 MaxV Cleaning', }), 'context': , - 'entity_id': 'binary_sensor.roborock_s7_maxv_2', + 'entity_id': 'binary_sensor.roborock_s7_maxv_cleaning', 'last_changed': , 'last_reported': , 'last_updated': , - 'state': 'on', + 'state': 'off', }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_3-entry] +# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_mop_attached-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -362,7 +362,7 @@ 'disabled_by': None, 'domain': 'binary_sensor', 'entity_category': , - 'entity_id': 'binary_sensor.roborock_s7_maxv_3', + 'entity_id': 'binary_sensor.roborock_s7_maxv_mop_attached', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -370,36 +370,36 @@ 'labels': set({ }), 'name': None, - 'object_id_base': None, + 'object_id_base': 'Mop attached', 'options': dict({ }), - 'original_device_class': , + 'original_device_class': , 'original_icon': None, - 'original_name': None, + 'original_name': 'Mop attached', 'platform': 'roborock', 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': 0, - 'translation_key': 'water_shortage', - 'unique_id': 'water_shortage_abc123', + 'translation_key': 'mop_attached', + 'unique_id': 'water_box_carriage_status_abc123', 'unit_of_measurement': None, }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_3-state] +# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_mop_attached-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - 'device_class': 'problem', - 'friendly_name': 'Roborock S7 MaxV None', + 'device_class': 'connectivity', + 'friendly_name': 'Roborock S7 MaxV Mop attached', }), 'context': , - 'entity_id': 'binary_sensor.roborock_s7_maxv_3', + 'entity_id': 'binary_sensor.roborock_s7_maxv_mop_attached', 'last_changed': , 'last_reported': , 'last_updated': , - 'state': 'off', + 'state': 'on', }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_4-entry] +# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_water_box_attached-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -412,7 +412,7 @@ 'disabled_by': None, 'domain': 'binary_sensor', 'entity_category': , - 'entity_id': 'binary_sensor.roborock_s7_maxv_4', + 'entity_id': 'binary_sensor.roborock_s7_maxv_water_box_attached', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -420,36 +420,36 @@ 'labels': set({ }), 'name': None, - 'object_id_base': None, + 'object_id_base': 'Water box attached', 'options': dict({ }), - 'original_device_class': , + 'original_device_class': , 'original_icon': None, - 'original_name': None, + 'original_name': 'Water box attached', 'platform': 'roborock', 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': 0, - 'translation_key': 'in_cleaning', - 'unique_id': 'in_cleaning_abc123', + 'translation_key': 'water_box_attached', + 'unique_id': 'water_box_status_abc123', 'unit_of_measurement': None, }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_4-state] +# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_water_box_attached-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - 'device_class': 'running', - 'friendly_name': 'Roborock S7 MaxV None', + 'device_class': 'connectivity', + 'friendly_name': 'Roborock S7 MaxV Water box attached', }), 'context': , - 'entity_id': 'binary_sensor.roborock_s7_maxv_4', + 'entity_id': 'binary_sensor.roborock_s7_maxv_water_box_attached', 'last_changed': , 'last_reported': , 'last_updated': , - 'state': 'off', + 'state': 'on', }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_5-entry] +# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_water_shortage-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -462,7 +462,7 @@ 'disabled_by': None, 'domain': 'binary_sensor', 'entity_category': , - 'entity_id': 'binary_sensor.roborock_s7_maxv_5', + 'entity_id': 'binary_sensor.roborock_s7_maxv_water_shortage', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -470,32 +470,32 @@ 'labels': set({ }), 'name': None, - 'object_id_base': None, + 'object_id_base': 'Water shortage', 'options': dict({ }), - 'original_device_class': , + 'original_device_class': , 'original_icon': None, - 'original_name': None, + 'original_name': 'Water shortage', 'platform': 'roborock', 'previous_unique_id': None, 'suggested_object_id': None, 'supported_features': 0, - 'translation_key': None, - 'unique_id': 'battery_charging_abc123', + 'translation_key': 'water_shortage', + 'unique_id': 'water_shortage_abc123', 'unit_of_measurement': None, }) # --- -# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_5-state] +# name: test_binary_sensors[binary_sensor.roborock_s7_maxv_water_shortage-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - 'device_class': 'battery_charging', - 'friendly_name': 'Roborock S7 MaxV None', + 'device_class': 'problem', + 'friendly_name': 'Roborock S7 MaxV Water shortage', }), 'context': , - 'entity_id': 'binary_sensor.roborock_s7_maxv_5', + 'entity_id': 'binary_sensor.roborock_s7_maxv_water_shortage', 'last_changed': , 'last_reported': , 'last_updated': , - 'state': 'on', + 'state': 'off', }) # --- From 401f7c1349e9febf5eb614671e68b146dcfba0a5 Mon Sep 17 00:00:00 2001 From: Paulo Ruberto Date: Mon, 26 Jan 2026 09:30:35 -0500 Subject: [PATCH 6/6] Fix json key ordering --- homeassistant/components/roborock/icons.json | 6 +++--- homeassistant/components/roborock/strings.json | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/homeassistant/components/roborock/icons.json b/homeassistant/components/roborock/icons.json index ab82988358e61a..f6053090bb7a97 100644 --- a/homeassistant/components/roborock/icons.json +++ b/homeassistant/components/roborock/icons.json @@ -1,6 +1,9 @@ { "entity": { "binary_sensor": { + "clean_fluid_empty": { + "default": "mdi:spray-bottle" + }, "in_cleaning": { "default": "mdi:vacuum" }, @@ -15,9 +18,6 @@ }, "water_shortage": { "default": "mdi:water" - }, - "clean_fluid_empty": { - "default": "mdi:spray-bottle" } }, "button": { diff --git a/homeassistant/components/roborock/strings.json b/homeassistant/components/roborock/strings.json index 99b2764752c8ca..b27f7175942c63 100644 --- a/homeassistant/components/roborock/strings.json +++ b/homeassistant/components/roborock/strings.json @@ -41,6 +41,9 @@ }, "entity": { "binary_sensor": { + "clean_fluid_empty": { + "name": "Cleaning fluid" + }, "in_cleaning": { "name": "Cleaning" }, @@ -55,9 +58,6 @@ }, "water_shortage": { "name": "Water shortage" - }, - "clean_fluid_empty": { - "name": "Cleaning fluid" } }, "button": {