/*
 *
 *    Copyright (c) 2021 Project CHIP Authors
 *
 *    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.
 */

// THIS FILE IS GENERATED BY ZAP

#include <core/CHIPCore.h>

#include <app/CommandSender.h>
#include <app/InteractionModelEngine.h>
#include <lib/support/Span.h>

#include <controller/CHIPClusters.h>
#include <controller/CHIPDevice.h>

using namespace chip;
using namespace chip::app;

extern "C" {

// Cluster ApplicationBasic
// End of Cluster ApplicationBasic

// Cluster BarrierControl
CHIP_ERROR chip_ime_AppendCommand_BarrierControl_BarrierControlGoToPercent(chip::Controller::Device * device,
                                                                           chip::EndpointId ZCLendpointId, chip::GroupId ZCLgroupId,
                                                                           uint8_t percentOpen)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::BarrierControlCluster clusterBarrierControl;
    (void) ZCLgroupId;
    clusterBarrierControl.Associate(device, ZCLendpointId);
    return clusterBarrierControl.BarrierControlGoToPercent(nullptr, nullptr, percentOpen);
}
CHIP_ERROR chip_ime_AppendCommand_BarrierControl_BarrierControlStop(chip::Controller::Device * device,
                                                                    chip::EndpointId ZCLendpointId, chip::GroupId ZCLgroupId)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::BarrierControlCluster clusterBarrierControl;
    (void) ZCLgroupId;
    clusterBarrierControl.Associate(device, ZCLendpointId);
    return clusterBarrierControl.BarrierControlStop(nullptr, nullptr);
}
// End of Cluster BarrierControl

// Cluster Basic
CHIP_ERROR chip_ime_AppendCommand_Basic_MfgSpecificPing(chip::Controller::Device * device, chip::EndpointId ZCLendpointId,
                                                        chip::GroupId ZCLgroupId)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::BasicCluster clusterBasic;
    (void) ZCLgroupId;
    clusterBasic.Associate(device, ZCLendpointId);
    return clusterBasic.MfgSpecificPing(nullptr, nullptr);
}
// End of Cluster Basic

// Cluster Binding
CHIP_ERROR chip_ime_AppendCommand_Binding_Bind(chip::Controller::Device * device, chip::EndpointId ZCLendpointId,
                                               chip::GroupId ZCLgroupId, chip::NodeId nodeId, chip::GroupId groupId,
                                               chip::EndpointId endpointId, chip::ClusterId clusterId)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::BindingCluster clusterBinding;
    (void) ZCLgroupId;
    clusterBinding.Associate(device, ZCLendpointId);
    return clusterBinding.Bind(nullptr, nullptr, nodeId, groupId, endpointId, clusterId);
}
CHIP_ERROR chip_ime_AppendCommand_Binding_Unbind(chip::Controller::Device * device, chip::EndpointId ZCLendpointId,
                                                 chip::GroupId ZCLgroupId, chip::NodeId nodeId, chip::GroupId groupId,
                                                 chip::EndpointId endpointId, chip::ClusterId clusterId)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::BindingCluster clusterBinding;
    (void) ZCLgroupId;
    clusterBinding.Associate(device, ZCLendpointId);
    return clusterBinding.Unbind(nullptr, nullptr, nodeId, groupId, endpointId, clusterId);
}
// End of Cluster Binding

