From 7f906930011a8b14c2e0a168bb999f662eb3dd94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cliuhongming=E2=80=9D?= Date: Thu, 29 Feb 2024 04:18:21 -0800 Subject: [PATCH 1/4] Aqara Wireless Remote Switch E1 (Single Rocker) --- .../zigbee-button/fingerprints.yml | 5 ++ .../zigbee-button/src/aqara/init.lua | 20 ++++-- .../src/test/test_aqara_button.lua | 63 +++++++++++++++---- 3 files changed, 72 insertions(+), 16 deletions(-) diff --git a/drivers/SmartThings/zigbee-button/fingerprints.yml b/drivers/SmartThings/zigbee-button/fingerprints.yml index 070fdcd8b2..04937ff5c7 100644 --- a/drivers/SmartThings/zigbee-button/fingerprints.yml +++ b/drivers/SmartThings/zigbee-button/fingerprints.yml @@ -4,6 +4,11 @@ zigbeeManufacturer: manufacturer: LUMI model: lumi.remote.b1acn02 deviceProfileName: one-button-battery + - id: "LUMI/lumi.remote.acn003" + deviceLabel: Aqara Wireless Remote Switch E1 (Single Rocker) + manufacturer: LUMI + model: lumi.remote.acn003 + deviceProfileName: one-button-battery - id: "HEIMAN/SOS-EM" deviceLabel: HEIMAN Button manufacturer: HEIMAN diff --git a/drivers/SmartThings/zigbee-button/src/aqara/init.lua b/drivers/SmartThings/zigbee-button/src/aqara/init.lua index 7b2da01c4e..8da34a996e 100644 --- a/drivers/SmartThings/zigbee-button/src/aqara/init.lua +++ b/drivers/SmartThings/zigbee-button/src/aqara/init.lua @@ -22,15 +22,18 @@ local capabilities = require "st.capabilities" local PowerConfiguration = clusters.PowerConfiguration local PRIVATE_CLUSTER_ID = 0xFCC0 local PRIVATE_ATTRIBUTE_ID = 0x0009 +local PRIVATE_SWITCH_MODE_ATTRIBUTE_ID = 0x0125 local MFG_CODE = 0x115F local MULTISTATE_INPUT_CLUSTER_ID = 0x0012 local PRESENT_ATTRIBUTE_ID = 0x0055 local FINGERPRINTS = { - { mfr = "LUMI", model = "lumi.remote.b1acn02" } + { mfr = "LUMI", model = "lumi.remote.b1acn02" }, + { mfr = "LUMI", model = "lumi.remote.acn003" } } + local configuration = { { cluster = MULTISTATE_INPUT_CLUSTER_ID, @@ -79,15 +82,23 @@ local function device_init(driver, device) end end - local function added_handler(self, device) - device:send(cluster_base.write_manufacturer_specific_attribute(device, - PRIVATE_CLUSTER_ID, PRIVATE_ATTRIBUTE_ID, MFG_CODE, data_types.Uint8, 1)) +local function added_handler(self, device) + if device:get_model() == "lumi.remote.b1acn02" then + device:send(cluster_base.write_manufacturer_specific_attribute(device, + PRIVATE_CLUSTER_ID, PRIVATE_ATTRIBUTE_ID, MFG_CODE, data_types.Uint8, 1)) + elseif device:get_model() == "lumi.remote.acn003" then + device:send(cluster_base.write_manufacturer_specific_attribute(device, + PRIVATE_CLUSTER_ID, PRIVATE_SWITCH_MODE_ATTRIBUTE_ID, MFG_CODE, data_types.Uint8, 2)) + end + device:emit_event(capabilities.button.supportedButtonValues({"pushed","held","double"}, {visibility = { displayed = false }})) device:emit_event(capabilities.button.numberOfButtons({value = 1})) device:emit_event(capabilities.button.button.pushed({state_change = false})) device:emit_event(capabilities.battery.battery(100)) end + + local aqara_wireless_switch_handler = { NAME = "Aqara Wireless Switch Handler", lifecycle_handlers = { @@ -105,4 +116,3 @@ local aqara_wireless_switch_handler = { } return aqara_wireless_switch_handler - diff --git a/drivers/SmartThings/zigbee-button/src/test/test_aqara_button.lua b/drivers/SmartThings/zigbee-button/src/test/test_aqara_button.lua index 0f23b3167f..9f12fadd53 100644 --- a/drivers/SmartThings/zigbee-button/src/test/test_aqara_button.lua +++ b/drivers/SmartThings/zigbee-button/src/test/test_aqara_button.lua @@ -1,3 +1,4 @@ +---@diagnostic disable: param-type-mismatch, missing-parameter -- Copyright 2024 SmartThings -- -- Licensed under the Apache License, Version 2.0 (the "License"); @@ -27,7 +28,21 @@ local PowerConfiguration = clusters.PowerConfiguration local MFG_CODE = 0x115F local PRIVATE_CLUSTER_ID = 0xFCC0 local PRIVATE_ATTRIBUTE_ID = 0x0009 +local PRIVATE_SWITCH_MODE_ATTRIBUTE_ID = 0x0125 +local mock_device_e1 = test.mock_device.build_test_zigbee_device( + { + profile = t_utils.get_profile_definition("one-button-battery.yml"), + zigbee_endpoints = { + [1] = { + id = 1, + manufacturer = "LUMI", + model = "lumi.remote.acn003", + server_clusters = { 0x0001, 0x0012 } + } + } + } +) local mock_device_t1 = test.mock_device.build_test_zigbee_device( { @@ -43,13 +58,35 @@ local mock_device_t1 = test.mock_device.build_test_zigbee_device( } ) + + + + zigbee_test_utils.prepare_zigbee_env_info() local function test_init() + test.mock_device.add_test_device(mock_device_e1) test.mock_device.add_test_device(mock_device_t1) end test.set_test_init_function(test_init) +test.register_coroutine_test( + "Handle added lifecycle", + function() + test.socket.device_lifecycle:__queue_receive({ mock_device_e1.id, "added" }) + + test.socket.zigbee:__expect_send({ mock_device_e1.id, + cluster_base.write_manufacturer_specific_attribute(mock_device_e1, PRIVATE_CLUSTER_ID, PRIVATE_SWITCH_MODE_ATTRIBUTE_ID, MFG_CODE, + data_types.Uint8, 2) }) + + + test.socket.capability:__expect_send(mock_device_e1:generate_test_message("main", capabilities.button.supportedButtonValues({"pushed","held","double"}, {visibility = { displayed = false }}))) + test.socket.capability:__expect_send(mock_device_e1:generate_test_message("main", capabilities.button.numberOfButtons({value = 1}))) + test.socket.capability:__expect_send(mock_device_e1:generate_test_message("main", capabilities.button.button.pushed({state_change = false}))) + test.socket.capability:__expect_send(mock_device_e1:generate_test_message("main", capabilities.battery.battery(100))) + end +) + test.register_coroutine_test( "Handle added lifecycle", function() @@ -67,6 +104,9 @@ test.register_coroutine_test( end ) + + + test.register_coroutine_test( "Reported button should be handled: pushed true", function() @@ -74,10 +114,10 @@ test.register_coroutine_test( { PRESENT_ATTRIBUTE_ID, data_types.Uint16.ID, 0x0001 } } test.socket.zigbee:__queue_receive({ - mock_device_t1.id, - zigbee_test_utils.build_attribute_report(mock_device_t1, MULTISTATE_INPUT_CLUSTER_ID, attr_report_data, MFG_CODE) + mock_device_e1.id, + zigbee_test_utils.build_attribute_report(mock_device_e1, MULTISTATE_INPUT_CLUSTER_ID, attr_report_data, MFG_CODE) }) - test.socket.capability:__expect_send(mock_device_t1:generate_test_message("main", + test.socket.capability:__expect_send(mock_device_e1:generate_test_message("main", capabilities.button.button.pushed({state_change = true}))) end ) @@ -90,14 +130,15 @@ test.register_coroutine_test( { PRESENT_ATTRIBUTE_ID, data_types.Uint16.ID, 0x0002 } } test.socket.zigbee:__queue_receive({ - mock_device_t1.id, - zigbee_test_utils.build_attribute_report(mock_device_t1, MULTISTATE_INPUT_CLUSTER_ID, attr_report_data, MFG_CODE) + mock_device_e1.id, + zigbee_test_utils.build_attribute_report(mock_device_e1, MULTISTATE_INPUT_CLUSTER_ID, attr_report_data, MFG_CODE) }) - test.socket.capability:__expect_send(mock_device_t1:generate_test_message("main", + test.socket.capability:__expect_send(mock_device_e1:generate_test_message("main", capabilities.button.button.double({state_change = true}))) end ) + test.register_coroutine_test( "Reported button should be handled: held true", function() @@ -105,10 +146,10 @@ test.register_coroutine_test( { PRESENT_ATTRIBUTE_ID, data_types.Uint16.ID, 0x0000 } } test.socket.zigbee:__queue_receive({ - mock_device_t1.id, - zigbee_test_utils.build_attribute_report(mock_device_t1, MULTISTATE_INPUT_CLUSTER_ID, attr_report_data, MFG_CODE) + mock_device_e1.id, + zigbee_test_utils.build_attribute_report(mock_device_e1, MULTISTATE_INPUT_CLUSTER_ID, attr_report_data, MFG_CODE) }) - test.socket.capability:__expect_send(mock_device_t1:generate_test_message("main", + test.socket.capability:__expect_send(mock_device_e1:generate_test_message("main", capabilities.button.button.held({state_change = true}))) end ) @@ -119,12 +160,12 @@ test.register_message_test( { channel = "zigbee", direction = "receive", - message = { mock_device_t1.id, PowerConfiguration.attributes.BatteryVoltage:build_test_attr_report(mock_device_t1, 30) } + message = { mock_device_e1.id, PowerConfiguration.attributes.BatteryVoltage:build_test_attr_report(mock_device_e1, 30) } }, { channel = "capability", direction = "send", - message = mock_device_t1:generate_test_message("main", capabilities.battery.battery(100)) + message = mock_device_e1:generate_test_message("main", capabilities.battery.battery(100)) } } ) From 556e8b421c4b06f184d8e0d05e145cb40c471142 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cliuhongming=E2=80=9D?= Date: Thu, 14 Mar 2024 19:28:53 -0700 Subject: [PATCH 2/4] fixed formatting & comment issues --- .../zigbee-button/src/aqara/init.lua | 11 ++++----- .../src/test/test_aqara_button.lua | 23 +++++-------------- 2 files changed, 10 insertions(+), 24 deletions(-) diff --git a/drivers/SmartThings/zigbee-button/src/aqara/init.lua b/drivers/SmartThings/zigbee-button/src/aqara/init.lua index 8da34a996e..45f9297935 100644 --- a/drivers/SmartThings/zigbee-button/src/aqara/init.lua +++ b/drivers/SmartThings/zigbee-button/src/aqara/init.lua @@ -21,8 +21,8 @@ local capabilities = require "st.capabilities" local PowerConfiguration = clusters.PowerConfiguration local PRIVATE_CLUSTER_ID = 0xFCC0 -local PRIVATE_ATTRIBUTE_ID = 0x0009 -local PRIVATE_SWITCH_MODE_ATTRIBUTE_ID = 0x0125 +local PRIVATE_ATTRIBUTE_ID_T1 = 0x0009 +local PRIVATE_ATTRIBUTE_ID_E1 = 0x0125 local MFG_CODE = 0x115F local MULTISTATE_INPUT_CLUSTER_ID = 0x0012 @@ -33,7 +33,6 @@ local FINGERPRINTS = { { mfr = "LUMI", model = "lumi.remote.acn003" } } - local configuration = { { cluster = MULTISTATE_INPUT_CLUSTER_ID, @@ -85,10 +84,10 @@ end local function added_handler(self, device) if device:get_model() == "lumi.remote.b1acn02" then device:send(cluster_base.write_manufacturer_specific_attribute(device, - PRIVATE_CLUSTER_ID, PRIVATE_ATTRIBUTE_ID, MFG_CODE, data_types.Uint8, 1)) + PRIVATE_CLUSTER_ID, PRIVATE_ATTRIBUTE_ID_T1, MFG_CODE, data_types.Uint8, 1)) elseif device:get_model() == "lumi.remote.acn003" then device:send(cluster_base.write_manufacturer_specific_attribute(device, - PRIVATE_CLUSTER_ID, PRIVATE_SWITCH_MODE_ATTRIBUTE_ID, MFG_CODE, data_types.Uint8, 2)) + PRIVATE_CLUSTER_ID, PRIVATE_ATTRIBUTE_ID_E1, MFG_CODE, data_types.Uint8, 2)) end device:emit_event(capabilities.button.supportedButtonValues({"pushed","held","double"}, {visibility = { displayed = false }})) @@ -97,8 +96,6 @@ local function added_handler(self, device) device:emit_event(capabilities.battery.battery(100)) end - - local aqara_wireless_switch_handler = { NAME = "Aqara Wireless Switch Handler", lifecycle_handlers = { diff --git a/drivers/SmartThings/zigbee-button/src/test/test_aqara_button.lua b/drivers/SmartThings/zigbee-button/src/test/test_aqara_button.lua index 9f12fadd53..0994bf95f0 100644 --- a/drivers/SmartThings/zigbee-button/src/test/test_aqara_button.lua +++ b/drivers/SmartThings/zigbee-button/src/test/test_aqara_button.lua @@ -27,8 +27,8 @@ local PowerConfiguration = clusters.PowerConfiguration local MFG_CODE = 0x115F local PRIVATE_CLUSTER_ID = 0xFCC0 -local PRIVATE_ATTRIBUTE_ID = 0x0009 -local PRIVATE_SWITCH_MODE_ATTRIBUTE_ID = 0x0125 +local PRIVATE_ATTRIBUTE_ID_T1 = 0x0009 +local PRIVATE_ATTRIBUTE_ID_E1 = 0x0125 local mock_device_e1 = test.mock_device.build_test_zigbee_device( { @@ -58,10 +58,6 @@ local mock_device_t1 = test.mock_device.build_test_zigbee_device( } ) - - - - zigbee_test_utils.prepare_zigbee_env_info() local function test_init() test.mock_device.add_test_device(mock_device_e1) @@ -71,12 +67,12 @@ end test.set_test_init_function(test_init) test.register_coroutine_test( - "Handle added lifecycle", + "Handle added lifecycle -- e1", function() test.socket.device_lifecycle:__queue_receive({ mock_device_e1.id, "added" }) test.socket.zigbee:__expect_send({ mock_device_e1.id, - cluster_base.write_manufacturer_specific_attribute(mock_device_e1, PRIVATE_CLUSTER_ID, PRIVATE_SWITCH_MODE_ATTRIBUTE_ID, MFG_CODE, + cluster_base.write_manufacturer_specific_attribute(mock_device_e1, PRIVATE_CLUSTER_ID, PRIVATE_ATTRIBUTE_ID_E1, MFG_CODE, data_types.Uint8, 2) }) @@ -88,12 +84,12 @@ test.register_coroutine_test( ) test.register_coroutine_test( - "Handle added lifecycle", + "Handle added lifecycle -- t1", function() test.socket.device_lifecycle:__queue_receive({ mock_device_t1.id, "added" }) test.socket.zigbee:__expect_send({ mock_device_t1.id, - cluster_base.write_manufacturer_specific_attribute(mock_device_t1, PRIVATE_CLUSTER_ID, PRIVATE_ATTRIBUTE_ID, MFG_CODE, + cluster_base.write_manufacturer_specific_attribute(mock_device_t1, PRIVATE_CLUSTER_ID, PRIVATE_ATTRIBUTE_ID_T1, MFG_CODE, data_types.Uint8, 1) }) @@ -104,9 +100,6 @@ test.register_coroutine_test( end ) - - - test.register_coroutine_test( "Reported button should be handled: pushed true", function() @@ -122,7 +115,6 @@ test.register_coroutine_test( end ) - test.register_coroutine_test( "Reported button should be handled: double true", function() @@ -138,7 +130,6 @@ test.register_coroutine_test( end ) - test.register_coroutine_test( "Reported button should be handled: held true", function() @@ -170,6 +161,4 @@ test.register_message_test( } ) - - test.run_registered_tests() From 7bbf247dbe702be48940cadded010ebef1d9e603 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cliuhongming=E2=80=9D?= Date: Sun, 17 Mar 2024 18:43:14 -0700 Subject: [PATCH 3/4] remove unnecessary comment --- drivers/SmartThings/zigbee-button/src/test/test_aqara_button.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/SmartThings/zigbee-button/src/test/test_aqara_button.lua b/drivers/SmartThings/zigbee-button/src/test/test_aqara_button.lua index 0994bf95f0..66844bea6b 100644 --- a/drivers/SmartThings/zigbee-button/src/test/test_aqara_button.lua +++ b/drivers/SmartThings/zigbee-button/src/test/test_aqara_button.lua @@ -1,4 +1,3 @@ ----@diagnostic disable: param-type-mismatch, missing-parameter -- Copyright 2024 SmartThings -- -- Licensed under the Apache License, Version 2.0 (the "License"); From 7134dc0db04fc0b6f8d5207854cfe72e2a4b6043 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cliuhongming=E2=80=9D?= Date: Sun, 17 Mar 2024 20:53:23 -0700 Subject: [PATCH 4/4] add note --- drivers/SmartThings/zigbee-button/src/aqara/init.lua | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/SmartThings/zigbee-button/src/aqara/init.lua b/drivers/SmartThings/zigbee-button/src/aqara/init.lua index 45f9297935..070b1d338a 100644 --- a/drivers/SmartThings/zigbee-button/src/aqara/init.lua +++ b/drivers/SmartThings/zigbee-button/src/aqara/init.lua @@ -89,7 +89,11 @@ local function added_handler(self, device) device:send(cluster_base.write_manufacturer_specific_attribute(device, PRIVATE_CLUSTER_ID, PRIVATE_ATTRIBUTE_ID_E1, MFG_CODE, data_types.Uint8, 2)) end - + -- when the wireless switch T1 accesses the network, the gateway sends + -- private attribute 0009 to make the device no longer distinguish + -- between the standard gateway and the aqara gateway. + -- When wireless switch E1 is connected to the network, the gateway sends + -- private attribute 0125 to enable the device to send double-click and long-press packets. device:emit_event(capabilities.button.supportedButtonValues({"pushed","held","double"}, {visibility = { displayed = false }})) device:emit_event(capabilities.button.numberOfButtons({value = 1})) device:emit_event(capabilities.button.button.pushed({state_change = false}))