Skip to content

Add step functionality to Zigbee curtains using Common Handler.#3108

Open
zhangshen001 wants to merge 1 commit into
SmartThingsCommunity:mainfrom
zhangshen001:zigbee_V2
Open

Add step functionality to Zigbee curtains using Common Handler.#3108
zhangshen001 wants to merge 1 commit into
SmartThingsCommunity:mainfrom
zhangshen001:zigbee_V2

Conversation

@zhangshen001

@zhangshen001 zhangshen001 commented Jul 9, 2026

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

@CLAassistant

CLAassistant commented Jul 9, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@@ -0,0 +1,16 @@
id: stse.statelessWindowShadeLevelStep

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Why do we need to define a proposed capability explicitly at edge driver?

end

local function shade_level_report_handler(driver, device, value, zb_rx)
local latest_target_level = device:get_field(LATEST_TARGET_LEVEL)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Here what we can get is current position of window treatment, right?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

The common driver only clears the "LATEST_TARGET_LEVEL" state when the device reports its location and does not handle report-level events. The child driver is responsible for report-level processing and UI events. The report handlers of both drivers will be triggered and will not affect each other.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Since the curtain position status has been updated, the target value is no longer used as a reference for position offset calculation, so LATEST_TARGET_LEVEL needs to be set to null.

device:get_latest_state("main", capabilities.windowShadeLevel.ID, capabilities.windowShadeLevel.shadeLevel.NAME) or 0

-- Calculate UI target_level (user's expected percentage)
local ui_target_level= utils.clamp_value(current_level + step, 0, 100)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

IS the variable name reasonable?

{
name = "aqara",
mfr = "LUMI",
models = { "lumi.curtain", "lumi.curtain.v1", "lumi.curtain.aq2", "lumi.curtain.agl001", "lumi.curtain.acn002" },

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Where is 'lumi.curtain.acn002' from?

invert_level = true,
},
{
name = "invert-lift-percentage",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

If we must need these three parts, please consider to merge them

-- Brand-specific configuration for window treatment devices
-- Supports statelessWindowShadeLevelStep capability

local BRAND_CONFIGS = {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Name file and variable using fingerprints

@zhangshen001 zhangshen001 force-pushed the zigbee_V2 branch 2 times, most recently from b89ff06 to 3573329 Compare July 10, 2026 04:44
-- Field keys for tracking target level and timeout timer
local LATEST_TARGET_LEVEL = "_latest_target_level"

-- Get brand configuration for a device

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

It's better to use 'fingerprint' into function name and comments

-- Step shade level handler for statelessWindowShadeLevelStep capability
local function step_shade_level_handler(driver, device, command)
-- Get brand-specific configuration
local brand_config = get_brand_config(device)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

same as above

end

local function shade_level_report_handler(driver, device, value, zb_rx)
local latest_target_level = device:get_field(LATEST_TARGET_LEVEL)

@vangoran vangoran Jul 10, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

merge into one sentence and explain why it is required

@zhangshen001 zhangshen001 force-pushed the zigbee_V2 branch 2 times, most recently from ef2520e to 8acd43e Compare July 10, 2026 07:31
Comment on lines +95 to +96
local current_level = latest_target_level or
device:get_latest_state("main", capabilities.windowShadeLevel.ID, capabilities.windowShadeLevel.shadeLevel.NAME) or 0

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

For example, if the curtain is initially at level 30 and receives a +10 command, setting the target_level to 40, and then receives a +2 command when the actual curtain position reaches 35, the current_level might still be 30. If the current_level were used as the baseline and the target_level were set to 32, the motor would reverse. Therefore, the target_level is calculated based on the saved LATEST_TARGET_LEVEL and is set to 42.

@zhangshen001 zhangshen001 marked this pull request as ready for review July 10, 2026 08:29
@tpmanley tpmanley requested review from hcarter-775 and inasail July 10, 2026 21:44
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