From 70238a613dceff57d75d94395cca8ec12a223a14 Mon Sep 17 00:00:00 2001 From: Aronne Brivio Date: Fri, 31 Oct 2025 02:18:39 +0100 Subject: [PATCH] Add border spin switch to Ecovacs (#155512) --- homeassistant/components/ecovacs/icons.json | 3 + homeassistant/components/ecovacs/strings.json | 3 + homeassistant/components/ecovacs/switch.py | 7 + .../fixtures/devices/55uoqe/device.json | 22 ++ .../ecovacs/snapshots/test_switch.ambr | 240 ++++++++++++++++++ tests/components/ecovacs/test_switch.py | 42 ++- 6 files changed, 315 insertions(+), 2 deletions(-) create mode 100644 tests/components/ecovacs/fixtures/devices/55uoqe/device.json diff --git a/homeassistant/components/ecovacs/icons.json b/homeassistant/components/ecovacs/icons.json index 5ebb898514d3..7f2782d8a339 100644 --- a/homeassistant/components/ecovacs/icons.json +++ b/homeassistant/components/ecovacs/icons.json @@ -160,6 +160,9 @@ "advanced_mode": { "default": "mdi:tune" }, + "border_spin": { + "default": "mdi:rotate-right" + }, "border_switch": { "default": "mdi:land-fields" }, diff --git a/homeassistant/components/ecovacs/strings.json b/homeassistant/components/ecovacs/strings.json index 84894c7dea8d..bb63057cee23 100644 --- a/homeassistant/components/ecovacs/strings.json +++ b/homeassistant/components/ecovacs/strings.json @@ -231,6 +231,9 @@ "advanced_mode": { "name": "Advanced mode" }, + "border_spin": { + "name": "Border spin" + }, "border_switch": { "name": "Border switch" }, diff --git a/homeassistant/components/ecovacs/switch.py b/homeassistant/components/ecovacs/switch.py index d151b55ca1c9..67d71cbd831f 100644 --- a/homeassistant/components/ecovacs/switch.py +++ b/homeassistant/components/ecovacs/switch.py @@ -99,6 +99,13 @@ ENTITY_DESCRIPTIONS: tuple[EcovacsSwitchEntityDescription, ...] = ( entity_registry_enabled_default=False, entity_category=EntityCategory.CONFIG, ), + EcovacsSwitchEntityDescription( + capability_fn=lambda c: c.settings.border_spin, + key="border_spin", + translation_key="border_spin", + entity_registry_enabled_default=False, + entity_category=EntityCategory.CONFIG, + ), ) diff --git a/tests/components/ecovacs/fixtures/devices/55uoqe/device.json b/tests/components/ecovacs/fixtures/devices/55uoqe/device.json new file mode 100644 index 000000000000..9adf7bb4e5f5 --- /dev/null +++ b/tests/components/ecovacs/fixtures/devices/55uoqe/device.json @@ -0,0 +1,22 @@ +{ + "did": "E1234567890000000002", + "name": "E1234567890000000002", + "class": "55uoqe", + "resource": "upQ7", + "company": "eco-ng", + "service": { + "jmq": "jmq-ngiot-eu.dc.ww.ecouser.net", + "mqs": "api-ngiot.dc-as.ww.ecouser.net" + }, + "deviceName": "DEEBOT Mini", + "icon": "https://portal-ww.ecouser.net/api/pim/file/get/606278df4a84d700082b39f1", + "UILogicId": "DX_9G", + "materialNo": "110-1820-0102", + "pid": "5c19a91ca1e6ee000178224b", + "product_category": "DEEBOT", + "model": "DX9H", + "nick": "DBMini", + "homeSort": 9999, + "status": 1, + "otaUpgrade": {} +} diff --git a/tests/components/ecovacs/snapshots/test_switch.ambr b/tests/components/ecovacs/snapshots/test_switch.ambr index e56142c2d826..ae669b72fd0f 100644 --- a/tests/components/ecovacs/snapshots/test_switch.ambr +++ b/tests/components/ecovacs/snapshots/test_switch.ambr @@ -479,3 +479,243 @@ 'state': 'on', }) # --- +# name: test_switch_entities[55uoqe][switch.dbmini_continuous_cleaning:entity-registry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'switch', + 'entity_category': , + 'entity_id': 'switch.dbmini_continuous_cleaning', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Continuous cleaning', + 'platform': 'ecovacs', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': 'continuous_cleaning', + 'unique_id': 'E1234567890000000002_continuous_cleaning', + 'unit_of_measurement': None, + }) +# --- +# name: test_switch_entities[55uoqe][switch.dbmini_carpet_auto_boost_suction:entity-registry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'switch', + 'entity_category': , + 'entity_id': 'switch.dbmini_carpet_auto_boost_suction', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Carpet auto-boost suction', + 'platform': 'ecovacs', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': 'carpet_auto_fan_boost', + 'unique_id': 'E1234567890000000002_carpet_auto_fan_boost', + 'unit_of_measurement': None, + }) +# --- +# name: test_switch_entities[55uoqe][switch.dbmini_true_detect:entity-registry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'switch', + 'entity_category': , + 'entity_id': 'switch.dbmini_true_detect', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'True detect', + 'platform': 'ecovacs', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': 'true_detect', + 'unique_id': 'E1234567890000000002_true_detect', + 'unit_of_measurement': None, + }) +# --- +# name: test_switch_entities[55uoqe][switch.dbmini_child_lock:entity-registry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'switch', + 'entity_category': , + 'entity_id': 'switch.dbmini_child_lock', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Child lock', + 'platform': 'ecovacs', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': 'child_lock', + 'unique_id': 'E1234567890000000002_child_lock', + 'unit_of_measurement': None, + }) +# --- +# name: test_switch_entities[55uoqe][switch.dbmini_border_spin:entity-registry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'switch', + 'entity_category': , + 'entity_id': 'switch.dbmini_border_spin', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Border spin', + 'platform': 'ecovacs', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': 'border_spin', + 'unique_id': 'E1234567890000000002_border_spin', + 'unit_of_measurement': None, + }) +# --- +# name: test_switch_entities[55uoqe][switch.dbmini_continuous_cleaning:state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'DBMini Continuous cleaning', + }), + 'context': , + 'entity_id': 'switch.dbmini_continuous_cleaning', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_switch_entities[55uoqe][switch.dbmini_carpet_auto_boost_suction:state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'DBMini Carpet auto-boost suction', + }), + 'context': , + 'entity_id': 'switch.dbmini_carpet_auto_boost_suction', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_switch_entities[55uoqe][switch.dbmini_true_detect:state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'DBMini True detect', + }), + 'context': , + 'entity_id': 'switch.dbmini_true_detect', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_switch_entities[55uoqe][switch.dbmini_child_lock:state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'DBMini Child lock', + }), + 'context': , + 'entity_id': 'switch.dbmini_child_lock', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_switch_entities[55uoqe][switch.dbmini_border_spin:state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'DBMini Border spin', + }), + 'context': , + 'entity_id': 'switch.dbmini_border_spin', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- diff --git a/tests/components/ecovacs/test_switch.py b/tests/components/ecovacs/test_switch.py index 23c802fa0efc..ef79865d354c 100644 --- a/tests/components/ecovacs/test_switch.py +++ b/tests/components/ecovacs/test_switch.py @@ -5,6 +5,7 @@ from dataclasses import dataclass from deebot_client.command import Command from deebot_client.commands.json import ( SetAdvancedMode, + SetBorderSpin, SetBorderSwitch, SetCarpetAutoFanBoost, SetChildLock, @@ -16,6 +17,7 @@ from deebot_client.commands.json import ( ) from deebot_client.events import ( AdvancedModeEvent, + BorderSpinEvent, BorderSwitchEvent, CarpetAutoFanBoostEvent, ChildLockEvent, @@ -127,8 +129,38 @@ class SwitchTestCase: ), ], ), + ( + "55uoqe", + [ + SwitchTestCase( + "switch.dbmini_continuous_cleaning", + ContinuousCleaningEvent(True), + SetContinuousCleaning, + ), + SwitchTestCase( + "switch.dbmini_carpet_auto_boost_suction", + CarpetAutoFanBoostEvent(True), + SetCarpetAutoFanBoost, + ), + SwitchTestCase( + "switch.dbmini_true_detect", + TrueDetectEvent(True), + SetTrueDetect, + ), + SwitchTestCase( + "switch.dbmini_child_lock", + ChildLockEvent(True), + SetChildLock, + ), + SwitchTestCase( + "switch.dbmini_border_spin", + BorderSpinEvent(True), + SetBorderSpin, + ), + ], + ), ], - ids=["yna5x1", "5xu9h3"], + ids=["yna5x1", "5xu9h3", "55uoqe"], ) async def test_switch_entities( hass: HomeAssistant, @@ -204,8 +236,14 @@ async def test_switch_entities( "switch.goat_g1_safe_protect", ], ), + ( + "55uoqe", + [ + "switch.dbmini_border_spin", + ], + ), ], - ids=["yna5x1", "5xu9h3"], + ids=["yna5x1", "5xu9h3", "55uoqe"], ) async def test_disabled_by_default_switch_entities( hass: HomeAssistant, entity_registry: er.EntityRegistry, entity_ids: list[str]