// Cluster ColorControl
CHIP_ERROR chip_ime_AppendCommand_ColorControl_MoveColor(chip::Controller::Device * device, chip::EndpointId ZCLendpointId,
                                                         chip::GroupId ZCLgroupId, int16_t rateX, int16_t rateY,
                                                         uint8_t optionsMask, uint8_t optionsOverride)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::ColorControlCluster clusterColorControl;
    (void) ZCLgroupId;
    clusterColorControl.Associate(device, ZCLendpointId);
    return clusterColorControl.MoveColor(nullptr, nullptr, rateX, rateY, optionsMask, optionsOverride);
}
CHIP_ERROR chip_ime_AppendCommand_ColorControl_MoveColorTemperature(
    chip::Controller::Device * device, chip::EndpointId ZCLendpointId, chip::GroupId ZCLgroupId, uint8_t moveMode, uint16_t rate,
    uint16_t colorTemperatureMinimum, uint16_t colorTemperatureMaximum, uint8_t optionsMask, uint8_t optionsOverride)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::ColorControlCluster clusterColorControl;
    (void) ZCLgroupId;
    clusterColorControl.Associate(device, ZCLendpointId);
    return clusterColorControl.MoveColorTemperature(nullptr, nullptr, moveMode, rate, colorTemperatureMinimum,
                                                    colorTemperatureMaximum, optionsMask, optionsOverride);
}
CHIP_ERROR chip_ime_AppendCommand_ColorControl_MoveHue(chip::Controller::Device * device, chip::EndpointId ZCLendpointId,
                                                       chip::GroupId ZCLgroupId, uint8_t moveMode, uint8_t rate,
                                                       uint8_t optionsMask, uint8_t optionsOverride)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::ColorControlCluster clusterColorControl;
    (void) ZCLgroupId;
    clusterColorControl.Associate(device, ZCLendpointId);
    return clusterColorControl.MoveHue(nullptr, nullptr, moveMode, rate, optionsMask, optionsOverride);
}
CHIP_ERROR chip_ime_AppendCommand_ColorControl_MoveSaturation(chip::Controller::Device * device, chip::EndpointId ZCLendpointId,
                                                              chip::GroupId ZCLgroupId, uint8_t moveMode, uint8_t rate,
                                                              uint8_t optionsMask, uint8_t optionsOverride)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::ColorControlCluster clusterColorControl;
    (void) ZCLgroupId;
    clusterColorControl.Associate(device, ZCLendpointId);
    return clusterColorControl.MoveSaturation(nullptr, nullptr, moveMode, rate, optionsMask, optionsOverride);
}
CHIP_ERROR chip_ime_AppendCommand_ColorControl_MoveToColor(chip::Controller::Device * device, chip::EndpointId ZCLendpointId,
                                                           chip::GroupId ZCLgroupId, uint16_t colorX, uint16_t colorY,
                                                           uint16_t transitionTime, uint8_t optionsMask, uint8_t optionsOverride)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::ColorControlCluster clusterColorControl;
    (void) ZCLgroupId;
    clusterColorControl.Associate(device, ZCLendpointId);
    return clusterColorControl.MoveToColor(nullptr, nullptr, colorX, colorY, transitionTime, optionsMask, optionsOverride);
}
CHIP_ERROR chip_ime_AppendCommand_ColorControl_MoveToColorTemperature(chip::Controller::Device * device,
                                                                      chip::EndpointId ZCLendpointId, chip::GroupId ZCLgroupId,
                                                                      uint16_t colorTemperature, uint16_t transitionTime,
                                                                      uint8_t optionsMask, uint8_t optionsOverride)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::ColorControlCluster clusterColorControl;
    (void) ZCLgroupId;
    clusterColorControl.Associate(device, ZCLendpointId);
    return clusterColorControl.MoveToColorTemperature(nullptr, nullptr, colorTemperature, transitionTime, optionsMask,
                                                      optionsOverride);
}
CHIP_ERROR chip_ime_AppendCommand_ColorControl_MoveToHue(chip::Controller::Device * device, chip::EndpointId ZCLendpointId,
                                                         chip::GroupId ZCLgroupId, uint8_t hue, uint8_t direction,
                                                         uint16_t transitionTime, uint8_t optionsMask, uint8_t optionsOverride)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::ColorControlCluster clusterColorControl;
    (void) ZCLgroupId;
    clusterColorControl.Associate(device, ZCLendpointId);
    return clusterColorControl.MoveToHue(nullptr, nullptr, hue, direction, transitionTime, optionsMask, optionsOverride);
}
CHIP_ERROR chip_ime_AppendCommand_ColorControl_MoveToHueAndSaturation(chip::Controller::Device * device,
                                                                      chip::EndpointId ZCLendpointId, chip::GroupId ZCLgroupId,
                                                                      uint8_t hue, uint8_t saturation, uint16_t transitionTime,
                                                                      uint8_t optionsMask, uint8_t optionsOverride)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::ColorControlCluster clusterColorControl;
    (void) ZCLgroupId;
    clusterColorControl.Associate(device, ZCLendpointId);
    return clusterColorControl.MoveToHueAndSaturation(nullptr, nullptr, hue, saturation, transitionTime, optionsMask,
                                                      optionsOverride);
}
CHIP_ERROR chip_ime_AppendCommand_ColorControl_MoveToSaturation(chip::Controller::Device * device, chip::EndpointId ZCLendpointId,
                                                                chip::GroupId ZCLgroupId, uint8_t saturation,
                                                                uint16_t transitionTime, uint8_t optionsMask,
                                                                uint8_t optionsOverride)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::ColorControlCluster clusterColorControl;
    (void) ZCLgroupId;
    clusterColorControl.Associate(device, ZCLendpointId);
    return clusterColorControl.MoveToSaturation(nullptr, nullptr, saturation, transitionTime, optionsMask, optionsOverride);
}
CHIP_ERROR chip_ime_AppendCommand_ColorControl_StepColor(chip::Controller::Device * device, chip::EndpointId ZCLendpointId,
                                                         chip::GroupId ZCLgroupId, int16_t stepX, int16_t stepY,
                                                         uint16_t transitionTime, uint8_t optionsMask, uint8_t optionsOverride)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::ColorControlCluster clusterColorControl;
    (void) ZCLgroupId;
    clusterColorControl.Associate(device, ZCLendpointId);
    return clusterColorControl.StepColor(nullptr, nullptr, stepX, stepY, transitionTime, optionsMask, optionsOverride);
}
CHIP_ERROR chip_ime_AppendCommand_ColorControl_StepColorTemperature(chip::Controller::Device * device,
                                                                    chip::EndpointId ZCLendpointId, chip::GroupId ZCLgroupId,
                                                                    uint8_t stepMode, uint16_t stepSize, uint16_t transitionTime,
                                                                    uint16_t colorTemperatureMinimum,
                                                                    uint16_t colorTemperatureMaximum, uint8_t optionsMask,
                                                                    uint8_t optionsOverride)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::ColorControlCluster clusterColorControl;
    (void) ZCLgroupId;
    clusterColorControl.Associate(device, ZCLendpointId);
    return clusterColorControl.StepColorTemperature(nullptr, nullptr, stepMode, stepSize, transitionTime, colorTemperatureMinimum,
                                                    colorTemperatureMaximum, optionsMask, optionsOverride);
}
CHIP_ERROR chip_ime_AppendCommand_ColorControl_StepHue(chip::Controller::Device * device, chip::EndpointId ZCLendpointId,
                                                       chip::GroupId ZCLgroupId, uint8_t stepMode, uint8_t stepSize,
                                                       uint8_t transitionTime, uint8_t optionsMask, uint8_t optionsOverride)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::ColorControlCluster clusterColorControl;
    (void) ZCLgroupId;
    clusterColorControl.Associate(device, ZCLendpointId);
    return clusterColorControl.StepHue(nullptr, nullptr, stepMode, stepSize, transitionTime, optionsMask, optionsOverride);
}
CHIP_ERROR chip_ime_AppendCommand_ColorControl_StepSaturation(chip::Controller::Device * device, chip::EndpointId ZCLendpointId,
                                                              chip::GroupId ZCLgroupId, uint8_t stepMode, uint8_t stepSize,
                                                              uint8_t transitionTime, uint8_t optionsMask, uint8_t optionsOverride)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::ColorControlCluster clusterColorControl;
    (void) ZCLgroupId;
    clusterColorControl.Associate(device, ZCLendpointId);
    return clusterColorControl.StepSaturation(nullptr, nullptr, stepMode, stepSize, transitionTime, optionsMask, optionsOverride);
}
CHIP_ERROR chip_ime_AppendCommand_ColorControl_StopMoveStep(chip::Controller::Device * device, chip::EndpointId ZCLendpointId,
                                                            chip::GroupId ZCLgroupId, uint8_t optionsMask, uint8_t optionsOverride)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::ColorControlCluster clusterColorControl;
    (void) ZCLgroupId;
    clusterColorControl.Associate(device, ZCLendpointId);
    return clusterColorControl.StopMoveStep(nullptr, nullptr, optionsMask, optionsOverride);
}
// End of Cluster ColorControl

