Skip to content

Commit cf1fc47

Browse files
committed
CHAD-17426: Add stateless step capabilities to zigbee-switch
1 parent ddc7c8a commit cf1fc47

File tree

3 files changed

+70
-1
lines changed

3 files changed

+70
-1
lines changed
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
-- Copyright 2026 SmartThings, Inc.
2+
-- Licensed under the Apache License, Version 2.0
3+
4+
local capabilities = require "st.capabilities"
5+
6+
return function(opts, driver, device)
7+
local can_handle = device:supports_capability(capabilities.statelessColorTemperatureStep)
8+
or device:supports_capability(capabilities.statelessSwitchLevelStep)
9+
if can_handle then
10+
local subdriver = require("stateless_handlers")
11+
return true, subdriver
12+
end
13+
return false
14+
end
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
-- Copyright 2026 SmartThings, Inc.
2+
-- Licensed under the Apache License, Version 2.0
3+
4+
local capabilities = require "st.capabilities"
5+
local st_utils = require "st.utils"
6+
local clusters = require "st.zigbee.zcl.clusters"
7+
local log = require "log"
8+
9+
-- The following definitions should be pulled from the `st.zigbee.constants` module once those changes land
10+
local KELVIN_MAX = "_max_kelvin"
11+
local KELVIN_MIN = "_min_kelvin"
12+
local MIREDS_CONVERSION_CONSTANT = 1000000
13+
local COLOR_TEMPERATURE_KELVIN_MAX = 15000
14+
local COLOR_TEMPERATURE_KELVIN_MIN = 1000
15+
local COLOR_TEMPERATURE_MIRED_MAX = st_utils.round(MIREDS_CONVERSION_CONSTANT/COLOR_TEMPERATURE_KELVIN_MIN) -- 1000
16+
local COLOR_TEMPERATURE_MIRED_MIN = st_utils.round(MIREDS_CONVERSION_CONSTANT/COLOR_TEMPERATURE_KELVIN_MAX) -- 67
17+
18+
-- Transition Time: The time that shall be taken to perform the step change, in units of 1/10ths of a second.
19+
local TRANSITION_TIME = 3 -- default: 0.3 seconds
20+
-- Options Mask & Override: Indicates which options are being overriden by the Level/ColorControl cluster commands
21+
local OPTIONS_MASK = 0x01 -- default: The `ExecuteIfOff` option is overriden
22+
local IGNORE_COMMAND_IF_OFF = 0x00 -- default: the command will not be executed if the device is off
23+
24+
local function step_color_temperature_by_percent_handler(driver, device, cmd)
25+
local step_percent_change = cmd.args and cmd.args.stepSize or 0
26+
if step_percent_change == 0 then return end
27+
local step_mode = step_percent_change > 0 and (clusters.ColorControl.types.CcStepMode and clusters.ColorControl.types.CcStepMode.DOWN or 3) or (clusters.ColorControl.types.CcStepMode and clusters.ColorControl.types.CcStepMode.UP or 1)
28+
local min_mireds = device:get_field(KELVIN_MIN) or COLOR_TEMPERATURE_MIRED_MIN -- default min mireds
29+
local max_mireds = device:get_field(KELVIN_MAX) or COLOR_TEMPERATURE_MIRED_MAX -- default max mireds
30+
local step_size_in_mireds = st_utils.round((max_mireds - min_mireds) * (math.abs(step_percent_change)/100.0))
31+
device:send(clusters.ColorControl.server.commands.StepColorTemperature(device, step_mode, step_size_in_mireds, TRANSITION_TIME, min_mireds, max_mireds, OPTIONS_MASK, IGNORE_COMMAND_IF_OFF))
32+
end
33+
34+
local function step_level_handler(driver, device, cmd)
35+
local step_size = st_utils.round((cmd.args and cmd.args.stepSize or 0)/100.0 * 254)
36+
if step_size == 0 then return end
37+
local step_mode = step_size > 0 and clusters.Level.types.MoveStepMode.UP or clusters.Level.types.MoveStepMode.DOWN
38+
device:send(clusters.Level.server.commands.Step(device, step_mode, math.abs(step_size), TRANSITION_TIME, OPTIONS_MASK, IGNORE_COMMAND_IF_OFF))
39+
end
40+
41+
local stateless_handlers = {
42+
Name = "Zigbee Stateless Step Handlers",
43+
capability_handlers = {
44+
[capabilities.statelessColorTemperatureStep.ID] = {
45+
[capabilities.statelessColorTemperatureStep.commands.stepColorTemperatureByPercent.NAME] = step_color_temperature_by_percent_handler,
46+
},
47+
[capabilities.statelessSwitchLevelStep.ID] = {
48+
[capabilities.statelessSwitchLevelStep.commands.stepLevel.NAME] = step_level_handler,
49+
},
50+
},
51+
can_handle = require("stateless_handlers.can_handle")
52+
}
53+
54+
return stateless_handlers

drivers/SmartThings/zigbee-switch/src/sub_drivers.lua

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,5 +35,6 @@ return {
3535
lazy_load_if_possible("tuya-multi"),
3636
lazy_load_if_possible("frient"),
3737
lazy_load_if_possible("frient-IO"),
38-
lazy_load_if_possible("color_temp_range_handlers")
38+
lazy_load_if_possible("color_temp_range_handlers"),
39+
lazy_load_if_possible("stateless_handlers")
3940
}

0 commit comments

Comments
 (0)