From 11ce7832e4e3be6dc8ab9a9caae7c2c5aa8f974f Mon Sep 17 00:00:00 2001 From: Harrison Carter Date: Tue, 19 May 2026 22:11:54 -0500 Subject: [PATCH 1/2] register setColorTemperature native handler --- .../switch_handlers/capability_handlers.lua | 3 + .../src/test/test_matter_light_fan.lua | 97 ------------------- .../test_matter_multi_button_switch_mcd.lua | 33 ------- .../test/test_matter_on_off_parent_child.lua | 8 ++ .../src/test/test_matter_switch.lua | 24 +++++ 5 files changed, 35 insertions(+), 130 deletions(-) diff --git a/drivers/SmartThings/matter-switch/src/switch_handlers/capability_handlers.lua b/drivers/SmartThings/matter-switch/src/switch_handlers/capability_handlers.lua index 6d035c3dc7..c5a1a728a9 100644 --- a/drivers/SmartThings/matter-switch/src/switch_handlers/capability_handlers.lua +++ b/drivers/SmartThings/matter-switch/src/switch_handlers/capability_handlers.lua @@ -107,6 +107,9 @@ end -- [[ COLOR TEMPERATURE CAPABILITY COMMANDS ]] -- function CapabilityHandlers.handle_set_color_temperature(driver, device, cmd) + if type(device.register_native_capability_cmd_handler) == "function" then + device:register_native_capability_cmd_handler(cmd.capability, cmd.command) + end local endpoint_id = device:component_to_endpoint(cmd.component) local temp_in_kelvin = cmd.args.temperature -- note: the field containing the color temp bounds will be associated with a parent device diff --git a/drivers/SmartThings/matter-switch/src/test/test_matter_light_fan.lua b/drivers/SmartThings/matter-switch/src/test/test_matter_light_fan.lua index 3dad8bf56d..32023a36cb 100644 --- a/drivers/SmartThings/matter-switch/src/test/test_matter_light_fan.lua +++ b/drivers/SmartThings/matter-switch/src/test/test_matter_light_fan.lua @@ -5,11 +5,6 @@ local capabilities = require "st.capabilities" local clusters = require "st.matter.generated.zap_clusters" local t_utils = require "integration_test.utils" local test = require "integration_test" -local version = require "version" - -local TRANSITION_TIME = 0 -local OPTIONS_MASK = 0x01 -local HANDLE_COMMAND_IF_OFF = 0x01 local mock_device_ep1 = 1 local mock_device_ep2 = 2 @@ -173,98 +168,6 @@ test.register_coroutine_test( { test_init = function() test.mock_device.add_test_device(mock_device_capabilities_disabled) end } ) - -test.register_coroutine_test( - "Switch capability should send the appropriate commands", function() - test.socket.capability:__queue_receive( - { - mock_child.id, - { capability = "switch", component = "main", command = "on", args = { } } - } - ) - if version.api >= 11 then - test.socket.devices:__expect_send( - { - "register_native_capability_cmd_handler", - { device_uuid = mock_child.id, capability_id = "switch", capability_cmd_id = "on" } - } - ) - end - test.socket.matter:__expect_send( - { - mock_device.id, - clusters.OnOff.server.commands.On(mock_device, mock_device_ep1) - } - ) - test.socket.matter:__queue_receive( - { - mock_device.id, - clusters.OnOff.attributes.OnOff:build_test_report_data(mock_device, mock_device_ep1, true) - } - ) - test.socket.devices:__expect_send( - { - "register_native_capability_attr_handler", - { device_uuid = mock_device.id, capability_id = "switch", capability_attr_id = "switch" } - } - ) - test.socket.capability:__expect_send( - mock_child:generate_test_message( - "main", capabilities.switch.switch.on() - ) - ) - end, - { - min_api_version = 17 - } -) - -test.register_message_test( - "Set color temperature should send the appropriate commands", - { - { - channel = "capability", - direction = "receive", - message = { - mock_child.id, - { capability = "colorTemperature", component = "main", command = "setColorTemperature", args = {1800} } - } - }, - { - channel = "matter", - direction = "send", - message = { - mock_device.id, - clusters.ColorControl.server.commands.MoveToColorTemperature(mock_device, mock_device_ep1, 556, TRANSITION_TIME, OPTIONS_MASK, HANDLE_COMMAND_IF_OFF) - } - }, - { - channel = "matter", - direction = "receive", - message = { - mock_device.id, - clusters.ColorControl.server.commands.MoveToColorTemperature:build_test_command_response(mock_device, mock_device_ep1) - } - }, - { - channel = "matter", - direction = "receive", - message = { - mock_device.id, - clusters.ColorControl.attributes.ColorTemperatureMireds:build_test_report_data(mock_device, mock_device_ep1, 556) - } - }, - { - channel = "capability", - direction = "send", - message = mock_child:generate_test_message("main", capabilities.colorTemperature.colorTemperature(1800)) - }, - }, - { - min_api_version = 17 - } -) - local FanMode = clusters.FanControl.attributes.FanMode test.register_message_test( "Fan mode reports should generate correct messages", diff --git a/drivers/SmartThings/matter-switch/src/test/test_matter_multi_button_switch_mcd.lua b/drivers/SmartThings/matter-switch/src/test/test_matter_multi_button_switch_mcd.lua index d469f72036..70f9666542 100644 --- a/drivers/SmartThings/matter-switch/src/test/test_matter_multi_button_switch_mcd.lua +++ b/drivers/SmartThings/matter-switch/src/test/test_matter_multi_button_switch_mcd.lua @@ -7,12 +7,8 @@ local t_utils = require "integration_test.utils" local clusters = require "st.matter.generated.zap_clusters" -local TRANSITION_TIME = 0 -local OPTIONS_MASK = 0x01 -local HANDLE_COMMAND_IF_OFF = 0x01 local button_attr = capabilities.button.button - local mock_device_ep1 = 1 local mock_device_ep2 = 2 local mock_device_ep3 = 3 @@ -360,35 +356,6 @@ test.register_coroutine_test( } ) -test.register_coroutine_test( - "Switch child device: Set color temperature should send the appropriate commands", - function() - test.mock_device.add_test_device(mock_child) - test.wait_for_events() - test.socket.capability:__queue_receive({ - mock_child.id, - { capability = "colorTemperature", component = "main", command = "setColorTemperature", args = {1800} } - }) - test.socket.matter:__expect_send({ - mock_device.id, - clusters.ColorControl.server.commands.MoveToColorTemperature(mock_device, mock_device_ep5, 556, TRANSITION_TIME, OPTIONS_MASK, HANDLE_COMMAND_IF_OFF) - }) - test.socket.matter:__queue_receive({ - mock_device.id, - clusters.ColorControl.server.commands.MoveToColorTemperature:build_test_command_response(mock_device, mock_device_ep5) - }) - test.wait_for_events() - test.socket.matter:__queue_receive({ - mock_device.id, - clusters.ColorControl.attributes.ColorTemperatureMireds:build_test_report_data(mock_device, mock_device_ep5, 556) - }) - test.socket.capability:__expect_send(mock_child:generate_test_message("main", capabilities.colorTemperature.colorTemperature(1800))) - end, - { - min_api_version = 17 - } -) - test.register_coroutine_test( "Test MCD configuration not including switch for unsupported switch device type, create child device instead", function() diff --git a/drivers/SmartThings/matter-switch/src/test/test_matter_on_off_parent_child.lua b/drivers/SmartThings/matter-switch/src/test/test_matter_on_off_parent_child.lua index 1531632d24..ff8238a52c 100644 --- a/drivers/SmartThings/matter-switch/src/test/test_matter_on_off_parent_child.lua +++ b/drivers/SmartThings/matter-switch/src/test/test_matter_on_off_parent_child.lua @@ -415,6 +415,14 @@ test.register_message_test( { capability = "colorTemperature", component = "main", command = "setColorTemperature", args = {1800} } } }, + { + channel = "devices", + direction = "send", + message = { + "register_native_capability_cmd_handler", + { device_uuid = mock_children[extended_color_ep_id].id, capability_id = "colorTemperature", capability_cmd_id = "setColorTemperature" } + } + }, { channel = "matter", direction = "send", diff --git a/drivers/SmartThings/matter-switch/src/test/test_matter_switch.lua b/drivers/SmartThings/matter-switch/src/test/test_matter_switch.lua index c34cbb8ed6..c3e472268f 100644 --- a/drivers/SmartThings/matter-switch/src/test/test_matter_switch.lua +++ b/drivers/SmartThings/matter-switch/src/test/test_matter_switch.lua @@ -244,6 +244,14 @@ test.register_message_test( { capability = "colorTemperature", component = "main", command = "setColorTemperature", args = {1800} } } }, + { + channel = "devices", + direction = "send", + message = { + "register_native_capability_cmd_handler", + { device_uuid = mock_device.id, capability_id = "colorTemperature", capability_cmd_id = "setColorTemperature" } + } + }, { channel = "matter", direction = "send", @@ -444,6 +452,14 @@ test.register_message_test( { capability = "colorTemperature", component = "main", command = "setColorTemperature", args = {6100} } } }, + { + channel = "devices", + direction = "send", + message = { + "register_native_capability_cmd_handler", + { device_uuid = mock_device.id, capability_id = "colorTemperature", capability_cmd_id = "setColorTemperature" } + } + }, { channel = "matter", direction = "send", @@ -460,6 +476,14 @@ test.register_message_test( { capability = "colorTemperature", component = "main", command = "setColorTemperature", args = {2700} } } }, + { + channel = "devices", + direction = "send", + message = { + "register_native_capability_cmd_handler", + { device_uuid = mock_device.id, capability_id = "colorTemperature", capability_cmd_id = "setColorTemperature" } + } + }, { channel = "matter", direction = "send", From 87da728952e127f5ec290694968a64f401753083 Mon Sep 17 00:00:00 2001 From: Harrison Carter Date: Wed, 20 May 2026 00:11:51 -0500 Subject: [PATCH 2/2] rename field for clarity, un-persist value to match native handler expectation --- .../src/switch_handlers/attribute_handlers.lua | 10 +++++----- .../src/switch_handlers/capability_handlers.lua | 2 +- .../matter-switch/src/switch_utils/fields.lua | 3 ++- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/SmartThings/matter-switch/src/switch_handlers/attribute_handlers.lua b/drivers/SmartThings/matter-switch/src/switch_handlers/attribute_handlers.lua index 0fdc9cc822..838f932d86 100644 --- a/drivers/SmartThings/matter-switch/src/switch_handlers/attribute_handlers.lua +++ b/drivers/SmartThings/matter-switch/src/switch_handlers/attribute_handlers.lua @@ -128,12 +128,12 @@ function AttributeHandlers.color_temperature_mireds_handler(driver, device, ib, if device:get_field(fields.IS_PARENT_CHILD_DEVICE) == true then temp_device = switch_utils.find_child(device, ib.endpoint_id) or device end - local most_recent_temp = temp_device:get_field(fields.MOST_RECENT_TEMP) + local latest_requested_kelvin = temp_device:get_field(fields.LATEST_REQUESTED_KELVIN) -- this is to avoid rounding errors from the round-trip conversion of Kelvin to mireds - if most_recent_temp ~= nil and - most_recent_temp <= st_utils.round(fields.MIRED_KELVIN_CONVERSION_CONSTANT/(temp_in_mired - 1)) and - most_recent_temp >= st_utils.round(fields.MIRED_KELVIN_CONVERSION_CONSTANT/(temp_in_mired + 1)) then - temp = most_recent_temp + if latest_requested_kelvin and + latest_requested_kelvin <= st_utils.round(fields.MIRED_KELVIN_CONVERSION_CONSTANT/(temp_in_mired - 1)) and + latest_requested_kelvin >= st_utils.round(fields.MIRED_KELVIN_CONVERSION_CONSTANT/(temp_in_mired + 1)) then + temp = latest_requested_kelvin end device:emit_event_for_endpoint(ib.endpoint_id, capabilities.colorTemperature.colorTemperature(temp)) end diff --git a/drivers/SmartThings/matter-switch/src/switch_handlers/capability_handlers.lua b/drivers/SmartThings/matter-switch/src/switch_handlers/capability_handlers.lua index c5a1a728a9..573d2b791b 100644 --- a/drivers/SmartThings/matter-switch/src/switch_handlers/capability_handlers.lua +++ b/drivers/SmartThings/matter-switch/src/switch_handlers/capability_handlers.lua @@ -124,7 +124,7 @@ function CapabilityHandlers.handle_set_color_temperature(driver, device, cmd) temp_in_mired = switch_utils.get_field_for_endpoint(field_device, fields.COLOR_TEMP_BOUND_RECEIVED_MIRED..fields.COLOR_TEMP_MIN, endpoint_id) end local req = clusters.ColorControl.server.commands.MoveToColorTemperature(device, endpoint_id, temp_in_mired, fields.ZERO_TRANSITION_TIME, fields.OPTIONS_MASK, fields.HANDLE_COMMAND_IF_OFF) - device:set_field(fields.MOST_RECENT_TEMP, cmd.args.temperature, {persist = true}) + device:set_field(fields.LATEST_REQUESTED_KELVIN, cmd.args.temperature) device:send(req) end diff --git a/drivers/SmartThings/matter-switch/src/switch_utils/fields.lua b/drivers/SmartThings/matter-switch/src/switch_utils/fields.lua index a8749a6480..f70a7e2160 100644 --- a/drivers/SmartThings/matter-switch/src/switch_utils/fields.lua +++ b/drivers/SmartThings/matter-switch/src/switch_utils/fields.lua @@ -5,7 +5,7 @@ local clusters = require "st.matter.clusters" local SwitchFields = {} -SwitchFields.MOST_RECENT_TEMP = "mostRecentTemp" +SwitchFields.LATEST_REQUESTED_KELVIN = "mostRecentTemp" SwitchFields.RECEIVED_X = "receivedX" SwitchFields.RECEIVED_Y = "receivedY" SwitchFields.HUESAT_SUPPORT = "huesatSupport" @@ -100,6 +100,7 @@ SwitchFields.updated_fields = { { current_field_name = "__energy_management_endpoint", updated_field_name = nil }, { current_field_name = "__total_imported_energy", updated_field_name = nil }, { current_field_name = "__last_imported_report_timestamp", updated_field_name = nil }, + { current_field_name = "mostRecentTemp", updated_field_name = nil }, } SwitchFields.vendor_overrides = {