// Cluster DoorLock
CHIP_ERROR chip_ime_AppendCommand_DoorLock_ClearAllPins(chip::Controller::Device * device, chip::EndpointId ZCLendpointId,
                                                        chip::GroupId ZCLgroupId)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::DoorLockCluster clusterDoorLock;
    (void) ZCLgroupId;
    clusterDoorLock.Associate(device, ZCLendpointId);
    return clusterDoorLock.ClearAllPins(nullptr, nullptr);
}
CHIP_ERROR chip_ime_AppendCommand_DoorLock_ClearAllRfids(chip::Controller::Device * device, chip::EndpointId ZCLendpointId,
                                                         chip::GroupId ZCLgroupId)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::DoorLockCluster clusterDoorLock;
    (void) ZCLgroupId;
    clusterDoorLock.Associate(device, ZCLendpointId);
    return clusterDoorLock.ClearAllRfids(nullptr, nullptr);
}
CHIP_ERROR chip_ime_AppendCommand_DoorLock_ClearHolidaySchedule(chip::Controller::Device * device, chip::EndpointId ZCLendpointId,
                                                                chip::GroupId ZCLgroupId, uint8_t scheduleId)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::DoorLockCluster clusterDoorLock;
    (void) ZCLgroupId;
    clusterDoorLock.Associate(device, ZCLendpointId);
    return clusterDoorLock.ClearHolidaySchedule(nullptr, nullptr, scheduleId);
}
CHIP_ERROR chip_ime_AppendCommand_DoorLock_ClearPin(chip::Controller::Device * device, chip::EndpointId ZCLendpointId,
                                                    chip::GroupId ZCLgroupId, uint16_t userId)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::DoorLockCluster clusterDoorLock;
    (void) ZCLgroupId;
    clusterDoorLock.Associate(device, ZCLendpointId);
    return clusterDoorLock.ClearPin(nullptr, nullptr, userId);
}
CHIP_ERROR chip_ime_AppendCommand_DoorLock_ClearRfid(chip::Controller::Device * device, chip::EndpointId ZCLendpointId,
                                                     chip::GroupId ZCLgroupId, uint16_t userId)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::DoorLockCluster clusterDoorLock;
    (void) ZCLgroupId;
    clusterDoorLock.Associate(device, ZCLendpointId);
    return clusterDoorLock.ClearRfid(nullptr, nullptr, userId);
}
CHIP_ERROR chip_ime_AppendCommand_DoorLock_ClearWeekdaySchedule(chip::Controller::Device * device, chip::EndpointId ZCLendpointId,
                                                                chip::GroupId ZCLgroupId, uint8_t scheduleId, uint16_t userId)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::DoorLockCluster clusterDoorLock;
    (void) ZCLgroupId;
    clusterDoorLock.Associate(device, ZCLendpointId);
    return clusterDoorLock.ClearWeekdaySchedule(nullptr, nullptr, scheduleId, userId);
}
CHIP_ERROR chip_ime_AppendCommand_DoorLock_ClearYeardaySchedule(chip::Controller::Device * device, chip::EndpointId ZCLendpointId,
                                                                chip::GroupId ZCLgroupId, uint8_t scheduleId, uint16_t userId)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::DoorLockCluster clusterDoorLock;
    (void) ZCLgroupId;
    clusterDoorLock.Associate(device, ZCLendpointId);
    return clusterDoorLock.ClearYeardaySchedule(nullptr, nullptr, scheduleId, userId);
}
CHIP_ERROR chip_ime_AppendCommand_DoorLock_GetHolidaySchedule(chip::Controller::Device * device, chip::EndpointId ZCLendpointId,
                                                              chip::GroupId ZCLgroupId, uint8_t scheduleId)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::DoorLockCluster clusterDoorLock;
    (void) ZCLgroupId;
    clusterDoorLock.Associate(device, ZCLendpointId);
    return clusterDoorLock.GetHolidaySchedule(nullptr, nullptr, scheduleId);
}
CHIP_ERROR chip_ime_AppendCommand_DoorLock_GetLogRecord(chip::Controller::Device * device, chip::EndpointId ZCLendpointId,
                                                        chip::GroupId ZCLgroupId, uint16_t logIndex)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::DoorLockCluster clusterDoorLock;
    (void) ZCLgroupId;
    clusterDoorLock.Associate(device, ZCLendpointId);
    return clusterDoorLock.GetLogRecord(nullptr, nullptr, logIndex);
}
CHIP_ERROR chip_ime_AppendCommand_DoorLock_GetPin(chip::Controller::Device * device, chip::EndpointId ZCLendpointId,
                                                  chip::GroupId ZCLgroupId, uint16_t userId)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::DoorLockCluster clusterDoorLock;
    (void) ZCLgroupId;
    clusterDoorLock.Associate(device, ZCLendpointId);
    return clusterDoorLock.GetPin(nullptr, nullptr, userId);
}
CHIP_ERROR chip_ime_AppendCommand_DoorLock_GetRfid(chip::Controller::Device * device, chip::EndpointId ZCLendpointId,
                                                   chip::GroupId ZCLgroupId, uint16_t userId)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::DoorLockCluster clusterDoorLock;
    (void) ZCLgroupId;
    clusterDoorLock.Associate(device, ZCLendpointId);
    return clusterDoorLock.GetRfid(nullptr, nullptr, userId);
}
CHIP_ERROR chip_ime_AppendCommand_DoorLock_GetUserType(chip::Controller::Device * device, chip::EndpointId ZCLendpointId,
                                                       chip::GroupId ZCLgroupId, uint16_t userId)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::DoorLockCluster clusterDoorLock;
    (void) ZCLgroupId;
    clusterDoorLock.Associate(device, ZCLendpointId);
    return clusterDoorLock.GetUserType(nullptr, nullptr, userId);
}
CHIP_ERROR chip_ime_AppendCommand_DoorLock_GetWeekdaySchedule(chip::Controller::Device * device, chip::EndpointId ZCLendpointId,
                                                              chip::GroupId ZCLgroupId, uint8_t scheduleId, uint16_t userId)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::DoorLockCluster clusterDoorLock;
    (void) ZCLgroupId;
    clusterDoorLock.Associate(device, ZCLendpointId);
    return clusterDoorLock.GetWeekdaySchedule(nullptr, nullptr, scheduleId, userId);
}
CHIP_ERROR chip_ime_AppendCommand_DoorLock_GetYeardaySchedule(chip::Controller::Device * device, chip::EndpointId ZCLendpointId,
                                                              chip::GroupId ZCLgroupId, uint8_t scheduleId, uint16_t userId)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::DoorLockCluster clusterDoorLock;
    (void) ZCLgroupId;
    clusterDoorLock.Associate(device, ZCLendpointId);
    return clusterDoorLock.GetYeardaySchedule(nullptr, nullptr, scheduleId, userId);
}
CHIP_ERROR chip_ime_AppendCommand_DoorLock_LockDoor(chip::Controller::Device * device, chip::EndpointId ZCLendpointId,
                                                    chip::GroupId ZCLgroupId, const uint8_t * pin, uint32_t pin_Len)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::DoorLockCluster clusterDoorLock;
    (void) ZCLgroupId;
    clusterDoorLock.Associate(device, ZCLendpointId);
    return clusterDoorLock.LockDoor(nullptr, nullptr, chip::ByteSpan(pin, pin_Len));
}
CHIP_ERROR chip_ime_AppendCommand_DoorLock_SetHolidaySchedule(chip::Controller::Device * device, chip::EndpointId ZCLendpointId,
                                                              chip::GroupId ZCLgroupId, uint8_t scheduleId, uint32_t localStartTime,
                                                              uint32_t localEndTime, uint8_t operatingModeDuringHoliday)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::DoorLockCluster clusterDoorLock;
    (void) ZCLgroupId;
    clusterDoorLock.Associate(device, ZCLendpointId);
    return clusterDoorLock.SetHolidaySchedule(nullptr, nullptr, scheduleId, localStartTime, localEndTime,
                                              operatingModeDuringHoliday);
}
CHIP_ERROR chip_ime_AppendCommand_DoorLock_SetPin(chip::Controller::Device * device, chip::EndpointId ZCLendpointId,
                                                  chip::GroupId ZCLgroupId, uint16_t userId, uint8_t userStatus, uint8_t userType,
                                                  const uint8_t * pin, uint32_t pin_Len)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::DoorLockCluster clusterDoorLock;
    (void) ZCLgroupId;
    clusterDoorLock.Associate(device, ZCLendpointId);
    return clusterDoorLock.SetPin(nullptr, nullptr, userId, userStatus, userType, chip::ByteSpan(pin, pin_Len));
}
CHIP_ERROR chip_ime_AppendCommand_DoorLock_SetRfid(chip::Controller::Device * device, chip::EndpointId ZCLendpointId,
                                                   chip::GroupId ZCLgroupId, uint16_t userId, uint8_t userStatus, uint8_t userType,
                                                   const uint8_t * id, uint32_t id_Len)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::DoorLockCluster clusterDoorLock;
    (void) ZCLgroupId;
    clusterDoorLock.Associate(device, ZCLendpointId);
    return clusterDoorLock.SetRfid(nullptr, nullptr, userId, userStatus, userType, chip::ByteSpan(id, id_Len));
}
CHIP_ERROR chip_ime_AppendCommand_DoorLock_SetUserType(chip::Controller::Device * device, chip::EndpointId ZCLendpointId,
                                                       chip::GroupId ZCLgroupId, uint16_t userId, uint8_t userType)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::DoorLockCluster clusterDoorLock;
    (void) ZCLgroupId;
    clusterDoorLock.Associate(device, ZCLendpointId);
    return clusterDoorLock.SetUserType(nullptr, nullptr, userId, userType);
}
CHIP_ERROR chip_ime_AppendCommand_DoorLock_SetWeekdaySchedule(chip::Controller::Device * device, chip::EndpointId ZCLendpointId,
                                                              chip::GroupId ZCLgroupId, uint8_t scheduleId, uint16_t userId,
                                                              uint8_t daysMask, uint8_t startHour, uint8_t startMinute,
                                                              uint8_t endHour, uint8_t endMinute)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::DoorLockCluster clusterDoorLock;
    (void) ZCLgroupId;
    clusterDoorLock.Associate(device, ZCLendpointId);
    return clusterDoorLock.SetWeekdaySchedule(nullptr, nullptr, scheduleId, userId, daysMask, startHour, startMinute, endHour,
                                              endMinute);
}
CHIP_ERROR chip_ime_AppendCommand_DoorLock_SetYeardaySchedule(chip::Controller::Device * device, chip::EndpointId ZCLendpointId,
                                                              chip::GroupId ZCLgroupId, uint8_t scheduleId, uint16_t userId,
                                                              uint32_t localStartTime, uint32_t localEndTime)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::DoorLockCluster clusterDoorLock;
    (void) ZCLgroupId;
    clusterDoorLock.Associate(device, ZCLendpointId);
    return clusterDoorLock.SetYeardaySchedule(nullptr, nullptr, scheduleId, userId, localStartTime, localEndTime);
}
CHIP_ERROR chip_ime_AppendCommand_DoorLock_UnlockDoor(chip::Controller::Device * device, chip::EndpointId ZCLendpointId,
                                                      chip::GroupId ZCLgroupId, const uint8_t * pin, uint32_t pin_Len)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::DoorLockCluster clusterDoorLock;
    (void) ZCLgroupId;
    clusterDoorLock.Associate(device, ZCLendpointId);
    return clusterDoorLock.UnlockDoor(nullptr, nullptr, chip::ByteSpan(pin, pin_Len));
}
CHIP_ERROR chip_ime_AppendCommand_DoorLock_UnlockWithTimeout(chip::Controller::Device * device, chip::EndpointId ZCLendpointId,
                                                             chip::GroupId ZCLgroupId, uint16_t timeoutInSeconds,
                                                             const uint8_t * pin, uint32_t pin_Len)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::DoorLockCluster clusterDoorLock;
    (void) ZCLgroupId;
    clusterDoorLock.Associate(device, ZCLendpointId);
    return clusterDoorLock.UnlockWithTimeout(nullptr, nullptr, timeoutInSeconds, chip::ByteSpan(pin, pin_Len));
}
// End of Cluster DoorLock

