Skip to content

Update matter window covering edge driver#3052

Open
hongye-samsung wants to merge 1 commit into
SmartThingsCommunity:mainfrom
hongye-samsung:matter_blind
Open

Update matter window covering edge driver#3052
hongye-samsung wants to merge 1 commit into
SmartThingsCommunity:mainfrom
hongye-samsung:matter_blind

Conversation

@hongye-samsung

Copy link
Copy Markdown

Check all that apply

Type of Change

  • WWST Certification Request
    • If this is your first time contributing code:
      • I have reviewed the README.md file
      • I have reviewed the CODE_OF_CONDUCT.md file
      • I have signed the CLA
    • I plan on entering a WWST Certification Request or have entered a request through the WWST Certification console at developer.smartthings.com
  • Bug fix
  • New feature
  • Refactor

Checklist

  • I have performed a self-review of my code
  • I have commented my code in hard-to-understand areas
  • I have verified my changes by testing with a device or have communicated a plan for testing
  • I am adding new behavior, such as adding a sub-driver, and have added and run new unit tests to cover the new behavior

Description of Change

Summary of Completed Tests

@hongye-samsung hongye-samsung marked this pull request as draft June 26, 2026 02:08
@hongye-samsung hongye-samsung force-pushed the matter_blind branch 3 times, most recently from 571f3d8 to efdf5b3 Compare June 26, 2026 08:35
@hongye-samsung hongye-samsung marked this pull request as ready for review June 29, 2026 04:56
@vangoran

Copy link
Copy Markdown

Edge driver development for R2 new feature (https://smartthings.atlassian.net/browse/CHAD-18661)

Signed-off-by: Hong Ye/MDE Lab /SRC-Nanjing/Staff Engineer/Samsung Electronics <hong.ye@samsung.com>
@hongye-samsung

Copy link
Copy Markdown
Author

@hcarter-775 hcarter-775 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like the new fields may be unnecessary, and may be adding some unnecessary complexity

[capabilities.windowShadeLevel.commands.setShadeLevel.NAME] = handle_shade_level,
},
[capabilities.statelessWindowShadeLevelStep.ID] = {
[capabilities.statelessWindowShadeLevelStep.commands.stepShadeLevel.NAME] = window_shade_step_level_cmd

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
[capabilities.statelessWindowShadeLevelStep.commands.stepShadeLevel.NAME] = window_shade_step_level_cmd
[capabilities.statelessWindowShadeLevelStep.commands.stepShadeLevel.NAME] = handle_step_shade_level

let's keep the same language consistency


local matter_driver = MatterDriver("matter-window-covering", matter_driver_template)
matter_driver:run()
matter_driver:run() No newline at end of file

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we shouldn't remove the newline


-- capability handlers
local function handle_preset(driver, device, cmd)
device:set_field(LATEST_TARGET_LEVEL, nil)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why are we setting this to nil in every handler?

Comment on lines +199 to +202
local target_level = current_level + step
if target_level > 100 then target_level = 100
elseif target_level < 0 then target_level = 0
end

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
local target_level = current_level + step
if target_level > 100 then target_level = 100
elseif target_level < 0 then target_level = 0
end
local target_level = st_utils.clamp_value(current_level + step, 0, 100)

and then you can do local st_utils = require "st.utils" at the top of the file.

Comment on lines +220 to +222
-- Matter uses inverted logic (like IKEA)
-- User level: 0=closed, 100=open
-- Matter level: 10000=open, 0=closed (in percent100ths)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove this comment

Comment on lines +223 to +230
local lift_percentage_value = 100 - target_level
local hundredths_lift_percentage = lift_percentage_value * 100

local endpoint_id = device:component_to_endpoint(cmd.component)
local req = clusters.WindowCovering.server.commands.GoToLiftPercentage(
device, endpoint_id, hundredths_lift_percentage
)
device:send(req)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we need to handle the case where the device is in the reverse mode

end

-- Update tracking state
device:set_field(LATEST_TARGET_LEVEL, target_level)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we even need this field? What purpose is it really serving here?

Comment on lines +253 to +266
-- Step control logic
local target_level_field = device:get_field(LATEST_TARGET_LEVEL)
if target_level_field and attribute == capabilities.windowShadeLevel.shadeLevel then
-- Allow ±1 degree tolerance for reaching target
if math.abs(position - target_level_field) <= TARGET_REACH_TOLERANCE then
-- Device reached target position, clear target marker and timeout timer
device:set_field(LATEST_TARGET_LEVEL, nil)
local timer = device:get_field(TARGET_LEVEL_TIME_OUT)
if timer ~= nil then
device.thread:cancel_timer(timer)
device:set_field(TARGET_LEVEL_TIME_OUT, nil)
end
end
end

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think I understand why this is useful. The command will send the device here anyway? This just removes the field without changing anything as far as I can see

device.thread:cancel_timer(timer)
device:set_field(TARGET_LEVEL_TIME_OUT, nil)
end
end

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see why this is needed. kinda repeating myself here, but I'm not really sure what this logic is gaining for us.

version: 1
- id: windowShadeTiltLevel
version: 1
- id: statelessWindowShadeLevelStep

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My initial thought is we'd only add the new capability to profiles that have the windowShadeLevel capability, and so it shouldn't be added to all these profiles that have windowShadeTiltLevel and not windowShadeLevel. In other words, we wouldn't support the stateless step commands on shades that only support tilt. If we want to do that in the future we should add a statelessWindowShadeTiltStep capability, but that isn't in scope for the current project.

Comment on lines +13 to +14
- id: statelessWindowShadeLevelStep
version: 1

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I might recommend moving the statelessWindowShadeLevelStep capability just below the windowShadeLevel capability in all cases, for consistency. A few of these profile updates have the new capability in different spots.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants