Skip to content

Commit 4f5abdd

Browse files
authored
Support power/energy for more Aqara (H1) switches, add devices (#2784)
* Have `OppleCluster` in `opple_remote.py` inherit `XiaomiAqaraE1Cluster` * Add `MODELS_INFO` to `XiaomiOpple2ButtonSwitchFace1`, `XiaomiOpple2ButtonSwitchFace2` These are the only models I found online. * Add power and energy support for `lumi.switch.n2aeu1`, `lumi.switch.b2naus01` Seems to be supported * Add alternative signature for `lumi.switch.n1aeu1`, support power/energy, refactor * Remove redundant `XiaomiMeteringCluster` * Use `LUMI` constant for `MODELS_INFO` * Remove cluster ID comments for opple_switch.py * Remove redundant device_automation_triggers assignment * Rename `switch_h1.py` to `switch_h1_single.py`, add comment * Add `switch_h1_double.py` and move H1 double switch quirk from `opple_switch.py` * Remove cluster ID comments from `XiaomiOpple2ButtonSwitchFace2` * Rename `lumi.switch.n2aeu1` quirk to `AqaraH1DoubleRockerSwitchWithNeutral` * Change imports slightly * Add support for `lumi.switch.l2aeu1`, `lumi.switch.l2aeu1` * Improve docstring for opple_switch.py
1 parent d35fc05 commit 4f5abdd

File tree

7 files changed

+559
-330
lines changed

7 files changed

+559
-330
lines changed

tests/test_quirks.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -401,8 +401,6 @@ def _check_range(cluster: zcl.Cluster) -> bool:
401401
# Some quirks do not yet have model info:
402402
zhaquirks.xbee.xbee_io.XBeeSensor,
403403
zhaquirks.xbee.xbee3_io.XBee3Sensor,
404-
zhaquirks.xiaomi.aqara.opple_switch.XiaomiOpple2ButtonSwitchFace2,
405-
zhaquirks.xiaomi.aqara.opple_switch.XiaomiOpple2ButtonSwitchFace1,
406404
zhaquirks.tuya.ts0201.MoesTemperatureHumidtySensorWithScreen,
407405
zhaquirks.smartthings.tag_v4.SmartThingsTagV4,
408406
zhaquirks.smartthings.multi.SmartthingsMultiPurposeSensor,

zhaquirks/xiaomi/__init__.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -542,10 +542,6 @@ class DeviceTemperatureCluster(LocalDataCluster, DeviceTemperature):
542542
"""Device Temperature Cluster."""
543543

544544

545-
class XiaomiMeteringCluster(LocalDataCluster, Metering):
546-
"""Xiaomi Metering Cluster."""
547-
548-
549545
class TemperatureMeasurementCluster(CustomCluster, TemperatureMeasurement):
550546
"""Temperature cluster that filters out invalid temperature readings."""
551547

zhaquirks/xiaomi/aqara/opple_remote.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,12 @@
5050
VALUE,
5151
ZHA_SEND_EVENT,
5252
)
53-
from zhaquirks.xiaomi import LUMI, BasicCluster, XiaomiCustomDevice
53+
from zhaquirks.xiaomi import (
54+
LUMI,
55+
BasicCluster,
56+
XiaomiAqaraE1Cluster,
57+
XiaomiCustomDevice,
58+
)
5459

5560
PRESS_TYPES = {0: "hold", 1: "single", 2: "double", 3: "triple", 255: "release"}
5661
STATUS_TYPE_ATTR = 0x0055 # decimal = 85
@@ -91,7 +96,6 @@
9196
COMMAND_6_HOLD = "6_hold"
9297
COMMAND_6_RELEASE = "6_release"
9398

94-
OPPLE_CLUSTER_ID = 0xFCC0
9599
OPPLE_MFG_CODE = 0x115F
96100

97101

@@ -129,11 +133,9 @@ def _update_attribute(self, attrid, value):
129133
super()._update_attribute(0, action)
130134

131135

132-
class OppleCluster(CustomCluster):
136+
class OppleCluster(XiaomiAqaraE1Cluster):
133137
"""Opple cluster."""
134138

135-
ep_attribute = "opple_cluster"
136-
cluster_id = OPPLE_CLUSTER_ID
137139
attributes = {
138140
0x0009: ("mode", types.uint8_t, True),
139141
}