// Cluster GeneralCommissioning
CHIP_ERROR chip_ime_AppendCommand_GeneralCommissioning_ArmFailSafe(chip::Controller::Device * device,
                                                                   chip::EndpointId ZCLendpointId, chip::GroupId ZCLgroupId,
                                                                   uint16_t expiryLengthSeconds, uint64_t breadcrumb,
                                                                   uint32_t timeoutMs)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::GeneralCommissioningCluster clusterGeneralCommissioning;
    (void) ZCLgroupId;
    clusterGeneralCommissioning.Associate(device, ZCLendpointId);
    return clusterGeneralCommissioning.ArmFailSafe(nullptr, nullptr, expiryLengthSeconds, breadcrumb, timeoutMs);
}
CHIP_ERROR chip_ime_AppendCommand_GeneralCommissioning_CommissioningComplete(chip::Controller::Device * device,
                                                                             chip::EndpointId ZCLendpointId,
                                                                             chip::GroupId ZCLgroupId)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::GeneralCommissioningCluster clusterGeneralCommissioning;
    (void) ZCLgroupId;
    clusterGeneralCommissioning.Associate(device, ZCLendpointId);
    return clusterGeneralCommissioning.CommissioningComplete(nullptr, nullptr);
}
CHIP_ERROR chip_ime_AppendCommand_GeneralCommissioning_SetFabric(chip::Controller::Device * device, chip::EndpointId ZCLendpointId,
                                                                 chip::GroupId ZCLgroupId, const uint8_t * fabricId,
                                                                 uint32_t fabricId_Len, const uint8_t * fabricSecret,
                                                                 uint32_t fabricSecret_Len, uint64_t breadcrumb, uint32_t timeoutMs)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::GeneralCommissioningCluster clusterGeneralCommissioning;
    (void) ZCLgroupId;
    clusterGeneralCommissioning.Associate(device, ZCLendpointId);
    return clusterGeneralCommissioning.SetFabric(nullptr, nullptr, chip::ByteSpan(fabricId, fabricId_Len),
                                                 chip::ByteSpan(fabricSecret, fabricSecret_Len), breadcrumb, timeoutMs);
}
// End of Cluster GeneralCommissioning

