Skip to content

Commit 84561cb

Browse files
authored
Use select entity for Ecovacs station auto empty settings (#155679)
1 parent 4e48c88 commit 84561cb

File tree

8 files changed

+159
-91
lines changed

8 files changed

+159
-91
lines changed

homeassistant/components/ecovacs/icons.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,9 @@
8181
"active_map": {
8282
"default": "mdi:floor-plan"
8383
},
84+
"auto_empty": {
85+
"default": "mdi:delete-empty"
86+
},
8487
"water_amount": {
8588
"default": "mdi:water"
8689
},
@@ -89,9 +92,6 @@
8992
}
9093
},
9194
"sensor": {
92-
"auto_empty": {
93-
"default": "mdi:delete-empty"
94-
},
9595
"error": {
9696
"default": "mdi:alert-circle"
9797
},

homeassistant/components/ecovacs/select.py

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55
from typing import TYPE_CHECKING, Any
66

77
from deebot_client.capabilities import CapabilityMap, CapabilitySet, CapabilitySetTypes
8+
from deebot_client.command import CommandWithMessageHandling
89
from deebot_client.device import Device
9-
from deebot_client.events import WorkModeEvent
10+
from deebot_client.events import WorkModeEvent, auto_empty
1011
from deebot_client.events.base import Event
1112
from deebot_client.events.map import CachedMapInfoEvent, MajorMapEvent
1213
from deebot_client.events.water_info import WaterAmountEvent
@@ -34,6 +35,9 @@ class EcovacsSelectEntityDescription[EventT: Event](
3435

3536
current_option_fn: Callable[[EventT], str | None]
3637
options_fn: Callable[[CapabilitySetTypes], list[str]]
38+
set_option_fn: Callable[[CapabilitySetTypes, str], CommandWithMessageHandling] = (
39+
lambda cap, option: cap.set(option)
40+
)
3741

3842

3943
ENTITY_DESCRIPTIONS: tuple[EcovacsSelectEntityDescription, ...] = (
@@ -58,6 +62,14 @@ class EcovacsSelectEntityDescription[EventT: Event](
5862
entity_registry_enabled_default=False,
5963
entity_category=EntityCategory.CONFIG,
6064
),
65+
EcovacsSelectEntityDescription[auto_empty.AutoEmptyEvent](
66+
capability_fn=lambda caps: caps.station.auto_empty if caps.station else None,
67+
current_option_fn=lambda e: get_name_key(e.frequency) if e.frequency else None,
68+
options_fn=lambda cap: [get_name_key(freq) for freq in cap.types],
69+
set_option_fn=lambda cap, option: cap.set(None, option),
70+
key="auto_empty",
71+
translation_key="auto_empty",
72+
),
6173
)
6274

6375

@@ -106,14 +118,17 @@ async def async_added_to_hass(self) -> None:
106118
await super().async_added_to_hass()
107119

108120
async def on_event(event: EventT) -> None:
109-
self._attr_current_option = self.entity_description.current_option_fn(event)
110-
self.async_write_ha_state()
121+
if (option := self.entity_description.current_option_fn(event)) is not None:
122+
self._attr_current_option = option
123+
self.async_write_ha_state()
111124

112125
self._subscribe(self._capability.event, on_event)
113126

114127
async def async_select_option(self, option: str) -> None:
115128
"""Change the selected option."""
116-
await self._device.execute_command(self._capability.set(option))
129+
await self._device.execute_command(
130+
self.entity_description.set_option_fn(self._capability, option)
131+
)
117132

118133

119134
class EcovacsActiveMapSelectEntity(

homeassistant/components/ecovacs/sensor.py

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
NetworkInfoEvent,
1818
StatsEvent,
1919
TotalStatsEvent,
20-
auto_empty,
2120
station,
2221
)
2322
from sucks import VacBot
@@ -159,14 +158,6 @@ def get_area_native_unit_of_measurement(device_type: DeviceType) -> str | None:
159158
device_class=SensorDeviceClass.ENUM,
160159
options=get_options(station.State),
161160
),
162-
EcovacsSensorEntityDescription[auto_empty.AutoEmptyEvent](
163-
capability_fn=lambda caps: caps.station.auto_empty if caps.station else None,
164-
value_fn=lambda e: get_name_key(e.frequency) if e.frequency else None,
165-
key="auto_empty",
166-
translation_key="auto_empty",
167-
device_class=SensorDeviceClass.ENUM,
168-
options=get_options(auto_empty.Frequency),
169-
),
170161
)
171162

172163

