From ec112fe26266375870bcb1510484b0bc81e083c5 Mon Sep 17 00:00:00 2001 From: Harrison Carter Date: Tue, 21 Oct 2025 17:15:51 -0500 Subject: [PATCH 1/3] update vendor overrides --- .../generic_handlers/attribute_handlers.lua | 3 +- .../src/test/test_matter_bridge.lua | 12 ++ .../test_multi_switch_parent_child_lights.lua | 3 +- .../test_multi_switch_parent_child_plugs.lua | 104 ------------------ .../src/utils/device_configuration.lua | 17 +-- .../matter-switch/src/utils/switch_fields.lua | 26 ++--- .../matter-switch/src/utils/switch_utils.lua | 53 ++++----- 7 files changed, 55 insertions(+), 163 deletions(-) diff --git a/drivers/SmartThings/matter-switch/src/generic_handlers/attribute_handlers.lua b/drivers/SmartThings/matter-switch/src/generic_handlers/attribute_handlers.lua index ad8a74a00f..73844f2fb7 100644 --- a/drivers/SmartThings/matter-switch/src/generic_handlers/attribute_handlers.lua +++ b/drivers/SmartThings/matter-switch/src/generic_handlers/attribute_handlers.lua @@ -361,8 +361,7 @@ function AttributeHandlers.power_source_attribute_list_handler(driver, device, i profile_name = string.format("%d-", #button_eps) .. profile_name end - if device.manufacturer_info.vendor_id == fields.AQARA_MANUFACTURER_ID and - device.manufacturer_info.product_id == fields.AQARA_CLIMATE_SENSOR_W100_ID then + if switch_utils.get_product_override_field(device, "is_climate_sensor_w100") then profile_name = profile_name .. "-temperature-humidity" end device:try_update_metadata({ profile = profile_name }) diff --git a/drivers/SmartThings/matter-switch/src/test/test_matter_bridge.lua b/drivers/SmartThings/matter-switch/src/test/test_matter_bridge.lua index 54eb21dc88..0d11bc8b5e 100644 --- a/drivers/SmartThings/matter-switch/src/test/test_matter_bridge.lua +++ b/drivers/SmartThings/matter-switch/src/test/test_matter_bridge.lua @@ -88,6 +88,18 @@ end test.register_coroutine_test( "Profile should not change for devices with aggregator device type (bridges)", function() + local subscribe_request = cluster_subscribe_list[1]:subscribe(mock_bridge) + for i, cluster in ipairs(cluster_subscribe_list) do + if i > 1 then + subscribe_request:merge(cluster:subscribe(mock_bridge)) + end + end + test.socket.device_lifecycle:__queue_receive({ mock_bridge.id, "added" }) + test.socket.matter:__expect_send({mock_bridge.id, subscribe_request}) + test.socket.device_lifecycle:__queue_receive({ mock_bridge.id, "init" }) + test.socket.matter:__expect_send({mock_bridge.id, subscribe_request}) + test.socket.device_lifecycle:__queue_receive({ mock_bridge.id, "doConfigure" }) + mock_bridge:expect_metadata_update({ provisioning_state = "PROVISIONED" }) end, { test_init = test_init_mock_bridge } ) diff --git a/drivers/SmartThings/matter-switch/src/test/test_multi_switch_parent_child_lights.lua b/drivers/SmartThings/matter-switch/src/test/test_multi_switch_parent_child_lights.lua index 21c9e1087d..6e65d3811e 100644 --- a/drivers/SmartThings/matter-switch/src/test/test_multi_switch_parent_child_lights.lua +++ b/drivers/SmartThings/matter-switch/src/test/test_multi_switch_parent_child_lights.lua @@ -274,11 +274,10 @@ local function test_init_parent_child_endpoints_non_sequential() parent_assigned_child_key = string.format("%d", child2_ep_non_sequential) }) - -- switch-binary will be selected as an overridden child device profile mock_device_parent_child_endpoints_non_sequential:expect_device_create({ type = "EDGE_CHILD", label = "Matter Switch 3", - profile = "switch-binary", + profile = "plug-binary", parent_device_id = mock_device_parent_child_endpoints_non_sequential.id, parent_assigned_child_key = string.format("%d", child3_ep_non_sequential) }) diff --git a/drivers/SmartThings/matter-switch/src/test/test_multi_switch_parent_child_plugs.lua b/drivers/SmartThings/matter-switch/src/test/test_multi_switch_parent_child_plugs.lua index 03c898b7f5..be963ea90f 100644 --- a/drivers/SmartThings/matter-switch/src/test/test_multi_switch_parent_child_plugs.lua +++ b/drivers/SmartThings/matter-switch/src/test/test_multi_switch_parent_child_plugs.lua @@ -20,7 +20,6 @@ local clusters = require "st.matter.clusters" test.disable_startup_messages() local child_profile = t_utils.get_profile_definition("plug-binary.yml") -local child_profile_override = t_utils.get_profile_definition("switch-binary.yml") local parent_ep = 10 local child1_ep = 20 local child2_ep = 30 @@ -72,53 +71,6 @@ local mock_device = test.mock_device.build_test_matter_device({ } }) -local mock_device_child_profile_override = test.mock_device.build_test_matter_device({ - label = "Matter Switch", - profile = t_utils.get_profile_definition("switch-binary.yml"), - manufacturer_info = { - vendor_id = 0x1321, - product_id = 0x000D, - }, - endpoints = { - { - endpoint_id = 0, - clusters = { - {cluster_id = clusters.Basic.ID, cluster_type = "SERVER"}, - }, - device_types = { - {device_type_id = 0x0016, device_type_revision = 1} -- RootNode - } - }, - { - endpoint_id = parent_ep, - clusters = { - {cluster_id = clusters.OnOff.ID, cluster_type = "SERVER"}, - }, - device_types = { - {device_type_id = 0x010A, device_type_revision = 2} -- On/Off Plug - } - }, - { - endpoint_id = child1_ep, - clusters = { - {cluster_id = clusters.OnOff.ID, cluster_type = "SERVER"}, - }, - device_types = { - {device_type_id = 0x010A, device_type_revision = 2} -- On/Off Plug - } - }, - { - endpoint_id = child2_ep, - clusters = { - {cluster_id = clusters.OnOff.ID, cluster_type = "SERVER"}, - }, - device_types = { - {device_type_id = 0x010A, device_type_revision = 2} -- On/Off Plug - } - }, - } -}) - local mock_children = {} for i, endpoint in ipairs(mock_device.endpoints) do if endpoint.endpoint_id ~= parent_ep and endpoint.endpoint_id ~= 0 then @@ -169,56 +121,6 @@ local function test_init() }) end -local mock_children_child_profile_override = {} -for i, endpoint in ipairs(mock_device_child_profile_override.endpoints) do - if endpoint.endpoint_id ~= parent_ep and endpoint.endpoint_id ~= 0 then - local child_data = { - profile = child_profile_override, - device_network_id = string.format("%s:%d", mock_device_child_profile_override.id, endpoint.endpoint_id), - parent_device_id = mock_device_child_profile_override.id, - parent_assigned_child_key = string.format("%d", endpoint.endpoint_id) - } - mock_children_child_profile_override[endpoint.endpoint_id] = test.mock_device.build_test_child_device(child_data) - end -end - -local function test_init_child_profile_override() - test.mock_device.add_test_device(mock_device_child_profile_override) - local cluster_subscribe_list = { - clusters.OnOff.attributes.OnOff, - } - local subscribe_request = cluster_subscribe_list[1]:subscribe(mock_device_child_profile_override) - - test.socket.device_lifecycle:__queue_receive({ mock_device_child_profile_override.id, "added" }) - test.socket.matter:__expect_send({mock_device_child_profile_override.id, subscribe_request}) - - test.socket.device_lifecycle:__queue_receive({ mock_device_child_profile_override.id, "init" }) - test.socket.matter:__expect_send({mock_device_child_profile_override.id, subscribe_request}) - - test.socket.device_lifecycle:__queue_receive({ mock_device_child_profile_override.id, "doConfigure" }) - mock_device_child_profile_override:expect_metadata_update({ provisioning_state = "PROVISIONED" }) - - for _, child in pairs(mock_children_child_profile_override) do - test.mock_device.add_test_device(child) - end - - mock_device:expect_device_create({ - type = "EDGE_CHILD", - label = "Matter Switch 2", - profile = "switch-binary", - parent_device_id = mock_device_child_profile_override.id, - parent_assigned_child_key = string.format("%d", child1_ep) - }) - - mock_device:expect_device_create({ - type = "EDGE_CHILD", - label = "Matter Switch 3", - profile = "switch-binary", - parent_device_id = mock_device_child_profile_override.id, - parent_assigned_child_key = string.format("%d", child2_ep) - }) -end - test.set_test_init_function(test_init) test.register_message_test( @@ -383,10 +285,4 @@ test.register_coroutine_test( end ) -test.register_coroutine_test( - "Child device profiles should be overriden for specific devices", function() - end, - { test_init = test_init_child_profile_override } -) - test.run_registered_tests() diff --git a/drivers/SmartThings/matter-switch/src/utils/device_configuration.lua b/drivers/SmartThings/matter-switch/src/utils/device_configuration.lua index 3870b82f9f..8548fb0c8a 100644 --- a/drivers/SmartThings/matter-switch/src/utils/device_configuration.lua +++ b/drivers/SmartThings/matter-switch/src/utils/device_configuration.lua @@ -50,20 +50,9 @@ function SwitchDeviceConfiguration.assign_child_profile(device, child_ep) end end - -- Check if device has an overridden child profile that differs from the profile that would match - -- the child's device type for the following two cases: - -- 1. To add Electrical Sensor only to the first EDGE_CHILD (light-power-energy-powerConsumption) - -- for the Aqara Light Switch H2. The profile of the second EDGE_CHILD for this device is - -- determined in the "for" loop above (e.g., light-binary) - -- 2. The selected profile for the child device matches the initial profile defined in - -- child_device_profile_overrides - for id, vendor in pairs(fields.child_device_profile_overrides_per_vendor_id) do - for _, fingerprint in ipairs(vendor) do - if device.manufacturer_info.product_id == fingerprint.product_id and - ((device.manufacturer_info.vendor_id == fields.AQARA_MANUFACTURER_ID and child_ep == 1) or profile == fingerprint.initial_profile) then - return fingerprint.target_profile - end - end + -- workaround: Aqara Light Switch H2: add Electrical Sensor profile only to the first EDGE_CHILD + if child_ep == 1 then + profile = switch_utils.get_product_override_field(device, "target_profile") or profile end -- default to "switch-binary" if no profile is found diff --git a/drivers/SmartThings/matter-switch/src/utils/switch_fields.lua b/drivers/SmartThings/matter-switch/src/utils/switch_fields.lua index 2244eab661..d922737355 100644 --- a/drivers/SmartThings/matter-switch/src/utils/switch_fields.lua +++ b/drivers/SmartThings/matter-switch/src/utils/switch_fields.lua @@ -106,19 +106,16 @@ SwitchFields.HUE_SAT_COLOR_MODE = clusters.ColorControl.types.ColorMode.CURRENT_ SwitchFields.X_Y_COLOR_MODE = clusters.ColorControl.types.ColorMode.CURRENTX_AND_CURRENTY -SwitchFields.child_device_profile_overrides_per_vendor_id = { - [0x1321] = { - { product_id = 0x000C, target_profile = "switch-binary", initial_profile = "plug-binary" }, - { product_id = 0x000D, target_profile = "switch-binary", initial_profile = "plug-binary" }, - }, - [0x115F] = { - { product_id = 0x1003, target_profile = "light-power-energy-powerConsumption" }, -- 2 Buttons(Generic Switch), 1 Channel(On/Off Light) - { product_id = 0x1004, target_profile = "light-power-energy-powerConsumption" }, -- 2 Buttons(Generic Switch), 2 Channels(On/Off Light) - { product_id = 0x1005, target_profile = "light-power-energy-powerConsumption" }, -- 4 Buttons(Generic Switch), 3 Channels(On/Off Light) - { product_id = 0x1006, target_profile = "light-level-power-energy-powerConsumption" }, -- 3 Buttons(Generic Switch), 1 Channels(Dimmable Light) - { 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) +SwitchFields.vendor_overrides = { + [0x115F] = { -- AQARA_MANUFACTURER_ID + [0x1003] = { target_profile = "light-power-energy-powerConsumption" }, -- 2 Buttons(Generic Switch), 1 Channel(On/Off Light) + [0x1004] = { target_profile = "light-power-energy-powerConsumption" }, -- 2 Buttons(Generic Switch), 2 Channels(On/Off Light) + [0x1005] = { target_profile = "light-power-energy-powerConsumption" }, -- 4 Buttons(Generic Switch), 3 Channels(On/Off Light) + [0x1008] = { target_profile = "light-power-energy-powerConsumption" }, -- 2 Buttons(Generic Switch), 1 Channel(On/Off Light) + [0x1009] = { target_profile = "light-power-energy-powerConsumption" }, -- 4 Buttons(Generic Switch), 2 Channels(On/Off Light) + [0x1006] = { ignore_combo_switch_button = true, target_profile = "light-level-power-energy-powerConsumption" }, -- 3 Buttons(Generic Switch), 1 Channels(Dimmable Light) + [0x100A] = { ignore_combo_switch_button = true, target_profile = "light-level-power-energy-powerConsumption" }, -- 1 Buttons(Generic Switch), 1 Channels(Dimmable Light) + [0x2004] = { is_climate_sensor_w100 = true }, -- Climate Sensor W100, requires unique profile } } @@ -150,9 +147,6 @@ SwitchFields.TEMP_BOUND_RECEIVED = "__temp_bound_received" SwitchFields.TEMP_MIN = "__temp_min" SwitchFields.TEMP_MAX = "__temp_max" -SwitchFields.AQARA_MANUFACTURER_ID = 0x115F -SwitchFields.AQARA_CLIMATE_SENSOR_W100_ID = 0x2004 - SwitchFields.TRANSITION_TIME = 0 --1/10ths of a second -- When sent with a command, these options mask and override bitmaps cause the command -- to take effect when the switch/light is off. diff --git a/drivers/SmartThings/matter-switch/src/utils/switch_utils.lua b/drivers/SmartThings/matter-switch/src/utils/switch_utils.lua index 86368e9208..2558429654 100644 --- a/drivers/SmartThings/matter-switch/src/utils/switch_utils.lua +++ b/drivers/SmartThings/matter-switch/src/utils/switch_utils.lua @@ -63,6 +63,14 @@ function utils.mired_to_kelvin(value, minOrMax) end end +function utils.get_product_override_field(device, override_key) + if fields.vendor_overrides[device.manufacturer_info.vendor_id] + and fields.vendor_overrides[device.manufacturer_info.vendor_id][device.manufacturer_info.product_id] + then + return fields.vendor_overrides[device.manufacturer_info.vendor_id][device.manufacturer_info.product_id][override_key] + end +end + function utils.check_field_name_updates(device) for _, field in ipairs(fields.updated_fields) do if device:get_field(field.current_field_name) then @@ -78,29 +86,18 @@ end --- whether the device type for an endpoint is currently supported by a profile for --- combination button/switch devices. function utils.device_type_supports_button_switch_combination(device, endpoint_id) - for _, ep in ipairs(device.endpoints) do - if ep.endpoint_id == endpoint_id then - for _, dt in ipairs(ep.device_types) do - if dt.device_type_id == fields.DIMMABLE_LIGHT_DEVICE_TYPE_ID then - for _, fingerprint in ipairs(fields.child_device_profile_overrides_per_vendor_id[0x115F]) do - if device.manufacturer_info.product_id == fingerprint.product_id then - return false -- For Aqara Dimmer Switch with Button. - end - end - return true - end - end - end + if utils.get_product_override_field(device, "ignore_combo_switch_button") then + return false end - return false + local dimmable_eps = utils.get_endpoints_by_device_type(device, fields.DIMMABLE_LIGHT_DEVICE_TYPE_ID) + return utils.tbl_contains(dimmable_eps, endpoint_id) end --- find_default_endpoint is a helper function to handle situations where --- device does not have endpoint ids in sequential order from 1 function utils.find_default_endpoint(device) - if device.manufacturer_info.vendor_id == fields.AQARA_MANUFACTURER_ID and - device.manufacturer_info.product_id == fields.AQARA_CLIMATE_SENSOR_W100_ID then - -- In case of Aqara Climate Sensor W100, in order to sequentially set the button name to button 1, 2, 3 + -- Buttons should not be set on the main component for the Aqara Climate Sensor W100, + if utils.get_product_override_field(device, "is_climate_sensor_w100") then return device.MATTER_DEFAULT_ENDPOINT end @@ -171,6 +168,19 @@ function utils.matter_handler(driver, device, response_block) device.log.info(string.format("Fallback handler for %s", response_block)) end +-- get a list of endpoints for a specified device type. +function utils.get_endpoints_by_device_type(device, device_type_id) + local dt_eps = {} + for _, ep in ipairs(device.endpoints) do + for _, dt in ipairs(ep.device_types) do + if dt.device_type_id == device_type_id then + table.insert(dt_eps, ep.endpoint_id) + end + end + end + return dt_eps +end + --helper function to create list of multi press values function utils.create_multi_press_values_list(size, supportsHeld) local list = {"pushed", "double"} @@ -183,14 +193,7 @@ function utils.create_multi_press_values_list(size, supportsHeld) end function utils.detect_bridge(device) - for _, ep in ipairs(device.endpoints) do - for _, dt in ipairs(ep.device_types) do - if dt.device_type_id == fields.AGGREGATOR_DEVICE_TYPE_ID then - return true - end - end - end - return false + return #utils.get_endpoints_by_device_type(device, fields.AGGREGATOR_DEVICE_TYPE_ID) > 0 end function utils.detect_matter_thing(device) From 88b3eb534331033ca54cce5bea0fe833c0b1cbf9 Mon Sep 17 00:00:00 2001 From: Harrison Carter Date: Tue, 28 Oct 2025 13:01:29 -0500 Subject: [PATCH 2/3] re-add sonoff override --- .../test_multi_switch_parent_child_lights.lua | 3 +- .../test_multi_switch_parent_child_plugs.lua | 104 ++++++++++++++++++ .../src/utils/device_configuration.lua | 2 +- .../matter-switch/src/utils/switch_fields.lua | 4 + 4 files changed, 111 insertions(+), 2 deletions(-) diff --git a/drivers/SmartThings/matter-switch/src/test/test_multi_switch_parent_child_lights.lua b/drivers/SmartThings/matter-switch/src/test/test_multi_switch_parent_child_lights.lua index 6e65d3811e..21c9e1087d 100644 --- a/drivers/SmartThings/matter-switch/src/test/test_multi_switch_parent_child_lights.lua +++ b/drivers/SmartThings/matter-switch/src/test/test_multi_switch_parent_child_lights.lua @@ -274,10 +274,11 @@ local function test_init_parent_child_endpoints_non_sequential() parent_assigned_child_key = string.format("%d", child2_ep_non_sequential) }) + -- switch-binary will be selected as an overridden child device profile mock_device_parent_child_endpoints_non_sequential:expect_device_create({ type = "EDGE_CHILD", label = "Matter Switch 3", - profile = "plug-binary", + profile = "switch-binary", parent_device_id = mock_device_parent_child_endpoints_non_sequential.id, parent_assigned_child_key = string.format("%d", child3_ep_non_sequential) }) diff --git a/drivers/SmartThings/matter-switch/src/test/test_multi_switch_parent_child_plugs.lua b/drivers/SmartThings/matter-switch/src/test/test_multi_switch_parent_child_plugs.lua index be963ea90f..03c898b7f5 100644 --- a/drivers/SmartThings/matter-switch/src/test/test_multi_switch_parent_child_plugs.lua +++ b/drivers/SmartThings/matter-switch/src/test/test_multi_switch_parent_child_plugs.lua @@ -20,6 +20,7 @@ local clusters = require "st.matter.clusters" test.disable_startup_messages() local child_profile = t_utils.get_profile_definition("plug-binary.yml") +local child_profile_override = t_utils.get_profile_definition("switch-binary.yml") local parent_ep = 10 local child1_ep = 20 local child2_ep = 30 @@ -71,6 +72,53 @@ local mock_device = test.mock_device.build_test_matter_device({ } }) +local mock_device_child_profile_override = test.mock_device.build_test_matter_device({ + label = "Matter Switch", + profile = t_utils.get_profile_definition("switch-binary.yml"), + manufacturer_info = { + vendor_id = 0x1321, + product_id = 0x000D, + }, + endpoints = { + { + endpoint_id = 0, + clusters = { + {cluster_id = clusters.Basic.ID, cluster_type = "SERVER"}, + }, + device_types = { + {device_type_id = 0x0016, device_type_revision = 1} -- RootNode + } + }, + { + endpoint_id = parent_ep, + clusters = { + {cluster_id = clusters.OnOff.ID, cluster_type = "SERVER"}, + }, + device_types = { + {device_type_id = 0x010A, device_type_revision = 2} -- On/Off Plug + } + }, + { + endpoint_id = child1_ep, + clusters = { + {cluster_id = clusters.OnOff.ID, cluster_type = "SERVER"}, + }, + device_types = { + {device_type_id = 0x010A, device_type_revision = 2} -- On/Off Plug + } + }, + { + endpoint_id = child2_ep, + clusters = { + {cluster_id = clusters.OnOff.ID, cluster_type = "SERVER"}, + }, + device_types = { + {device_type_id = 0x010A, device_type_revision = 2} -- On/Off Plug + } + }, + } +}) + local mock_children = {} for i, endpoint in ipairs(mock_device.endpoints) do if endpoint.endpoint_id ~= parent_ep and endpoint.endpoint_id ~= 0 then @@ -121,6 +169,56 @@ local function test_init() }) end +local mock_children_child_profile_override = {} +for i, endpoint in ipairs(mock_device_child_profile_override.endpoints) do + if endpoint.endpoint_id ~= parent_ep and endpoint.endpoint_id ~= 0 then + local child_data = { + profile = child_profile_override, + device_network_id = string.format("%s:%d", mock_device_child_profile_override.id, endpoint.endpoint_id), + parent_device_id = mock_device_child_profile_override.id, + parent_assigned_child_key = string.format("%d", endpoint.endpoint_id) + } + mock_children_child_profile_override[endpoint.endpoint_id] = test.mock_device.build_test_child_device(child_data) + end +end + +local function test_init_child_profile_override() + test.mock_device.add_test_device(mock_device_child_profile_override) + local cluster_subscribe_list = { + clusters.OnOff.attributes.OnOff, + } + local subscribe_request = cluster_subscribe_list[1]:subscribe(mock_device_child_profile_override) + + test.socket.device_lifecycle:__queue_receive({ mock_device_child_profile_override.id, "added" }) + test.socket.matter:__expect_send({mock_device_child_profile_override.id, subscribe_request}) + + test.socket.device_lifecycle:__queue_receive({ mock_device_child_profile_override.id, "init" }) + test.socket.matter:__expect_send({mock_device_child_profile_override.id, subscribe_request}) + + test.socket.device_lifecycle:__queue_receive({ mock_device_child_profile_override.id, "doConfigure" }) + mock_device_child_profile_override:expect_metadata_update({ provisioning_state = "PROVISIONED" }) + + for _, child in pairs(mock_children_child_profile_override) do + test.mock_device.add_test_device(child) + end + + mock_device:expect_device_create({ + type = "EDGE_CHILD", + label = "Matter Switch 2", + profile = "switch-binary", + parent_device_id = mock_device_child_profile_override.id, + parent_assigned_child_key = string.format("%d", child1_ep) + }) + + mock_device:expect_device_create({ + type = "EDGE_CHILD", + label = "Matter Switch 3", + profile = "switch-binary", + parent_device_id = mock_device_child_profile_override.id, + parent_assigned_child_key = string.format("%d", child2_ep) + }) +end + test.set_test_init_function(test_init) test.register_message_test( @@ -285,4 +383,10 @@ test.register_coroutine_test( end ) +test.register_coroutine_test( + "Child device profiles should be overriden for specific devices", function() + end, + { test_init = test_init_child_profile_override } +) + test.run_registered_tests() diff --git a/drivers/SmartThings/matter-switch/src/utils/device_configuration.lua b/drivers/SmartThings/matter-switch/src/utils/device_configuration.lua index 8548fb0c8a..6c3e9814dc 100644 --- a/drivers/SmartThings/matter-switch/src/utils/device_configuration.lua +++ b/drivers/SmartThings/matter-switch/src/utils/device_configuration.lua @@ -51,7 +51,7 @@ function SwitchDeviceConfiguration.assign_child_profile(device, child_ep) end -- workaround: Aqara Light Switch H2: add Electrical Sensor profile only to the first EDGE_CHILD - if child_ep == 1 then + if child_ep == 1 or profile == switch_utils.get_product_override_field(device, "initial_profile") then profile = switch_utils.get_product_override_field(device, "target_profile") or profile end diff --git a/drivers/SmartThings/matter-switch/src/utils/switch_fields.lua b/drivers/SmartThings/matter-switch/src/utils/switch_fields.lua index d922737355..0d6af1862e 100644 --- a/drivers/SmartThings/matter-switch/src/utils/switch_fields.lua +++ b/drivers/SmartThings/matter-switch/src/utils/switch_fields.lua @@ -107,6 +107,10 @@ SwitchFields.X_Y_COLOR_MODE = clusters.ColorControl.types.ColorMode.CURRENTX_AND SwitchFields.vendor_overrides = { + [0x1321] = { + [0x000C] = { target_profile = "switch-binary", initial_profile = "plug-binary" }, + [0x000D] = { target_profile = "switch-binary", initial_profile = "plug-binary" }, + }, [0x115F] = { -- AQARA_MANUFACTURER_ID [0x1003] = { target_profile = "light-power-energy-powerConsumption" }, -- 2 Buttons(Generic Switch), 1 Channel(On/Off Light) [0x1004] = { target_profile = "light-power-energy-powerConsumption" }, -- 2 Buttons(Generic Switch), 2 Channels(On/Off Light) From 118fe383da39b18d5869e8fd089f5241e4617b9f Mon Sep 17 00:00:00 2001 From: Harrison Carter Date: Tue, 28 Oct 2025 13:05:51 -0500 Subject: [PATCH 3/3] update vendor override table --- .../src/utils/device_configuration.lua | 4 ++-- .../matter-switch/src/utils/switch_fields.lua | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/SmartThings/matter-switch/src/utils/device_configuration.lua b/drivers/SmartThings/matter-switch/src/utils/device_configuration.lua index 6c3e9814dc..b2d066ce61 100644 --- a/drivers/SmartThings/matter-switch/src/utils/device_configuration.lua +++ b/drivers/SmartThings/matter-switch/src/utils/device_configuration.lua @@ -50,8 +50,8 @@ function SwitchDeviceConfiguration.assign_child_profile(device, child_ep) end end - -- workaround: Aqara Light Switch H2: add Electrical Sensor profile only to the first EDGE_CHILD - if child_ep == 1 or profile == switch_utils.get_product_override_field(device, "initial_profile") then + -- vendor override checks + if child_ep == switch_utils.get_product_override_field(device, "ep_id") or profile == switch_utils.get_product_override_field(device, "initial_profile") then profile = switch_utils.get_product_override_field(device, "target_profile") or profile end diff --git a/drivers/SmartThings/matter-switch/src/utils/switch_fields.lua b/drivers/SmartThings/matter-switch/src/utils/switch_fields.lua index 0d6af1862e..07ad0fdbeb 100644 --- a/drivers/SmartThings/matter-switch/src/utils/switch_fields.lua +++ b/drivers/SmartThings/matter-switch/src/utils/switch_fields.lua @@ -112,13 +112,13 @@ SwitchFields.vendor_overrides = { [0x000D] = { target_profile = "switch-binary", initial_profile = "plug-binary" }, }, [0x115F] = { -- AQARA_MANUFACTURER_ID - [0x1003] = { target_profile = "light-power-energy-powerConsumption" }, -- 2 Buttons(Generic Switch), 1 Channel(On/Off Light) - [0x1004] = { target_profile = "light-power-energy-powerConsumption" }, -- 2 Buttons(Generic Switch), 2 Channels(On/Off Light) - [0x1005] = { target_profile = "light-power-energy-powerConsumption" }, -- 4 Buttons(Generic Switch), 3 Channels(On/Off Light) - [0x1008] = { target_profile = "light-power-energy-powerConsumption" }, -- 2 Buttons(Generic Switch), 1 Channel(On/Off Light) - [0x1009] = { target_profile = "light-power-energy-powerConsumption" }, -- 4 Buttons(Generic Switch), 2 Channels(On/Off Light) - [0x1006] = { ignore_combo_switch_button = true, target_profile = "light-level-power-energy-powerConsumption" }, -- 3 Buttons(Generic Switch), 1 Channels(Dimmable Light) - [0x100A] = { ignore_combo_switch_button = true, target_profile = "light-level-power-energy-powerConsumption" }, -- 1 Buttons(Generic Switch), 1 Channels(Dimmable Light) + [0x1003] = { target_profile = "light-power-energy-powerConsumption", ep_id = 1 }, -- 2 Buttons(Generic Switch), 1 Channel(On/Off Light) + [0x1004] = { target_profile = "light-power-energy-powerConsumption", ep_id = 1 }, -- 2 Buttons(Generic Switch), 2 Channels(On/Off Light) + [0x1005] = { target_profile = "light-power-energy-powerConsumption", ep_id = 1 }, -- 4 Buttons(Generic Switch), 3 Channels(On/Off Light) + [0x1008] = { target_profile = "light-power-energy-powerConsumption", ep_id = 1 }, -- 2 Buttons(Generic Switch), 1 Channel(On/Off Light) + [0x1009] = { target_profile = "light-power-energy-powerConsumption", ep_id = 1 }, -- 4 Buttons(Generic Switch), 2 Channels(On/Off Light) + [0x1006] = { ignore_combo_switch_button = true, target_profile = "light-level-power-energy-powerConsumption", ep_id = 1 }, -- 3 Buttons(Generic Switch), 1 Channels(Dimmable Light) + [0x100A] = { ignore_combo_switch_button = true, target_profile = "light-level-power-energy-powerConsumption", ep_id = 1 }, -- 1 Buttons(Generic Switch), 1 Channels(Dimmable Light) [0x2004] = { is_climate_sensor_w100 = true }, -- Climate Sensor W100, requires unique profile } }