Add ColorControl cluster commands to chip-tool and src/app/ (#2792)

diff --git a/examples/chip-tool/commands/clusters/ColorControl/Commands.h b/examples/chip-tool/commands/clusters/ColorControl/Commands.h
new file mode 100644
index 0000000..baf3692
--- /dev/null
+++ b/examples/chip-tool/commands/clusters/ColorControl/Commands.h
@@ -0,0 +1,278 @@
+/*
+ *   Copyright (c) 2020 Project CHIP Authors
+ *   All rights reserved.
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+#ifndef __CHIPTOOL_COLORCONTROL_COMMANDS_H__
+#define __CHIPTOOL_COLORCONTROL_COMMANDS_H__
+
+#include "../../common/ModelCommand.h"
+
+class MoveToHue : public ModelCommand
+{
+public:
+    MoveToHue(const uint16_t clusterId) : ModelCommand("move-to-hue", clusterId) {}
+
+    size_t EncodeCommand(PacketBuffer * buffer, size_t bufferSize, uint16_t endPointId) override
+    {
+        uint8_t hue             = 30;
+        uint8_t direction       = 2;
+        uint16_t transitionTime = 10;
+        uint8_t optionsMask     = 0;
+        uint8_t optionsOverride = 0;
+        return encodeMoveToHueCommand(buffer->Start(), bufferSize, endPointId, hue, direction, transitionTime, optionsMask,
+                                      optionsOverride);
+    }
+};
+
+class MoveHue : public ModelCommand
+{
+public:
+    MoveHue(const uint16_t clusterId) : ModelCommand("move-hue", clusterId) {}
+
+    size_t EncodeCommand(PacketBuffer * buffer, size_t bufferSize, uint16_t endPointId) override
+    {
+        uint8_t moveMode        = 2;
+        uint8_t rate            = 127;
+        uint8_t optionsMask     = 0;
+        uint8_t optionsOverride = 0;
+        return encodeMoveHueCommand(buffer->Start(), bufferSize, endPointId, moveMode, rate, optionsMask, optionsOverride);
+    }
+};
+
+class StepHue : public ModelCommand
+{
+public:
+    StepHue(const uint16_t clusterId) : ModelCommand("step-hue", clusterId) {}
+
+    size_t EncodeCommand(PacketBuffer * buffer, size_t bufferSize, uint16_t endPointId) override
+    {
+        uint8_t stepMode        = 2;
+        uint8_t stepSize        = 127;
+        uint16_t transitionTime = 10;
+        uint8_t optionsMask     = 0;
+        uint8_t optionsOverride = 0;
+        return encodeStepHueCommand(buffer->Start(), bufferSize, endPointId, stepMode, stepSize, transitionTime, optionsMask,
+                                    optionsOverride);
+    }
+};
+
+class MoveToSaturation : public ModelCommand
+{
+public:
+    MoveToSaturation(const uint16_t clusterId) : ModelCommand("move-to-saturation", clusterId) {}
+
+    size_t EncodeCommand(PacketBuffer * buffer, size_t bufferSize, uint16_t endPointId) override
+    {
+        uint8_t saturation      = 30;
+        uint16_t transitionTime = 10;
+        uint8_t optionsMask     = 0;
+        uint8_t optionsOverride = 0;
+        return encodeMoveToSaturationCommand(buffer->Start(), bufferSize, endPointId, saturation, transitionTime, optionsMask,
+                                             optionsOverride);
+    }
+};
+
+class MoveSaturation : public ModelCommand
+{
+public:
+    MoveSaturation(const uint16_t clusterId) : ModelCommand("move-saturation", clusterId) {}
+
+    size_t EncodeCommand(PacketBuffer * buffer, size_t bufferSize, uint16_t endPointId) override
+    {
+        uint8_t moveMode        = 30;
+        uint8_t rate            = 100;
+        uint8_t optionsMask     = 0;
+        uint8_t optionsOverride = 0;
+        return encodeMoveSaturationCommand(buffer->Start(), bufferSize, endPointId, moveMode, rate, optionsMask, optionsOverride);
+    }
+};
+
+class StepSaturation : public ModelCommand
+{
+public:
+    StepSaturation(const uint16_t clusterId) : ModelCommand("step-saturation", clusterId) {}
+
+    size_t EncodeCommand(PacketBuffer * buffer, size_t bufferSize, uint16_t endPointId) override
+    {
+        uint8_t stepMode        = 30;
+        uint8_t stepSize        = 100;
+        uint16_t transitionTime = 10;
+        uint8_t optionsMask     = 0;
+        uint8_t optionsOverride = 0;
+        return encodeStepSaturationCommand(buffer->Start(), bufferSize, endPointId, stepMode, stepSize, transitionTime, optionsMask,
+                                           optionsOverride);
+    }
+};
+
+class MoveToHueSaturation : public ModelCommand
+{
+public:
+    MoveToHueSaturation(const uint16_t clusterId) : ModelCommand("move-to-hue-saturation", clusterId) {}
+
+    size_t EncodeCommand(PacketBuffer * buffer, size_t bufferSize, uint16_t endPointId) override
+    {
+        uint8_t hue             = 30;
+        uint8_t saturation      = 100;
+        uint16_t transitionTime = 10;
+        uint8_t optionsMask     = 0;
+        uint8_t optionsOverride = 0;
+        return encodeMoveToHueSaturationCommand(buffer->Start(), bufferSize, endPointId, hue, saturation, transitionTime,
+                                                optionsMask, optionsOverride);
+    }
+};
+
+class MoveToColor : public ModelCommand
+{
+public:
+    MoveToColor(const uint16_t clusterId) : ModelCommand("move-to-color", clusterId) {}
+
+    size_t EncodeCommand(PacketBuffer * buffer, size_t bufferSize, uint16_t endPointId) override
+    {
+        uint16_t colorX         = 30;
+        uint16_t colorY         = 30;
+        uint16_t transitionTime = 10;
+        uint8_t optionsMask     = 0;
+        uint8_t optionsOverride = 0;
+        return encodeMoveToColorCommand(buffer->Start(), bufferSize, endPointId, colorX, colorY, transitionTime, optionsMask,
+                                        optionsOverride);
+    }
+};
+
+class MoveColor : public ModelCommand
+{
+public:
+    MoveColor(const uint16_t clusterId) : ModelCommand("move-color", clusterId) {}
+
+    size_t EncodeCommand(PacketBuffer * buffer, size_t bufferSize, uint16_t endPointId) override
+    {
+        uint16_t rateX          = 30;
+        uint16_t rateY          = 30;
+        uint8_t optionsMask     = 0;
+        uint8_t optionsOverride = 0;
+        return encodeMoveColorCommand(buffer->Start(), bufferSize, endPointId, rateX, rateY, optionsMask, optionsOverride);
+    }
+};
+
+class StepColor : public ModelCommand
+{
+public:
+    StepColor(const uint16_t clusterId) : ModelCommand("step-color", clusterId) {}
+
+    size_t EncodeCommand(PacketBuffer * buffer, size_t bufferSize, uint16_t endPointId) override
+    {
+        uint16_t stepX          = 30;
+        uint16_t stepY          = 30;
+        uint16_t transitionTime = 10;
+        uint8_t optionsMask     = 0;
+        uint8_t optionsOverride = 0;
+        return encodeStepColorCommand(buffer->Start(), bufferSize, endPointId, stepX, stepY, transitionTime, optionsMask,
+                                      optionsOverride);
+    }
+};
+
+class MoveToColorTemperature : public ModelCommand
+{
+public:
+    MoveToColorTemperature(const uint16_t clusterId) : ModelCommand("move-to-color-temperature", clusterId) {}
+
+    size_t EncodeCommand(PacketBuffer * buffer, size_t bufferSize, uint16_t endPointId) override
+    {
+        uint16_t colorTemperature = 50000;
+        uint16_t transitionTime   = 50;
+        uint8_t optionsMask       = 0;
+        uint8_t optionsOverride   = 0;
+        return encodeMoveToColorTemperatureCommand(buffer->Start(), bufferSize, endPointId, colorTemperature, transitionTime,
+                                                   optionsMask, optionsOverride);
+    }
+};
+
+class MoveColorTemperature : public ModelCommand
+{
+public:
+    MoveColorTemperature(const uint16_t clusterId) : ModelCommand("move-color-temperature", clusterId) {}
+
+    size_t EncodeCommand(PacketBuffer * buffer, size_t bufferSize, uint16_t endPointId) override
+    {
+        uint8_t moveMode             = 4;
+        uint16_t rate                = 100;
+        uint16_t colorTemperatureMin = 1000;
+        uint16_t colorTemperatureMax = 5000;
+        uint8_t optionsMask          = 0;
+        uint8_t optionsOverride      = 0;
+        return encodeMoveColorTemperatureCommand(buffer->Start(), bufferSize, endPointId, moveMode, rate, colorTemperatureMin,
+                                                 colorTemperatureMax, optionsMask, optionsOverride);
+    }
+};
+
+class StepColorTemperature : public ModelCommand
+{
+public:
+    StepColorTemperature(const uint16_t clusterId) : ModelCommand("step-color-temperature", clusterId) {}
+
+    size_t EncodeCommand(PacketBuffer * buffer, size_t bufferSize, uint16_t endPointId) override
+    {
+        uint8_t stepMode             = 4;
+        uint16_t stepSize            = 100;
+        uint16_t transitionTime      = 10;
+        uint16_t colorTemperatureMin = 1000;
+        uint16_t colorTemperatureMax = 5000;
+        uint8_t optionsMask          = 0;
+        uint8_t optionsOverride      = 0;
+        return encodeStepColorTemperatureCommand(buffer->Start(), bufferSize, endPointId, stepMode, stepSize, colorTemperatureMin,
+                                                 colorTemperatureMax, transitionTime, optionsMask, optionsOverride);
+    }
+};
+
+class StopMoveStep : public ModelCommand
+{
+public:
+    StopMoveStep(const uint16_t clusterId) : ModelCommand("stop-move-step", clusterId) {}
+
+    size_t EncodeCommand(PacketBuffer * buffer, size_t bufferSize, uint16_t endPointId) override
+    {
+        uint8_t optionsMask     = 0;
+        uint8_t optionsOverride = 0;
+        return encodeStopMoveStepCommand(buffer->Start(), bufferSize, endPointId, optionsMask, optionsOverride);
+    }
+};
+
+void registerClusterColorControl(Commands & commands)
+{
+    const char * clusterName = "ColorControl";
+    const uint16_t clusterId = 0x0300;
+
+    commands_list clusterCommands = {
+        make_unique<MoveToHue>(clusterId),
+        make_unique<MoveHue>(clusterId),
+        make_unique<StepHue>(clusterId),
+        make_unique<MoveToSaturation>(clusterId),
+        make_unique<MoveSaturation>(clusterId),
+        make_unique<StepSaturation>(clusterId),
+        make_unique<MoveToHueSaturation>(clusterId),
+        make_unique<MoveToColor>(clusterId),
+        make_unique<MoveColor>(clusterId),
+        make_unique<StepColor>(clusterId),
+        make_unique<MoveToColorTemperature>(clusterId),
+        make_unique<MoveColorTemperature>(clusterId),
+        make_unique<StepColorTemperature>(clusterId),
+        make_unique<StopMoveStep>(clusterId),
+    };
+
+    commands.Register(clusterName, clusterCommands);
+}
+
+#endif // __CHIPTOOL_COLORCONTROL_COMMANDS_H__
diff --git a/examples/chip-tool/main.cpp b/examples/chip-tool/main.cpp
index f8ba428..6094da7 100644
--- a/examples/chip-tool/main.cpp
+++ b/examples/chip-tool/main.cpp
@@ -18,6 +18,7 @@
 
 #include "commands/common/Commands.h"
 
+#include "commands/clusters/ColorControl/Commands.h"
 #include "commands/clusters/Identify/Commands.h"
 #include "commands/clusters/OnOff/Commands.h"
 #include "commands/clusters/TemperatureMeasurement/Commands.h"
@@ -37,6 +38,7 @@
     Commands commands;
 
     registerCommandsEcho(commands);
+    registerClusterColorControl(commands);
     registerClusterIdentify(commands);
     registerClusterOnOff(commands);
     registerClusterTemperatureMeasurement(commands);
diff --git a/src/app/chip-zcl-zpro-codec.h b/src/app/chip-zcl-zpro-codec.h
index 03eb2b2..6f99816 100644
--- a/src/app/chip-zcl-zpro-codec.h
+++ b/src/app/chip-zcl-zpro-codec.h
@@ -142,6 +142,204 @@
  */
 uint16_t encodeReadCurrentTemperatureCommand(uint8_t * buffer, uint16_t buf_length, uint8_t destination_endpoint);
 
+/*
+ * Color control cluster commands
+ */
+
+/**
+ * @brief Encode a move-to-hue command for the Color Control cluster
+ * @param buffer                Buffer to encode into
+ * @param buf_length            Length of buffer
+ * @param destination_endpoint  Destination endpoint
+ * @param hue                   The hue value of the color
+ * @param direction             A direction to change the hue to
+ * @param transitionTime        The number of steps for the color transition
+ * @param optionMask            An option mask
+ * @param optionOverride        An option override
+ * */
+uint16_t encodeMoveToHueCommand(uint8_t * buffer, uint16_t buf_length, uint8_t destination_endpoint, uint8_t hue, uint8_t direction,
+                                uint16_t transitionTime, uint8_t optionMask, uint8_t optionOverride);
+
+/**
+ * @brief Encode a move-hue command for the Color Control cluster
+ * @param buffer                Buffer to encode into
+ * @param buf_length            Length of buffer
+ * @param destination_endpoint  Destination endpoint
+ * @param moveMode              The move mode to apply
+ * @param rate                  The rate of the move
+ * @param optionMask            An option mask
+ * @param optionOverride        An option override
+ * */
+uint16_t encodeMoveHueCommand(uint8_t * buffer, uint16_t buf_length, uint8_t destination_endpoint, uint8_t moveMode, uint8_t rate,
+                              uint8_t optionMask, uint8_t optionOverride);
+
+/**
+ * @brief Encode a step-hue command for the Color Control cluster
+ * @param buffer                Buffer to encode into
+ * @param buf_length            Length of buffer
+ * @param destination_endpoint  Destination endpoint
+ * @param stepMode              The step mode to apply
+ * @param stepSize              The step size
+ * @param transitionTime        The number of steps for the color transition
+ * @param optionMask            An option mask
+ * @param optionOverride        An option override
+ * */
+uint16_t encodeStepHueCommand(uint8_t * buffer, uint16_t buf_length, uint8_t destination_endpoint, uint8_t stepMode,
+                              uint8_t stepSize, uint16_t transitionTime, uint8_t optionMask, uint8_t optionOverride);
+
+/**
+ * @brief Encode a move-to-saturation command for the Color Control cluster
+ * @param buffer                Buffer to encode into
+ * @param buf_length            Length of buffer
+ * @param destination_endpoint  Destination endpoint
+ * @param saturation            The saturation value of the color
+ * @param transitionTime        The number of steps for the color transition
+ * @param optionMask            An option mask
+ * @param optionOverride        An option override
+ * */
+uint16_t encodeMoveToSaturationCommand(uint8_t * buffer, uint16_t buf_length, uint8_t destination_endpoint, uint8_t saturation,
+                                       uint16_t transitionTime, uint8_t optionMask, uint8_t optionOverride);
+
+/**
+ * @brief Encode a move-saturation command for the Color Control cluster
+ * @param buffer                Buffer to encode into
+ * @param buf_length            Length of buffer
+ * @param destination_endpoint  Destination endpoint
+ * @param moveMode              The move mode to apply
+ * @param rate                  The rate of the move
+ * @param optionMask            An option mask
+ * @param optionOverride        An option override
+ * */
+uint16_t encodeMoveSaturationCommand(uint8_t * buffer, uint16_t buf_length, uint8_t destination_endpoint, uint8_t moveMode,
+                                     uint8_t rate, uint8_t optionMask, uint8_t optionOverride);
+
+/**
+ * @brief Encode a step-saturation command for the Color Control cluster
+ * @param buffer                Buffer to encode into
+ * @param buf_length            Length of buffer
+ * @param destination_endpoint  Destination endpoint
+ * @param stepMode              The step mode to apply
+ * @param stepSize              The step size
+ * @param transitionTime        The number of steps for the color transition
+ * @param optionMask            An option mask
+ * @param optionOverride        An option override
+ * */
+uint16_t encodeStepSaturationCommand(uint8_t * buffer, uint16_t buf_length, uint8_t destination_endpoint, uint8_t stepMode,
+                                     uint8_t stepSize, uint16_t transitionTime, uint8_t optionMask, uint8_t optionOverride);
+
+/**
+ * @brief Encode a move-to-hue-saturation command for the Color Control cluster
+ * @param buffer                Buffer to encode into
+ * @param buf_length            Length of buffer
+ * @param destination_endpoint  Destination endpoint
+ * @param hue                   The hue value of the color
+ * @param saturation            The saturation value of the color
+ * @param transitionTime        The number of steps for the color transition
+ * @param optionMask            An option mask
+ * @param optionOverride        An option override
+ * */
+uint16_t encodeMoveToHueSaturationCommand(uint8_t * buffer, uint16_t buf_length, uint8_t destination_endpoint, uint8_t hue,
+                                          uint8_t saturation, uint16_t transitionTime, uint8_t optionMask, uint8_t optionOverride);
+
+/**
+ * @brief Encode a move-to-color command for the Color Control cluster
+ * @param buffer                Buffer to encode into
+ * @param buf_length            Length of buffer
+ * @param destination_endpoint  Destination endpoint
+ * @param colorX                The x color value
+ * @param colorY                The y color value
+ * @param transitionTime        The number of steps for the color transition
+ * @param optionMask            An option mask
+ * @param optionOverride        An option override
+ * */
+uint16_t encodeMoveToColorCommand(uint8_t * buffer, uint16_t buf_length, uint8_t destination_endpoint, uint16_t colorX,
+                                  uint16_t colorY, uint16_t transitionTime, uint8_t optionMask, uint8_t optionOverride);
+
+/**
+ * @brief Encode a move-color command for the Color Control cluster
+ * @param buffer                Buffer to encode into
+ * @param buf_length            Length of buffer
+ * @param destination_endpoint  Destination endpoint
+ * @param rateX                 The x rate value
+ * @param rateY                 The y rate value
+ * @param optionMask            An option mask
+ * @param optionOverride        An option override
+ * */
+uint16_t encodeMoveColorCommand(uint8_t * buffer, uint16_t buf_length, uint8_t destination_endpoint, uint16_t rateX, uint16_t rateY,
+                                uint8_t optionMask, uint8_t optionOverride);
+
+/**
+ * @brief Encode a step-color command for the Color Control cluster
+ * @param buffer                Buffer to encode into
+ * @param buf_length            Length of buffer
+ * @param destination_endpoint  Destination endpoint
+ * @param stepX                 The x step value
+ * @param stepY                 The y step value
+ * @param transitionTime        The number of steps for the color transition
+ * @param optionMask            An option mask
+ * @param optionOverride        An option override
+ * */
+uint16_t encodeStepColorCommand(uint8_t * buffer, uint16_t buf_length, uint8_t destination_endpoint, uint16_t stepX, uint16_t stepY,
+                                uint16_t transitionTime, uint8_t optionMask, uint8_t optionOverride);
+
+/**
+ * @brief Encode a move-to-color-temperature command for the Color Control cluster
+ * @param buffer                Buffer to encode into
+ * @param buf_length            Length of buffer
+ * @param destination_endpoint  Destination endpoint
+ * @param colorTemperature      The temperature of the color
+ * @param transitionTime        The number of steps for the color transition
+ * @param optionMask            An option mask
+ * @param optionOverride        An option override
+ * */
+uint16_t encodeMoveToColorTemperatureCommand(uint8_t * buffer, uint16_t buf_length, uint8_t destination_endpoint,
+                                             uint16_t colorTemperature, uint16_t transitionTime, uint8_t optionMask,
+                                             uint8_t optionOverride);
+
+/**
+ * @brief Encode a move-color-temperature command for the Color Control cluster
+ * @param buffer                Buffer to encode into
+ * @param buf_length            Length of buffer
+ * @param destination_endpoint  Destination endpoint
+ * @param moveMode              The move mode to apply
+ * @param rate                  The rate of the move
+ * @param colorTemperatureMin   The min temperature of the color
+ * @param colorTemperatureMax   The max temperature of the color
+ * @param optionMask            An option mask
+ * @param optionOverride        An option override
+ * */
+uint16_t encodeMoveColorTemperatureCommand(uint8_t * buffer, uint16_t buf_length, uint8_t destination_endpoint, uint8_t moveMode,
+                                           uint16_t rate, uint16_t colorTemperatureMin, uint16_t colorTemperatureMax,
+                                           uint8_t optionMask, uint8_t optionOverride);
+
+/**
+ * @brief Encode a step-color-temperature command for the Color Control cluster
+ * @param buffer                Buffer to encode into
+ * @param buf_length            Length of buffer
+ * @param destination_endpoint  Destination endpoint
+ * @param stepMode              The step mode to apply
+ * @param stepSize              The step size
+ * @param transitionTime        The number of steps for the color transition
+ * @param colorTemperatureMin   The min temperature of the color
+ * @param colorTemperatureMax   The max temperature of the color
+ * @param optionMask            An option mask
+ * @param optionOverride        An option override
+ * */
+uint16_t encodeStepColorTemperatureCommand(uint8_t * buffer, uint16_t buf_length, uint8_t destination_endpoint, uint8_t stepMode,
+                                           uint16_t stepSize, uint16_t transitionTime, uint16_t colorTemperatureMin,
+                                           uint16_t colorTemperatureMax, uint8_t optionMask, uint8_t optionOverride);
+
+/**
+ * @brief Encode a stop-move-step command for the Color Control cluster
+ * @param buffer                Buffer to encode into
+ * @param buf_length            Length of buffer
+ * @param destination_endpoint  Destination endpoint
+ * @param optionMask            An option mask
+ * @param optionOverride        An option override
+ * */
+uint16_t encodeStopMoveStepCommand(uint8_t * buffer, uint16_t buf_length, uint8_t destination_endpoint, uint8_t optionMask,
+                                   uint8_t optionOverride);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/app/encoder.cpp b/src/app/encoder.cpp
index ef10f25..bb7642c 100644
--- a/src/app/encoder.cpp
+++ b/src/app/encoder.cpp
@@ -169,6 +169,7 @@
 #define ONOFF_CLUSTER_ID 0x0006
 #define IDENTIFY_CLUSTER_ID 0x0003
 #define TEMP_MEASUREMENT_CLUSTER_ID 0x0402
+#define COLORCONTROL_CLUSTER_ID 0x0300
 
 /*
  * On/Off Cluster commands
@@ -195,6 +196,10 @@
     READ_ATTRIBUTES("ReadOnOff", ONOFF_CLUSTER_ID);
 }
 
+/*
+ * Identify Cluster commands
+ */
+
 uint16_t encodeIdentifyCommand(uint8_t * buffer, uint16_t buf_length, uint8_t destination_endpoint, uint16_t duration)
 {
     COMMAND_HEADER("Identify", IDENTIFY_CLUSTER_ID, 0x00);
@@ -216,4 +221,174 @@
     READ_ATTRIBUTES("ReadCurrentTemperature", TEMP_MEASUREMENT_CLUSTER_ID);
 }
 
+/*
+ * Color Control Cluster commands
+ */
+
+uint16_t encodeMoveToHueCommand(uint8_t * buffer, uint16_t buf_length, uint8_t destination_endpoint, uint8_t hue, uint8_t direction,
+                                uint16_t transitionTime, uint8_t optionMask, uint8_t optionOverride)
+{
+    COMMAND_HEADER("MoveToHue", COLORCONTROL_CLUSTER_ID, 0x00);
+    buf.Put(hue);
+    buf.Put(direction);
+    buf.PutLE16(transitionTime);
+    buf.Put(optionMask);
+    buf.Put(optionOverride);
+    COMMAND_FOOTER("MoveToHue");
+}
+
+uint16_t encodeMoveHueCommand(uint8_t * buffer, uint16_t buf_length, uint8_t destination_endpoint, uint8_t moveMode, uint8_t rate,
+                              uint8_t optionMask, uint8_t optionOverride)
+{
+    COMMAND_HEADER("MoveHue", COLORCONTROL_CLUSTER_ID, 0x01);
+    buf.Put(moveMode);
+    buf.Put(rate);
+    buf.Put(optionMask);
+    buf.Put(optionOverride);
+    COMMAND_FOOTER("MoveHue");
+}
+
+uint16_t encodeStepHueCommand(uint8_t * buffer, uint16_t buf_length, uint8_t destination_endpoint, uint8_t stepMode,
+                              uint8_t stepSize, uint16_t transitionTime, uint8_t optionMask, uint8_t optionOverride)
+{
+    COMMAND_HEADER("StepHue", COLORCONTROL_CLUSTER_ID, 0x02);
+    buf.Put(stepMode);
+    buf.Put(stepSize);
+    buf.PutLE16(transitionTime);
+    buf.Put(optionMask);
+    buf.Put(optionOverride);
+    COMMAND_FOOTER("StepHue");
+}
+
+uint16_t encodeMoveToSaturationCommand(uint8_t * buffer, uint16_t buf_length, uint8_t destination_endpoint, uint8_t saturation,
+                                       uint16_t transitionTime, uint8_t optionMask, uint8_t optionOverride)
+{
+    COMMAND_HEADER("MoveToSaturation", COLORCONTROL_CLUSTER_ID, 0x03);
+    buf.Put(saturation);
+    buf.PutLE16(transitionTime);
+    buf.Put(optionMask);
+    buf.Put(optionOverride);
+    COMMAND_FOOTER("MoveToSaturation");
+}
+
+uint16_t encodeMoveSaturationCommand(uint8_t * buffer, uint16_t buf_length, uint8_t destination_endpoint, uint8_t moveMode,
+                                     uint8_t rate, uint8_t optionMask, uint8_t optionOverride)
+{
+    COMMAND_HEADER("MoveSaturation", COLORCONTROL_CLUSTER_ID, 0x04);
+    buf.Put(moveMode);
+    buf.Put(rate);
+    buf.Put(optionMask);
+    buf.Put(optionOverride);
+    COMMAND_FOOTER("MoveSaturation");
+}
+
+uint16_t encodeStepSaturationCommand(uint8_t * buffer, uint16_t buf_length, uint8_t destination_endpoint, uint8_t stepMode,
+                                     uint8_t stepSize, uint16_t transitionTime, uint8_t optionMask, uint8_t optionOverride)
+{
+    COMMAND_HEADER("StepSaturation", COLORCONTROL_CLUSTER_ID, 0x05);
+    buf.Put(stepMode);
+    buf.Put(stepSize);
+    buf.PutLE16(transitionTime);
+    buf.Put(optionMask);
+    buf.Put(optionOverride);
+    COMMAND_FOOTER("StepSaturation");
+}
+
+uint16_t encodeMoveToHueSaturationCommand(uint8_t * buffer, uint16_t buf_length, uint8_t destination_endpoint, uint8_t hue,
+                                          uint8_t saturation, uint16_t transitionTime, uint8_t optionMask, uint8_t optionOverride)
+{
+    COMMAND_HEADER("MoveToHueSaturation", COLORCONTROL_CLUSTER_ID, 0x06);
+    buf.Put(hue);
+    buf.Put(saturation);
+    buf.PutLE16(transitionTime);
+    buf.Put(optionMask);
+    buf.Put(optionOverride);
+    COMMAND_FOOTER("MoveToHueSaturation");
+}
+
+uint16_t encodeMoveToColorCommand(uint8_t * buffer, uint16_t buf_length, uint8_t destination_endpoint, uint16_t colorX,
+                                  uint16_t colorY, uint16_t transitionTime, uint8_t optionMask, uint8_t optionOverride)
+{
+    COMMAND_HEADER("MoveToColor", COLORCONTROL_CLUSTER_ID, 0x07);
+    buf.PutLE16(colorX);
+    buf.PutLE16(colorY);
+    buf.PutLE16(transitionTime);
+    buf.Put(optionMask);
+    buf.Put(optionOverride);
+    COMMAND_FOOTER("MoveToColor");
+}
+
+uint16_t encodeMoveColorCommand(uint8_t * buffer, uint16_t buf_length, uint8_t destination_endpoint, uint16_t rateX, uint16_t rateY,
+                                uint8_t optionMask, uint8_t optionOverride)
+{
+    COMMAND_HEADER("MoveColor", COLORCONTROL_CLUSTER_ID, 0x08);
+    buf.PutLE16(rateX);
+    buf.PutLE16(rateY);
+    buf.Put(optionMask);
+    buf.Put(optionOverride);
+    COMMAND_FOOTER("MoveColor");
+}
+
+uint16_t encodeStepColorCommand(uint8_t * buffer, uint16_t buf_length, uint8_t destination_endpoint, uint16_t stepX, uint16_t stepY,
+                                uint16_t transitionTime, uint8_t optionMask, uint8_t optionOverride)
+{
+    COMMAND_HEADER("StepColor", COLORCONTROL_CLUSTER_ID, 0x09);
+    buf.PutLE16(stepX);
+    buf.PutLE16(stepY);
+    buf.PutLE16(transitionTime);
+    buf.Put(optionMask);
+    buf.Put(optionOverride);
+    COMMAND_FOOTER("StepColor");
+}
+
+uint16_t encodeMoveToColorTemperatureCommand(uint8_t * buffer, uint16_t buf_length, uint8_t destination_endpoint,
+                                             uint16_t colorTemperature, uint16_t transitionTime, uint8_t optionMask,
+                                             uint8_t optionOverride)
+{
+    COMMAND_HEADER("MoveToColorTemperature", COLORCONTROL_CLUSTER_ID, 0x0A);
+    buf.PutLE16(colorTemperature);
+    buf.PutLE16(transitionTime);
+    buf.Put(optionMask);
+    buf.Put(optionOverride);
+    COMMAND_FOOTER("MoveToColorTemperature");
+}
+
+uint16_t encodeMoveColorTemperatureCommand(uint8_t * buffer, uint16_t buf_length, uint8_t destination_endpoint, uint8_t moveMode,
+                                           uint16_t rate, uint16_t colorTemperatureMin, uint16_t colorTemperatureMax,
+                                           uint8_t optionMask, uint8_t optionOverride)
+{
+    COMMAND_HEADER("MoveColorTemperature", COLORCONTROL_CLUSTER_ID, 0x4B);
+    buf.Put(moveMode);
+    buf.PutLE16(rate);
+    buf.PutLE16(colorTemperatureMin);
+    buf.PutLE16(colorTemperatureMax);
+    buf.Put(optionMask);
+    buf.Put(optionOverride);
+    COMMAND_FOOTER("MoveColorTemperature");
+}
+
+uint16_t encodeStepColorTemperatureCommand(uint8_t * buffer, uint16_t buf_length, uint8_t destination_endpoint, uint8_t stepMode,
+                                           uint16_t stepSize, uint16_t transitionTime, uint16_t colorTemperatureMin,
+                                           uint16_t colorTemperatureMax, uint8_t optionMask, uint8_t optionOverride)
+{
+    COMMAND_HEADER("StepColorTemperature", COLORCONTROL_CLUSTER_ID, 0x4C);
+    buf.Put(stepMode);
+    buf.PutLE16(stepSize);
+    buf.PutLE16(transitionTime);
+    buf.PutLE16(colorTemperatureMin);
+    buf.PutLE16(colorTemperatureMax);
+    buf.Put(optionMask);
+    buf.Put(optionOverride);
+    COMMAND_FOOTER("StepColorTemperature");
+}
+
+uint16_t encodeStopMoveStepCommand(uint8_t * buffer, uint16_t buf_length, uint8_t destination_endpoint, uint8_t optionMask,
+                                   uint8_t optionOverride)
+{
+    COMMAND_HEADER("StopMoveStep", COLORCONTROL_CLUSTER_ID, 0x47);
+    buf.Put(optionMask);
+    buf.Put(optionOverride);
+    COMMAND_FOOTER("StopMoveStep");
+}
+
 } // extern "C"