zhaquirks/xiaomi/aqara/opple_switch.py

Lines changed: 49 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
"""Xiaomi aqara single key wall switch devices."""
1+
"""Xiaomi Aqara wall switch devices. Also see switch_h1 files similar H1 rocker switches."""
22
import copy
33
from enum import Enum
44

@@ -33,18 +33,22 @@
3333
ENDPOINT_ID,
3434
ENDPOINTS,
3535
INPUT_CLUSTERS,
36+
MODELS_INFO,
3637
OUTPUT_CLUSTERS,
3738
PRESS_TYPE,
3839
PROFILE_ID,
3940
VALUE,
4041
ZHA_SEND_EVENT,
4142
)
4243
from zhaquirks.xiaomi import (
44+
LUMI,
45+
AnalogInputCluster,
4346
BasicCluster,
4447
DeviceTemperatureCluster,
48+
ElectricalMeasurementCluster,
49+
MeteringCluster,
4550
OnOffCluster,
4651
XiaomiCustomDevice,
47-
XiaomiMeteringCluster,
4852
)
4953

5054
from .opple_remote import MultistateInputCluster, OppleCluster
@@ -85,7 +89,6 @@ class OppleSwitchCluster(OppleCluster):
8589
"""Xiaomi mfg cluster implementation."""
8690

8791
attributes = copy.deepcopy(OppleCluster.attributes)
88-
8992
attributes.update(
9093
{
9194
0x0002: ("power_outage_count", t.uint8_t, True),
@@ -124,28 +127,29 @@ class XiaomiOpple2ButtonSwitchBase(XiaomiCustomDevice):
124127
DEVICE_TYPE: zha.DeviceType.ON_OFF_SWITCH,
125128
INPUT_CLUSTERS: [
126129
BasicCluster,
127-
DeviceTemperatureCluster, # 2
128-
Identify.cluster_id, # 3
129-
Groups.cluster_id, # 4
130-
Scenes.cluster_id, # 5
131-
OnOffCluster, # 6
132-
Alarms.cluster_id, # 9
133-
MultistateInputCluster, # 18
134-
XiaomiMeteringCluster, # 0x0702
135-
OppleSwitchCluster, # 0xFCC0 / 64704
130+
DeviceTemperatureCluster,
131+
Identify.cluster_id,
132+
Groups.cluster_id,
133+
Scenes.cluster_id,
134+
OnOffCluster,
135+
Alarms.cluster_id,
136+
MultistateInputCluster,
137+
MeteringCluster,
138+
ElectricalMeasurementCluster,
139+
OppleSwitchCluster,
136140
],
137141
OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
138142
},
139143
2: {
140144
DEVICE_TYPE: zha.DeviceType.ON_OFF_SWITCH,
141145
INPUT_CLUSTERS: [
142146
BasicCluster,
143-
Identify.cluster_id, # 3
144-
Groups.cluster_id, # 4
145-
Scenes.cluster_id, # 5
146-
OnOffCluster, # 6
147-
MultistateInputCluster, # 18
148-
OppleSwitchCluster, # 0xFCC0 / 64704
147+
Identify.cluster_id,
148+
Groups.cluster_id,
149+
Scenes.cluster_id,
150+
OnOffCluster,
151+
MultistateInputCluster,
152+
OppleSwitchCluster,
149153
],
150154
OUTPUT_CLUSTERS: [],
151155
},
@@ -154,7 +158,7 @@ class XiaomiOpple2ButtonSwitchBase(XiaomiCustomDevice):
154158
PROFILE_ID: zha.PROFILE_ID,
155159
DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
156160
INPUT_CLUSTERS: [
157-
AnalogInput.cluster_id, # 12
161+
AnalogInputCluster,
158162
],
159163
OUTPUT_CLUSTERS: [],
160164
},
@@ -163,7 +167,7 @@ class XiaomiOpple2ButtonSwitchBase(XiaomiCustomDevice):
163167
PROFILE_ID: zha.PROFILE_ID,
164168
DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
165169
INPUT_CLUSTERS: [
166-
AnalogInput.cluster_id, # 12
170+
AnalogInput.cluster_id,
167171
],
168172
OUTPUT_CLUSTERS: [],
169173
},
@@ -172,7 +176,7 @@ class XiaomiOpple2ButtonSwitchBase(XiaomiCustomDevice):
172176
PROFILE_ID: zha.PROFILE_ID,
173177
DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
174178
INPUT_CLUSTERS: [
175-
MultistateInputCluster, # 18
179+
MultistateInputCluster,
176180
],
177181
OUTPUT_CLUSTERS: [],
178182
},
@@ -181,7 +185,7 @@ class XiaomiOpple2ButtonSwitchBase(XiaomiCustomDevice):
181185
PROFILE_ID: zha.PROFILE_ID,
182186
DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
183187
INPUT_CLUSTERS: [
184-
MultistateInputCluster, # 18
188+
MultistateInputCluster,
185189
],
186190
OUTPUT_CLUSTERS: [],
187191
},
@@ -190,7 +194,7 @@ class XiaomiOpple2ButtonSwitchBase(XiaomiCustomDevice):
190194
PROFILE_ID: zha.PROFILE_ID,
191195
DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
192196
INPUT_CLUSTERS: [
193-
MultistateInputCluster, # 18
197+
MultistateInputCluster,
194198
],
195199
OUTPUT_CLUSTERS: [],
196200
},
@@ -199,7 +203,7 @@ class XiaomiOpple2ButtonSwitchBase(XiaomiCustomDevice):
199203
PROFILE_ID: zha.PROFILE_ID,
200204
DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
201205
INPUT_CLUSTERS: [
202-
MultistateInputCluster, # 18
206+
MultistateInputCluster,
203207
],
204208
OUTPUT_CLUSTERS: [],
205209
},
@@ -273,23 +277,22 @@ class XiaomiOpple2ButtonSwitchBase(XiaomiCustomDevice):
273277
class XiaomiOpple2ButtonSwitchFace1(XiaomiOpple2ButtonSwitchBase):
274278
"""Xiaomi Opple 2 Button Switch. Face 1."""
275279

