diff --git a/homeassistant/components/ecovacs/manifest.json b/homeassistant/components/ecovacs/manifest.json index e38a53e35d0c..932e805c13eb 100644 --- a/homeassistant/components/ecovacs/manifest.json +++ b/homeassistant/components/ecovacs/manifest.json @@ -7,5 +7,5 @@ "integration_type": "hub", "iot_class": "cloud_push", "loggers": ["sleekxmppfs", "sucks", "deebot_client"], - "requirements": ["py-sucks==0.9.11", "deebot-client==18.5.1"] + "requirements": ["py-sucks==0.9.11", "deebot-client==18.6.0"] } diff --git a/homeassistant/components/ecovacs/select.py b/homeassistant/components/ecovacs/select.py index 4add729cb131..ea74b407deb3 100644 --- a/homeassistant/components/ecovacs/select.py +++ b/homeassistant/components/ecovacs/select.py @@ -2,7 +2,7 @@ from collections.abc import Callable from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, override +from typing import Any, override from deebot_client.capabilities import CapabilityMap, CapabilitySet, CapabilitySetTypes from deebot_client.command import CommandWithMessageHandling @@ -84,10 +84,10 @@ async def async_setup_entry( controller, EcovacsSelectEntity, ENTITY_DESCRIPTIONS ) entities.extend( - EcovacsActiveMapSelectEntity(device, device.capabilities.map) + EcovacsActiveMapSelectEntity(device, map_cap, major) for device in controller.devices if (map_cap := device.capabilities.map) - and isinstance(map_cap.major, CapabilitySet) + and isinstance(major := map_cap.major, CapabilitySet) ) if entities: async_add_entities(entities) @@ -149,10 +149,12 @@ class EcovacsActiveMapSelectEntity( self, device: Device, capability: CapabilityMap, + major: CapabilitySet[MajorMapEvent, [str]], **kwargs: Any, ) -> None: """Initialize entity.""" super().__init__(device, capability, **kwargs) + self._major = major self._option_to_id: dict[str, str] = {} self._id_to_option: dict[str, str] = {} @@ -197,13 +199,9 @@ class EcovacsActiveMapSelectEntity( self._attr_current_option = self._id_to_option.get(event.map_id) self.async_write_ha_state() - self._subscribe(self._capability.major.event, on_major_map) + self._subscribe(self._major.event, on_major_map) @override async def async_select_option(self, option: str) -> None: """Change the selected option.""" - if TYPE_CHECKING: - assert isinstance(self._capability.major, CapabilitySet) - await self._device.execute_command( - self._capability.major.set(self._option_to_id[option]) - ) + await self._device.execute_command(self._major.set(self._option_to_id[option])) diff --git a/requirements_all.txt b/requirements_all.txt index 85e00e8ce6da..5464038f3cfa 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -837,7 +837,7 @@ debugpy==1.8.21 decora-wifi==1.4 # homeassistant.components.ecovacs -deebot-client==18.5.1 +deebot-client==18.6.0 # homeassistant.components.ihc # homeassistant.components.ohmconnect diff --git a/tests/components/ecovacs/fixtures/devices/twunby/device.json b/tests/components/ecovacs/fixtures/devices/twunby/device.json new file mode 100644 index 000000000000..7ba468c3cfce --- /dev/null +++ b/tests/components/ecovacs/fixtures/devices/twunby/device.json @@ -0,0 +1,29 @@ +{ + "did": "8516fbb1-17f1-4194-0000003", + "name": "E1234567890000000005", + "class": "twunby", + "resource": "NHl7", + "company": "eco-ng", + "bindTs": 1734792100300, + "service": { + "jmq": "jmq-ngiot-eu.dc.ww.ecouser.net", + "mqs": "api-ngiot.dc-eu.ww.ecouser.net" + }, + "deviceName": "DEEBOT T90 PRO OMNI", + "icon": "https://portal-ww.ecouser.net/api/pim/file/get/0000003", + "ota": true, + "UILogicId": "shakespeare_ww_h_shakespeareh5", + "materialNo": "110-2522-0200", + "pid": "0000003", + "product_category": "DEEBOT", + "model": "SHAKESPEARE_AM_BLK", + "updateInfo": { + "needUpdate": false, + "changeLog": "" + }, + "nick": "T90 PRO OMNI", + "homeId": "1234567890abcdef12345678", + "homeSort": 3, + "status": 1, + "otaUpgrade": {} +} diff --git a/tests/components/ecovacs/snapshots/test_select.ambr b/tests/components/ecovacs/snapshots/test_select.ambr index 0c66914b6639..34fe2d24e2f7 100644 --- a/tests/components/ecovacs/snapshots/test_select.ambr +++ b/tests/components/ecovacs/snapshots/test_select.ambr @@ -359,6 +359,128 @@ 'state': 'unknown', }) # --- +# name: test_selects[twunby-entity_ids3][select.t90_pro_omni_auto_empty_frequency:entity-registry] + EntityRegistryEntrySnapshot({ + 'aliases': list([ + None, + ]), + 'area_id': None, + 'capabilities': dict({ + : list([ + 'auto', + 'smart', + ]), + }), + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'select', + 'entity_category': None, + 'entity_id': 'select.t90_pro_omni_auto_empty_frequency', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'object_id_base': 'Auto-empty frequency', + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Auto-empty frequency', + 'platform': 'ecovacs', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': 'auto_empty', + 'unique_id': '8516fbb1-17f1-4194-0000003_auto_empty', + 'unit_of_measurement': None, + }) +# --- +# name: test_selects[twunby-entity_ids3][select.t90_pro_omni_auto_empty_frequency:state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + : 'T90 PRO OMNI Auto-empty frequency', + : list([ + 'auto', + 'smart', + ]), + }), + 'context': , + 'entity_id': 'select.t90_pro_omni_auto_empty_frequency', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'auto', + }) +# --- +# name: test_selects[twunby-entity_ids3][select.t90_pro_omni_work_mode:entity-registry] + EntityRegistryEntrySnapshot({ + 'aliases': list([ + None, + ]), + 'area_id': None, + 'capabilities': dict({ + : list([ + 'mop', + 'mop_after_vacuum', + 'vacuum', + 'vacuum_and_mop', + ]), + }), + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'select', + 'entity_category': , + 'entity_id': 'select.t90_pro_omni_work_mode', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'object_id_base': 'Work mode', + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Work mode', + 'platform': 'ecovacs', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': 'work_mode', + 'unique_id': '8516fbb1-17f1-4194-0000003_work_mode', + 'unit_of_measurement': None, + }) +# --- +# name: test_selects[twunby-entity_ids3][select.t90_pro_omni_work_mode:state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + : 'T90 PRO OMNI Work mode', + : list([ + 'mop', + 'mop_after_vacuum', + 'vacuum', + 'vacuum_and_mop', + ]), + }), + 'context': , + 'entity_id': 'select.t90_pro_omni_work_mode', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'vacuum', + }) +# --- # name: test_selects[yna5x1-entity_ids0][select.ozmo_950_active_map:entity-registry] EntityRegistryEntrySnapshot({ 'aliases': list([ diff --git a/tests/components/ecovacs/test_init.py b/tests/components/ecovacs/test_init.py index 662a179b3ab6..38ac8d3ec387 100644 --- a/tests/components/ecovacs/test_init.py +++ b/tests/components/ecovacs/test_init.py @@ -176,6 +176,7 @@ async def test_devices_in_dr( [ ("yna5x1", 27), ("5xu9h3", 25), + ("twunby", 40), ("123", 3), ], ) diff --git a/tests/components/ecovacs/test_select.py b/tests/components/ecovacs/test_select.py index f0507b6850b6..eace1b96a876 100644 --- a/tests/components/ecovacs/test_select.py +++ b/tests/components/ecovacs/test_select.py @@ -88,6 +88,13 @@ async def notify_events(hass: HomeAssistant, event_bus: EventBus): "select.x8_pro_omni_active_map", ], ), + ( + "twunby", + [ + "select.t90_pro_omni_work_mode", + "select.t90_pro_omni_auto_empty_frequency", + ], + ), ], ) async def test_selects(