// Cluster GroupKeyManagement
// End of Cluster GroupKeyManagement

// Cluster Groups
CHIP_ERROR chip_ime_AppendCommand_Groups_AddGroup(chip::Controller::Device * device, chip::EndpointId ZCLendpointId,
                                                  chip::GroupId ZCLgroupId, uint16_t groupId, const uint8_t * groupName,
                                                  uint32_t groupName_Len)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::GroupsCluster clusterGroups;
    (void) ZCLgroupId;
    clusterGroups.Associate(device, ZCLendpointId);
    return clusterGroups.AddGroup(nullptr, nullptr, groupId, chip::ByteSpan(groupName, groupName_Len));
}
CHIP_ERROR chip_ime_AppendCommand_Groups_AddGroupIfIdentifying(chip::Controller::Device * device, chip::EndpointId ZCLendpointId,
                                                               chip::GroupId ZCLgroupId, uint16_t groupId,
                                                               const uint8_t * groupName, uint32_t groupName_Len)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::GroupsCluster clusterGroups;
    (void) ZCLgroupId;
    clusterGroups.Associate(device, ZCLendpointId);
    return clusterGroups.AddGroupIfIdentifying(nullptr, nullptr, groupId, chip::ByteSpan(groupName, groupName_Len));
}
CHIP_ERROR chip_ime_AppendCommand_Groups_GetGroupMembership(chip::Controller::Device * device, chip::EndpointId ZCLendpointId,
                                                            chip::GroupId ZCLgroupId, uint8_t groupCount, uint16_t groupList)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::GroupsCluster clusterGroups;
    (void) ZCLgroupId;
    clusterGroups.Associate(device, ZCLendpointId);
    return clusterGroups.GetGroupMembership(nullptr, nullptr, groupCount, groupList);
}
CHIP_ERROR chip_ime_AppendCommand_Groups_RemoveAllGroups(chip::Controller::Device * device, chip::EndpointId ZCLendpointId,
                                                         chip::GroupId ZCLgroupId)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::GroupsCluster clusterGroups;
    (void) ZCLgroupId;
    clusterGroups.Associate(device, ZCLendpointId);
    return clusterGroups.RemoveAllGroups(nullptr, nullptr);
}
CHIP_ERROR chip_ime_AppendCommand_Groups_RemoveGroup(chip::Controller::Device * device, chip::EndpointId ZCLendpointId,
                                                     chip::GroupId ZCLgroupId, uint16_t groupId)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::GroupsCluster clusterGroups;
    (void) ZCLgroupId;
    clusterGroups.Associate(device, ZCLendpointId);
    return clusterGroups.RemoveGroup(nullptr, nullptr, groupId);
}
CHIP_ERROR chip_ime_AppendCommand_Groups_ViewGroup(chip::Controller::Device * device, chip::EndpointId ZCLendpointId,
                                                   chip::GroupId ZCLgroupId, uint16_t groupId)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::GroupsCluster clusterGroups;
    (void) ZCLgroupId;
    clusterGroups.Associate(device, ZCLendpointId);
    return clusterGroups.ViewGroup(nullptr, nullptr, groupId);
}
// End of Cluster Groups

// Cluster IasZone
// End of Cluster IasZone

// Cluster Identify
CHIP_ERROR chip_ime_AppendCommand_Identify_Identify(chip::Controller::Device * device, chip::EndpointId ZCLendpointId,
                                                    chip::GroupId ZCLgroupId, uint16_t identifyTime)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::IdentifyCluster clusterIdentify;
    (void) ZCLgroupId;
    clusterIdentify.Associate(device, ZCLendpointId);
    return clusterIdentify.Identify(nullptr, nullptr, identifyTime);
}
CHIP_ERROR chip_ime_AppendCommand_Identify_IdentifyQuery(chip::Controller::Device * device, chip::EndpointId ZCLendpointId,
                                                         chip::GroupId ZCLgroupId)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::IdentifyCluster clusterIdentify;
    (void) ZCLgroupId;
    clusterIdentify.Associate(device, ZCLendpointId);
    return clusterIdentify.IdentifyQuery(nullptr, nullptr);
}
// End of Cluster Identify

// Cluster LevelControl
CHIP_ERROR chip_ime_AppendCommand_LevelControl_Move(chip::Controller::Device * device, chip::EndpointId ZCLendpointId,
                                                    chip::GroupId ZCLgroupId, uint8_t moveMode, uint8_t rate, uint8_t optionMask,
                                                    uint8_t optionOverride)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::LevelControlCluster clusterLevelControl;
    (void) ZCLgroupId;
    clusterLevelControl.Associate(device, ZCLendpointId);
    return clusterLevelControl.Move(nullptr, nullptr, moveMode, rate, optionMask, optionOverride);
}
CHIP_ERROR chip_ime_AppendCommand_LevelControl_MoveToLevel(chip::Controller::Device * device, chip::EndpointId ZCLendpointId,
                                                           chip::GroupId ZCLgroupId, uint8_t level, uint16_t transitionTime,
                                                           uint8_t optionMask, uint8_t optionOverride)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::LevelControlCluster clusterLevelControl;
    (void) ZCLgroupId;
    clusterLevelControl.Associate(device, ZCLendpointId);
    return clusterLevelControl.MoveToLevel(nullptr, nullptr, level, transitionTime, optionMask, optionOverride);
}
CHIP_ERROR chip_ime_AppendCommand_LevelControl_MoveToLevelWithOnOff(chip::Controller::Device * device,
                                                                    chip::EndpointId ZCLendpointId, chip::GroupId ZCLgroupId,
                                                                    uint8_t level, uint16_t transitionTime)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::LevelControlCluster clusterLevelControl;
    (void) ZCLgroupId;
    clusterLevelControl.Associate(device, ZCLendpointId);
    return clusterLevelControl.MoveToLevelWithOnOff(nullptr, nullptr, level, transitionTime);
}
CHIP_ERROR chip_ime_AppendCommand_LevelControl_MoveWithOnOff(chip::Controller::Device * device, chip::EndpointId ZCLendpointId,
                                                             chip::GroupId ZCLgroupId, uint8_t moveMode, uint8_t rate)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::LevelControlCluster clusterLevelControl;
    (void) ZCLgroupId;
    clusterLevelControl.Associate(device, ZCLendpointId);
    return clusterLevelControl.MoveWithOnOff(nullptr, nullptr, moveMode, rate);
}
CHIP_ERROR chip_ime_AppendCommand_LevelControl_Step(chip::Controller::Device * device, chip::EndpointId ZCLendpointId,
                                                    chip::GroupId ZCLgroupId, uint8_t stepMode, uint8_t stepSize,
                                                    uint16_t transitionTime, uint8_t optionMask, uint8_t optionOverride)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::LevelControlCluster clusterLevelControl;
    (void) ZCLgroupId;
    clusterLevelControl.Associate(device, ZCLendpointId);
    return clusterLevelControl.Step(nullptr, nullptr, stepMode, stepSize, transitionTime, optionMask, optionOverride);
}
CHIP_ERROR chip_ime_AppendCommand_LevelControl_StepWithOnOff(chip::Controller::Device * device, chip::EndpointId ZCLendpointId,
                                                             chip::GroupId ZCLgroupId, uint8_t stepMode, uint8_t stepSize,
                                                             uint16_t transitionTime)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::LevelControlCluster clusterLevelControl;
    (void) ZCLgroupId;
    clusterLevelControl.Associate(device, ZCLendpointId);
    return clusterLevelControl.StepWithOnOff(nullptr, nullptr, stepMode, stepSize, transitionTime);
}
CHIP_ERROR chip_ime_AppendCommand_LevelControl_Stop(chip::Controller::Device * device, chip::EndpointId ZCLendpointId,
                                                    chip::GroupId ZCLgroupId, uint8_t optionMask, uint8_t optionOverride)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::LevelControlCluster clusterLevelControl;
    (void) ZCLgroupId;
    clusterLevelControl.Associate(device, ZCLendpointId);
    return clusterLevelControl.Stop(nullptr, nullptr, optionMask, optionOverride);
}
CHIP_ERROR chip_ime_AppendCommand_LevelControl_StopWithOnOff(chip::Controller::Device * device, chip::EndpointId ZCLendpointId,
                                                             chip::GroupId ZCLgroupId)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::LevelControlCluster clusterLevelControl;
    (void) ZCLgroupId;
    clusterLevelControl.Associate(device, ZCLendpointId);
    return clusterLevelControl.StopWithOnOff(nullptr, nullptr);
}
// End of Cluster LevelControl

// Cluster LowPower
CHIP_ERROR chip_ime_AppendCommand_LowPower_Sleep(chip::Controller::Device * device, chip::EndpointId ZCLendpointId,
                                                 chip::GroupId ZCLgroupId)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::LowPowerCluster clusterLowPower;
    (void) ZCLgroupId;
    clusterLowPower.Associate(device, ZCLendpointId);
    return clusterLowPower.Sleep(nullptr, nullptr);
}
// End of Cluster LowPower

