Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions drivers/SmartThings/matter-switch/profiles/ikea-scroll.yml
Original file line number Diff line number Diff line change
@@ -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
1 change: 1 addition & 0 deletions drivers/SmartThings/matter-switch/src/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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")
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
-- Copyright © 2025 SmartThings, Inc.
-- Licensed under the Apache License, Version 2.0

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,
}

return IkeaScrollFields
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
-- 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
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

return IkeaScrollUtils
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down
Loading
Loading