From adf3b32240179e8e2788dc28c16ce775efbe4a27 Mon Sep 17 00:00:00 2001 From: simon3panda Date: Tue, 16 Sep 2025 10:40:55 +0800 Subject: [PATCH 1/4] Add Linxura Aura smart button support 12 Matter buttons. 1.Add Linxura Aura smart button support 12 Matter buttons. 2.Each button support click, double click, held. 3.12 buttons mapped in Smartthings app as button 1-12. Does not show main button. --- .../matter-switch/fingerprints.yml | 8 ++ .../12-buttons-without-main-button.yml | 80 +++++++++++++++++++ .../SmartThings/matter-switch/src/init.lua | 57 +++++++++++-- 3 files changed, 138 insertions(+), 7 deletions(-) create mode 100644 drivers/SmartThings/matter-switch/profiles/12-buttons-without-main-button.yml diff --git a/drivers/SmartThings/matter-switch/fingerprints.yml b/drivers/SmartThings/matter-switch/fingerprints.yml index e5b25558a1..dcdf0cf438 100644 --- a/drivers/SmartThings/matter-switch/fingerprints.yml +++ b/drivers/SmartThings/matter-switch/fingerprints.yml @@ -1,4 +1,12 @@ matterManufacturer: +#Linxura + - id: "Aura Smart Button" + deviceLabel: Aura Smart Button + vendorId: 0xFFF1 + productId: 0x8004 + deviceProfileName: 12-buttons-without-main-button + # deviceProfileName: 8-buttons-without-main-button + # deviceProfileName: four-buttons-without-main-button #Aqara - id: "4447/6145" deviceLabel: Aqara LED Bulb T2 RGB CCT diff --git a/drivers/SmartThings/matter-switch/profiles/12-buttons-without-main-button.yml b/drivers/SmartThings/matter-switch/profiles/12-buttons-without-main-button.yml new file mode 100644 index 0000000000..05cbfe81d6 --- /dev/null +++ b/drivers/SmartThings/matter-switch/profiles/12-buttons-without-main-button.yml @@ -0,0 +1,80 @@ +name: 12-buttons-without-main-button +components: + - id: main + capabilities: + - id: refresh + version: 1 + categories: + - name: RemoteController + - id: button1 + capabilities: + - id: button + version: 1 + categories: + - name: RemoteController + - id: button2 + capabilities: + - id: button + version: 1 + categories: + - name: RemoteController + - id: button3 + capabilities: + - id: button + version: 1 + categories: + - name: RemoteController + - id: button4 + capabilities: + - id: button + version: 1 + categories: + - name: RemoteController + - id: button5 + capabilities: + - id: button + version: 1 + categories: + - name: RemoteController + - id: button6 + capabilities: + - id: button + version: 1 + categories: + - name: RemoteController + - id: button7 + capabilities: + - id: button + version: 1 + categories: + - name: RemoteController + - id: button8 + capabilities: + - id: button + version: 1 + categories: + - name: RemoteController + - id: button9 + capabilities: + - id: button + version: 1 + categories: + - name: RemoteController + - id: button10 + capabilities: + - id: button + version: 1 + categories: + - name: RemoteController + - id: button11 + capabilities: + - id: button + version: 1 + categories: + - name: RemoteController + - id: button12 + capabilities: + - id: button + version: 1 + categories: + - name: RemoteController \ No newline at end of file diff --git a/drivers/SmartThings/matter-switch/src/init.lua b/drivers/SmartThings/matter-switch/src/init.lua index a4bf6e64f9..9bddafbc47 100644 --- a/drivers/SmartThings/matter-switch/src/init.lua +++ b/drivers/SmartThings/matter-switch/src/init.lua @@ -187,6 +187,9 @@ local child_device_profile_overrides_per_vendor_id = { { product_id = 0x1008, target_profile = "light-power-energy-powerConsumption" }, -- 2 Buttons(Generic Switch), 1 Channel(On/Off Light) { product_id = 0x1009, target_profile = "light-power-energy-powerConsumption" }, -- 4 Buttons(Generic Switch), 2 Channels(On/Off Light) { product_id = 0x100A, target_profile = "light-level-power-energy-powerConsumption" }, -- 1 Buttons(Generic Switch), 1 Channels(Dimmable Light) + }, + [0xFFF1] = { + { product_id = 0x8004, target_profile = "12-buttons-without-main-button"}, } } @@ -289,7 +292,8 @@ local START_BUTTON_PRESS = "__start_button_press" local TIMEOUT_THRESHOLD = 10 --arbitrary timeout local HELD_THRESHOLD = 1 -- this is the number of buttons for which we have a static profile already made -local STATIC_BUTTON_PROFILE_SUPPORTED = {1, 2, 3, 4, 5, 6, 7, 8, 9} +-- local STATIC_BUTTON_PROFILE_SUPPORTED = {1, 2, 3, 4, 5, 6, 7, 8} +local STATIC_BUTTON_PROFILE_SUPPORTED = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12} -- Some switches will send a MultiPressComplete event as part of a long press sequence. Normally the driver will create a -- button capability event on receipt of MultiPressComplete, but in this case that would result in an extra event because @@ -421,6 +425,14 @@ local function find_default_endpoint(device) return device.MATTER_DEFAULT_ENDPOINT end + if device.manufacturer_info.vendor_id == 0xFFF1 and + device.manufacturer_info.product_id == 0x8004 then + log.warn(string.format("return main endpoint")) + log.info(string.format("Matter default endpoint: %d", device.MATTER_DEFAULT_ENDPOINT)) + -- In case of Aura, in order to sequentially set the button name to button 1,-12 + return device.MATTER_DEFAULT_ENDPOINT +end + local switch_eps = device:get_endpoints(clusters.OnOff.ID) local button_eps = device:get_endpoints(clusters.Switch.ID, {feature_bitmap=clusters.Switch.types.SwitchFeature.MOMENTARY_SWITCH}) @@ -562,14 +574,25 @@ local function build_button_component_map(device, main_endpoint, button_eps) -- create component mapping on the main profile button endpoints table.sort(button_eps) local component_map = {} - component_map["main"] = main_endpoint + --component_map["main"] = main_endpoint + if device.manufacturer_info.vendor_id == 0xFFF1 and + device.manufacturer_info.product_id == 0x8004 then + else + component_map["main"] = main_endpoint + end for component_num, ep in ipairs(button_eps) do - if ep ~= main_endpoint then - local button_component = "button" - if #button_eps > 1 then - button_component = button_component .. component_num + if device.manufacturer_info.vendor_id == 0xFFF1 and + device.manufacturer_info.product_id == 0x8004 then + local button_component = "button" .. component_num + component_map[button_component] = ep + else + if ep ~= main_endpoint then + local button_component = "button" + if #button_eps > 1 then + button_component = button_component .. component_num + end + component_map[button_component] = ep end - component_map[button_component] = ep end end device:set_field(COMPONENT_TO_ENDPOINT_MAP, component_map, {persist = true}) @@ -584,6 +607,10 @@ local function build_button_profile(device, main_endpoint, num_button_eps) if battery_supported then -- battery profiles are configured later, in power_source_attribute_list_handler device:send(clusters.PowerSource.attributes.AttributeList:read(device)) else + if device.manufacturer_info.vendor_id == 0xFFF1 and + device.manufacturer_info.product_id == 0x8004 then -- for aura smart button + profile_name = "12-buttons-without-main-button" + end device:try_update_metadata({profile = profile_name}) end end @@ -685,6 +712,22 @@ local function detect_bridge(device) return false end +local function clean_supported_values(device) + local supported = capabilities.button.supportedButtonValues({"pushed", "double", "held"}, {visibility = {displayed = false}}) + device:emit_event_for_endpoint(1, supported) + device:emit_event_for_endpoint(2, supported) + device:emit_event_for_endpoint(3, supported) + device:emit_event_for_endpoint(4, supported) + device:emit_event_for_endpoint(5, supported) + device:emit_event_for_endpoint(6, supported) + device:emit_event_for_endpoint(7, supported) + device:emit_event_for_endpoint(8, supported) + device:emit_event_for_endpoint(9, supported) + device:emit_event_for_endpoint(10, supported) + device:emit_event_for_endpoint(11, supported) + device:emit_event_for_endpoint(12, supported) +end + local function device_init(driver, device) if device.network_type == device_lib.NETWORK_TYPE_MATTER then check_field_name_updates(device) From 64f241e22a8a50d3984265a4d749f5319c95233e Mon Sep 17 00:00:00 2001 From: simon3panda Date: Tue, 16 Sep 2025 10:54:31 +0800 Subject: [PATCH 2/4] remove warning --- drivers/SmartThings/matter-switch/src/init.lua | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/SmartThings/matter-switch/src/init.lua b/drivers/SmartThings/matter-switch/src/init.lua index 9bddafbc47..385893cf21 100644 --- a/drivers/SmartThings/matter-switch/src/init.lua +++ b/drivers/SmartThings/matter-switch/src/init.lua @@ -577,14 +577,15 @@ local function build_button_component_map(device, main_endpoint, button_eps) --component_map["main"] = main_endpoint if device.manufacturer_info.vendor_id == 0xFFF1 and device.manufacturer_info.product_id == 0x8004 then - else - component_map["main"] = main_endpoint + do end + else + component_map["main"] = main_endpoint end for component_num, ep in ipairs(button_eps) do if device.manufacturer_info.vendor_id == 0xFFF1 and device.manufacturer_info.product_id == 0x8004 then local button_component = "button" .. component_num - component_map[button_component] = ep + component_map[button_component] = ep else if ep ~= main_endpoint then local button_component = "button" @@ -1354,6 +1355,7 @@ local function max_press_handler(driver, device, ib, response) end local function info_changed(driver, device, event, args) + clean_supported_values(device) if device.profile.id ~= args.old_st_store.profile.id then device:subscribe() local button_eps = device:get_endpoints(clusters.Switch.ID, {feature_bitmap=clusters.Switch.types.SwitchFeature.MOMENTARY_SWITCH}) From 5cfdb9bfba8361b7003c813b72133bb8d06750d5 Mon Sep 17 00:00:00 2001 From: simon3panda Date: Tue, 16 Sep 2025 14:32:14 +0800 Subject: [PATCH 3/4] fix warning. --- drivers/SmartThings/matter-switch/src/init.lua | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/SmartThings/matter-switch/src/init.lua b/drivers/SmartThings/matter-switch/src/init.lua index 385893cf21..70b1938a73 100644 --- a/drivers/SmartThings/matter-switch/src/init.lua +++ b/drivers/SmartThings/matter-switch/src/init.lua @@ -575,10 +575,8 @@ local function build_button_component_map(device, main_endpoint, button_eps) table.sort(button_eps) local component_map = {} --component_map["main"] = main_endpoint - if device.manufacturer_info.vendor_id == 0xFFF1 and - device.manufacturer_info.product_id == 0x8004 then - do end - else + if device.manufacturer_info.vendor_id ~= 0xFFF1 or + device.manufacturer_info.product_id ~= 0x8004 then component_map["main"] = main_endpoint end for component_num, ep in ipairs(button_eps) do @@ -609,7 +607,7 @@ local function build_button_profile(device, main_endpoint, num_button_eps) device:send(clusters.PowerSource.attributes.AttributeList:read(device)) else if device.manufacturer_info.vendor_id == 0xFFF1 and - device.manufacturer_info.product_id == 0x8004 then -- for aura smart button + device.manufacturer_info.product_id == 0x8004 then -- for aura smart button profile_name = "12-buttons-without-main-button" end device:try_update_metadata({profile = profile_name}) From a689a860c4ce2dc0d7741b7c77e74b8f9edd9b50 Mon Sep 17 00:00:00 2001 From: simon3panda Date: Tue, 16 Sep 2025 15:06:13 +0800 Subject: [PATCH 4/4] remove test fails --- drivers/SmartThings/matter-switch/src/init.lua | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/drivers/SmartThings/matter-switch/src/init.lua b/drivers/SmartThings/matter-switch/src/init.lua index 70b1938a73..c7ca3a33f6 100644 --- a/drivers/SmartThings/matter-switch/src/init.lua +++ b/drivers/SmartThings/matter-switch/src/init.lua @@ -711,22 +711,6 @@ local function detect_bridge(device) return false end -local function clean_supported_values(device) - local supported = capabilities.button.supportedButtonValues({"pushed", "double", "held"}, {visibility = {displayed = false}}) - device:emit_event_for_endpoint(1, supported) - device:emit_event_for_endpoint(2, supported) - device:emit_event_for_endpoint(3, supported) - device:emit_event_for_endpoint(4, supported) - device:emit_event_for_endpoint(5, supported) - device:emit_event_for_endpoint(6, supported) - device:emit_event_for_endpoint(7, supported) - device:emit_event_for_endpoint(8, supported) - device:emit_event_for_endpoint(9, supported) - device:emit_event_for_endpoint(10, supported) - device:emit_event_for_endpoint(11, supported) - device:emit_event_for_endpoint(12, supported) -end - local function device_init(driver, device) if device.network_type == device_lib.NETWORK_TYPE_MATTER then check_field_name_updates(device) @@ -1353,7 +1337,6 @@ local function max_press_handler(driver, device, ib, response) end local function info_changed(driver, device, event, args) - clean_supported_values(device) if device.profile.id ~= args.old_st_store.profile.id then device:subscribe() local button_eps = device:get_endpoints(clusters.Switch.ID, {feature_bitmap=clusters.Switch.types.SwitchFeature.MOMENTARY_SWITCH})