276-
device_automation_triggers = XiaomiOpple2ButtonSwitchBase.device_automation_triggers
277-
278280
signature = {
281+
MODELS_INFO: [(LUMI, "lumi.switch.b2naus01")],
279282
ENDPOINTS: {
280283
# input_clusters=[0, 2, 3, 4, 5, 6, 18, 64704], output_clusters=[10, 25]
281284
1: {
282285
PROFILE_ID: zha.PROFILE_ID,
283286
DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
284287
INPUT_CLUSTERS: [
285-
Basic.cluster_id, # 0
286-
DeviceTemperatureCluster.cluster_id, # 2
287-
Identify.cluster_id, # 3
288-
Groups.cluster_id, # 4
289-
Scenes.cluster_id, # 5
290-
OnOff.cluster_id, # 6
291-
MultistateInputCluster.cluster_id, # 18
292-
OppleSwitchCluster.cluster_id, # 0xFCC0 / 64704
288+
Basic.cluster_id,
289+
DeviceTemperatureCluster.cluster_id,
290+
Identify.cluster_id,
291+
Groups.cluster_id,
292+
Scenes.cluster_id,
293+
OnOff.cluster_id,
294+
MultistateInputCluster.cluster_id,
295+
OppleSwitchCluster.cluster_id,
293296
],
294297
OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
295298
},
@@ -298,13 +301,13 @@ class XiaomiOpple2ButtonSwitchFace1(XiaomiOpple2ButtonSwitchBase):
298301
PROFILE_ID: zha.PROFILE_ID,
299302
DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
300303
INPUT_CLUSTERS: [
301-
Basic.cluster_id, # 0
302-
Identify.cluster_id, # 3
303-
Groups.cluster_id, # 4
304-
Scenes.cluster_id, # 5
305-
OnOff.cluster_id, # 6
306-
MultistateInputCluster.cluster_id, # 18
307-
OppleSwitchCluster.cluster_id, # 0xFCC0 / 64704
304+
Basic.cluster_id,
305+
Identify.cluster_id,
306+
Groups.cluster_id,
307+
Scenes.cluster_id,
308+
OnOff.cluster_id,
309+
MultistateInputCluster.cluster_id,
310+
OppleSwitchCluster.cluster_id,
308311
],
309312
OUTPUT_CLUSTERS: [],
310313
},
@@ -313,7 +316,7 @@ class XiaomiOpple2ButtonSwitchFace1(XiaomiOpple2ButtonSwitchBase):
313316
PROFILE_ID: zha.PROFILE_ID,
314317
DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
315318
INPUT_CLUSTERS: [
316-
AnalogInput.cluster_id, # 12
319+
AnalogInput.cluster_id,
317320
],
318321
OUTPUT_CLUSTERS: [],
319322
},
@@ -322,7 +325,7 @@ class XiaomiOpple2ButtonSwitchFace1(XiaomiOpple2ButtonSwitchBase):
322325
PROFILE_ID: zha.PROFILE_ID,
323326
DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
324327
INPUT_CLUSTERS: [
325-
AnalogInput.cluster_id, # 12
328+
AnalogInput.cluster_id,
326329
],
327330
OUTPUT_CLUSTERS: [],
328331
},
@@ -331,7 +334,7 @@ class XiaomiOpple2ButtonSwitchFace1(XiaomiOpple2ButtonSwitchBase):
331334
PROFILE_ID: zha.PROFILE_ID,
332335
DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
333336
INPUT_CLUSTERS: [
334-
MultistateInputCluster.cluster_id, # 18
337+
MultistateInputCluster.cluster_id,
335338
],
336339
OUTPUT_CLUSTERS: [],
337340
},
@@ -340,7 +343,7 @@ class XiaomiOpple2ButtonSwitchFace1(XiaomiOpple2ButtonSwitchBase):
340343
PROFILE_ID: zha.PROFILE_ID,
341344
DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
342345
INPUT_CLUSTERS: [
343-
MultistateInputCluster.cluster_id, # 18
346+
MultistateInputCluster.cluster_id,
344347
],
345348
OUTPUT_CLUSTERS: [],
346349
},
@@ -349,54 +352,7 @@ class XiaomiOpple2ButtonSwitchFace1(XiaomiOpple2ButtonSwitchBase):
349352
PROFILE_ID: zha.PROFILE_ID,
350353
DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
351354
INPUT_CLUSTERS: [
352-
MultistateInputCluster.cluster_id, # 18
353-
],
354-
OUTPUT_CLUSTERS: [],
355-
},
356-
242: {
357-
PROFILE_ID: zgp.PROFILE_ID,
358-
DEVICE_TYPE: zgp.DeviceType.PROXY_BASIC,
359-
INPUT_CLUSTERS: [],
360-
OUTPUT_CLUSTERS: [GreenPowerProxy.cluster_id],
361-
},
362-
},
363-
}
364-
365-
366-
class XiaomiOpple2ButtonSwitchFace2(XiaomiOpple2ButtonSwitchBase):
367-
"""Xiaomi Opple 2 Button Switch. Face 2."""
368-
369-
device_automation_triggers = XiaomiOpple2ButtonSwitchBase.device_automation_triggers
370-
371-
signature = {
372-
ENDPOINTS: {
373-
# input_clusters=[0, 2, 3, 4, 5, 6, 18, 64704], output_clusters=[10, 25]
374-
1: {
375-
PROFILE_ID: zha.PROFILE_ID,
376-
DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
377-
INPUT_CLUSTERS: [
378-
Basic.cluster_id, # 0
379-
DeviceTemperatureCluster.cluster_id, # 2
380-
Identify.cluster_id, # 3
381-
Groups.cluster_id, # 4
382-
Scenes.cluster_id, # 5
383-
OnOff.cluster_id, # 6
384-
Alarms.cluster_id, # 9
385-
XiaomiMeteringCluster.cluster_id, # 0x0702
386-
0x0B04,
387-
],
388-
OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
389-
},
390-
# input_clusters=[0, 3, 4, 5, 6, 18, 64704], output_clusters=[]
391-
2: {
392-
PROFILE_ID: zha.PROFILE_ID,
393-
DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
394-
INPUT_CLUSTERS: [
395-
Basic.cluster_id, # 0
396-
Identify.cluster_id, # 3
397-
Groups.cluster_id, # 4
398-
Scenes.cluster_id, # 5
399-
OnOff.cluster_id, # 6
355+
MultistateInputCluster.cluster_id,
400356
],
401357
OUTPUT_CLUSTERS: [],
402358
},

0 commit comments

Comments
 (0)