diff --git a/homeassistant/components/ecovacs/manifest.json b/homeassistant/components/ecovacs/manifest.json index b45c06062ee..3495126fd15 100644 --- a/homeassistant/components/ecovacs/manifest.json +++ b/homeassistant/components/ecovacs/manifest.json @@ -6,5 +6,5 @@ "documentation": "https://www.home-assistant.io/integrations/ecovacs", "iot_class": "cloud_push", "loggers": ["sleekxmppfs", "sucks", "deebot_client"], - "requirements": ["py-sucks==0.9.11", "deebot-client==13.7.0"] + "requirements": ["py-sucks==0.9.11", "deebot-client==14.0.0"] } diff --git a/homeassistant/components/ecovacs/select.py b/homeassistant/components/ecovacs/select.py index 84f86fdd2cd..dc64f70da31 100644 --- a/homeassistant/components/ecovacs/select.py +++ b/homeassistant/components/ecovacs/select.py @@ -33,7 +33,9 @@ class EcovacsSelectEntityDescription[EventT: Event]( ENTITY_DESCRIPTIONS: tuple[EcovacsSelectEntityDescription, ...] = ( EcovacsSelectEntityDescription[WaterAmountEvent]( - capability_fn=lambda caps: caps.water.amount if caps.water else None, + capability_fn=lambda caps: caps.water.amount + if caps.water and isinstance(caps.water.amount, CapabilitySetTypes) + else None, current_option_fn=lambda e: get_name_key(e.value), options_fn=lambda water: [get_name_key(amount) for amount in water.types], key="water_amount", diff --git a/homeassistant/components/ecovacs/strings.json b/homeassistant/components/ecovacs/strings.json index 1be81ab1292..8d2d387f6e6 100644 --- a/homeassistant/components/ecovacs/strings.json +++ b/homeassistant/components/ecovacs/strings.json @@ -152,8 +152,10 @@ "station_state": { "name": "Station state", "state": { + "drying_mop": "Drying mop", "idle": "[%key:common::state::idle%]", - "emptying_dustbin": "Emptying dustbin" + "emptying_dustbin": "Emptying dustbin", + "washing_mop": "Washing mop" } }, "stats_area": { diff --git a/homeassistant/components/ecovacs/util.py b/homeassistant/components/ecovacs/util.py index 968ab92851b..d26bd1981d7 100644 --- a/homeassistant/components/ecovacs/util.py +++ b/homeassistant/components/ecovacs/util.py @@ -7,8 +7,6 @@ import random import string from typing import TYPE_CHECKING -from deebot_client.events.station import State - from homeassistant.core import HomeAssistant, callback from homeassistant.util import slugify @@ -49,9 +47,6 @@ def get_supported_entities( @callback def get_name_key(enum: Enum) -> str: """Return the lower case name of the enum.""" - if enum is State.EMPTYING: - # Will be fixed in the next major release of deebot-client - return "emptying_dustbin" return enum.name.lower() diff --git a/requirements_all.txt b/requirements_all.txt index 370631c95ed..1a6649fa558 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -782,7 +782,7 @@ decora-wifi==1.4 # decora==0.6 # homeassistant.components.ecovacs -deebot-client==13.7.0 +deebot-client==14.0.0 # homeassistant.components.ihc # homeassistant.components.namecheapdns diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 6a5ffbb7862..4f28c7b5bcf 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -682,7 +682,7 @@ debugpy==1.8.16 # decora==0.6 # homeassistant.components.ecovacs -deebot-client==13.7.0 +deebot-client==14.0.0 # homeassistant.components.ihc # homeassistant.components.namecheapdns diff --git a/tests/components/ecovacs/fixtures/devices/n0vyif/device.json b/tests/components/ecovacs/fixtures/devices/n0vyif/device.json new file mode 100644 index 00000000000..71aec03a786 --- /dev/null +++ b/tests/components/ecovacs/fixtures/devices/n0vyif/device.json @@ -0,0 +1,27 @@ +{ + "did": "E1234567890000000009", + "name": "E1234567890000000009", + "class": "n0vyif", + "resource": "eSQtNR9N", + "company": "eco-ng", + "service": { + "jmq": "jmq-ngiot-eu.dc.ww.ecouser.net", + "mqs": "api-ngiot.dc-eu.ww.ecouser.net" + }, + "deviceName": "DEEBOT X8 PRO OMNI", + "icon": "https://api-app.dc-eu.ww.ecouser.net/api/pim/file/get/66e3ac63a2928902a25d83a0", + "ota": true, + "UILogicId": "keplerh_ww_h_keplerh5", + "materialNo": "110-2417-0402", + "pid": "66daaa789dd37cf146cb1d2e", + "product_category": "DEEBOT", + "model": "KEPLER_BLACK_AI_INT", + "updateInfo": { + "needUpdate": false, + "changeLog": "" + }, + "nick": "X8 PRO OMNI", + "homeSort": 9999, + "status": 1, + "otaUpgrade": {} +} diff --git a/tests/components/ecovacs/snapshots/test_select.ambr b/tests/components/ecovacs/snapshots/test_select.ambr index 420a4a2d48e..f8e269593d9 100644 --- a/tests/components/ecovacs/snapshots/test_select.ambr +++ b/tests/components/ecovacs/snapshots/test_select.ambr @@ -1,4 +1,65 @@ # serializer version: 1 +# name: test_selects[n0vyif-entity_ids1][select.x8_pro_omni_work_mode:entity-registry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'options': 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.x8_pro_omni_work_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': 'Work mode', + 'platform': 'ecovacs', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': 'work_mode', + 'unique_id': 'E1234567890000000009_work_mode', + 'unit_of_measurement': None, + }) +# --- +# name: test_selects[n0vyif-entity_ids1][select.x8_pro_omni_work_mode:state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'X8 PRO OMNI Work mode', + 'options': list([ + 'mop', + 'mop_after_vacuum', + 'vacuum', + 'vacuum_and_mop', + ]), + }), + 'context': , + 'entity_id': 'select.x8_pro_omni_work_mode', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'vacuum', + }) +# --- # name: test_selects[yna5x1-entity_ids0][select.ozmo_950_water_flow_level:entity-registry] EntityRegistryEntrySnapshot({ 'aliases': set({ diff --git a/tests/components/ecovacs/snapshots/test_sensor.ambr b/tests/components/ecovacs/snapshots/test_sensor.ambr index c216c4c9e4a..a3a891e6a87 100644 --- a/tests/components/ecovacs/snapshots/test_sensor.ambr +++ b/tests/components/ecovacs/snapshots/test_sensor.ambr @@ -1288,6 +1288,8 @@ 'options': list([ 'idle', 'emptying_dustbin', + 'washing_mop', + 'drying_mop', ]), }), 'config_entry_id': , @@ -1327,6 +1329,8 @@ 'options': list([ 'idle', 'emptying_dustbin', + 'washing_mop', + 'drying_mop', ]), }), 'context': , diff --git a/tests/components/ecovacs/test_select.py b/tests/components/ecovacs/test_select.py index c3025d99cfa..538ab66bed0 100644 --- a/tests/components/ecovacs/test_select.py +++ b/tests/components/ecovacs/test_select.py @@ -4,6 +4,7 @@ from deebot_client.command import Command from deebot_client.commands.json import SetWaterInfo from deebot_client.event_bus import EventBus from deebot_client.events.water_info import WaterAmount, WaterAmountEvent +from deebot_client.events.work_mode import WorkMode, WorkModeEvent import pytest from syrupy.assertion import SnapshotAssertion @@ -34,6 +35,7 @@ def platforms() -> Platform | list[Platform]: async def notify_events(hass: HomeAssistant, event_bus: EventBus): """Notify events.""" event_bus.notify(WaterAmountEvent(WaterAmount.ULTRAHIGH)) + event_bus.notify(WorkModeEvent(WorkMode.VACUUM)) await block_till_done(hass, event_bus) @@ -47,6 +49,12 @@ async def notify_events(hass: HomeAssistant, event_bus: EventBus): "select.ozmo_950_water_flow_level", ], ), + ( + "n0vyif", + [ + "select.x8_pro_omni_work_mode", + ], + ), ], ) async def test_selects( diff --git a/tests/components/ecovacs/test_sensor.py b/tests/components/ecovacs/test_sensor.py index 6c3900ccd19..5e7173912ba 100644 --- a/tests/components/ecovacs/test_sensor.py +++ b/tests/components/ecovacs/test_sensor.py @@ -46,7 +46,7 @@ async def notify_events(hass: HomeAssistant, event_bus: EventBus): event_bus.notify(LifeSpanEvent(LifeSpan.FILTER, 56, 40 * 60)) event_bus.notify(LifeSpanEvent(LifeSpan.SIDE_BRUSH, 40, 20 * 60)) event_bus.notify(ErrorEvent(0, "NoError: Robot is operational")) - event_bus.notify(station.StationEvent(station.State.EMPTYING)) + event_bus.notify(station.StationEvent(station.State.EMPTYING_DUSTBIN)) await block_till_done(hass, event_bus)