// Cluster NetworkCommissioning
CHIP_ERROR chip_ime_AppendCommand_NetworkCommissioning_AddThreadNetwork(chip::Controller::Device * device,
                                                                        chip::EndpointId ZCLendpointId, chip::GroupId ZCLgroupId,
                                                                        const uint8_t * operationalDataset,
                                                                        uint32_t operationalDataset_Len, uint64_t breadcrumb,
                                                                        uint32_t timeoutMs)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::NetworkCommissioningCluster clusterNetworkCommissioning;
    (void) ZCLgroupId;
    clusterNetworkCommissioning.Associate(device, ZCLendpointId);
    return clusterNetworkCommissioning.AddThreadNetwork(
        nullptr, nullptr, chip::ByteSpan(operationalDataset, operationalDataset_Len), breadcrumb, timeoutMs);
}
CHIP_ERROR chip_ime_AppendCommand_NetworkCommissioning_AddWiFiNetwork(chip::Controller::Device * device,
                                                                      chip::EndpointId ZCLendpointId, chip::GroupId ZCLgroupId,
                                                                      const uint8_t * ssid, uint32_t ssid_Len,
                                                                      const uint8_t * credentials, uint32_t credentials_Len,
                                                                      uint64_t breadcrumb, uint32_t timeoutMs)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::NetworkCommissioningCluster clusterNetworkCommissioning;
    (void) ZCLgroupId;
    clusterNetworkCommissioning.Associate(device, ZCLendpointId);
    return clusterNetworkCommissioning.AddWiFiNetwork(nullptr, nullptr, chip::ByteSpan(ssid, ssid_Len),
                                                      chip::ByteSpan(credentials, credentials_Len), breadcrumb, timeoutMs);
}
CHIP_ERROR chip_ime_AppendCommand_NetworkCommissioning_DisableNetwork(chip::Controller::Device * device,
                                                                      chip::EndpointId ZCLendpointId, chip::GroupId ZCLgroupId,
                                                                      const uint8_t * networkID, uint32_t networkID_Len,
                                                                      uint64_t breadcrumb, uint32_t timeoutMs)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::NetworkCommissioningCluster clusterNetworkCommissioning;
    (void) ZCLgroupId;
    clusterNetworkCommissioning.Associate(device, ZCLendpointId);
    return clusterNetworkCommissioning.DisableNetwork(nullptr, nullptr, chip::ByteSpan(networkID, networkID_Len), breadcrumb,
                                                      timeoutMs);
}
CHIP_ERROR chip_ime_AppendCommand_NetworkCommissioning_EnableNetwork(chip::Controller::Device * device,
                                                                     chip::EndpointId ZCLendpointId, chip::GroupId ZCLgroupId,
                                                                     const uint8_t * networkID, uint32_t networkID_Len,
                                                                     uint64_t breadcrumb, uint32_t timeoutMs)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::NetworkCommissioningCluster clusterNetworkCommissioning;
    (void) ZCLgroupId;
    clusterNetworkCommissioning.Associate(device, ZCLendpointId);
    return clusterNetworkCommissioning.EnableNetwork(nullptr, nullptr, chip::ByteSpan(networkID, networkID_Len), breadcrumb,
                                                     timeoutMs);
}
CHIP_ERROR chip_ime_AppendCommand_NetworkCommissioning_GetLastNetworkCommissioningResult(chip::Controller::Device * device,
                                                                                         chip::EndpointId ZCLendpointId,
                                                                                         chip::GroupId ZCLgroupId,
                                                                                         uint32_t timeoutMs)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::NetworkCommissioningCluster clusterNetworkCommissioning;
    (void) ZCLgroupId;
    clusterNetworkCommissioning.Associate(device, ZCLendpointId);
    return clusterNetworkCommissioning.GetLastNetworkCommissioningResult(nullptr, nullptr, timeoutMs);
}
CHIP_ERROR chip_ime_AppendCommand_NetworkCommissioning_RemoveNetwork(chip::Controller::Device * device,
                                                                     chip::EndpointId ZCLendpointId, chip::GroupId ZCLgroupId,
                                                                     const uint8_t * networkID, uint32_t networkID_Len,
                                                                     uint64_t breadcrumb, uint32_t timeoutMs)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::NetworkCommissioningCluster clusterNetworkCommissioning;
    (void) ZCLgroupId;
    clusterNetworkCommissioning.Associate(device, ZCLendpointId);
    return clusterNetworkCommissioning.RemoveNetwork(nullptr, nullptr, chip::ByteSpan(networkID, networkID_Len), breadcrumb,
                                                     timeoutMs);
}
CHIP_ERROR chip_ime_AppendCommand_NetworkCommissioning_ScanNetworks(chip::Controller::Device * device,
                                                                    chip::EndpointId ZCLendpointId, chip::GroupId ZCLgroupId,
                                                                    const uint8_t * ssid, uint32_t ssid_Len, uint64_t breadcrumb,
                                                                    uint32_t timeoutMs)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::NetworkCommissioningCluster clusterNetworkCommissioning;
    (void) ZCLgroupId;
    clusterNetworkCommissioning.Associate(device, ZCLendpointId);
    return clusterNetworkCommissioning.ScanNetworks(nullptr, nullptr, chip::ByteSpan(ssid, ssid_Len), breadcrumb, timeoutMs);
}
CHIP_ERROR chip_ime_AppendCommand_NetworkCommissioning_UpdateThreadNetwork(chip::Controller::Device * device,
                                                                           chip::EndpointId ZCLendpointId, chip::GroupId ZCLgroupId,
                                                                           const uint8_t * operationalDataset,
                                                                           uint32_t operationalDataset_Len, uint64_t breadcrumb,
                                                                           uint32_t timeoutMs)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::NetworkCommissioningCluster clusterNetworkCommissioning;
    (void) ZCLgroupId;
    clusterNetworkCommissioning.Associate(device, ZCLendpointId);
    return clusterNetworkCommissioning.UpdateThreadNetwork(
        nullptr, nullptr, chip::ByteSpan(operationalDataset, operationalDataset_Len), breadcrumb, timeoutMs);
}
CHIP_ERROR chip_ime_AppendCommand_NetworkCommissioning_UpdateWiFiNetwork(chip::Controller::Device * device,
                                                                         chip::EndpointId ZCLendpointId, chip::GroupId ZCLgroupId,
                                                                         const uint8_t * ssid, uint32_t ssid_Len,
                                                                         const uint8_t * credentials, uint32_t credentials_Len,
                                                                         uint64_t breadcrumb, uint32_t timeoutMs)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::NetworkCommissioningCluster clusterNetworkCommissioning;
    (void) ZCLgroupId;
    clusterNetworkCommissioning.Associate(device, ZCLendpointId);
    return clusterNetworkCommissioning.UpdateWiFiNetwork(nullptr, nullptr, chip::ByteSpan(ssid, ssid_Len),
                                                         chip::ByteSpan(credentials, credentials_Len), breadcrumb, timeoutMs);
}
// End of Cluster NetworkCommissioning

