From 0421088e1e573951ca2fa79bda2e438f633ab7e0 Mon Sep 17 00:00:00 2001 From: Dmitry Berezovsky Date: Mon, 23 Oct 2023 05:45:02 +0300 Subject: [PATCH] Add "power outage memory" support for Aqara ceiling light L1-350 (#2658) feat: add support for aqara ceiling light L1-350 (#2649) This quirk adds support for power on behavior of the device --- tests/test_xiaomi.py | 30 ++++++++++ zhaquirks/xiaomi/aqara/light_acn.py | 86 +++++++++++++++++++++++++++++ 2 files changed, 116 insertions(+) create mode 100644 zhaquirks/xiaomi/aqara/light_acn.py diff --git a/tests/test_xiaomi.py b/tests/test_xiaomi.py index 23c32b0388..c8a4c97b68 100644 --- a/tests/test_xiaomi.py +++ b/tests/test_xiaomi.py @@ -1509,3 +1509,33 @@ async def test_xiaomi_e1_roller_commands_2(zigpy_device_from_quirk, command, val assert ( analog_cluster._write_attributes.call_args[0][0][0].value.value == 100 - value ) + + +def test_aqara_acn003_signature_match(assert_signature_matches_quirk): + signature = { + "node_descriptor": "NodeDescriptor(logical_type=, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, frequency_band=, mac_capability_flags=, manufacturer_code=4447, maximum_buffer_size=82, maximum_incoming_transfer_size=82, server_mask=11264, maximum_outgoing_transfer_size=82, descriptor_capability_field=, *allocate_address=True, *is_alternate_pan_coordinator=False, *is_coordinator=False, *is_end_device=False, *is_full_function_device=True, *is_mains_powered=True, *is_receiver_on_when_idle=True, *is_router=True, *is_security_capable=False)", + "endpoints": { + "1": { + "profile_id": 0x0104, + "device_type": "0x0102", + "in_clusters": [ + "0x0000", + "0x0003", + "0x0004", + "0x0005", + "0x0006", + "0x0008", + "0x0300", + "0xfcc0", + ], + "out_clusters": ["0x000a", "0x0019"], + } + }, + "manufacturer": "Aqara", + "model": "lumi.light.acn003", + "class": "aqara_light.LumiLightAcn003", + } + + assert_signature_matches_quirk( + zhaquirks.xiaomi.aqara.light_acn.LumiLightAcn003, signature + ) diff --git a/zhaquirks/xiaomi/aqara/light_acn.py b/zhaquirks/xiaomi/aqara/light_acn.py new file mode 100644 index 0000000000..b9c50f1b21 --- /dev/null +++ b/zhaquirks/xiaomi/aqara/light_acn.py @@ -0,0 +1,86 @@ +from zigpy import types as t +from zigpy.profiles import zha +from zigpy.zcl.clusters.general import ( + Groups, + Identify, + LevelControl, + OnOff, + Ota, + Scenes, + Time, +) +from zigpy.zcl.clusters.lighting import Color + +from zhaquirks.const import ( + DEVICE_TYPE, + ENDPOINTS, + INPUT_CLUSTERS, + MODELS_INFO, + OUTPUT_CLUSTERS, + PROFILE_ID, +) +from zhaquirks.xiaomi import BasicCluster, XiaomiAqaraE1Cluster, XiaomiCustomDevice + + +class OppleClusterLight(XiaomiAqaraE1Cluster): + """Add Opple cluster for power outage memory attribute.""" + + attributes = { + 0x0201: ("power_outage_memory", t.Bool, True), + } + + +class LumiLightAcn003(XiaomiCustomDevice): + """Quirk for Aqara ceiling light L1-350 also known as Xiaomi ZNXDD01LM. + + Provides dimmable light control with color temperature setting. + This quirk adds support for power on behavior by adding the power_outage_memory attribute. + """ + + signature = { + MODELS_INFO: [ + ("Aqara", "lumi.light.acn003"), + ], + ENDPOINTS: { + 1: { + PROFILE_ID: zha.PROFILE_ID, + DEVICE_TYPE: zha.DeviceType.COLOR_DIMMABLE_LIGHT, + INPUT_CLUSTERS: [ + BasicCluster.cluster_id, # 0x0000 + Identify.cluster_id, # 0x0003 + Groups.cluster_id, # 0x0004 + Scenes.cluster_id, # 0x0005 + OnOff.cluster_id, # 0x0006 + LevelControl.cluster_id, # 0x0008 + Color.cluster_id, # 0x0300 + OppleClusterLight.cluster_id, # 0xFCC0 - manufacturer specific + ], + OUTPUT_CLUSTERS: [ + Time.cluster_id, # 0x000A + Ota.cluster_id, # 0x0019 + ], + } + }, + } + replacement = { + ENDPOINTS: { + 1: { + PROFILE_ID: zha.PROFILE_ID, + DEVICE_TYPE: zha.DeviceType.COLOR_DIMMABLE_LIGHT, + INPUT_CLUSTERS: [ + BasicCluster, + Identify.cluster_id, # 0x0003 + Groups.cluster_id, # 0x0004 + Scenes.cluster_id, # 0x0005 + OnOff.cluster_id, # 0x0006 + LevelControl.cluster_id, # 0x0008 + Color.cluster_id, # 0x0300 + OppleClusterLight, + ], + OUTPUT_CLUSTERS: [ + Time.cluster_id, # 0x000A + Ota.cluster_id, # 0x0019 + ], + } + } + }