From 397ba7086f19c3d1480fba54dcde70a740da5662 Mon Sep 17 00:00:00 2001 From: Harrison Carter Date: Fri, 31 Oct 2025 17:52:31 -0500 Subject: [PATCH 1/4] Bilresa Support --- .../matter-switch/profiles/ikea-scroll.yml | 33 +++ .../SmartThings/matter-switch/src/init.lua | 1 + .../src/sub_drivers/ikea_scroll/init.lua | 51 ++++ .../scroll_utils/device_configuration.lua | 25 ++ .../ikea_scroll/scroll_utils/fields.lua | 15 ++ .../ikea_scroll/scroll_utils/utils.lua | 28 +++ .../matter-switch/src/switch_utils/fields.lua | 7 +- .../src/test/test_ikea_scroll.lua | 228 ++++++++++++++++++ 8 files changed, 387 insertions(+), 1 deletion(-) create mode 100644 drivers/SmartThings/matter-switch/profiles/ikea-scroll.yml create mode 100644 drivers/SmartThings/matter-switch/src/sub_drivers/ikea_scroll/init.lua create mode 100644 drivers/SmartThings/matter-switch/src/sub_drivers/ikea_scroll/scroll_utils/device_configuration.lua create mode 100644 drivers/SmartThings/matter-switch/src/sub_drivers/ikea_scroll/scroll_utils/fields.lua create mode 100644 drivers/SmartThings/matter-switch/src/sub_drivers/ikea_scroll/scroll_utils/utils.lua create mode 100644 drivers/SmartThings/matter-switch/src/test/test_ikea_scroll.lua diff --git a/drivers/SmartThings/matter-switch/profiles/ikea-scroll.yml b/drivers/SmartThings/matter-switch/profiles/ikea-scroll.yml new file mode 100644 index 0000000000..98486f9c4f --- /dev/null +++ b/drivers/SmartThings/matter-switch/profiles/ikea-scroll.yml @@ -0,0 +1,33 @@ +name: ikea-scroll +components: + - id: main + capabilities: + - id: battery + version: 1 + - id: firmwareUpdate + version: 1 + - id: refresh + version: 1 + categories: + - name: RemoteController + - id: group1 + label: Group 1 + capabilities: + - id: button + version: 1 + categories: + - name: RemoteController + - id: group2 + label: Group 2 + capabilities: + - id: button + version: 1 + categories: + - name: RemoteController + - id: group3 + label: Group 3 + capabilities: + - id: button + version: 1 + categories: + - name: RemoteController diff --git a/drivers/SmartThings/matter-switch/src/init.lua b/drivers/SmartThings/matter-switch/src/init.lua index ec3c5df9ba..c3c3a361cd 100644 --- a/drivers/SmartThings/matter-switch/src/init.lua +++ b/drivers/SmartThings/matter-switch/src/init.lua @@ -299,6 +299,7 @@ local matter_driver_template = { require("sub_drivers.aqara_cube"), switch_utils.lazy_load("sub_drivers.camera"), require("sub_drivers.eve_energy"), + require("sub_drivers.ikea_scroll"), require("sub_drivers.third_reality_mk1") } } diff --git a/drivers/SmartThings/matter-switch/src/sub_drivers/ikea_scroll/init.lua b/drivers/SmartThings/matter-switch/src/sub_drivers/ikea_scroll/init.lua new file mode 100644 index 0000000000..83f2e9fb31 --- /dev/null +++ b/drivers/SmartThings/matter-switch/src/sub_drivers/ikea_scroll/init.lua @@ -0,0 +1,51 @@ +-- Copyright © 2025 SmartThings, Inc. +-- Licensed under the Apache License, Version 2.0 + +local switch_utils = require "switch_utils.utils" +local button_cfg = require "switch_utils.device_configuration".ButtonCfg +local scroll_utils = require "sub_drivers.ikea_scroll.scroll_utils.utils" +local scroll_cfg = require "sub_drivers.ikea_scroll.scroll_utils.device_configuration" + +local IkeaScrollLifecycleHandlers = {} + +-- prevent main driver device_added handling from running +function IkeaScrollLifecycleHandlers.device_added(driver, device) +end + +function IkeaScrollLifecycleHandlers.device_init(driver, device) + device:set_endpoint_to_component_fn(switch_utils.endpoint_to_component) + device:extend_device("subscribe", scroll_utils.subscribe) + device:subscribe() +end + +function IkeaScrollLifecycleHandlers.do_configure(driver, device) + scroll_cfg.match_profile(driver, device) +end + +function IkeaScrollLifecycleHandlers.driver_switched(driver, device) + scroll_cfg.match_profile(driver, device) +end + +function IkeaScrollLifecycleHandlers.info_changed(driver, device, event, args) + if device.profile.id ~= args.old_st_store.profile.id then + button_cfg.configure_buttons(device) + device:subscribe() + end +end + + +-- DEVICE TEMPLATE -- + +local ikea_scroll_handler = { + NAME = "Ikea Scroll Handler", + lifecycle_handlers = { + added = IkeaScrollLifecycleHandlers.device_added, + doConfigure = IkeaScrollLifecycleHandlers.do_configure, + driverSwitched = IkeaScrollLifecycleHandlers.driver_switched, + infoChanged = IkeaScrollLifecycleHandlers.info_changed, + init = IkeaScrollLifecycleHandlers.device_init, + }, + can_handle = scroll_utils.is_ikea_scroll +} + +return ikea_scroll_handler diff --git a/drivers/SmartThings/matter-switch/src/sub_drivers/ikea_scroll/scroll_utils/device_configuration.lua b/drivers/SmartThings/matter-switch/src/sub_drivers/ikea_scroll/scroll_utils/device_configuration.lua new file mode 100644 index 0000000000..0cf2ec9fbe --- /dev/null +++ b/drivers/SmartThings/matter-switch/src/sub_drivers/ikea_scroll/scroll_utils/device_configuration.lua @@ -0,0 +1,25 @@ +-- Copyright © 2025 SmartThings, Inc. +-- Licensed under the Apache License, Version 2.0 + +local button_cfg = require "switch_utils.device_configuration".ButtonCfg +local switch_fields = require "switch_utils.fields" +local scroll_fields = require "sub_drivers.ikea_scroll.scroll_utils.fields" + +local IkeaScrollConfiguration = {} + +function IkeaScrollConfiguration.build_button_component_map(device) + local component_map = { + group1 = scroll_fields.ENDPOINTS_PRESS[1], + group2 = scroll_fields.ENDPOINTS_PRESS[2], + group3 = scroll_fields.ENDPOINTS_PRESS[3], + } + device:set_field(switch_fields.COMPONENT_TO_ENDPOINT_MAP, component_map, {persist = true}) +end + +function IkeaScrollConfiguration.match_profile(driver, device) + device:try_update_metadata({profile = "ikea-scroll"}) + IkeaScrollConfiguration.build_button_component_map(device) + button_cfg.configure_buttons(device) +end + +return IkeaScrollConfiguration diff --git a/drivers/SmartThings/matter-switch/src/sub_drivers/ikea_scroll/scroll_utils/fields.lua b/drivers/SmartThings/matter-switch/src/sub_drivers/ikea_scroll/scroll_utils/fields.lua new file mode 100644 index 0000000000..18dcc7aa44 --- /dev/null +++ b/drivers/SmartThings/matter-switch/src/sub_drivers/ikea_scroll/scroll_utils/fields.lua @@ -0,0 +1,15 @@ +-- Copyright © 2025 SmartThings, Inc. +-- Licensed under the Apache License, Version 2.0 + +local clusters = require "st.matter.clusters" + +local IkeaScrollFields = {} + +IkeaScrollFields.ENDPOINTS_PRESS = {3, 6, 9} + +IkeaScrollFields.switch_press_subscribed_events = { + clusters.Switch.events.MultiPressComplete.ID, + clusters.Switch.events.LongPress.ID, +} + +return IkeaScrollFields diff --git a/drivers/SmartThings/matter-switch/src/sub_drivers/ikea_scroll/scroll_utils/utils.lua b/drivers/SmartThings/matter-switch/src/sub_drivers/ikea_scroll/scroll_utils/utils.lua new file mode 100644 index 0000000000..7d5a660a34 --- /dev/null +++ b/drivers/SmartThings/matter-switch/src/sub_drivers/ikea_scroll/scroll_utils/utils.lua @@ -0,0 +1,28 @@ +-- Copyright © 2025 SmartThings, Inc. +-- Licensed under the Apache License, Version 2.0 + +local im = require "st.matter.interaction_model" +local clusters = require "st.matter.clusters" +local switch_utils = require "switch_utils.utils" +local scroll_fields = require "sub_drivers.ikea_scroll.scroll_utils.fields" + +local IkeaScrollUtils = {} + +function IkeaScrollUtils.is_ikea_scroll(opts, driver, device) + return switch_utils.get_product_override_field(device, "is_ikea_scroll") +end + +-- override subscribe function to prevent subscribing to additional events from the main driver +function IkeaScrollUtils.subscribe(device) + local subscribe_request = im.InteractionRequest(im.InteractionRequest.RequestType.SUBSCRIBE, {}) + for _, ep_press in ipairs(scroll_fields.ENDPOINTS_PRESS) do + for _, switch_event in ipairs(scroll_fields.switch_press_subscribed_events) do + print("##", ep_press) + local ib = im.InteractionInfoBlock(ep_press, clusters.Switch.ID, nil, switch_event) + subscribe_request:with_info_block(ib) + end + end + device:send(subscribe_request) +end + +return IkeaScrollUtils \ No newline at end of file diff --git a/drivers/SmartThings/matter-switch/src/switch_utils/fields.lua b/drivers/SmartThings/matter-switch/src/switch_utils/fields.lua index 3a0bdc9fdb..68a4876478 100644 --- a/drivers/SmartThings/matter-switch/src/switch_utils/fields.lua +++ b/drivers/SmartThings/matter-switch/src/switch_utils/fields.lua @@ -117,7 +117,10 @@ SwitchFields.vendor_overrides = { [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 - } + }, + [0x117C] = { -- IKEA_MANUFACTURER_ID + [0x8000] = { is_ikea_scroll = true } + }, } SwitchFields.switch_category_vendor_overrides = { @@ -163,6 +166,8 @@ SwitchFields.STATIC_BUTTON_PROFILE_SUPPORTED = {1, 2, 3, 4, 5, 6, 7, 8, 9} -- to tell the driver to ignore MultiPressComplete if it is received after a long press to avoid this extra event. SwitchFields.IGNORE_NEXT_MPC = "__ignore_next_mpc" +SwitchFields.MP_ONGOING = "__multipress_ongoing" + -- These are essentially storing the supported features of a given endpoint -- TODO: add an is_feature_supported_for_endpoint function to matter.device that takes an endpoint SwitchFields.EMULATE_HELD = "__emulate_held" -- for non-MSR (MomentarySwitchRelease) devices we can emulate this on the software side diff --git a/drivers/SmartThings/matter-switch/src/test/test_ikea_scroll.lua b/drivers/SmartThings/matter-switch/src/test/test_ikea_scroll.lua new file mode 100644 index 0000000000..b3603a2c69 --- /dev/null +++ b/drivers/SmartThings/matter-switch/src/test/test_ikea_scroll.lua @@ -0,0 +1,228 @@ +local test = require "integration_test" +local t_utils = require "integration_test.utils" +local capabilities = require "st.capabilities" +local clusters = require "st.matter.clusters" + +local mock_ikea_scroll = test.mock_device.build_test_matter_device({ + profile = t_utils.get_profile_definition("ikea-scroll.yml"), + manufacturer_info = {vendor_id = 0x117C, product_id = 0x8000, product_name = "Ikea Scroll"}, + label = "Ikea Scroll", + 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 = 1, + clusters = {{ + cluster_id = clusters.Switch.ID, + feature_map = + clusters.Switch.types.Feature.MOMENTARY_SWITCH | + clusters.Switch.types.SwitchFeature.MOMENTARY_SWITCH_MULTI_PRESS, + cluster_type = "SERVER" + },}, + device_types = {{device_type_id = 0x000F, device_type_revision = 1}} -- GENERIC SWITCH + }, + { + endpoint_id = 2, + clusters = {{ + cluster_id = clusters.Switch.ID, + feature_map = + clusters.Switch.types.Feature.MOMENTARY_SWITCH | + clusters.Switch.types.SwitchFeature.MOMENTARY_SWITCH_MULTI_PRESS, + cluster_type = "SERVER" + },}, + device_types = {{device_type_id = 0x000F, device_type_revision = 1}} -- GENERIC SWITCH + }, + { + endpoint_id = 3, + clusters = {{ + cluster_id = clusters.Switch.ID, + feature_map = + clusters.Switch.types.SwitchFeature.MOMENTARY_SWITCH | + clusters.Switch.types.SwitchFeature.MOMENTARY_SWITCH_MULTI_PRESS | + clusters.Switch.types.SwitchFeature.MOMENTARY_SWITCH_LONG_PRESS, + cluster_type = "SERVER"}, + }, + device_types = {{device_type_id = 0x000F, device_type_revision = 1}} -- GENERIC SWITCH + }, + { + endpoint_id = 4, + clusters = {{ + cluster_id = clusters.Switch.ID, + feature_map = + clusters.Switch.types.Feature.MOMENTARY_SWITCH | + clusters.Switch.types.SwitchFeature.MOMENTARY_SWITCH_MULTI_PRESS, + cluster_type = "SERVER" + },}, + device_types = {{device_type_id = 0x000F, device_type_revision = 1}} -- GENERIC SWITCH + }, + { + endpoint_id = 5, + clusters = {{ + cluster_id = clusters.Switch.ID, + feature_map = + clusters.Switch.types.Feature.MOMENTARY_SWITCH | + clusters.Switch.types.SwitchFeature.MOMENTARY_SWITCH_MULTI_PRESS, + cluster_type = "SERVER" + },}, + device_types = {{device_type_id = 0x000F, device_type_revision = 1}} -- GENERIC SWITCH + }, + { + endpoint_id = 6, + clusters = {{ + cluster_id = clusters.Switch.ID, + feature_map = + clusters.Switch.types.SwitchFeature.MOMENTARY_SWITCH | + clusters.Switch.types.SwitchFeature.MOMENTARY_SWITCH_MULTI_PRESS | + clusters.Switch.types.SwitchFeature.MOMENTARY_SWITCH_LONG_PRESS, + cluster_type = "SERVER"}, + }, + device_types = {{device_type_id = 0x000F, device_type_revision = 1}} -- GENERIC SWITCH + }, + { + endpoint_id = 7, + clusters = {{ + cluster_id = clusters.Switch.ID, + feature_map = + clusters.Switch.types.Feature.MOMENTARY_SWITCH | + clusters.Switch.types.SwitchFeature.MOMENTARY_SWITCH_MULTI_PRESS, + cluster_type = "SERVER" + },}, + device_types = {{device_type_id = 0x000F, device_type_revision = 1}} -- GENERIC SWITCH + }, + { + endpoint_id = 8, + clusters = {{ + cluster_id = clusters.Switch.ID, + feature_map = + clusters.Switch.types.Feature.MOMENTARY_SWITCH | + clusters.Switch.types.SwitchFeature.MOMENTARY_SWITCH_MULTI_PRESS, + cluster_type = "SERVER" + },}, + device_types = {{device_type_id = 0x000F, device_type_revision = 1}} -- GENERIC SWITCH + }, + { + endpoint_id = 9, + clusters = {{ + cluster_id = clusters.Switch.ID, + feature_map = + clusters.Switch.types.SwitchFeature.MOMENTARY_SWITCH | + clusters.Switch.types.SwitchFeature.MOMENTARY_SWITCH_MULTI_PRESS | + clusters.Switch.types.SwitchFeature.MOMENTARY_SWITCH_LONG_PRESS, + cluster_type = "SERVER"}, + }, + device_types = {{device_type_id = 0x000F, device_type_revision = 1}} -- GENERIC SWITCH + }, + } +}) + +local ENDPOINTS_PRESS = { 3, 6, 9 } + +-- the ikea scroll subdriver has overriden subscribe behavior +local function ikea_scroll_subscribe() + local CLUSTER_SUBSCRIBE_LIST ={ + clusters.Switch.server.events.LongPress, + clusters.Switch.server.events.MultiPressComplete, + } + local subscribe_request = CLUSTER_SUBSCRIBE_LIST[1]:subscribe(mock_ikea_scroll, ENDPOINTS_PRESS[1]) + for _, ep_press in ipairs(ENDPOINTS_PRESS) do + for _, event in ipairs(CLUSTER_SUBSCRIBE_LIST) do + subscribe_request:merge(event:subscribe(mock_ikea_scroll, ep_press)) + end + end + return subscribe_request +end + +local function expect_configure_buttons() + local button_attr = capabilities.button.button + test.socket.matter:__expect_send({mock_ikea_scroll.id, clusters.Switch.attributes.MultiPressMax:read(mock_ikea_scroll, 1)}) + test.socket.matter:__expect_send({mock_ikea_scroll.id, clusters.Switch.attributes.MultiPressMax:read(mock_ikea_scroll, 2)}) + test.socket.matter:__expect_send({mock_ikea_scroll.id, clusters.Switch.attributes.MultiPressMax:read(mock_ikea_scroll, 3)}) + test.socket.capability:__expect_send(mock_ikea_scroll:generate_test_message("group1", button_attr.pushed({state_change = false}))) + test.socket.matter:__expect_send({mock_ikea_scroll.id, clusters.Switch.attributes.MultiPressMax:read(mock_ikea_scroll, 4)}) + test.socket.matter:__expect_send({mock_ikea_scroll.id, clusters.Switch.attributes.MultiPressMax:read(mock_ikea_scroll, 5)}) + test.socket.matter:__expect_send({mock_ikea_scroll.id, clusters.Switch.attributes.MultiPressMax:read(mock_ikea_scroll, 6)}) + test.socket.capability:__expect_send(mock_ikea_scroll:generate_test_message("group2", button_attr.pushed({state_change = false}))) + test.socket.matter:__expect_send({mock_ikea_scroll.id, clusters.Switch.attributes.MultiPressMax:read(mock_ikea_scroll, 7)}) + test.socket.matter:__expect_send({mock_ikea_scroll.id, clusters.Switch.attributes.MultiPressMax:read(mock_ikea_scroll, 8)}) + test.socket.matter:__expect_send({mock_ikea_scroll.id, clusters.Switch.attributes.MultiPressMax:read(mock_ikea_scroll, 9)}) + test.socket.capability:__expect_send(mock_ikea_scroll:generate_test_message("group3", button_attr.pushed({state_change = false}))) +end + +local function test_init() + test.disable_startup_messages() + test.mock_device.add_test_device(mock_ikea_scroll) + local subscribe_request = ikea_scroll_subscribe() + + test.socket.device_lifecycle:__queue_receive({ mock_ikea_scroll.id, "added" }) + + test.socket.device_lifecycle:__queue_receive({ mock_ikea_scroll.id, "init" }) + test.socket.matter:__expect_send({mock_ikea_scroll.id, subscribe_request}) + + mock_ikea_scroll:expect_metadata_update({ profile = "ikea-scroll" }) + mock_ikea_scroll:expect_metadata_update({ provisioning_state = "PROVISIONED" }) + expect_configure_buttons() + test.socket.device_lifecycle:__queue_receive({ mock_ikea_scroll.id, "doConfigure" }) +end +test.set_test_init_function(test_init) + +test.register_message_test( + "Ensure Ikea Scroll Button initialization works as expected", { + { + channel = "matter", + direction = "receive", + message = { + mock_ikea_scroll.id, + clusters.Switch.attributes.MultiPressMax:build_test_report_data( + mock_ikea_scroll, 3, 3 + ) + }, + }, + { + channel = "capability", + direction = "send", + message = mock_ikea_scroll:generate_test_message("group1", + capabilities.button.supportedButtonValues({"pushed", "double", "held", "pushed_3x"}, {visibility = {displayed = false}})) + }, + { + channel = "matter", + direction = "receive", + message = { + mock_ikea_scroll.id, + clusters.Switch.attributes.MultiPressMax:build_test_report_data( + mock_ikea_scroll, 6, 3 + ) + }, + }, + { + channel = "capability", + direction = "send", + message = mock_ikea_scroll:generate_test_message("group2", + capabilities.button.supportedButtonValues({"pushed", "double", "held", "pushed_3x"}, {visibility = {displayed = false}})) + }, + { + channel = "matter", + direction = "receive", + message = { + mock_ikea_scroll.id, + clusters.Switch.attributes.MultiPressMax:build_test_report_data( + mock_ikea_scroll, 9, 3 + ) + }, + }, + { + channel = "capability", + direction = "send", + message = mock_ikea_scroll:generate_test_message("group3", + capabilities.button.supportedButtonValues({"pushed", "double", "held", "pushed_3x"}, {visibility = {displayed = false}})) + }, + } +) + +test.run_registered_tests() \ No newline at end of file From 446457a3e605e67bd2e344c5b5c0d17f706e7162 Mon Sep 17 00:00:00 2001 From: Harrison Carter Date: Mon, 24 Nov 2025 16:02:04 -0600 Subject: [PATCH 2/4] sub_drivers/ --- drivers/SmartThings/matter-switch/src/test/test_ikea_scroll.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/SmartThings/matter-switch/src/test/test_ikea_scroll.lua b/drivers/SmartThings/matter-switch/src/test/test_ikea_scroll.lua index b3603a2c69..2e99e3fca3 100644 --- a/drivers/SmartThings/matter-switch/src/test/test_ikea_scroll.lua +++ b/drivers/SmartThings/matter-switch/src/test/test_ikea_scroll.lua @@ -136,6 +136,7 @@ local function ikea_scroll_subscribe() subscribe_request:merge(event:subscribe(mock_ikea_scroll, ep_press)) end end + subscribe_request:merge(clusters.PowerSource.attributes.BatPercentRemaining:subscribe(mock_ikea_scroll, 0)) return subscribe_request end From a22770a1cfa045e15db24f45ea5f52e17196707d Mon Sep 17 00:00:00 2001 From: Harrison Carter Date: Mon, 24 Nov 2025 16:02:18 -0600 Subject: [PATCH 3/4] add subscription to battery --- .../src/sub_drivers/ikea_scroll/scroll_utils/fields.lua | 5 +++++ .../src/sub_drivers/ikea_scroll/scroll_utils/utils.lua | 5 ++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/SmartThings/matter-switch/src/sub_drivers/ikea_scroll/scroll_utils/fields.lua b/drivers/SmartThings/matter-switch/src/sub_drivers/ikea_scroll/scroll_utils/fields.lua index 18dcc7aa44..b31777ec20 100644 --- a/drivers/SmartThings/matter-switch/src/sub_drivers/ikea_scroll/scroll_utils/fields.lua +++ b/drivers/SmartThings/matter-switch/src/sub_drivers/ikea_scroll/scroll_utils/fields.lua @@ -5,8 +5,13 @@ local clusters = require "st.matter.clusters" local IkeaScrollFields = {} +-- PowerSource supported on Root Node +IkeaScrollFields.ENDPOINT_POWER_SOURCE = 0 + +-- Switch Endpoints used for basic press functionality IkeaScrollFields.ENDPOINTS_PRESS = {3, 6, 9} +-- Required Events for the ENDPOINTS_PRESS. Ignore InitialPress since this slows handling. IkeaScrollFields.switch_press_subscribed_events = { clusters.Switch.events.MultiPressComplete.ID, clusters.Switch.events.LongPress.ID, diff --git a/drivers/SmartThings/matter-switch/src/sub_drivers/ikea_scroll/scroll_utils/utils.lua b/drivers/SmartThings/matter-switch/src/sub_drivers/ikea_scroll/scroll_utils/utils.lua index 7d5a660a34..9be4d8601d 100644 --- a/drivers/SmartThings/matter-switch/src/sub_drivers/ikea_scroll/scroll_utils/utils.lua +++ b/drivers/SmartThings/matter-switch/src/sub_drivers/ikea_scroll/scroll_utils/utils.lua @@ -17,11 +17,14 @@ function IkeaScrollUtils.subscribe(device) local subscribe_request = im.InteractionRequest(im.InteractionRequest.RequestType.SUBSCRIBE, {}) for _, ep_press in ipairs(scroll_fields.ENDPOINTS_PRESS) do for _, switch_event in ipairs(scroll_fields.switch_press_subscribed_events) do - print("##", ep_press) local ib = im.InteractionInfoBlock(ep_press, clusters.Switch.ID, nil, switch_event) subscribe_request:with_info_block(ib) end end + local ib = im.InteractionInfoBlock( + scroll_fields.ENDPOINT_POWER_SOURCE, clusters.PowerSource.ID, clusters.PowerSource.attributes.BatPercentRemaining.ID + ) + subscribe_request:with_info_block(ib) device:send(subscribe_request) end From cde9d4ec4525d40135276a1afc6670824837744f Mon Sep 17 00:00:00 2001 From: Harrison Carter Date: Tue, 25 Nov 2025 19:27:33 -0600 Subject: [PATCH 4/4] remove unused field --- drivers/SmartThings/matter-switch/src/switch_utils/fields.lua | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/SmartThings/matter-switch/src/switch_utils/fields.lua b/drivers/SmartThings/matter-switch/src/switch_utils/fields.lua index 68a4876478..33138fb922 100644 --- a/drivers/SmartThings/matter-switch/src/switch_utils/fields.lua +++ b/drivers/SmartThings/matter-switch/src/switch_utils/fields.lua @@ -166,8 +166,6 @@ SwitchFields.STATIC_BUTTON_PROFILE_SUPPORTED = {1, 2, 3, 4, 5, 6, 7, 8, 9} -- to tell the driver to ignore MultiPressComplete if it is received after a long press to avoid this extra event. SwitchFields.IGNORE_NEXT_MPC = "__ignore_next_mpc" -SwitchFields.MP_ONGOING = "__multipress_ongoing" - -- These are essentially storing the supported features of a given endpoint -- TODO: add an is_feature_supported_for_endpoint function to matter.device that takes an endpoint SwitchFields.EMULATE_HELD = "__emulate_held" -- for non-MSR (MomentarySwitchRelease) devices we can emulate this on the software side