homeassistant/components/ecovacs/strings.json

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,16 @@
129129
"active_map": {
130130
"name": "Active map"
131131
},
132+
"auto_empty": {
133+
"name": "Auto-empty frequency",
134+
"state": {
135+
"auto": "Auto",
136+
"min_10": "10 minutes",
137+
"min_15": "15 minutes",
138+
"min_25": "25 minutes",
139+
"smart": "Smart"
140+
}
141+
},
132142
"water_amount": {
133143
"name": "[%key:component::ecovacs::entity::number::water_amount::name%]",
134144
"state": {
@@ -149,13 +159,6 @@
149159
}
150160
},
151161
"sensor": {
152-
"auto_empty": {
153-
"name": "Auto-empty frequency",
154-
"state": {
155-
"auto": "Auto",
156-
"smart": "Smart"
157-
}
158-
},
159162
"error": {
160163
"name": "Error",
161164
"state_attributes": {

tests/components/ecovacs/snapshots/test_select.ambr

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,63 @@
5656
'state': 'Map 2',
5757
})
5858
# ---
59+
# name: test_selects[n0vyif-entity_ids2][select.x8_pro_omni_auto_empty_frequency:entity-registry]
60+
EntityRegistryEntrySnapshot({
61+
'aliases': set({
62+
}),
63+
'area_id': None,
64+
'capabilities': dict({
65+
'options': list([
66+
'auto',
67+
'smart',
68+
]),
69+
}),
70+
'config_entry_id': <ANY>,
71+
'config_subentry_id': <ANY>,
72+
'device_class': None,
73+
'device_id': <ANY>,
74+
'disabled_by': None,
75+
'domain': 'select',
76+
'entity_category': None,
77+
'entity_id': 'select.x8_pro_omni_auto_empty_frequency',
78+
'has_entity_name': True,
79+
'hidden_by': None,
80+
'icon': None,
81+
'id': <ANY>,
82+
'labels': set({
83+
}),
84+
'name': None,
85+
'options': dict({
86+
}),
87+
'original_device_class': None,
88+
'original_icon': None,
89+
'original_name': 'Auto-empty frequency',
90+
'platform': 'ecovacs',
91+
'previous_unique_id': None,
92+
'suggested_object_id': None,
93+
'supported_features': 0,
94+
'translation_key': 'auto_empty',
95+
'unique_id': 'E1234567890000000009_auto_empty',
96+
'unit_of_measurement': None,
97+
})
98+
# ---
99+
# name: test_selects[n0vyif-entity_ids2][select.x8_pro_omni_auto_empty_frequency:state]
100+
StateSnapshot({
101+
'attributes': ReadOnlyDict({
102+
'friendly_name': 'X8 PRO OMNI Auto-empty frequency',
103+
'options': list([
104+
'auto',
105+
'smart',
106+
]),
107+
}),
108+
'context': <ANY>,
109+
'entity_id': 'select.x8_pro_omni_auto_empty_frequency',
110+
'last_changed': <ANY>,
111+
'last_reported': <ANY>,
112+
'last_updated': <ANY>,
113+
'state': 'auto',
114+
})
115+
# ---
59116
# name: test_selects[n0vyif-entity_ids2][select.x8_pro_omni_work_mode:entity-registry]
60117
EntityRegistryEntrySnapshot({
61118
'aliases': set({
@@ -174,6 +231,63 @@
174231
'state': 'Map 2',
175232
})
176233
# ---
234+
# name: test_selects[qhe2o2-entity_ids1][select.dusty_auto_empty_frequency:entity-registry]
235+
EntityRegistryEntrySnapshot({
236+
'aliases': set({
237+
}),
238+
'area_id': None,
239+
'capabilities': dict({
240+
'options': list([
241+
'auto',
242+
'smart',
243+
]),
244+
}),
245+
'config_entry_id': <ANY>,
246+
'config_subentry_id': <ANY>,
247+
'device_class': None,
248+
'device_id': <ANY>,
249+
'disabled_by': None,
250+
'domain': 'select',
251+
'entity_category': None,
252+
'entity_id': 'select.dusty_auto_empty_frequency',
253+
'has_entity_name': True,
254+
'hidden_by': None,
255+
'icon': None,
256+
'id': <ANY>,
257+
'labels': set({
258+
}),
259+
'name': None,
260+
'options': dict({
261+
}),
262+
'original_device_class': None,
263+
'original_icon': None,
264+
'original_name': 'Auto-empty frequency',
265+
'platform': 'ecovacs',
266+
'previous_unique_id': None,
267+
'suggested_object_id': None,
268+
'supported_features': 0,
269+
'translation_key': 'auto_empty',
270+
'unique_id': '8516fbb1-17f1-4194-0000001_auto_empty',
271+
'unit_of_measurement': None,
272+
})
273+
# ---
274+
# name: test_selects[qhe2o2-entity_ids1][select.dusty_auto_empty_frequency:state]
275+
StateSnapshot({
276+
'attributes': ReadOnlyDict({
277+
'friendly_name': 'Dusty Auto-empty frequency',
278+
'options': list([
279+
'auto',
280+
'smart',
281+
]),
282+
}),
283+
'context': <ANY>,
284+
'entity_id': 'select.dusty_auto_empty_frequency',
285+
'last_changed': <ANY>,
286+
'last_reported': <ANY>,
287+
'last_updated': <ANY>,
288+
'state': 'auto',
289+
})
290+
# ---
177291
# name: test_selects[qhe2o2-entity_ids1][select.dusty_water_flow_level:entity-registry]
178292
EntityRegistryEntrySnapshot({
179293
'aliases': set({

tests/components/ecovacs/snapshots/test_sensor.ambr

Lines changed: 0 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1652,70 +1652,6 @@
16521652
'state': 'Testnetwork',
16531653
})
16541654
# ---
1655-
# name: test_sensors[qhe2o2][sensor.dusty_auto_empty_frequency:state]
1656-
StateSnapshot({
1657-
'attributes': ReadOnlyDict({
1658-
'device_class': 'enum',
1659-
'friendly_name': 'Dusty Auto-empty frequency',
1660-
'options': list([
1661-
'min_10',
1662-
'min_15',
1663-
'min_25',
1664-
'auto',
1665-
'smart',
1666-
]),
1667-
}),
1668-
'context': <ANY>,
1669-
'entity_id': 'sensor.dusty_auto_empty_frequency',
1670-
'last_changed': <ANY>,
1671-
'last_reported': <ANY>,
1672-
'last_updated': <ANY>,
1673-
'state': 'auto',
1674-
})
1675-
# ---
1676-
# name: test_sensors[qhe2o2][sensor.dusty_auto_empty_frequency:entity-registry]
1677-
EntityRegistryEntrySnapshot({
1678-
'aliases': set({
1679-
}),
1680-
'area_id': None,
1681-
'capabilities': dict({
1682-
'options': list([
1683-
'min_10',
1684-
'min_15',
1685-
'min_25',
1686-
'auto',
1687-
'smart',
1688-
]),
1689-
}),
1690-
'config_entry_id': <ANY>,
1691-
'config_subentry_id': <ANY>,
1692-
'device_class': None,
1693-
'device_id': <ANY>,
1694-
'disabled_by': None,
1695-
'domain': 'sensor',
1696-
'entity_category': None,
1697-
'entity_id': 'sensor.dusty_auto_empty_frequency',
1698-
'has_entity_name': True,
1699-
'hidden_by': None,
1700-
'icon': None,
1701-
'id': <ANY>,
1702-
'labels': set({
1703-
}),
1704-
'name': None,
1705-
'options': dict({
1706-
}),
1707-
'original_device_class': <SensorDeviceClass.ENUM: 'enum'>,
1708-
'original_icon': None,
1709-
'original_name': 'Auto-empty frequency',
1710-
'platform': 'ecovacs',
1711-
'previous_unique_id': None,
1712-
'suggested_object_id': None,
1713-
'supported_features': 0,
1714-
'translation_key': 'auto_empty',
1715-
'unique_id': '8516fbb1-17f1-4194-0000001_auto_empty',
1716-
'unit_of_measurement': None,
1717-
})
1718-
# ---
17191655
# name: test_sensors[yna5x1][sensor.ozmo_950_area_cleaned:entity-registry]
17201656
EntityRegistryEntrySnapshot({
17211657
'aliases': set({

tests/components/ecovacs/test_select.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22

33
from deebot_client.command import Command
44
from deebot_client.commands.json import SetWaterInfo
5+
from deebot_client.commands.json.auto_empty import SetAutoEmpty
56
from deebot_client.event_bus import EventBus
7+
from deebot_client.events import auto_empty
68
from deebot_client.events.map import CachedMapInfoEvent, MajorMapEvent, Map
79
from deebot_client.events.water_info import WaterAmount, WaterAmountEvent
810
from deebot_client.events.work_mode import WorkMode, WorkModeEvent
@@ -55,6 +57,7 @@ async def notify_events(hass: HomeAssistant, event_bus: EventBus):
5557
)
5658
)
5759
event_bus.notify(MajorMapEvent("2", [], requested=False))
60+
event_bus.notify(auto_empty.AutoEmptyEvent(True, auto_empty.Frequency.AUTO))
5861
await block_till_done(hass, event_bus)
5962

6063

@@ -73,13 +76,15 @@ async def notify_events(hass: HomeAssistant, event_bus: EventBus):
7376
"qhe2o2",
7477
[
7578
"select.dusty_water_flow_level",
79+
"select.dusty_auto_empty_frequency",
7680
"select.dusty_active_map",
7781
],
7882
),
7983
(
8084
"n0vyif",
8185
[
8286
"select.x8_pro_omni_work_mode",
87+
"select.x8_pro_omni_auto_empty_frequency",
8388
"select.x8_pro_omni_active_map",
8489
],
8590
),
@@ -94,7 +99,7 @@ async def test_selects(
9499
entity_ids: list[str],
95100
) -> None:
96101
"""Test that select entity snapshots match."""
97-
assert entity_ids == hass.states.async_entity_ids()
102+
assert hass.states.async_entity_ids() == entity_ids
98103
for entity_id in entity_ids:
99104
assert (state := hass.states.get(entity_id)), f"State of {entity_id} is missing"
100105
assert state.state == STATE_UNKNOWN
@@ -124,6 +129,13 @@ async def test_selects(
124129
"low",
125130
SetWaterInfo(WaterAmount.LOW),
126131
),
132+
(
133+
"qhe2o2",
134+
"select.dusty_auto_empty_frequency",
135+
"auto",
136+
"smart",
137+
SetAutoEmpty(None, auto_empty.Frequency.SMART),
138+
),
127139
],
128140
)
129141
async def test_selects_change(

0 commit comments

Comments
 (0)