Skip to content

Commit 2cacfc7

Browse files
authored
Migrate Tuya fan (preset) to use wrapper class (home-assistant#156922)
1 parent 388ab5c commit 2cacfc7

File tree

2 files changed

+34
-43
lines changed

2 files changed

+34
-43
lines changed

homeassistant/components/tuya/fan.py

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,11 @@
2323
from . import TuyaConfigEntry
2424
from .const import TUYA_DISCOVERY_NEW, DeviceCategory, DPCode, DPType
2525
from .entity import TuyaEntity
26-
from .models import EnumTypeData, IntegerTypeData, find_dpcode
26+
from .models import DPCodeEnumWrapper, EnumTypeData, IntegerTypeData, find_dpcode
2727
from .util import get_dpcode
2828

2929
_DIRECTION_DPCODES = (DPCode.FAN_DIRECTION,)
30+
_MODE_DPCODES = (DPCode.FAN_MODE, DPCode.MODE)
3031
_OSCILLATE_DPCODES = (DPCode.SWITCH_HORIZONTAL, DPCode.SWITCH_VERTICAL)
3132
_SPEED_DPCODES = (
3233
DPCode.FAN_SPEED_PERCENT,
@@ -74,7 +75,15 @@ def async_discover_device(device_ids: list[str]) -> None:
7475
for device_id in device_ids:
7576
device = manager.device_map[device_id]
7677
if device.category in TUYA_SUPPORT_TYPE and _has_a_valid_dpcode(device):
77-
entities.append(TuyaFanEntity(device, manager))
78+
entities.append(
79+
TuyaFanEntity(
80+
device,
81+
manager,
82+
mode_wrapper=DPCodeEnumWrapper.find_dpcode(
83+
device, _MODE_DPCODES, prefer_function=True
84+
),
85+
)
86+
)
7887
async_add_entities(entities)
7988

8089
async_discover_device([*manager.device_map])
@@ -89,7 +98,6 @@ class TuyaFanEntity(TuyaEntity, FanEntity):
8998

9099
_direction: EnumTypeData | None = None
91100
_oscillate: DPCode | None = None
92-
_presets: EnumTypeData | None = None
93101
_speed: IntegerTypeData | None = None
94102
_speeds: EnumTypeData | None = None
95103
_switch: DPCode | None = None
@@ -99,22 +107,18 @@ def __init__(
99107
self,
100108
device: CustomerDevice,
101109
device_manager: Manager,
110+
*,
111+
mode_wrapper: DPCodeEnumWrapper | None,
102112
) -> None:
103113
"""Init Tuya Fan Device."""
104114
super().__init__(device, device_manager)
115+
self._mode_wrapper = mode_wrapper
105116

106117
self._switch = get_dpcode(self.device, _SWITCH_DPCODES)
107118

108-
self._attr_preset_modes = []
109-
if enum_type := find_dpcode(
110-
self.device,
111-
(DPCode.FAN_MODE, DPCode.MODE),
112-
dptype=DPType.ENUM,
113-
prefer_function=True,
114-
):
115-
self._presets = enum_type
119+
if mode_wrapper:
116120
self._attr_supported_features |= FanEntityFeature.PRESET_MODE
117-
self._attr_preset_modes = enum_type.range
121+
self._attr_preset_modes = mode_wrapper.type_information.range
118122

119123
# Find speed controls, can be either percentage or a set of speeds
120124
if int_type := find_dpcode(
@@ -142,11 +146,9 @@ def __init__(
142146
FanEntityFeature.TURN_ON | FanEntityFeature.TURN_OFF
143147
)
144148

145-
def set_preset_mode(self, preset_mode: str) -> None:
149+
async def async_set_preset_mode(self, preset_mode: str) -> None:
146150
"""Set the preset mode of the fan."""
147-
if self._presets is None:
148-
return
149-
self._send_command([{"code": self._presets.dpcode, "value": preset_mode}])
151+
await self._async_send_dpcode_update(self._mode_wrapper, preset_mode)
150152

151153
def set_direction(self, direction: str) -> None:
152154
"""Set the direction of the fan."""
@@ -215,9 +217,10 @@ def turn_on(
215217
}
216218
)
217219

218-
if preset_mode is not None and self._presets is not None:
219-
commands.append({"code": self._presets.dpcode, "value": preset_mode})
220-
220+
if preset_mode is not None and self._mode_wrapper:
221+
commands.append(
222+
self._mode_wrapper.get_update_command(self.device, preset_mode)
223+
)
221224
self._send_command(commands)
222225

223226
def oscillate(self, oscillating: bool) -> None:
@@ -260,9 +263,7 @@ def oscillating(self) -> bool | None:
260263
@property
261264
def preset_mode(self) -> str | None:
262265
"""Return the current preset_mode."""
263-
if self._presets is None:
264-
return None
265-
return self.device.status.get(self._presets.dpcode)
266+
return self._read_wrapper(self._mode_wrapper)
266267

267268
@property
268269
def percentage(self) -> int | None:

tests/components/tuya/snapshots/test_fan.ambr

Lines changed: 11 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@
9292
StateSnapshot({
9393
'attributes': ReadOnlyDict({
9494
'friendly_name': 'Bree',
95-
'preset_mode': 'normal',
95+
'preset_mode': None,
9696
'preset_modes': list([
9797
'sleep',
9898
]),
@@ -112,8 +112,7 @@
112112
}),
113113
'area_id': None,
114114
'capabilities': dict({
115-
'preset_modes': list([
116-
]),
115+
'preset_modes': None,
117116
}),
118117
'config_entry_id': <ANY>,
119118
'config_subentry_id': <ANY>,
@@ -152,8 +151,7 @@
152151
'percentage': 20,
153152
'percentage_step': 1.0,
154153
'preset_mode': None,
155-
'preset_modes': list([
156-
]),
154+
'preset_modes': None,
157155
'supported_features': <FanEntityFeature: 53>,
158156
}),
159157
'context': <ANY>,
@@ -234,8 +232,7 @@
234232
}),
235233
'area_id': None,
236234
'capabilities': dict({
237-
'preset_modes': list([
238-
]),
235+
'preset_modes': None,
239236
}),
240237
'config_entry_id': <ANY>,
241238
'config_subentry_id': <ANY>,
@@ -270,8 +267,7 @@
270267
StateSnapshot({
271268
'attributes': ReadOnlyDict({
272269
'friendly_name': 'Dehumidifer',
273-
'preset_modes': list([
274-
]),
270+
'preset_modes': None,
275271
'supported_features': <FanEntityFeature: 49>,
276272
}),
277273
'context': <ANY>,
@@ -338,8 +334,7 @@
338334
}),
339335
'area_id': None,
340336
'capabilities': dict({
341-
'preset_modes': list([
342-
]),
337+
'preset_modes': None,
343338
}),
344339
'config_entry_id': <ANY>,
345340
'config_subentry_id': <ANY>,
@@ -377,8 +372,7 @@
377372
'percentage': 50,
378373
'percentage_step': 50.0,
379374
'preset_mode': None,
380-
'preset_modes': list([
381-
]),
375+
'preset_modes': None,
382376
'supported_features': <FanEntityFeature: 49>,
383377
}),
384378
'context': <ANY>,
@@ -395,8 +389,7 @@
395389
}),
396390
'area_id': None,
397391
'capabilities': dict({
398-
'preset_modes': list([
399-
]),
392+
'preset_modes': None,
400393
}),
401394
'config_entry_id': <ANY>,
402395
'config_subentry_id': <ANY>,
@@ -434,8 +427,7 @@
434427
'percentage': None,
435428
'percentage_step': 33.333333333333336,
436429
'preset_mode': None,
437-
'preset_modes': list([
438-
]),
430+
'preset_modes': None,
439431
'supported_features': <FanEntityFeature: 49>,
440432
}),
441433
'context': <ANY>,
@@ -563,8 +555,7 @@
563555
}),
564556
'area_id': None,
565557
'capabilities': dict({
566-
'preset_modes': list([
567-
]),
558+
'preset_modes': None,
568559
}),
569560
'config_entry_id': <ANY>,
570561
'config_subentry_id': <ANY>,
@@ -602,8 +593,7 @@
602593
'percentage': 100,
603594
'percentage_step': 50.0,
604595
'preset_mode': None,
605-
'preset_modes': list([
606-
]),
596+
'preset_modes': None,
607597
'supported_features': <FanEntityFeature: 49>,
608598
}),
609599
'context': <ANY>,

0 commit comments

Comments
 (0)