From d53f57cd260598a83de56adc2ed25a1cec96553c Mon Sep 17 00:00:00 2001 From: "Jan Jakubiszyn/SmartThings Integrations (BJ.jakubiszynS) /SRPOL/Engineer/Samsung Electronics" Date: Fri, 19 Dec 2025 16:20:20 +0100 Subject: [PATCH] Adding attribute reading after Offset preference change for instant update --- .../SmartThings/matter-switch/src/init.lua | 12 ++ .../test_matter_sensor_offset_preferences.lua | 123 ++++++++++++++++++ 2 files changed, 135 insertions(+) create mode 100644 drivers/SmartThings/matter-switch/src/test/test_matter_sensor_offset_preferences.lua diff --git a/drivers/SmartThings/matter-switch/src/init.lua b/drivers/SmartThings/matter-switch/src/init.lua index 6655f81e56..0bb9d57ab5 100644 --- a/drivers/SmartThings/matter-switch/src/init.lua +++ b/drivers/SmartThings/matter-switch/src/init.lua @@ -81,6 +81,18 @@ function SwitchLifecycleHandlers.info_changed(driver, device, event, args) device_cfg.match_profile(driver, device) end end + + -- instant update of values after offset preference change + for name, info in pairs(device.preferences or {}) do + if (device.preferences[name] ~= nil and args.old_st_store.preferences[name] ~= nil and args.old_st_store.preferences[name] ~= device.preferences[name]) then + if name == "tempOffset" then + device:send(clusters.TemperatureMeasurement.attributes.MeasuredValue:read(device)) + elseif name == "humidityOffset" then + device:send(clusters.RelativeHumidityMeasurement.attributes.MeasuredValue:read(device)) + end + end + end + end function SwitchLifecycleHandlers.device_init(driver, device) diff --git a/drivers/SmartThings/matter-switch/src/test/test_matter_sensor_offset_preferences.lua b/drivers/SmartThings/matter-switch/src/test/test_matter_sensor_offset_preferences.lua new file mode 100644 index 0000000000..de2afe3bd3 --- /dev/null +++ b/drivers/SmartThings/matter-switch/src/test/test_matter_sensor_offset_preferences.lua @@ -0,0 +1,123 @@ +local test = require "integration_test" +local capabilities = require "st.capabilities" +local t_utils = require "integration_test.utils" +local utils = require "st.utils" +local dkjson = require "dkjson" +local clusters = require "st.matter.clusters" + +local mock_device = test.mock_device.build_test_matter_device({ + profile = t_utils.get_profile_definition("3-button-battery-temperature-humidity.yml"), + matter_version = {hardware = 1, software = 1}, + manufacturer_info = { + vendor_id = 0x0000, + product_id = 0x0000, + }, + endpoints = { + { + endpoint_id = 1, + clusters = { + {cluster_id = clusters.TemperatureMeasurement.ID, cluster_type = "SERVER"}, + }, + device_types = { + {device_type_id = 0x0302, device_type_revision = 1}, + } + }, + { + endpoint_id = 2, + clusters = { + {cluster_id = clusters.RelativeHumidityMeasurement.ID, cluster_type = "BOTH"}, + }, + device_types = { + {device_type_id = 0x0307, device_type_revision = 1}, + } + }, + } +}) + +local function test_init() + test.disable_startup_messages() + test.mock_device.add_test_device(mock_device) + + local cluster_subscribe_list = { + clusters.Switch.events.InitialPress, + clusters.Switch.events.LongPress, + clusters.Switch.events.ShortRelease, + clusters.Switch.events.MultiPressComplete, + + clusters.TemperatureMeasurement.attributes.MeasuredValue, + clusters.TemperatureMeasurement.attributes.MinMeasuredValue, + clusters.TemperatureMeasurement.attributes.MaxMeasuredValue, + + clusters.RelativeHumidityMeasurement.attributes.MeasuredValue, + clusters.PowerSource.attributes.BatPercentRemaining + } + + local subscribe_request = cluster_subscribe_list[1]:subscribe(mock_device) + for i, cluster in ipairs(cluster_subscribe_list) do + if i > 1 then + subscribe_request:merge(cluster:subscribe(mock_device)) + end + end + + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "added" }) + test.socket.matter:__expect_send({mock_device.id, subscribe_request}) + + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "init" }) + test.socket.matter:__expect_send({mock_device.id, subscribe_request}) + + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "doConfigure" }) + test.socket.matter:__expect_send({mock_device.id, subscribe_request}) + + mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" }) + + local device_info_copy = utils.deep_copy(mock_device.raw_st_data) + device_info_copy.profile.id = "3-button-battery-temperature-humidity" + local device_info_json = dkjson.encode(device_info_copy) + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "infoChanged", device_info_json}) + test.socket.matter:__expect_send({mock_device.id, subscribe_request}) + +end + +test.register_coroutine_test("Read appropriate attribute values after tempOffset preference change", function() + local report = clusters.TemperatureMeasurement.attributes.MeasuredValue:build_test_report_data(mock_device,1, 2000) + mock_device.st_store.preferences = {tempOffset = "0"} + + test.socket.matter:__queue_receive({mock_device.id, report}) + test.socket.capability:__expect_send(mock_device:generate_test_message("main",capabilities.temperatureMeasurement.temperature({ + value = 20.0, + unit = "C" + }))) + test.socket.device_lifecycle():__queue_receive(mock_device:generate_info_changed({preferences = {tempOffset = "5"}})) + test.socket.matter:__expect_send({mock_device.id, clusters.TemperatureMeasurement.attributes.MeasuredValue:read(mock_device)}) + + test.wait_for_events() + + test.socket.matter:__queue_receive({mock_device.id, report}) + test.socket.capability:__expect_send(mock_device:generate_test_message("main",capabilities.temperatureMeasurement.temperature({ + value = 20.0, + unit = "C" + }))) +end) + +test.register_coroutine_test("Read appropriate attribute values after humidityOffset preference change", function() + local report = clusters.RelativeHumidityMeasurement.attributes.MeasuredValue:build_test_report_data(mock_device,2, 2000) + mock_device.st_store.preferences = {humidityOffset = "0"} + + test.socket.matter:__queue_receive({mock_device.id, report}) + test.socket.capability:__expect_send(mock_device:generate_test_message("main",capabilities.relativeHumidityMeasurement.humidity({ + value = 20 + }))) + test.socket.device_lifecycle():__queue_receive(mock_device:generate_info_changed({preferences = {humidityOffset = "5"}})) + test.socket.matter:__expect_send({mock_device.id, clusters.RelativeHumidityMeasurement.attributes.MeasuredValue:read(mock_device)}) + + test.wait_for_events() + + test.socket.matter:__queue_receive({mock_device.id, report}) + test.socket.capability:__expect_send(mock_device:generate_test_message("main",capabilities.relativeHumidityMeasurement.humidity({ + value = 20 + }))) +end) + +test.set_test_init_function(test_init) + +test.run_registered_tests()