diff --git a/docs/en/zigbee/ep_color_dimmer_switch.rst b/docs/en/zigbee/ep_color_dimmer_switch.rst index 720c5d8f5bf..b7e56cbd9e0 100644 --- a/docs/en/zigbee/ep_color_dimmer_switch.rst +++ b/docs/en/zigbee/ep_color_dimmer_switch.rst @@ -116,6 +116,33 @@ Sets the brightness level of bound lights. * ``short_addr`` - Target device short address (optional) * ``ieee_addr`` - Target device IEEE address (optional) +setLightLevelStep +^^^^^^^^^^^^^^^^^ + +Sends a level step command to bound lights: changes the current level by a fixed step size in the given direction. + +.. code-block:: arduino + + void setLightLevelStep(ZigbeeLevelStepDirection direction, uint8_t step_size, uint16_t transition_time); + void setLightLevelStep(ZigbeeLevelStepDirection direction, uint8_t step_size, uint16_t transition_time, uint16_t group_addr); + void setLightLevelStep(ZigbeeLevelStepDirection direction, uint8_t step_size, uint16_t transition_time, uint8_t endpoint, uint16_t short_addr); + void setLightLevelStep(ZigbeeLevelStepDirection direction, uint8_t step_size, uint16_t transition_time, uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr); + +* ``direction`` - ``ZIGBEE_LEVEL_STEP_UP`` (0) or ``ZIGBEE_LEVEL_STEP_DOWN`` (1) +* ``step_size`` - Number of level units to step (e.g. 1–254; one step = one unit change in CurrentLevel) +* ``transition_time`` - Time to perform the step, in tenths of a second (see below) + +**Transition time (ZCL Step command):** + +* The transition time is the duration, in **tenths of a second**, that the device should take to perform the step. A step is a change in CurrentLevel of ``step_size`` units. +* The device should take as close to this time as it is able. If the device cannot move at a variable rate, it may disregard the transition time and move at a fixed rate. +* Use **0xFFFF** (65535) to request the device to move **as fast as it is able** (no specific duration). + +**Examples:** + +* Step level up by 10 units over 1 second: ``setLightLevelStep(ZIGBEE_LEVEL_STEP_UP, 10, 10);`` +* Step level down by 5 units as fast as possible: ``setLightLevelStep(ZIGBEE_LEVEL_STEP_DOWN, 5, 0xFFFF);`` + Color Control Commands ********************** diff --git a/libraries/Zigbee/examples/Zigbee_Color_Dimmer_Switch/Zigbee_Color_Dimmer_Switch.ino b/libraries/Zigbee/examples/Zigbee_Color_Dimmer_Switch/Zigbee_Color_Dimmer_Switch.ino index a313f3c0594..bc57300d30e 100644 --- a/libraries/Zigbee/examples/Zigbee_Color_Dimmer_Switch/Zigbee_Color_Dimmer_Switch.ino +++ b/libraries/Zigbee/examples/Zigbee_Color_Dimmer_Switch/Zigbee_Color_Dimmer_Switch.ino @@ -18,7 +18,7 @@ * The example demonstrates how to use Zigbee library to control a RGB light bulb. * The RGB light bulb is a Zigbee end device, which is controlled by a Zigbee coordinator (Switch). * To turn on/off the light, push the button on the switch. - * To change the color or level of the light, send serial commands to the switch. + * To change the color, level, or step the level of the light, send serial commands to the switch. * * By setting the switch to allow multiple binding, so it can bind to multiple lights. * Also every 30 seconds, all bound lights are printed to the serial console. @@ -133,8 +133,26 @@ void loop() { } int level = Serial.parseInt(); zbSwitch.setLightLevel(level); + } else if (command == "stepup") { + // Step level up by 20 units over 1 second + zbSwitch.setLightLevelStep(ZIGBEE_LEVEL_STEP_UP, 20, 10); + Serial.println("Step level up"); + } else if (command == "stepdown") { + // Step level down by 20 units over 1 second + zbSwitch.setLightLevelStep(ZIGBEE_LEVEL_STEP_DOWN, 20, 10); + Serial.println("Step level down"); + } else if (command == "stepupfast") { + // Step level up by 10 units as fast as possible (transition_time 0xFFFF) + zbSwitch.setLightLevelStep(ZIGBEE_LEVEL_STEP_UP, 10, 0xFFFF); + Serial.println("Step level up (fast)"); + } else if (command == "stepdownfast") { + // Step level down by 10 units as fast as possible + zbSwitch.setLightLevelStep(ZIGBEE_LEVEL_STEP_DOWN, 10, 0xFFFF); + Serial.println("Step level down (fast)"); + } else if (command == "help") { + Serial.println("Commands: on, off, toggle, red, green, blue, white, color, level, stepup, stepdown, stepupfast, stepdownfast"); } else { - Serial.println("Unknown command"); + Serial.println("Unknown command (type 'help' for list)"); } } diff --git a/libraries/Zigbee/keywords.txt b/libraries/Zigbee/keywords.txt index 9d981dcc39c..48b4f3ddbc0 100644 --- a/libraries/Zigbee/keywords.txt +++ b/libraries/Zigbee/keywords.txt @@ -46,6 +46,7 @@ zb_device_params_t KEYWORD1 zigbee_scan_result_t KEYWORD1 zb_power_source_t KEYWORD1 ZigbeeWindowCoveringType KEYWORD1 +ZigbeeLevelStepDirection KEYWORD1 ZigbeeFanMode KEYWORD1 ZigbeeFanModeSequence KEYWORD1 zb_cmd_type_t KEYWORD1 @@ -141,6 +142,7 @@ lightOffWithEffect KEYWORD2 lightOnWithTimedOff KEYWORD2 lightOnWithSceneRecall KEYWORD2 setLightLevel KEYWORD2 +setLightLevelStep KEYWORD2 setLightColor KEYWORD2 getLightState KEYWORD2 getLightLevel KEYWORD2 @@ -338,6 +340,10 @@ ZB_MULTISTATE_APPLICATION_TYPE_11_NUM_STATES LITERAL1 ZB_MULTISTATE_APPLICATION_TYPE_11_STATE_NAMES LITERAL1 ZB_MULTISTATE_APPLICATION_TYPE_OTHER_INDEX LITERAL1 +# ZigbeeColorDimmerSwitch level step +ZIGBEE_LEVEL_STEP_UP LITERAL1 +ZIGBEE_LEVEL_STEP_DOWN LITERAL1 + #ZigbeeColorDimmableLight ZIGBEE_COLOR_CAPABILITY_HUE_SATURATION LITERAL1 ZIGBEE_COLOR_CAPABILITY_ENHANCED_HUE LITERAL1 diff --git a/libraries/Zigbee/src/ep/ZigbeeColorDimmerSwitch.cpp b/libraries/Zigbee/src/ep/ZigbeeColorDimmerSwitch.cpp index 18465104dfa..a67f3686150 100644 --- a/libraries/Zigbee/src/ep/ZigbeeColorDimmerSwitch.cpp +++ b/libraries/Zigbee/src/ep/ZigbeeColorDimmerSwitch.cpp @@ -826,6 +826,71 @@ void ZigbeeColorDimmerSwitch::getLightColorHS(uint8_t endpoint, esp_zb_ieee_addr } } +void ZigbeeColorDimmerSwitch::setLightLevelStep(ZigbeeLevelStepDirection direction, uint8_t step_size, uint16_t transition_time) { + if (_is_bound) { + esp_zb_zcl_level_step_cmd_t cmd_req; + memset(&cmd_req, 0, sizeof(cmd_req)); + cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT; + cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; + cmd_req.step_mode = (uint8_t)direction; + cmd_req.step_size = step_size; + cmd_req.transition_time = transition_time; + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_level_step_cmd_req(&cmd_req); + esp_zb_lock_release(); + } +} + +void ZigbeeColorDimmerSwitch::setLightLevelStep(ZigbeeLevelStepDirection direction, uint8_t step_size, uint16_t transition_time, uint16_t group_addr) { + if (_is_bound) { + esp_zb_zcl_level_step_cmd_t cmd_req; + memset(&cmd_req, 0, sizeof(cmd_req)); + cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_GROUP_ENDP_NOT_PRESENT; + cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; + cmd_req.zcl_basic_cmd.dst_addr_u.addr_short = group_addr; + cmd_req.step_mode = (uint8_t)direction; + cmd_req.step_size = step_size; + cmd_req.transition_time = transition_time; + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_level_step_cmd_req(&cmd_req); + esp_zb_lock_release(); + } +} + +void ZigbeeColorDimmerSwitch::setLightLevelStep(ZigbeeLevelStepDirection direction, uint8_t step_size, uint16_t transition_time, uint8_t endpoint, uint16_t short_addr) { + if (_is_bound) { + esp_zb_zcl_level_step_cmd_t cmd_req; + memset(&cmd_req, 0, sizeof(cmd_req)); + cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT; + cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; + cmd_req.zcl_basic_cmd.dst_endpoint = endpoint; + cmd_req.zcl_basic_cmd.dst_addr_u.addr_short = short_addr; + cmd_req.step_mode = (uint8_t)direction; + cmd_req.step_size = step_size; + cmd_req.transition_time = transition_time; + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_level_step_cmd_req(&cmd_req); + esp_zb_lock_release(); + } +} + +void ZigbeeColorDimmerSwitch::setLightLevelStep(ZigbeeLevelStepDirection direction, uint8_t step_size, uint16_t transition_time, uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr) { + if (_is_bound) { + esp_zb_zcl_level_step_cmd_t cmd_req; + memset(&cmd_req, 0, sizeof(cmd_req)); + cmd_req.address_mode = ESP_ZB_APS_ADDR_MODE_64_ENDP_PRESENT; + cmd_req.zcl_basic_cmd.src_endpoint = _endpoint; + cmd_req.zcl_basic_cmd.dst_endpoint = endpoint; + memcpy(cmd_req.zcl_basic_cmd.dst_addr_u.addr_long, ieee_addr, sizeof(esp_zb_ieee_addr_t)); + cmd_req.step_mode = (uint8_t)direction; + cmd_req.step_size = step_size; + cmd_req.transition_time = transition_time; + esp_zb_lock_acquire(portMAX_DELAY); + esp_zb_zcl_level_step_cmd_req(&cmd_req); + esp_zb_lock_release(); + } +} + void ZigbeeColorDimmerSwitch::zbAttributeRead( uint16_t cluster_id, const esp_zb_zcl_attribute_t *attribute, uint8_t src_endpoint, esp_zb_zcl_addr_t src_address ) { diff --git a/libraries/Zigbee/src/ep/ZigbeeColorDimmerSwitch.h b/libraries/Zigbee/src/ep/ZigbeeColorDimmerSwitch.h index 10484a6867f..3ea5cf614c0 100644 --- a/libraries/Zigbee/src/ep/ZigbeeColorDimmerSwitch.h +++ b/libraries/Zigbee/src/ep/ZigbeeColorDimmerSwitch.h @@ -23,6 +23,12 @@ #include "ZigbeeEP.h" #include "ha/esp_zigbee_ha_standard.h" +/** Level step direction for setLightLevelStep (ZCL Step command: 0 = Up, 1 = Down) */ +enum ZigbeeLevelStepDirection { + ZIGBEE_LEVEL_STEP_UP = 0, + ZIGBEE_LEVEL_STEP_DOWN = 1 +}; + class ZigbeeColorDimmerSwitch : public ZigbeeEP { public: ZigbeeColorDimmerSwitch(uint8_t endpoint); @@ -53,6 +59,11 @@ class ZigbeeColorDimmerSwitch : public ZigbeeEP { void setLightLevel(uint8_t level, uint8_t endpoint, uint16_t short_addr); void setLightLevel(uint8_t level, uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr); + void setLightLevelStep(ZigbeeLevelStepDirection direction, uint8_t step_size, uint16_t transition_time); + void setLightLevelStep(ZigbeeLevelStepDirection direction, uint8_t step_size, uint16_t transition_time, uint16_t group_addr); + void setLightLevelStep(ZigbeeLevelStepDirection direction, uint8_t step_size, uint16_t transition_time, uint8_t endpoint, uint16_t short_addr); + void setLightLevelStep(ZigbeeLevelStepDirection direction, uint8_t step_size, uint16_t transition_time, uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr); + void setLightColor(uint8_t red, uint8_t green, uint8_t blue); void setLightColor(uint8_t red, uint8_t green, uint8_t blue, uint16_t group_addr); void setLightColor(uint8_t red, uint8_t green, uint8_t blue, uint8_t endpoint, uint16_t short_addr);