29
29
TUYA_DEVICE_MANAGER ,
30
30
TUYA_DISCOVERY_NEW ,
31
31
TUYA_HA_DEVICES ,
32
- TUYA_HA_TUYA_MAP ,
33
- TUYA_AIR_PURIFIER_TYPE ,
34
- TUYA_FAN_TYPE ,
32
+ TUYA_HA_TUYA_MAP
35
33
)
36
34
37
35
_LOGGER = logging .getLogger (__name__ )
47
45
48
46
# Air Purifier
49
47
# https://developer.tuya.com/en/docs/iot/s?id=K9gf48r41mn81
50
- DPCODE_AP_FAN_SPEED = "speed"
48
+ DPCODE_AP_FAN_SPEED = "speed"
51
49
DPCODE_AP_FAN_SPEED_ENUM = "fan_speed_enum"
52
50
53
51
TUYA_SUPPORT_TYPE = {
54
- TUYA_FAN_TYPE ,
55
- TUYA_AIR_PURIFIER_TYPE
52
+ "fs" , # Fan
53
+ "kj" , # Air Purifier
56
54
}
57
55
56
+
58
57
async def async_setup_entry (
59
58
hass : HomeAssistant , _entry : ConfigEntry , async_add_entities
60
59
):
61
60
"""Set up tuya fan dynamically through tuya discovery."""
62
61
_LOGGER .info ("fan init" )
63
62
64
- hass .data [DOMAIN ][TUYA_HA_TUYA_MAP ].update ({DEVICE_DOMAIN : TUYA_SUPPORT_TYPE })
63
+ hass .data [DOMAIN ][TUYA_HA_TUYA_MAP ].update (
64
+ {DEVICE_DOMAIN : TUYA_SUPPORT_TYPE })
65
65
66
66
async def async_discover_device (dev_ids ):
67
67
"""Discover and add a discovered tuya fan."""
@@ -98,30 +98,33 @@ def _setup_entities(hass, device_ids: list):
98
98
99
99
class TuyaHaFan (TuyaHaDevice , FanEntity ):
100
100
"""Tuya Fan Device."""
101
-
101
+
102
102
def __init__ (self , device : TuyaDevice , device_manager : TuyaDeviceManager ):
103
103
"""Init Tuya Fan Device."""
104
104
super ().__init__ (device , device_manager )
105
-
105
+
106
106
# Air purifier fan can be controlled either via the ranged values or via the enum.
107
107
# We will always prefer the enumeration if available
108
108
# Enum is used for e.g. MEES SmartHIMOX-H06
109
109
# Range is used for e.g. Concept CA3000
110
- self .air_purifier_speed_range = (0 , 0 )
111
- self .air_purifier_speed_range_len = 0
110
+ self .air_purifier_speed_range = (0 , 0 )
111
+ self .air_purifier_speed_range_len = 0
112
112
self .air_purifier_speed_range_enum = []
113
- if self .tuya_device .category == TUYA_AIR_PURIFIER_TYPE :
113
+ if self .tuya_device .category == "kj" :
114
114
try :
115
115
if DPCODE_AP_FAN_SPEED_ENUM in self .tuya_device .status :
116
- data = json .loads (self .tuya_device .function .get (DPCODE_AP_FAN_SPEED_ENUM , {}).values ).get ("range" )
116
+ data = json .loads (self .tuya_device .function .get (
117
+ DPCODE_AP_FAN_SPEED_ENUM , {}).values ).get ("range" )
117
118
if data :
118
119
self .air_purifier_speed_range = (1 , len (data ))
119
120
self .air_purifier_speed_range_len = len (data )
120
121
self .air_purifier_speed_range_enum = data
121
122
elif DPCODE_AP_FAN_SPEED in self .tuya_device .status :
122
- data = json .loads (self .tuya_device .function .get (DPCODE_AP_FAN_SPEED , {}).values ).get ("range" )
123
+ data = json .loads (self .tuya_device .function .get (
124
+ DPCODE_AP_FAN_SPEED , {}).values ).get ("range" )
123
125
if data :
124
- self .air_purifier_speed_range = (int (data [0 ]), int (data [- 1 ]))
126
+ self .air_purifier_speed_range = (
127
+ int (data [0 ]), int (data [- 1 ]))
125
128
self .air_purifier_speed_range_len = len (data )
126
129
except :
127
130
_LOGGER .warn ("Cannot parse the air-purifier speed range" )
@@ -132,17 +135,21 @@ def set_preset_mode(self, preset_mode: str) -> None:
132
135
133
136
def set_direction (self , direction : str ) -> None :
134
137
"""Set the direction of the fan."""
135
- self ._send_command ([{"code" : DPCODE_FAN_DIRECTION , "value" : direction }])
136
-
138
+ self ._send_command (
139
+ [{"code" : DPCODE_FAN_DIRECTION , "value" : direction }])
140
+
137
141
def set_percentage (self , percentage : int ) -> None :
138
142
"""Set the speed of the fan, as a percentage."""
139
- if self .tuya_device .category == TUYA_AIR_PURIFIER_TYPE :
140
- value_in_range = ceil (percentage_to_ranged_value (self .air_purifier_speed_range , percentage ))
143
+ if self .tuya_device .category == "kj" :
144
+ value_in_range = ceil (percentage_to_ranged_value (
145
+ self .air_purifier_speed_range , percentage ))
141
146
if len (self .air_purifier_speed_range_enum ):
142
147
# if air-purifier speed enumeration is supported we will prefer it.
143
- self ._send_command ([{"code" : DPCODE_AP_FAN_SPEED_ENUM , "value" : str (self .air_purifier_speed_range_enum [value_in_range - 1 ])}])
148
+ self ._send_command ([{"code" : DPCODE_AP_FAN_SPEED_ENUM , "value" : str (
149
+ self .air_purifier_speed_range_enum [value_in_range - 1 ])}])
144
150
else :
145
- self ._send_command ([{"code" : DPCODE_AP_FAN_SPEED , "value" : str (value_in_range )}])
151
+ self ._send_command (
152
+ [{"code" : DPCODE_AP_FAN_SPEED , "value" : str (value_in_range )}])
146
153
else :
147
154
super ().set_percentage (percentage )
148
155
@@ -162,7 +169,8 @@ def turn_on(
162
169
163
170
def oscillate (self , oscillating : bool ) -> None :
164
171
"""Oscillate the fan."""
165
- self ._send_command ([{"code" : DPCODE_SWITCH_HORIZONTAL , "value" : oscillating }])
172
+ self ._send_command (
173
+ [{"code" : DPCODE_SWITCH_HORIZONTAL , "value" : oscillating }])
166
174
167
175
# property
168
176
@property
@@ -206,29 +214,30 @@ def percentage(self) -> int:
206
214
"""Return the current speed."""
207
215
if not self .is_on :
208
216
return 0
209
-
210
- if self .tuya_device .category == TUYA_AIR_PURIFIER_TYPE :
217
+
218
+ if self .tuya_device .category == "kj" :
211
219
if self .air_purifier_speed_range_len > 1 :
212
220
if len (self .air_purifier_speed_range_enum ):
213
221
# if air-purifier speed enumeration is supported we will prefer it.
214
222
index = self .air_purifier_speed_range_enum .index (
215
- self .tuya_device .status .get (DPCODE_AP_FAN_SPEED_ENUM , 0 )
223
+ self .tuya_device .status .get (
224
+ DPCODE_AP_FAN_SPEED_ENUM , 0 )
216
225
)
217
226
return ranged_value_to_percentage (self .air_purifier_speed_range ,
218
- index + 1
219
- )
227
+ index + 1
228
+ )
220
229
else :
221
230
return ranged_value_to_percentage (self .air_purifier_speed_range ,
222
- int (self .tuya_device .status .get (DPCODE_AP_FAN_SPEED , 0 )
223
- )
224
- )
231
+ int (self .tuya_device .status .get (DPCODE_AP_FAN_SPEED , 0 )
232
+ )
233
+ )
225
234
else :
226
235
return self .tuya_device .status .get (DPCODE_FAN_SPEED , 0 )
227
236
228
237
@property
229
238
def speed_count (self ) -> int :
230
239
"""Return the number of speeds the fan supports."""
231
- if self .tuya_device .category == TUYA_AIR_PURIFIER_TYPE :
240
+ if self .tuya_device .category == "kj" :
232
241
return self .air_purifier_speed_range_len
233
242
return super ().speed_count ()
234
243
@@ -244,7 +253,7 @@ def supported_features(self):
244
253
supports = supports | SUPPORT_OSCILLATE
245
254
if DPCODE_FAN_DIRECTION in self .tuya_device .status :
246
255
supports = supports | SUPPORT_DIRECTION
247
-
256
+
248
257
# Air Purifier specific
249
258
if DPCODE_AP_FAN_SPEED in self .tuya_device .status or DPCODE_AP_FAN_SPEED_ENUM in self .tuya_device .status :
250
259
supports = supports | SUPPORT_SET_SPEED
0 commit comments