Skip to content

Commit 6f7ae12

Browse files
Add Aqara T1M ceiling light support (#4136)
Co-authored-by: TheJulianJES <[email protected]>
1 parent 40e5917 commit 6f7ae12

File tree

3 files changed

+81
-0
lines changed

3 files changed

+81
-0
lines changed

tests/test_xiaomi.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
BatterySize,
5151
)
5252
from zhaquirks.xiaomi import (
53+
AQARA,
5354
LUMI,
5455
XIAOMI_AQARA_ATTRIBUTE,
5556
XIAOMI_AQARA_ATTRIBUTE_E1,
@@ -78,6 +79,7 @@
7879
AqaraFeederAcn001,
7980
OppleCluster,
8081
)
82+
from zhaquirks.xiaomi.aqara.light_acn import AqaraLightT1M, LumiPowerOnStateMode
8183
import zhaquirks.xiaomi.aqara.magnet_ac01
8284
import zhaquirks.xiaomi.aqara.magnet_acn001
8385
import zhaquirks.xiaomi.aqara.magnet_agl02
@@ -2219,3 +2221,31 @@ def test_h1_wireless_remotes(zigpy_device_from_v2_quirk):
22192221

22202222
assert MultistateInput.cluster_id in device.endpoints[2].in_clusters
22212223
assert MultistateInput.cluster_id in device.endpoints[3].in_clusters
2224+
2225+
2226+
@pytest.mark.parametrize("endpoint", [(1), (2)])
2227+
def test_t1m_ceiling_light(zigpy_device_from_v2_quirk, endpoint):
2228+
"""Test Aqara T1M ceiling light quirk adds missing endpoints."""
2229+
2230+
# create the device with 2 endpoints (one for each light on the T1M)
2231+
device = zigpy_device_from_v2_quirk(AQARA, "lumi.light.acn032", endpoint_ids=[1, 2])
2232+
assert AqaraLightT1M.cluster_id in device.endpoints[endpoint].in_clusters
2233+
2234+
aqara_cluster = device.endpoints[endpoint].opple_cluster
2235+
cluster_listener = ClusterListener(aqara_cluster)
2236+
2237+
aqara_cluster.update_attribute(AqaraLightT1M.AttributeDefs.power_on_state.id, 0x01)
2238+
assert len(cluster_listener.attribute_updates) == 1
2239+
assert (
2240+
cluster_listener.attribute_updates[0][0]
2241+
== AqaraLightT1M.AttributeDefs.power_on_state.id
2242+
)
2243+
assert cluster_listener.attribute_updates[0][1] == LumiPowerOnStateMode.LastState
2244+
2245+
aqara_cluster.update_attribute(AqaraLightT1M.AttributeDefs.power_on_state.id, 0x02)
2246+
assert len(cluster_listener.attribute_updates) == 2
2247+
assert (
2248+
cluster_listener.attribute_updates[1][0]
2249+
== AqaraLightT1M.AttributeDefs.power_on_state.id
2250+
)
2251+
assert cluster_listener.attribute_updates[1][1] == LumiPowerOnStateMode.Off

zhaquirks/xiaomi/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
BatterySize,
5252
)
5353

54+
AQARA = "Aqara"
5455
BATTERY_LEVEL = "battery_level"
5556
BATTERY_PERCENTAGE_REMAINING = 0x0021
5657
BATTERY_PERCENTAGE_REMAINING_ATTRIBUTE = "battery_percentage"

zhaquirks/xiaomi/aqara/light_acn.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
from zigpy import types as t
44
from zigpy.profiles import zgp, zha
5+
from zigpy.quirks.v2 import QuirkBuilder
56
from zigpy.zcl.clusters.general import (
67
Alarms,
78
AnalogInput,
@@ -20,6 +21,7 @@
2021
from zigpy.zcl.clusters.homeautomation import ElectricalMeasurement
2122
from zigpy.zcl.clusters.lighting import Color
2223
from zigpy.zcl.clusters.smartenergy import Metering
24+
from zigpy.zcl.foundation import BaseAttributeDefs, DataTypeId, ZCLAttributeDef
2325

2426
from zhaquirks.const import (
2527
DEVICE_TYPE,
@@ -30,13 +32,22 @@
3032
PROFILE_ID,
3133
)
3234
from zhaquirks.xiaomi import (
35+
AQARA,
3336
LUMI,
3437
BasicCluster,
3538
XiaomiAqaraE1Cluster,
3639
XiaomiCustomDevice,
3740
)
3841

3942

43+
class LumiPowerOnStateMode(t.enum8):
44+
"""Power on state mode."""
45+
46+
On = 0x00
47+
LastState = 0x01
48+
Off = 0x02
49+
50+
4051
class OppleClusterLight(XiaomiAqaraE1Cluster):
4152
"""Add Opple cluster for power outage memory attribute."""
4253

@@ -45,6 +56,21 @@ class OppleClusterLight(XiaomiAqaraE1Cluster):
4556
}
4657

4758

59+
class AqaraLightT1M(XiaomiAqaraE1Cluster):
60+
"""Add power on state management for Lumi devices."""
61+
62+
class AttributeDefs(BaseAttributeDefs):
63+
"""Manufacturer specific attributes."""
64+
65+
power_on_state = ZCLAttributeDef(
66+
id=0x0517,
67+
type=LumiPowerOnStateMode,
68+
zcl_type=DataTypeId.uint8,
69+
access="rw",
70+
is_manufacturer_specific=True,
71+
)
72+
73+
4874
class LumiLightAcn003(XiaomiCustomDevice):
4975
"""Quirk for Aqara ceiling light L1-350 also known as Xiaomi ZNXDD01LM.
5076
@@ -200,3 +226,27 @@ class LumiLightAcn014(XiaomiCustomDevice):
200226
},
201227
}
202228
}
229+
230+
231+
(
232+
QuirkBuilder(AQARA, "lumi.light.acn032")
233+
.friendly_name(manufacturer="Aqara", model="Ceiling Light T1M")
234+
.replaces(AqaraLightT1M)
235+
.replaces(AqaraLightT1M, endpoint_id=2)
236+
.enum(
237+
AqaraLightT1M.AttributeDefs.power_on_state.name,
238+
LumiPowerOnStateMode,
239+
AqaraLightT1M.cluster_id,
240+
translation_key="power_on_state",
241+
fallback_name="Power on state",
242+
)
243+
.enum(
244+
AqaraLightT1M.AttributeDefs.power_on_state.name,
245+
LumiPowerOnStateMode,
246+
AqaraLightT1M.cluster_id,
247+
endpoint_id=2,
248+
translation_key="power_on_state",
249+
fallback_name="Power on state",
250+
)
251+
.add_to_registry()
252+
)

0 commit comments

Comments
 (0)