4
4
import math
5
5
from typing import Any
6
6
7
- from zigpy .quirks .v2 import EntityType
7
+ from zigpy .quirks .v2 import EntityPlatform , EntityType
8
8
from zigpy .quirks .v2 .homeassistant import UnitOfLength , UnitOfTime
9
9
from zigpy .quirks .v2 .homeassistant .sensor import SensorDeviceClass , SensorStateClass
10
10
import zigpy .types as t
@@ -57,6 +57,17 @@ def _update_attribute(self, attrid: int | t.uint16_t, value: Any) -> None:
57
57
super ()._update_attribute (attrid , value )
58
58
59
59
60
+ class TuyaSelfCheckResult (t .enum8 ):
61
+ """Tuya self check result enum."""
62
+
63
+ Checking = 0x00
64
+ CheckSuccess = 0x01
65
+ CheckFailure = 0x02
66
+ Others = 0x03
67
+ CommFault = 0x04
68
+ RadarFault = 0x05
69
+
70
+
60
71
base_tuya_motion = (
61
72
TuyaQuirkBuilder ()
62
73
.adds (TuyaOccupancySensing )
@@ -79,6 +90,7 @@ def _update_attribute(self, attrid: int | t.uint16_t, value: Any) -> None:
79
90
min_value = 0 ,
80
91
max_value = 8.25 ,
81
92
step = 0.75 ,
93
+ multiplier = 0.01 ,
82
94
translation_key = "detection_distance_min" ,
83
95
fallback_name = "Minimum range" ,
84
96
)
@@ -91,21 +103,36 @@ def _update_attribute(self, attrid: int | t.uint16_t, value: Any) -> None:
91
103
min_value = 0.75 ,
92
104
max_value = 9.0 ,
93
105
step = 0.75 ,
106
+ multiplier = 0.01 ,
94
107
translation_key = "detection_distance_max" ,
95
108
fallback_name = "Maximum range" ,
96
109
)
97
110
.tuya_sensor (
98
111
dp_id = 9 ,
99
112
attribute_name = "distance" ,
100
113
type = t .uint16_t ,
101
- divisor = 10 ,
114
+ divisor = 100 ,
102
115
state_class = SensorStateClass .MEASUREMENT ,
103
116
device_class = SensorDeviceClass .DISTANCE ,
104
117
unit = UnitOfLength .METERS ,
105
118
entity_type = EntityType .STANDARD ,
106
119
translation_key = "distance" ,
107
120
fallback_name = "Target distance" ,
108
121
)
122
+ .adds (TuyaIlluminanceCluster )
123
+ .skip_configuration ()
124
+ )
125
+
126
+ (
127
+ base_tuya_motion .clone ()
128
+ .applies_to ("_TZE200_ya4ft0w4" , "TS0601" )
129
+ .tuya_dp (
130
+ dp_id = 1 ,
131
+ ep_attribute = TuyaOccupancySensing .ep_attribute ,
132
+ attribute_name = OccupancySensing .AttributeDefs .occupancy .name ,
133
+ converter = lambda x : True if x in (1 , 2 ) else False ,
134
+ )
135
+ # 2, 3, 4, and 9 from base
109
136
.tuya_switch (
110
137
dp_id = 101 ,
111
138
attribute_name = "find_switch" ,
@@ -120,22 +147,10 @@ def _update_attribute(self, attrid: int | t.uint16_t, value: Any) -> None:
120
147
min_value = 0 ,
121
148
max_value = 10 ,
122
149
step = 1 ,
150
+ multiplier = 0.1 ,
123
151
translation_key = "presence_sensitivity" ,
124
152
fallback_name = "Presence sensitivity" ,
125
153
)
126
- .adds (TuyaIlluminanceCluster )
127
- .skip_configuration ()
128
- )
129
-
130
- (
131
- base_tuya_motion .clone ()
132
- .applies_to ("_TZE200_ya4ft0w4" , "TS0601" )
133
- .tuya_dp (
134
- dp_id = 1 ,
135
- ep_attribute = TuyaOccupancySensing .ep_attribute ,
136
- attribute_name = OccupancySensing .AttributeDefs .occupancy .name ,
137
- converter = lambda x : True if x in (1 , 2 ) else False ,
138
- )
139
154
.tuya_dp (
140
155
dp_id = 103 ,
141
156
ep_attribute = TuyaIlluminanceCluster .ep_attribute ,
@@ -157,52 +172,114 @@ def _update_attribute(self, attrid: int | t.uint16_t, value: Any) -> None:
157
172
.add_to_registry ()
158
173
)
159
174
160
- # Neo motion, NAS-PD07 occupancy sensor
161
175
(
162
- TuyaQuirkBuilder ("_TZE200_7hfcudw5" , "TS0601" )
163
- .applies_to ("_TZE200_ppuj1vem" , "TS0601" )
176
+ base_tuya_motion .clone ()
177
+ .applies_to ("_TZE200_ar0slwnd" , "TS0601" ) # Not present in z2m
178
+ .applies_to ("_TZE200_mrf6vtua" , "TS0601" ) # Not present in z2m
179
+ .applies_to ("_TZE200_sfiy5tfs" , "TS0601" ) # Not present in z2m
180
+ .applies_to ("_TZE204_sooucan5" , "TS0601" ) # Not present in z2m
181
+ .applies_to ("_TZE200_wukb7rhc" , "TS0601" ) # Listed in z2m
182
+ .applies_to ("_TZE200_ztc6ggyl" , "TS0601" ) # Listed in z2m
183
+ .applies_to ("_TZE204_ztc6ggyl" , "TS0601" ) # Listed in z2m
184
+ .applies_to ("_TZE200_ikvncluo" , "TS0601" ) # Added from z2m, not present prior
185
+ .applies_to ("_TZE200_lyetpprm" , "TS0601" ) # Added from z2m, not present prior
186
+ .applies_to ("_TZE200_jva8ink8" , "TS0601" ) # Added from z2m, not present prior
187
+ .applies_to ("_TZE204_xpq2rzhq" , "TS0601" ) # Added from z2m, not present prior
188
+ .applies_to ("_TZE200_holel4dk" , "TS0601" ) # Added from z2m, not present prior
189
+ .applies_to ("_TZE200_xpq2rzhq" , "TS0601" ) # Added from z2m, not present prior
190
+ .applies_to ("_TZE204_xsm7l9xa" , "TS0601" ) # Added from z2m, not present prior
191
+ .applies_to ("_TZE200_sgpeacqp" , "TS0601" ) # Added from z2m, not present prior
192
+ .applies_to ("_TZE204_fwondbzy" , "TS0601" ) # Added from z2m, not present prior
164
193
.tuya_dp (
165
- dp_id = 101 ,
194
+ dp_id = 1 ,
166
195
ep_attribute = TuyaOccupancySensing .ep_attribute ,
167
196
attribute_name = OccupancySensing .AttributeDefs .occupancy .name ,
168
197
converter = lambda x : x == 1 ,
169
198
)
170
- .adds (TuyaOccupancySensing )
171
- .tuya_temperature (dp_id = 104 , scale = 10 )
172
- .tuya_humidity (dp_id = 105 )
173
- .skip_configuration ()
199
+ # 2, 3, 4, and 9 from base
200
+ .tuya_enum (
201
+ dp_id = 6 , # z2m lists as not working, yet exposes
202
+ attribute_name = "self_test" ,
203
+ enum_class = TuyaSelfCheckResult ,
204
+ entity_platform = EntityPlatform .SENSOR ,
205
+ entity_type = EntityType .DIAGNOSTIC ,
206
+ translation_key = "self_test" ,
207
+ fallback_name = "Self test result" ,
208
+ )
209
+ .tuya_switch (
210
+ dp_id = 101 ,
211
+ attribute_name = "find_switch" ,
212
+ entity_type = EntityType .STANDARD ,
213
+ translation_key = "find_switch" ,
214
+ fallback_name = "Distance switch" ,
215
+ )
216
+ .tuya_number (
217
+ dp_id = 102 ,
218
+ attribute_name = "presence_sensitivity" ,
219
+ type = t .uint16_t ,
220
+ min_value = 0 ,
221
+ max_value = 10 ,
222
+ step = 1 ,
223
+ multiplier = 0.1 ,
224
+ translation_key = "presence_sensitivity" ,
225
+ fallback_name = "Presence sensitivity" ,
226
+ )
227
+ .tuya_dp (
228
+ dp_id = 104 ,
229
+ ep_attribute = TuyaIlluminanceCluster .ep_attribute ,
230
+ attribute_name = TuyaIlluminanceCluster .AttributeDefs .measured_value .name ,
231
+ converter = lambda x : 10000 * math .log10 (x ) + 1 if x != 0 else 0 ,
232
+ )
233
+ # 103 cli, z2m lists as not working
174
234
.add_to_registry ()
175
235
)
176
236
177
237
(
178
238
base_tuya_motion .clone ()
179
- .applies_to ("_TZE200_ar0slwnd" , "TS0601" )
180
- .applies_to ("_TZE200_mrf6vtua" , "TS0601" )
181
- .applies_to ("_TZE200_sfiy5tfs" , "TS0601" )
182
- .applies_to ("_TZE204_sooucan5" , "TS0601" )
183
- .applies_to ("_TZE200_wukb7rhc" , "TS0601" )
184
239
.applies_to ("_TZE204_qasjif9e" , "TS0601" )
185
- .applies_to ("_TZE200_ztc6ggyl" , "TS0601" )
186
- .applies_to ("_TZE204_ztc6ggyl" , "TS0601" )
187
240
.applies_to ("_TZE204_ztqnh5cg" , "TS0601" )
188
241
.tuya_dp (
189
242
dp_id = 1 ,
190
243
ep_attribute = TuyaOccupancySensing .ep_attribute ,
191
244
attribute_name = OccupancySensing .AttributeDefs .occupancy .name ,
192
245
converter = lambda x : x == 1 ,
193
246
)
194
- # 103?
247
+ # 2, 3, 4, and 9 from base
248
+ .tuya_number (
249
+ dp_id = 101 ,
250
+ attribute_name = "detection_delay" ,
251
+ type = t .uint16_t ,
252
+ device_class = SensorDeviceClass .DURATION ,
253
+ unit = UnitOfTime .SECONDS ,
254
+ min_value = 1 ,
255
+ max_value = 10 ,
256
+ step = 0.1 ,
257
+ multiplier = 0.1 ,
258
+ translation_key = "detection_delay" ,
259
+ fallback_name = "Detection delay" ,
260
+ )
261
+ .tuya_number (
262
+ dp_id = 102 ,
263
+ attribute_name = "fading_time" ,
264
+ type = t .uint16_t ,
265
+ device_class = SensorDeviceClass .DURATION ,
266
+ unit = UnitOfTime .SECONDS ,
267
+ min_value = 1 ,
268
+ max_value = 1500 ,
269
+ step = 0.1 ,
270
+ multiplier = 0.1 ,
271
+ translation_key = "fading_time" ,
272
+ fallback_name = "Fading time" ,
273
+ )
195
274
.tuya_dp (
196
275
dp_id = 104 ,
197
276
ep_attribute = TuyaIlluminanceCluster .ep_attribute ,
198
277
attribute_name = TuyaIlluminanceCluster .AttributeDefs .measured_value .name ,
199
278
converter = lambda x : 10000 * math .log10 (x ) + 1 if x != 0 else 0 ,
200
279
)
201
- # 106?
202
280
.add_to_registry ()
203
281
)
204
282
205
-
206
283
(
207
284
TuyaQuirkBuilder ("_TYST11_i5j6ifxj" , "5j6ifxj" )
208
285
.applies_to ("_TYST11_7hfcudw5" , "hfcudw5" )
@@ -214,3 +291,20 @@ def _update_attribute(self, attrid: int | t.uint16_t, value: Any) -> None:
214
291
.skip_configuration ()
215
292
.add_to_registry ()
216
293
)
294
+
295
+ # Neo motion, NAS-PD07 occupancy sensor
296
+ (
297
+ TuyaQuirkBuilder ("_TZE200_7hfcudw5" , "TS0601" )
298
+ .applies_to ("_TZE200_ppuj1vem" , "TS0601" )
299
+ .tuya_dp (
300
+ dp_id = 101 ,
301
+ ep_attribute = TuyaOccupancySensing .ep_attribute ,
302
+ attribute_name = OccupancySensing .AttributeDefs .occupancy .name ,
303
+ converter = lambda x : x == 1 ,
304
+ )
305
+ .adds (TuyaOccupancySensing )
306
+ .tuya_temperature (dp_id = 104 , scale = 10 )
307
+ .tuya_humidity (dp_id = 105 )
308
+ .skip_configuration ()
309
+ .add_to_registry ()
310
+ )
0 commit comments