From cd5377367ab02ffbbb021f8212353f4e48693dc8 Mon Sep 17 00:00:00 2001 From: Andy Date: Wed, 28 Feb 2024 20:43:53 +0100 Subject: [PATCH] Add Ecovacs goat switch entities (#111751) --- CODEOWNERS | 4 +- homeassistant/components/ecovacs/icons.json | 15 + .../components/ecovacs/manifest.json | 2 +- homeassistant/components/ecovacs/strings.json | 15 + homeassistant/components/ecovacs/switch.py | 40 +++ .../ecovacs/snapshots/test_switch.ambr | 315 ++++++++++++++++++ tests/components/ecovacs/test_init.py | 2 +- tests/components/ecovacs/test_switch.py | 68 +++- 8 files changed, 455 insertions(+), 6 deletions(-) diff --git a/CODEOWNERS b/CODEOWNERS index 33d954b8740..1424469a94b 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -331,8 +331,8 @@ build.json @home-assistant/supervisor /tests/components/ecoforest/ @pjanuario /homeassistant/components/econet/ @w1ll1am23 /tests/components/econet/ @w1ll1am23 -/homeassistant/components/ecovacs/ @OverloadUT @mib1185 @edenhaus @augar -/tests/components/ecovacs/ @OverloadUT @mib1185 @edenhaus @augar +/homeassistant/components/ecovacs/ @OverloadUT @mib1185 @edenhaus @Augar +/tests/components/ecovacs/ @OverloadUT @mib1185 @edenhaus @Augar /homeassistant/components/ecowitt/ @pvizeli /tests/components/ecowitt/ @pvizeli /homeassistant/components/efergy/ @tkdrob diff --git a/homeassistant/components/ecovacs/icons.json b/homeassistant/components/ecovacs/icons.json index b639ff81e63..7a57259ca5a 100644 --- a/homeassistant/components/ecovacs/icons.json +++ b/homeassistant/components/ecovacs/icons.json @@ -83,15 +83,30 @@ "advanced_mode": { "default": "mdi:tune" }, + "border_switch": { + "default": "mdi:land-fields" + }, "carpet_auto_fan_boost": { "default": "mdi:fan-auto" }, + "child_lock": { + "default": "mdi:teddy-bear" + }, "clean_preference": { "default": "mdi:broom" }, + "cross_map_border_warning": { + "default": "mdi:border-none-variant" + }, "continuous_cleaning": { "default": "mdi:refresh-auto" }, + "move_up_warning": { + "default": "mdi:arrow-up-bold-box-outline" + }, + "safe_protect": { + "default": "mdi:shield-half-full" + }, "true_detect": { "default": "mdi:laser-pointer" } diff --git a/homeassistant/components/ecovacs/manifest.json b/homeassistant/components/ecovacs/manifest.json index 7c5e527c464..52753e6eb39 100644 --- a/homeassistant/components/ecovacs/manifest.json +++ b/homeassistant/components/ecovacs/manifest.json @@ -1,7 +1,7 @@ { "domain": "ecovacs", "name": "Ecovacs", - "codeowners": ["@OverloadUT", "@mib1185", "@edenhaus", "@augar"], + "codeowners": ["@OverloadUT", "@mib1185", "@edenhaus", "@Augar"], "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/ecovacs", "iot_class": "cloud_push", diff --git a/homeassistant/components/ecovacs/strings.json b/homeassistant/components/ecovacs/strings.json index 7a456483877..1f43b830778 100644 --- a/homeassistant/components/ecovacs/strings.json +++ b/homeassistant/components/ecovacs/strings.json @@ -136,15 +136,30 @@ "advanced_mode": { "name": "Advanced mode" }, + "border_switch": { + "name": "Border switch" + }, "carpet_auto_fan_boost": { "name": "Carpet auto-boost suction" }, + "child_lock": { + "name": "Child lock" + }, "clean_preference": { "name": "Clean preference" }, + "cross_map_border_warning": { + "name": "Cross map border warning" + }, "continuous_cleaning": { "name": "Continuous cleaning" }, + "move_up_warning": { + "name": "Move up warning" + }, + "safe_protect": { + "name": "Safe protect" + }, "true_detect": { "name": "True detect" } diff --git a/homeassistant/components/ecovacs/switch.py b/homeassistant/components/ecovacs/switch.py index 119de35e786..316ed5427ba 100644 --- a/homeassistant/components/ecovacs/switch.py +++ b/homeassistant/components/ecovacs/switch.py @@ -75,6 +75,46 @@ ENTITY_DESCRIPTIONS: tuple[EcovacsSwitchEntityDescription, ...] = ( entity_registry_enabled_default=False, entity_category=EntityCategory.CONFIG, ), + EcovacsSwitchEntityDescription[Capabilities]( + device_capabilities=Capabilities, + capability_fn=lambda c: c.settings.border_switch, + key="border_switch", + translation_key="border_switch", + entity_registry_enabled_default=False, + entity_category=EntityCategory.CONFIG, + ), + EcovacsSwitchEntityDescription[Capabilities]( + device_capabilities=Capabilities, + capability_fn=lambda c: c.settings.child_lock, + key="child_lock", + translation_key="child_lock", + entity_registry_enabled_default=False, + entity_category=EntityCategory.CONFIG, + ), + EcovacsSwitchEntityDescription[Capabilities]( + device_capabilities=Capabilities, + capability_fn=lambda c: c.settings.moveup_warning, + key="move_up_warning", + translation_key="move_up_warning", + entity_registry_enabled_default=False, + entity_category=EntityCategory.CONFIG, + ), + EcovacsSwitchEntityDescription[Capabilities]( + device_capabilities=Capabilities, + capability_fn=lambda c: c.settings.cross_map_border_warning, + key="cross_map_border_warning", + translation_key="cross_map_border_warning", + entity_registry_enabled_default=False, + entity_category=EntityCategory.CONFIG, + ), + EcovacsSwitchEntityDescription[Capabilities]( + device_capabilities=Capabilities, + capability_fn=lambda c: c.settings.safe_protect, + key="safe_protect", + translation_key="safe_protect", + entity_registry_enabled_default=False, + entity_category=EntityCategory.CONFIG, + ), ) diff --git a/tests/components/ecovacs/snapshots/test_switch.ambr b/tests/components/ecovacs/snapshots/test_switch.ambr index ddbcfed1347..ecb5bc0dbe5 100644 --- a/tests/components/ecovacs/snapshots/test_switch.ambr +++ b/tests/components/ecovacs/snapshots/test_switch.ambr @@ -1,4 +1,319 @@ # serializer version: 1 +# name: test_switch_entities[5xu9h3][switch.goat_g1_advanced_mode:entity-registry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'switch', + 'entity_category': , + 'entity_id': 'switch.goat_g1_advanced_mode', + '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': 'Advanced mode', + 'platform': 'ecovacs', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'advanced_mode', + 'unique_id': '8516fbb1-17f1-4194-0000000_advanced_mode', + 'unit_of_measurement': None, + }) +# --- +# name: test_switch_entities[5xu9h3][switch.goat_g1_advanced_mode:state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'Goat G1 Advanced mode', + }), + 'context': , + 'entity_id': 'switch.goat_g1_advanced_mode', + 'last_changed': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_switch_entities[5xu9h3][switch.goat_g1_border_switch:entity-registry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'switch', + 'entity_category': , + 'entity_id': 'switch.goat_g1_border_switch', + '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 switch', + 'platform': 'ecovacs', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'border_switch', + 'unique_id': '8516fbb1-17f1-4194-0000000_border_switch', + 'unit_of_measurement': None, + }) +# --- +# name: test_switch_entities[5xu9h3][switch.goat_g1_border_switch:state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'Goat G1 Border switch', + }), + 'context': , + 'entity_id': 'switch.goat_g1_border_switch', + 'last_changed': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_switch_entities[5xu9h3][switch.goat_g1_child_lock:entity-registry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'switch', + 'entity_category': , + 'entity_id': 'switch.goat_g1_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, + 'supported_features': 0, + 'translation_key': 'child_lock', + 'unique_id': '8516fbb1-17f1-4194-0000000_child_lock', + 'unit_of_measurement': None, + }) +# --- +# name: test_switch_entities[5xu9h3][switch.goat_g1_child_lock:state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'Goat G1 Child lock', + }), + 'context': , + 'entity_id': 'switch.goat_g1_child_lock', + 'last_changed': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_switch_entities[5xu9h3][switch.goat_g1_cross_map_border_warning:entity-registry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'switch', + 'entity_category': , + 'entity_id': 'switch.goat_g1_cross_map_border_warning', + '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': 'Cross map border warning', + 'platform': 'ecovacs', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'cross_map_border_warning', + 'unique_id': '8516fbb1-17f1-4194-0000000_cross_map_border_warning', + 'unit_of_measurement': None, + }) +# --- +# name: test_switch_entities[5xu9h3][switch.goat_g1_cross_map_border_warning:state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'Goat G1 Cross map border warning', + }), + 'context': , + 'entity_id': 'switch.goat_g1_cross_map_border_warning', + 'last_changed': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_switch_entities[5xu9h3][switch.goat_g1_move_up_warning:entity-registry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'switch', + 'entity_category': , + 'entity_id': 'switch.goat_g1_move_up_warning', + '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': 'Move up warning', + 'platform': 'ecovacs', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'move_up_warning', + 'unique_id': '8516fbb1-17f1-4194-0000000_move_up_warning', + 'unit_of_measurement': None, + }) +# --- +# name: test_switch_entities[5xu9h3][switch.goat_g1_move_up_warning:state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'Goat G1 Move up warning', + }), + 'context': , + 'entity_id': 'switch.goat_g1_move_up_warning', + 'last_changed': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_switch_entities[5xu9h3][switch.goat_g1_safe_protect:entity-registry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'switch', + 'entity_category': , + 'entity_id': 'switch.goat_g1_safe_protect', + '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': 'Safe protect', + 'platform': 'ecovacs', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'safe_protect', + 'unique_id': '8516fbb1-17f1-4194-0000000_safe_protect', + 'unit_of_measurement': None, + }) +# --- +# name: test_switch_entities[5xu9h3][switch.goat_g1_safe_protect:state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'Goat G1 Safe protect', + }), + 'context': , + 'entity_id': 'switch.goat_g1_safe_protect', + 'last_changed': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_switch_entities[5xu9h3][switch.goat_g1_true_detect:entity-registry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'switch', + 'entity_category': , + 'entity_id': 'switch.goat_g1_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, + 'supported_features': 0, + 'translation_key': 'true_detect', + 'unique_id': '8516fbb1-17f1-4194-0000000_true_detect', + 'unit_of_measurement': None, + }) +# --- +# name: test_switch_entities[5xu9h3][switch.goat_g1_true_detect:state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'Goat G1 True detect', + }), + 'context': , + 'entity_id': 'switch.goat_g1_true_detect', + 'last_changed': , + 'last_updated': , + 'state': 'on', + }) +# --- # name: test_switch_entities[yna5x1][switch.ozmo_950_advanced_mode:entity-registry] EntityRegistryEntrySnapshot({ 'aliases': set({ diff --git a/tests/components/ecovacs/test_init.py b/tests/components/ecovacs/test_init.py index a567ea3253d..4cad3e74ae0 100644 --- a/tests/components/ecovacs/test_init.py +++ b/tests/components/ecovacs/test_init.py @@ -121,7 +121,7 @@ async def test_devices_in_dr( ("device_fixture", "entities"), [ ("yna5x1", 25), - ("5xu9h3", 14), + ("5xu9h3", 19), ], ) async def test_all_entities_loaded( diff --git a/tests/components/ecovacs/test_switch.py b/tests/components/ecovacs/test_switch.py index e405a1ee3ec..fee348149ee 100644 --- a/tests/components/ecovacs/test_switch.py +++ b/tests/components/ecovacs/test_switch.py @@ -6,14 +6,26 @@ from deebot_client.capabilities import Capabilities from deebot_client.command import Command from deebot_client.commands.json import ( SetAdvancedMode, + SetBorderSwitch, SetCarpetAutoFanBoost, + SetChildLock, SetContinuousCleaning, + SetCrossMapBorderWarning, + SetMoveUpWarning, + SetSafeProtect, + SetTrueDetect, ) from deebot_client.events import ( AdvancedModeEvent, + BorderSwitchEvent, CarpetAutoFanBoostEvent, + ChildLockEvent, ContinuousCleaningEvent, + CrossMapBorderWarningEvent, Event, + MoveUpWarningEvent, + SafeProtectEvent, + TrueDetectEvent, ) import pytest from syrupy import SnapshotAssertion @@ -76,8 +88,48 @@ class SwitchTestCase: ), ], ), + ( + "5xu9h3", + [ + SwitchTestCase( + "switch.goat_g1_advanced_mode", + AdvancedModeEvent(True), + SetAdvancedMode, + ), + SwitchTestCase( + "switch.goat_g1_true_detect", + TrueDetectEvent(True), + SetTrueDetect, + ), + SwitchTestCase( + "switch.goat_g1_border_switch", + BorderSwitchEvent(True), + SetBorderSwitch, + ), + SwitchTestCase( + "switch.goat_g1_child_lock", + ChildLockEvent(True), + SetChildLock, + ), + SwitchTestCase( + "switch.goat_g1_move_up_warning", + MoveUpWarningEvent(True), + SetMoveUpWarning, + ), + SwitchTestCase( + "switch.goat_g1_cross_map_border_warning", + CrossMapBorderWarningEvent(True), + SetCrossMapBorderWarning, + ), + SwitchTestCase( + "switch.goat_g1_safe_protect", + SafeProtectEvent(True), + SetSafeProtect, + ), + ], + ), ], - ids=["yna5x1"], + ids=["yna5x1", "5xu9h3"], ) async def test_switch_entities( hass: HomeAssistant, @@ -141,8 +193,20 @@ async def test_switch_entities( "switch.ozmo_950_carpet_auto_boost_suction", ], ), + ( + "5xu9h3", + [ + "switch.goat_g1_advanced_mode", + "switch.goat_g1_true_detect", + "switch.goat_g1_border_switch", + "switch.goat_g1_child_lock", + "switch.goat_g1_move_up_warning", + "switch.goat_g1_cross_map_border_warning", + "switch.goat_g1_safe_protect", + ], + ), ], - ids=["yna5x1"], + ids=["yna5x1", "5xu9h3"], ) async def test_disabled_by_default_switch_entities( hass: HomeAssistant, entity_registry: er.EntityRegistry, entity_ids: list[str]