// Cluster OnOff
CHIP_ERROR chip_ime_AppendCommand_OnOff_Off(chip::Controller::Device * device, chip::EndpointId ZCLendpointId,
                                            chip::GroupId ZCLgroupId)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::OnOffCluster clusterOnOff;
    (void) ZCLgroupId;
    clusterOnOff.Associate(device, ZCLendpointId);
    return clusterOnOff.Off(nullptr, nullptr);
}
CHIP_ERROR chip_ime_AppendCommand_OnOff_On(chip::Controller::Device * device, chip::EndpointId ZCLendpointId,
                                           chip::GroupId ZCLgroupId)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::OnOffCluster clusterOnOff;
    (void) ZCLgroupId;
    clusterOnOff.Associate(device, ZCLendpointId);
    return clusterOnOff.On(nullptr, nullptr);
}
CHIP_ERROR chip_ime_AppendCommand_OnOff_Toggle(chip::Controller::Device * device, chip::EndpointId ZCLendpointId,
                                               chip::GroupId ZCLgroupId)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::OnOffCluster clusterOnOff;
    (void) ZCLgroupId;
    clusterOnOff.Associate(device, ZCLendpointId);
    return clusterOnOff.Toggle(nullptr, nullptr);
}
// End of Cluster OnOff

// Cluster Scenes
CHIP_ERROR chip_ime_AppendCommand_Scenes_AddScene(chip::Controller::Device * device, chip::EndpointId ZCLendpointId,
                                                  chip::GroupId ZCLgroupId, uint16_t groupId, uint8_t sceneId,
                                                  uint16_t transitionTime, const uint8_t * sceneName, uint32_t sceneName_Len,
                                                  chip::ClusterId clusterId, uint8_t length, uint8_t value)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::ScenesCluster clusterScenes;
    (void) ZCLgroupId;
    clusterScenes.Associate(device, ZCLendpointId);
    return clusterScenes.AddScene(nullptr, nullptr, groupId, sceneId, transitionTime, chip::ByteSpan(sceneName, sceneName_Len),
                                  clusterId, length, value);
}
CHIP_ERROR chip_ime_AppendCommand_Scenes_GetSceneMembership(chip::Controller::Device * device, chip::EndpointId ZCLendpointId,
                                                            chip::GroupId ZCLgroupId, uint16_t groupId)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::ScenesCluster clusterScenes;
    (void) ZCLgroupId;
    clusterScenes.Associate(device, ZCLendpointId);
    return clusterScenes.GetSceneMembership(nullptr, nullptr, groupId);
}
CHIP_ERROR chip_ime_AppendCommand_Scenes_RecallScene(chip::Controller::Device * device, chip::EndpointId ZCLendpointId,
                                                     chip::GroupId ZCLgroupId, uint16_t groupId, uint8_t sceneId,
                                                     uint16_t transitionTime)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::ScenesCluster clusterScenes;
    (void) ZCLgroupId;
    clusterScenes.Associate(device, ZCLendpointId);
    return clusterScenes.RecallScene(nullptr, nullptr, groupId, sceneId, transitionTime);
}
CHIP_ERROR chip_ime_AppendCommand_Scenes_RemoveAllScenes(chip::Controller::Device * device, chip::EndpointId ZCLendpointId,
                                                         chip::GroupId ZCLgroupId, uint16_t groupId)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::ScenesCluster clusterScenes;
    (void) ZCLgroupId;
    clusterScenes.Associate(device, ZCLendpointId);
    return clusterScenes.RemoveAllScenes(nullptr, nullptr, groupId);
}
CHIP_ERROR chip_ime_AppendCommand_Scenes_RemoveScene(chip::Controller::Device * device, chip::EndpointId ZCLendpointId,
                                                     chip::GroupId ZCLgroupId, uint16_t groupId, uint8_t sceneId)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::ScenesCluster clusterScenes;
    (void) ZCLgroupId;
    clusterScenes.Associate(device, ZCLendpointId);
    return clusterScenes.RemoveScene(nullptr, nullptr, groupId, sceneId);
}
CHIP_ERROR chip_ime_AppendCommand_Scenes_StoreScene(chip::Controller::Device * device, chip::EndpointId ZCLendpointId,
                                                    chip::GroupId ZCLgroupId, uint16_t groupId, uint8_t sceneId)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::ScenesCluster clusterScenes;
    (void) ZCLgroupId;
    clusterScenes.Associate(device, ZCLendpointId);
    return clusterScenes.StoreScene(nullptr, nullptr, groupId, sceneId);
}
CHIP_ERROR chip_ime_AppendCommand_Scenes_ViewScene(chip::Controller::Device * device, chip::EndpointId ZCLendpointId,
                                                   chip::GroupId ZCLgroupId, uint16_t groupId, uint8_t sceneId)
{
    VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
    chip::Controller::ScenesCluster clusterScenes;
    (void) ZCLgroupId;
    clusterScenes.Associate(device, ZCLendpointId);
    return clusterScenes.ViewScene(nullptr, nullptr, groupId, sceneId);
}
// End of Cluster Scenes

// Cluster TemperatureMeasurement
// End of Cluster TemperatureMeasurement
}
