-
Notifications
You must be signed in to change notification settings - Fork 524
Matter Switch: Include Ikea subdriver support for knob capability #2678
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
48d592b
3b6f11f
93f2cf4
788d543
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,58 @@ | ||
| -- Copyright © 2025 SmartThings, Inc. | ||
| -- Licensed under the Apache License, Version 2.0 | ||
|
|
||
| local st_utils = require "st.utils" | ||
| local capabilities = require "st.capabilities" | ||
| local switch_utils = require "switch_utils.utils" | ||
| local generic_event_handlers = require "switch_handlers.event_handlers" | ||
| local scroll_fields = require "sub_drivers.ikea_scroll.scroll_utils.fields" | ||
|
|
||
| local IkeaScrollEventHandlers = {} | ||
|
|
||
| local function rotate_amount_event_helper(device, endpoint_id, num_presses_to_handle) | ||
| -- to cut down on checks, we can assume that if the endpoint is not in ENDPOINTS_UP_SCROLL, it is in ENDPOINTS_DOWN_SCROLL | ||
| local scroll_direction = switch_utils.tbl_contains(scroll_fields.ENDPOINTS_UP_SCROLL, endpoint_id) and 1 or -1 | ||
| local scroll_amount = st_utils.clamp_value(scroll_direction * scroll_fields.PER_SCROLL_EVENT_ROTATION * num_presses_to_handle, -100, 100) | ||
| device:emit_event_for_endpoint(endpoint_id, capabilities.knob.rotateAmount(scroll_amount, {state_change = true})) | ||
| end | ||
|
|
||
| -- Used by ENDPOINTS_UP_SCROLL and ENDPOINTS_DOWN_SCROLL, not ENDPOINTS_PUSH | ||
| function IkeaScrollEventHandlers.multi_press_ongoing_handler(driver, device, ib, response) | ||
| if switch_utils.tbl_contains(scroll_fields.ENDPOINTS_PUSH, ib.endpoint_id) then | ||
| -- Ignore MultiPressOngoing events from push endpoints. | ||
| device.log.debug("Received MultiPressOngoing event from push endpoint, ignoring.") | ||
| else | ||
| local cur_num_presses_counted = ib.data and ib.data.elements and ib.data.elements.current_number_of_presses_counted.value or 0 | ||
| local num_presses_to_handle = cur_num_presses_counted - (device:get_field(scroll_fields.LATEST_NUMBER_OF_PRESSES_COUNTED) or 0) | ||
| if num_presses_to_handle > 0 then | ||
| device:set_field(scroll_fields.LATEST_NUMBER_OF_PRESSES_COUNTED, cur_num_presses_counted) | ||
| rotate_amount_event_helper(device, ib.endpoint_id, num_presses_to_handle) | ||
| end | ||
| end | ||
| end | ||
|
|
||
| function IkeaScrollEventHandlers.multi_press_complete_handler(driver, device, ib, response) | ||
| if switch_utils.tbl_contains(scroll_fields.ENDPOINTS_PUSH, ib.endpoint_id) then | ||
| generic_event_handlers.multi_press_complete_handler(driver, device, ib, response) | ||
| else | ||
| local total_num_presses_counted = ib.data and ib.data.elements and ib.data.elements.total_number_of_presses_counted.value or 0 | ||
| local num_presses_to_handle = total_num_presses_counted - (device:get_field(scroll_fields.LATEST_NUMBER_OF_PRESSES_COUNTED) or 0) | ||
| if num_presses_to_handle > 0 then | ||
| rotate_amount_event_helper(device, ib.endpoint_id, num_presses_to_handle) | ||
| end | ||
| -- reset the LATEST_NUMBER_OF_PRESSES_COUNTED to nil at the end of a MultiPress chain. | ||
| device:set_field(scroll_fields.LATEST_NUMBER_OF_PRESSES_COUNTED, nil) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I may have missed this during prior reviews, but I think we need to be looking at the
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That might be a nice check, though per spec and in all testing I've done, the final MultiPressOngoing event should be equivalent to the last MultiPressComplete event.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. added!
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was thinking it could report a different number, but on re-review of the spec I think you're correct that the values reported should be equivalent and since we're using the
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You were fast! I think it's also fine to leave this change in now that you made it, shouldn't hurt anything. |
||
| end | ||
| end | ||
|
|
||
| function IkeaScrollEventHandlers.initial_press_handler(driver, device, ib, response) | ||
| if switch_utils.tbl_contains(scroll_fields.ENDPOINTS_PUSH, ib.endpoint_id) then | ||
| generic_event_handlers.initial_press_handler(driver, device, ib, response) | ||
| else | ||
| -- Ignore InitialPress events from non-push endpoints. Presently, we want to solely | ||
| -- rely on MultiPressOngoing events to handle rotation for those endpoints. | ||
| device.log.debug("Received InitialPress event from scroll endpoint, ignoring.") | ||
| end | ||
| end | ||
|
|
||
| return IkeaScrollEventHandlers | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,21 +1,44 @@ | ||
| -- Copyright © 2025 SmartThings, Inc. | ||
| -- Licensed under the Apache License, Version 2.0 | ||
|
|
||
| local st_utils = require "st.utils" | ||
| 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} | ||
| -- Generic Switch Endpoints used for basic push functionality | ||
| IkeaScrollFields.ENDPOINTS_PUSH = {3, 6, 9} | ||
|
|
||
| -- Required Events for the ENDPOINTS_PRESS. | ||
| -- Generic Switch Endpoints used for Up Scroll functionality | ||
| IkeaScrollFields.ENDPOINTS_UP_SCROLL = {1, 4, 7} | ||
|
|
||
| -- Generic Switch Endpoints used for Down Scroll functionality | ||
| IkeaScrollFields.ENDPOINTS_DOWN_SCROLL = {2, 5, 8} | ||
|
|
||
| -- Maximum number of presses at a time | ||
| IkeaScrollFields.MAX_SCROLL_PRESSES = 18 | ||
|
|
||
| -- Amount to rotate per scroll event | ||
| IkeaScrollFields.PER_SCROLL_EVENT_ROTATION = st_utils.round(1 / IkeaScrollFields.MAX_SCROLL_PRESSES * 100) | ||
|
|
||
| -- Field to track the latest number of presses counted during a single scroll event sequence | ||
| IkeaScrollFields.LATEST_NUMBER_OF_PRESSES_COUNTED = "__latest_number_of_presses_counted" | ||
|
|
||
| -- Required Events for the ENDPOINTS_PUSH. | ||
| IkeaScrollFields.switch_press_subscribed_events = { | ||
| clusters.Switch.events.InitialPress.ID, | ||
| clusters.Switch.events.MultiPressComplete.ID, | ||
| clusters.Switch.events.LongPress.ID, | ||
| } | ||
|
|
||
| -- Required Events for the ENDPOINTS_UP_SCROLL and ENDPOINTS_DOWN_SCROLL. Adds a | ||
| -- MultiPressOngoing subscription to handle step functionality in real-time | ||
| IkeaScrollFields.switch_scroll_subscribed_events = { | ||
| clusters.Switch.events.MultiPressOngoing.ID, | ||
| clusters.Switch.events.MultiPressComplete.ID, | ||
| } | ||
|
|
||
| return IkeaScrollFields |
Uh oh!
There was an error while loading. Please reload this page.