/*
 *
 *    Copyright (c) 2022 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

/**
 *  @file
 *    This file contains definitions for accessors around clusters attributes.
 */

#include <app-common/zap-generated/attributes/Accessors.h>

#include <app-common/zap-generated/attribute-type.h>
#include <app-common/zap-generated/ids/Attributes.h>
#include <app-common/zap-generated/ids/Clusters.h>
#include <app/util/af.h>
#include <app/util/attribute-storage-null-handling.h>
#include <app/util/odd-sized-integers.h>

namespace chip {
namespace app {
namespace Clusters {

namespace Identify {
namespace Attributes {

namespace IdentifyTime {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Identify::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Identify::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace IdentifyTime

namespace IdentifyType {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Identify::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Identify::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace IdentifyType

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Identify::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Identify::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Identify::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Identify::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace Identify

namespace Groups {
namespace Attributes {

namespace NameSupport {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Groups::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Groups::Id, Id, writable, ZCL_BITMAP8_ATTRIBUTE_TYPE);
}

} // namespace NameSupport

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Groups::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Groups::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Groups::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Groups::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace Groups

namespace Scenes {
namespace Attributes {

namespace SceneCount {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Scenes::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Scenes::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

} // namespace SceneCount

namespace CurrentScene {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Scenes::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Scenes::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

} // namespace CurrentScene

namespace CurrentGroup {

EmberAfStatus Get(chip::EndpointId endpoint, chip::GroupId * value)
{
    using Traits = NumericAttributeTraits<chip::GroupId>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Scenes::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::GroupId value)
{
    using Traits = NumericAttributeTraits<chip::GroupId>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Scenes::Id, Id, writable, ZCL_GROUP_ID_ATTRIBUTE_TYPE);
}

} // namespace CurrentGroup

namespace SceneValid {

EmberAfStatus Get(chip::EndpointId endpoint, bool * value)
{
    using Traits = NumericAttributeTraits<bool>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Scenes::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, bool value)
{
    using Traits = NumericAttributeTraits<bool>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Scenes::Id, Id, writable, ZCL_BOOLEAN_ATTRIBUTE_TYPE);
}

} // namespace SceneValid

namespace NameSupport {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Scenes::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Scenes::Id, Id, writable, ZCL_BITMAP8_ATTRIBUTE_TYPE);
}

} // namespace NameSupport

namespace LastConfiguredBy {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<chip::NodeId> & value)
{
    using Traits = NumericAttributeTraits<chip::NodeId>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Scenes::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::NodeId value)
{
    using Traits = NumericAttributeTraits<chip::NodeId>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Scenes::Id, Id, writable, ZCL_NODE_ID_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<chip::NodeId>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::Scenes::Id, Id, writable, ZCL_NODE_ID_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<chip::NodeId> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace LastConfiguredBy

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Scenes::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Scenes::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Scenes::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Scenes::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace Scenes

namespace OnOff {
namespace Attributes {

namespace OnOff {

EmberAfStatus Get(chip::EndpointId endpoint, bool * value)
{
    using Traits = NumericAttributeTraits<bool>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::OnOff::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, bool value)
{
    using Traits = NumericAttributeTraits<bool>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::OnOff::Id, Id, writable, ZCL_BOOLEAN_ATTRIBUTE_TYPE);
}

} // namespace OnOff

namespace GlobalSceneControl {

EmberAfStatus Get(chip::EndpointId endpoint, bool * value)
{
    using Traits = NumericAttributeTraits<bool>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::OnOff::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, bool value)
{
    using Traits = NumericAttributeTraits<bool>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::OnOff::Id, Id, writable, ZCL_BOOLEAN_ATTRIBUTE_TYPE);
}

} // namespace GlobalSceneControl

namespace OnTime {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::OnOff::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::OnOff::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace OnTime

namespace OffWaitTime {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::OnOff::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::OnOff::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace OffWaitTime

namespace StartUpOnOff {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<chip::app::Clusters::OnOff::OnOffStartUpOnOff> & value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::OnOff::OnOffStartUpOnOff>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::OnOff::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::app::Clusters::OnOff::OnOffStartUpOnOff value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::OnOff::OnOffStartUpOnOff>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::OnOff::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::OnOff::OnOffStartUpOnOff>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::OnOff::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint,
                  const chip::app::DataModel::Nullable<chip::app::Clusters::OnOff::OnOffStartUpOnOff> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace StartUpOnOff

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::OnOff::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::OnOff::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::OnOff::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::OnOff::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace OnOff

namespace OnOffSwitchConfiguration {
namespace Attributes {

namespace SwitchType {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::OnOffSwitchConfiguration::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::OnOffSwitchConfiguration::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace SwitchType

namespace SwitchActions {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::OnOffSwitchConfiguration::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::OnOffSwitchConfiguration::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace SwitchActions

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::OnOffSwitchConfiguration::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::OnOffSwitchConfiguration::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::OnOffSwitchConfiguration::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::OnOffSwitchConfiguration::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace OnOffSwitchConfiguration

namespace LevelControl {
namespace Attributes {

namespace CurrentLevel {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint8_t> & value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::LevelControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::LevelControl::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::LevelControl::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint8_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace CurrentLevel

namespace RemainingTime {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::LevelControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::LevelControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace RemainingTime

namespace MinLevel {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::LevelControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::LevelControl::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

} // namespace MinLevel

namespace MaxLevel {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::LevelControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::LevelControl::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

} // namespace MaxLevel

namespace CurrentFrequency {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::LevelControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::LevelControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace CurrentFrequency

namespace MinFrequency {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::LevelControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::LevelControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace MinFrequency

namespace MaxFrequency {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::LevelControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::LevelControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace MaxFrequency

namespace Options {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::LevelControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::LevelControl::Id, Id, writable, ZCL_BITMAP8_ATTRIBUTE_TYPE);
}

} // namespace Options

namespace OnOffTransitionTime {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::LevelControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::LevelControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace OnOffTransitionTime

namespace OnLevel {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint8_t> & value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::LevelControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::LevelControl::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::LevelControl::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint8_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace OnLevel

namespace OnTransitionTime {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint16_t> & value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::LevelControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::LevelControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::LevelControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint16_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace OnTransitionTime

namespace OffTransitionTime {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint16_t> & value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::LevelControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::LevelControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::LevelControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint16_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace OffTransitionTime

namespace DefaultMoveRate {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint8_t> & value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::LevelControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::LevelControl::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::LevelControl::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint8_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace DefaultMoveRate

namespace StartUpCurrentLevel {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint8_t> & value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::LevelControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::LevelControl::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::LevelControl::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint8_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace StartUpCurrentLevel

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::LevelControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::LevelControl::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::LevelControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::LevelControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace LevelControl

namespace BinaryInputBasic {
namespace Attributes {

namespace ActiveText {

EmberAfStatus Get(chip::EndpointId endpoint, chip::MutableCharSpan value)
{
    uint8_t zclString[16 + 1];
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::BinaryInputBasic::Id, Id, zclString, sizeof(zclString));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    size_t length = emberAfStringLength(zclString);
    if (length == NumericAttributeTraits<uint8_t>::kNullValue)
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }

    VerifyOrReturnError(value.size() == 16, EMBER_ZCL_STATUS_INVALID_DATA_TYPE);
    memcpy(value.data(), &zclString[1], 16);
    value.reduce_size(length);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::CharSpan value)
{
    static_assert(16 < NumericAttributeTraits<uint8_t>::kNullValue, "value.size() might be too big");
    VerifyOrReturnError(value.size() <= 16, EMBER_ZCL_STATUS_CONSTRAINT_ERROR);
    uint8_t zclString[16 + 1];
    emberAfCopyInt8u(zclString, 0, static_cast<uint8_t>(value.size()));
    memcpy(&zclString[1], value.data(), value.size());
    return emberAfWriteServerAttribute(endpoint, Clusters::BinaryInputBasic::Id, Id, zclString, ZCL_CHAR_STRING_ATTRIBUTE_TYPE);
}

} // namespace ActiveText

namespace Description {

EmberAfStatus Get(chip::EndpointId endpoint, chip::MutableCharSpan value)
{
    uint8_t zclString[16 + 1];
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::BinaryInputBasic::Id, Id, zclString, sizeof(zclString));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    size_t length = emberAfStringLength(zclString);
    if (length == NumericAttributeTraits<uint8_t>::kNullValue)
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }

    VerifyOrReturnError(value.size() == 16, EMBER_ZCL_STATUS_INVALID_DATA_TYPE);
    memcpy(value.data(), &zclString[1], 16);
    value.reduce_size(length);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::CharSpan value)
{
    static_assert(16 < NumericAttributeTraits<uint8_t>::kNullValue, "value.size() might be too big");
    VerifyOrReturnError(value.size() <= 16, EMBER_ZCL_STATUS_CONSTRAINT_ERROR);
    uint8_t zclString[16 + 1];
    emberAfCopyInt8u(zclString, 0, static_cast<uint8_t>(value.size()));
    memcpy(&zclString[1], value.data(), value.size());
    return emberAfWriteServerAttribute(endpoint, Clusters::BinaryInputBasic::Id, Id, zclString, ZCL_CHAR_STRING_ATTRIBUTE_TYPE);
}

} // namespace Description

namespace InactiveText {

EmberAfStatus Get(chip::EndpointId endpoint, chip::MutableCharSpan value)
{
    uint8_t zclString[16 + 1];
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::BinaryInputBasic::Id, Id, zclString, sizeof(zclString));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    size_t length = emberAfStringLength(zclString);
    if (length == NumericAttributeTraits<uint8_t>::kNullValue)
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }

    VerifyOrReturnError(value.size() == 16, EMBER_ZCL_STATUS_INVALID_DATA_TYPE);
    memcpy(value.data(), &zclString[1], 16);
    value.reduce_size(length);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::CharSpan value)
{
    static_assert(16 < NumericAttributeTraits<uint8_t>::kNullValue, "value.size() might be too big");
    VerifyOrReturnError(value.size() <= 16, EMBER_ZCL_STATUS_CONSTRAINT_ERROR);
    uint8_t zclString[16 + 1];
    emberAfCopyInt8u(zclString, 0, static_cast<uint8_t>(value.size()));
    memcpy(&zclString[1], value.data(), value.size());
    return emberAfWriteServerAttribute(endpoint, Clusters::BinaryInputBasic::Id, Id, zclString, ZCL_CHAR_STRING_ATTRIBUTE_TYPE);
}

} // namespace InactiveText

namespace OutOfService {

EmberAfStatus Get(chip::EndpointId endpoint, bool * value)
{
    using Traits = NumericAttributeTraits<bool>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::BinaryInputBasic::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, bool value)
{
    using Traits = NumericAttributeTraits<bool>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::BinaryInputBasic::Id, Id, writable, ZCL_BOOLEAN_ATTRIBUTE_TYPE);
}

} // namespace OutOfService

namespace Polarity {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::BinaryInputBasic::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::BinaryInputBasic::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace Polarity

namespace PresentValue {

EmberAfStatus Get(chip::EndpointId endpoint, bool * value)
{
    using Traits = NumericAttributeTraits<bool>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::BinaryInputBasic::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, bool value)
{
    using Traits = NumericAttributeTraits<bool>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::BinaryInputBasic::Id, Id, writable, ZCL_BOOLEAN_ATTRIBUTE_TYPE);
}

} // namespace PresentValue

namespace Reliability {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::BinaryInputBasic::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::BinaryInputBasic::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace Reliability

namespace StatusFlags {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::BinaryInputBasic::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::BinaryInputBasic::Id, Id, writable, ZCL_BITMAP8_ATTRIBUTE_TYPE);
}

} // namespace StatusFlags

namespace ApplicationType {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::BinaryInputBasic::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::BinaryInputBasic::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

} // namespace ApplicationType

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::BinaryInputBasic::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::BinaryInputBasic::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::BinaryInputBasic::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::BinaryInputBasic::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace BinaryInputBasic

namespace PulseWidthModulation {
namespace Attributes {

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::PulseWidthModulation::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PulseWidthModulation::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::PulseWidthModulation::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PulseWidthModulation::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace PulseWidthModulation

namespace Descriptor {
namespace Attributes {

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Descriptor::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Descriptor::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Descriptor::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Descriptor::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace Descriptor

namespace Binding {
namespace Attributes {

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Binding::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Binding::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Binding::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Binding::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace Binding

namespace AccessControl {
namespace Attributes {

namespace SubjectsPerAccessControlEntry {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::AccessControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::AccessControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace SubjectsPerAccessControlEntry

namespace TargetsPerAccessControlEntry {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::AccessControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::AccessControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace TargetsPerAccessControlEntry

namespace AccessControlEntriesPerFabric {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::AccessControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::AccessControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace AccessControlEntriesPerFabric

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::AccessControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::AccessControl::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::AccessControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::AccessControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace AccessControl

namespace BridgedActions {
namespace Attributes {

namespace SetupUrl {

EmberAfStatus Get(chip::EndpointId endpoint, chip::MutableCharSpan value)
{
    uint8_t zclString[512 + 2];
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::BridgedActions::Id, Id, zclString, sizeof(zclString));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    size_t length = emberAfLongStringLength(zclString);
    if (length == NumericAttributeTraits<uint16_t>::kNullValue)
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }

    VerifyOrReturnError(value.size() == 512, EMBER_ZCL_STATUS_INVALID_DATA_TYPE);
    memcpy(value.data(), &zclString[2], 512);
    value.reduce_size(length);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::CharSpan value)
{
    static_assert(512 < NumericAttributeTraits<uint16_t>::kNullValue, "value.size() might be too big");
    VerifyOrReturnError(value.size() <= 512, EMBER_ZCL_STATUS_CONSTRAINT_ERROR);
    uint8_t zclString[512 + 2];
    emberAfCopyInt16u(zclString, 0, static_cast<uint16_t>(value.size()));
    memcpy(&zclString[2], value.data(), value.size());
    return emberAfWriteServerAttribute(endpoint, Clusters::BridgedActions::Id, Id, zclString, ZCL_LONG_CHAR_STRING_ATTRIBUTE_TYPE);
}

} // namespace SetupUrl

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::BridgedActions::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::BridgedActions::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::BridgedActions::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::BridgedActions::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace BridgedActions

namespace Basic {
namespace Attributes {

namespace DataModelRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Basic::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Basic::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace DataModelRevision

namespace VendorName {

EmberAfStatus Get(chip::EndpointId endpoint, chip::MutableCharSpan value)
{
    uint8_t zclString[32 + 1];
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Basic::Id, Id, zclString, sizeof(zclString));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    size_t length = emberAfStringLength(zclString);
    if (length == NumericAttributeTraits<uint8_t>::kNullValue)
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }

    VerifyOrReturnError(value.size() == 32, EMBER_ZCL_STATUS_INVALID_DATA_TYPE);
    memcpy(value.data(), &zclString[1], 32);
    value.reduce_size(length);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::CharSpan value)
{
    static_assert(32 < NumericAttributeTraits<uint8_t>::kNullValue, "value.size() might be too big");
    VerifyOrReturnError(value.size() <= 32, EMBER_ZCL_STATUS_CONSTRAINT_ERROR);
    uint8_t zclString[32 + 1];
    emberAfCopyInt8u(zclString, 0, static_cast<uint8_t>(value.size()));
    memcpy(&zclString[1], value.data(), value.size());
    return emberAfWriteServerAttribute(endpoint, Clusters::Basic::Id, Id, zclString, ZCL_CHAR_STRING_ATTRIBUTE_TYPE);
}

} // namespace VendorName

namespace VendorID {

EmberAfStatus Get(chip::EndpointId endpoint, chip::VendorId * value)
{
    using Traits = NumericAttributeTraits<chip::VendorId>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Basic::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::VendorId value)
{
    using Traits = NumericAttributeTraits<chip::VendorId>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Basic::Id, Id, writable, ZCL_VENDOR_ID_ATTRIBUTE_TYPE);
}

} // namespace VendorID

namespace ProductName {

EmberAfStatus Get(chip::EndpointId endpoint, chip::MutableCharSpan value)
{
    uint8_t zclString[32 + 1];
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Basic::Id, Id, zclString, sizeof(zclString));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    size_t length = emberAfStringLength(zclString);
    if (length == NumericAttributeTraits<uint8_t>::kNullValue)
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }

    VerifyOrReturnError(value.size() == 32, EMBER_ZCL_STATUS_INVALID_DATA_TYPE);
    memcpy(value.data(), &zclString[1], 32);
    value.reduce_size(length);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::CharSpan value)
{
    static_assert(32 < NumericAttributeTraits<uint8_t>::kNullValue, "value.size() might be too big");
    VerifyOrReturnError(value.size() <= 32, EMBER_ZCL_STATUS_CONSTRAINT_ERROR);
    uint8_t zclString[32 + 1];
    emberAfCopyInt8u(zclString, 0, static_cast<uint8_t>(value.size()));
    memcpy(&zclString[1], value.data(), value.size());
    return emberAfWriteServerAttribute(endpoint, Clusters::Basic::Id, Id, zclString, ZCL_CHAR_STRING_ATTRIBUTE_TYPE);
}

} // namespace ProductName

namespace ProductID {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Basic::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Basic::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ProductID

namespace NodeLabel {

EmberAfStatus Get(chip::EndpointId endpoint, chip::MutableCharSpan value)
{
    uint8_t zclString[32 + 1];
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Basic::Id, Id, zclString, sizeof(zclString));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    size_t length = emberAfStringLength(zclString);
    if (length == NumericAttributeTraits<uint8_t>::kNullValue)
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }

    VerifyOrReturnError(value.size() == 32, EMBER_ZCL_STATUS_INVALID_DATA_TYPE);
    memcpy(value.data(), &zclString[1], 32);
    value.reduce_size(length);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::CharSpan value)
{
    static_assert(32 < NumericAttributeTraits<uint8_t>::kNullValue, "value.size() might be too big");
    VerifyOrReturnError(value.size() <= 32, EMBER_ZCL_STATUS_CONSTRAINT_ERROR);
    uint8_t zclString[32 + 1];
    emberAfCopyInt8u(zclString, 0, static_cast<uint8_t>(value.size()));
    memcpy(&zclString[1], value.data(), value.size());
    return emberAfWriteServerAttribute(endpoint, Clusters::Basic::Id, Id, zclString, ZCL_CHAR_STRING_ATTRIBUTE_TYPE);
}

} // namespace NodeLabel

namespace Location {

EmberAfStatus Get(chip::EndpointId endpoint, chip::MutableCharSpan value)
{
    uint8_t zclString[2 + 1];
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Basic::Id, Id, zclString, sizeof(zclString));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    size_t length = emberAfStringLength(zclString);
    if (length == NumericAttributeTraits<uint8_t>::kNullValue)
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }

    VerifyOrReturnError(value.size() == 2, EMBER_ZCL_STATUS_INVALID_DATA_TYPE);
    memcpy(value.data(), &zclString[1], 2);
    value.reduce_size(length);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::CharSpan value)
{
    static_assert(2 < NumericAttributeTraits<uint8_t>::kNullValue, "value.size() might be too big");
    VerifyOrReturnError(value.size() <= 2, EMBER_ZCL_STATUS_CONSTRAINT_ERROR);
    uint8_t zclString[2 + 1];
    emberAfCopyInt8u(zclString, 0, static_cast<uint8_t>(value.size()));
    memcpy(&zclString[1], value.data(), value.size());
    return emberAfWriteServerAttribute(endpoint, Clusters::Basic::Id, Id, zclString, ZCL_CHAR_STRING_ATTRIBUTE_TYPE);
}

} // namespace Location

namespace HardwareVersion {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Basic::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Basic::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace HardwareVersion

namespace HardwareVersionString {

EmberAfStatus Get(chip::EndpointId endpoint, chip::MutableCharSpan value)
{
    uint8_t zclString[64 + 1];
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Basic::Id, Id, zclString, sizeof(zclString));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    size_t length = emberAfStringLength(zclString);
    if (length == NumericAttributeTraits<uint8_t>::kNullValue)
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }

    VerifyOrReturnError(value.size() == 64, EMBER_ZCL_STATUS_INVALID_DATA_TYPE);
    memcpy(value.data(), &zclString[1], 64);
    value.reduce_size(length);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::CharSpan value)
{
    static_assert(64 < NumericAttributeTraits<uint8_t>::kNullValue, "value.size() might be too big");
    VerifyOrReturnError(value.size() <= 64, EMBER_ZCL_STATUS_CONSTRAINT_ERROR);
    uint8_t zclString[64 + 1];
    emberAfCopyInt8u(zclString, 0, static_cast<uint8_t>(value.size()));
    memcpy(&zclString[1], value.data(), value.size());
    return emberAfWriteServerAttribute(endpoint, Clusters::Basic::Id, Id, zclString, ZCL_CHAR_STRING_ATTRIBUTE_TYPE);
}

} // namespace HardwareVersionString

namespace SoftwareVersion {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Basic::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Basic::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

} // namespace SoftwareVersion

namespace SoftwareVersionString {

EmberAfStatus Get(chip::EndpointId endpoint, chip::MutableCharSpan value)
{
    uint8_t zclString[64 + 1];
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Basic::Id, Id, zclString, sizeof(zclString));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    size_t length = emberAfStringLength(zclString);
    if (length == NumericAttributeTraits<uint8_t>::kNullValue)
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }

    VerifyOrReturnError(value.size() == 64, EMBER_ZCL_STATUS_INVALID_DATA_TYPE);
    memcpy(value.data(), &zclString[1], 64);
    value.reduce_size(length);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::CharSpan value)
{
    static_assert(64 < NumericAttributeTraits<uint8_t>::kNullValue, "value.size() might be too big");
    VerifyOrReturnError(value.size() <= 64, EMBER_ZCL_STATUS_CONSTRAINT_ERROR);
    uint8_t zclString[64 + 1];
    emberAfCopyInt8u(zclString, 0, static_cast<uint8_t>(value.size()));
    memcpy(&zclString[1], value.data(), value.size());
    return emberAfWriteServerAttribute(endpoint, Clusters::Basic::Id, Id, zclString, ZCL_CHAR_STRING_ATTRIBUTE_TYPE);
}

} // namespace SoftwareVersionString

namespace ManufacturingDate {

EmberAfStatus Get(chip::EndpointId endpoint, chip::MutableCharSpan value)
{
    uint8_t zclString[16 + 1];
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Basic::Id, Id, zclString, sizeof(zclString));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    size_t length = emberAfStringLength(zclString);
    if (length == NumericAttributeTraits<uint8_t>::kNullValue)
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }

    VerifyOrReturnError(value.size() == 16, EMBER_ZCL_STATUS_INVALID_DATA_TYPE);
    memcpy(value.data(), &zclString[1], 16);
    value.reduce_size(length);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::CharSpan value)
{
    static_assert(16 < NumericAttributeTraits<uint8_t>::kNullValue, "value.size() might be too big");
    VerifyOrReturnError(value.size() <= 16, EMBER_ZCL_STATUS_CONSTRAINT_ERROR);
    uint8_t zclString[16 + 1];
    emberAfCopyInt8u(zclString, 0, static_cast<uint8_t>(value.size()));
    memcpy(&zclString[1], value.data(), value.size());
    return emberAfWriteServerAttribute(endpoint, Clusters::Basic::Id, Id, zclString, ZCL_CHAR_STRING_ATTRIBUTE_TYPE);
}

} // namespace ManufacturingDate

namespace PartNumber {

EmberAfStatus Get(chip::EndpointId endpoint, chip::MutableCharSpan value)
{
    uint8_t zclString[32 + 1];
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Basic::Id, Id, zclString, sizeof(zclString));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    size_t length = emberAfStringLength(zclString);
    if (length == NumericAttributeTraits<uint8_t>::kNullValue)
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }

    VerifyOrReturnError(value.size() == 32, EMBER_ZCL_STATUS_INVALID_DATA_TYPE);
    memcpy(value.data(), &zclString[1], 32);
    value.reduce_size(length);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::CharSpan value)
{
    static_assert(32 < NumericAttributeTraits<uint8_t>::kNullValue, "value.size() might be too big");
    VerifyOrReturnError(value.size() <= 32, EMBER_ZCL_STATUS_CONSTRAINT_ERROR);
    uint8_t zclString[32 + 1];
    emberAfCopyInt8u(zclString, 0, static_cast<uint8_t>(value.size()));
    memcpy(&zclString[1], value.data(), value.size());
    return emberAfWriteServerAttribute(endpoint, Clusters::Basic::Id, Id, zclString, ZCL_CHAR_STRING_ATTRIBUTE_TYPE);
}

} // namespace PartNumber

namespace ProductURL {

EmberAfStatus Get(chip::EndpointId endpoint, chip::MutableCharSpan value)
{
    uint8_t zclString[256 + 2];
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Basic::Id, Id, zclString, sizeof(zclString));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    size_t length = emberAfLongStringLength(zclString);
    if (length == NumericAttributeTraits<uint16_t>::kNullValue)
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }

    VerifyOrReturnError(value.size() == 256, EMBER_ZCL_STATUS_INVALID_DATA_TYPE);
    memcpy(value.data(), &zclString[2], 256);
    value.reduce_size(length);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::CharSpan value)
{
    static_assert(256 < NumericAttributeTraits<uint16_t>::kNullValue, "value.size() might be too big");
    VerifyOrReturnError(value.size() <= 256, EMBER_ZCL_STATUS_CONSTRAINT_ERROR);
    uint8_t zclString[256 + 2];
    emberAfCopyInt16u(zclString, 0, static_cast<uint16_t>(value.size()));
    memcpy(&zclString[2], value.data(), value.size());
    return emberAfWriteServerAttribute(endpoint, Clusters::Basic::Id, Id, zclString, ZCL_LONG_CHAR_STRING_ATTRIBUTE_TYPE);
}

} // namespace ProductURL

namespace ProductLabel {

EmberAfStatus Get(chip::EndpointId endpoint, chip::MutableCharSpan value)
{
    uint8_t zclString[64 + 1];
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Basic::Id, Id, zclString, sizeof(zclString));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    size_t length = emberAfStringLength(zclString);
    if (length == NumericAttributeTraits<uint8_t>::kNullValue)
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }

    VerifyOrReturnError(value.size() == 64, EMBER_ZCL_STATUS_INVALID_DATA_TYPE);
    memcpy(value.data(), &zclString[1], 64);
    value.reduce_size(length);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::CharSpan value)
{
    static_assert(64 < NumericAttributeTraits<uint8_t>::kNullValue, "value.size() might be too big");
    VerifyOrReturnError(value.size() <= 64, EMBER_ZCL_STATUS_CONSTRAINT_ERROR);
    uint8_t zclString[64 + 1];
    emberAfCopyInt8u(zclString, 0, static_cast<uint8_t>(value.size()));
    memcpy(&zclString[1], value.data(), value.size());
    return emberAfWriteServerAttribute(endpoint, Clusters::Basic::Id, Id, zclString, ZCL_CHAR_STRING_ATTRIBUTE_TYPE);
}

} // namespace ProductLabel

namespace SerialNumber {

EmberAfStatus Get(chip::EndpointId endpoint, chip::MutableCharSpan value)
{
    uint8_t zclString[32 + 1];
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Basic::Id, Id, zclString, sizeof(zclString));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    size_t length = emberAfStringLength(zclString);
    if (length == NumericAttributeTraits<uint8_t>::kNullValue)
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }

    VerifyOrReturnError(value.size() == 32, EMBER_ZCL_STATUS_INVALID_DATA_TYPE);
    memcpy(value.data(), &zclString[1], 32);
    value.reduce_size(length);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::CharSpan value)
{
    static_assert(32 < NumericAttributeTraits<uint8_t>::kNullValue, "value.size() might be too big");
    VerifyOrReturnError(value.size() <= 32, EMBER_ZCL_STATUS_CONSTRAINT_ERROR);
    uint8_t zclString[32 + 1];
    emberAfCopyInt8u(zclString, 0, static_cast<uint8_t>(value.size()));
    memcpy(&zclString[1], value.data(), value.size());
    return emberAfWriteServerAttribute(endpoint, Clusters::Basic::Id, Id, zclString, ZCL_CHAR_STRING_ATTRIBUTE_TYPE);
}

} // namespace SerialNumber

namespace LocalConfigDisabled {

EmberAfStatus Get(chip::EndpointId endpoint, bool * value)
{
    using Traits = NumericAttributeTraits<bool>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Basic::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, bool value)
{
    using Traits = NumericAttributeTraits<bool>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Basic::Id, Id, writable, ZCL_BOOLEAN_ATTRIBUTE_TYPE);
}

} // namespace LocalConfigDisabled

namespace Reachable {

EmberAfStatus Get(chip::EndpointId endpoint, bool * value)
{
    using Traits = NumericAttributeTraits<bool>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Basic::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, bool value)
{
    using Traits = NumericAttributeTraits<bool>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Basic::Id, Id, writable, ZCL_BOOLEAN_ATTRIBUTE_TYPE);
}

} // namespace Reachable

namespace UniqueID {

EmberAfStatus Get(chip::EndpointId endpoint, chip::MutableCharSpan value)
{
    uint8_t zclString[32 + 1];
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Basic::Id, Id, zclString, sizeof(zclString));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    size_t length = emberAfStringLength(zclString);
    if (length == NumericAttributeTraits<uint8_t>::kNullValue)
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }

    VerifyOrReturnError(value.size() == 32, EMBER_ZCL_STATUS_INVALID_DATA_TYPE);
    memcpy(value.data(), &zclString[1], 32);
    value.reduce_size(length);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::CharSpan value)
{
    static_assert(32 < NumericAttributeTraits<uint8_t>::kNullValue, "value.size() might be too big");
    VerifyOrReturnError(value.size() <= 32, EMBER_ZCL_STATUS_CONSTRAINT_ERROR);
    uint8_t zclString[32 + 1];
    emberAfCopyInt8u(zclString, 0, static_cast<uint8_t>(value.size()));
    memcpy(&zclString[1], value.data(), value.size());
    return emberAfWriteServerAttribute(endpoint, Clusters::Basic::Id, Id, zclString, ZCL_CHAR_STRING_ATTRIBUTE_TYPE);
}

} // namespace UniqueID

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Basic::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Basic::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Basic::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Basic::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace Basic

namespace OtaSoftwareUpdateProvider {
namespace Attributes {

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::OtaSoftwareUpdateProvider::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::OtaSoftwareUpdateProvider::Id, Id, writable,
                                       ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::OtaSoftwareUpdateProvider::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::OtaSoftwareUpdateProvider::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace OtaSoftwareUpdateProvider

namespace OtaSoftwareUpdateRequestor {
namespace Attributes {

namespace UpdatePossible {

EmberAfStatus Get(chip::EndpointId endpoint, bool * value)
{
    using Traits = NumericAttributeTraits<bool>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::OtaSoftwareUpdateRequestor::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, bool value)
{
    using Traits = NumericAttributeTraits<bool>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::OtaSoftwareUpdateRequestor::Id, Id, writable,
                                       ZCL_BOOLEAN_ATTRIBUTE_TYPE);
}

} // namespace UpdatePossible

namespace UpdateState {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::OtaSoftwareUpdateRequestor::OTAUpdateStateEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::OtaSoftwareUpdateRequestor::OTAUpdateStateEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::OtaSoftwareUpdateRequestor::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::app::Clusters::OtaSoftwareUpdateRequestor::OTAUpdateStateEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::OtaSoftwareUpdateRequestor::OTAUpdateStateEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::OtaSoftwareUpdateRequestor::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace UpdateState

namespace UpdateStateProgress {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint8_t> & value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::OtaSoftwareUpdateRequestor::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::OtaSoftwareUpdateRequestor::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::OtaSoftwareUpdateRequestor::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint8_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace UpdateStateProgress

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::OtaSoftwareUpdateRequestor::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::OtaSoftwareUpdateRequestor::Id, Id, writable,
                                       ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::OtaSoftwareUpdateRequestor::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::OtaSoftwareUpdateRequestor::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace OtaSoftwareUpdateRequestor

namespace LocalizationConfiguration {
namespace Attributes {

namespace ActiveLocale {

EmberAfStatus Get(chip::EndpointId endpoint, chip::MutableCharSpan value)
{
    uint8_t zclString[35 + 1];
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::LocalizationConfiguration::Id, Id, zclString, sizeof(zclString));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    size_t length = emberAfStringLength(zclString);
    if (length == NumericAttributeTraits<uint8_t>::kNullValue)
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }

    VerifyOrReturnError(value.size() == 35, EMBER_ZCL_STATUS_INVALID_DATA_TYPE);
    memcpy(value.data(), &zclString[1], 35);
    value.reduce_size(length);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::CharSpan value)
{
    static_assert(35 < NumericAttributeTraits<uint8_t>::kNullValue, "value.size() might be too big");
    VerifyOrReturnError(value.size() <= 35, EMBER_ZCL_STATUS_CONSTRAINT_ERROR);
    uint8_t zclString[35 + 1];
    emberAfCopyInt8u(zclString, 0, static_cast<uint8_t>(value.size()));
    memcpy(&zclString[1], value.data(), value.size());
    return emberAfWriteServerAttribute(endpoint, Clusters::LocalizationConfiguration::Id, Id, zclString,
                                       ZCL_CHAR_STRING_ATTRIBUTE_TYPE);
}

} // namespace ActiveLocale

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::LocalizationConfiguration::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::LocalizationConfiguration::Id, Id, writable,
                                       ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::LocalizationConfiguration::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::LocalizationConfiguration::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace LocalizationConfiguration

namespace TimeFormatLocalization {
namespace Attributes {

namespace HourFormat {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::TimeFormatLocalization::HourFormat * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::TimeFormatLocalization::HourFormat>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TimeFormatLocalization::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::app::Clusters::TimeFormatLocalization::HourFormat value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::TimeFormatLocalization::HourFormat>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TimeFormatLocalization::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace HourFormat

namespace ActiveCalendarType {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::TimeFormatLocalization::CalendarType * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::TimeFormatLocalization::CalendarType>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TimeFormatLocalization::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::app::Clusters::TimeFormatLocalization::CalendarType value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::TimeFormatLocalization::CalendarType>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TimeFormatLocalization::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace ActiveCalendarType

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TimeFormatLocalization::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TimeFormatLocalization::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TimeFormatLocalization::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TimeFormatLocalization::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace TimeFormatLocalization

namespace UnitLocalization {
namespace Attributes {

namespace TemperatureUnit {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::UnitLocalization::TempUnit * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::UnitLocalization::TempUnit>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::UnitLocalization::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::app::Clusters::UnitLocalization::TempUnit value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::UnitLocalization::TempUnit>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::UnitLocalization::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace TemperatureUnit

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::UnitLocalization::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::UnitLocalization::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::UnitLocalization::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::UnitLocalization::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace UnitLocalization

namespace PowerSourceConfiguration {
namespace Attributes {

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::PowerSourceConfiguration::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PowerSourceConfiguration::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::PowerSourceConfiguration::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PowerSourceConfiguration::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace PowerSourceConfiguration

namespace PowerSource {
namespace Attributes {

namespace Status {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::PowerSource::PowerSourceStatus * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::PowerSource::PowerSourceStatus>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::PowerSource::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::app::Clusters::PowerSource::PowerSourceStatus value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::PowerSource::PowerSourceStatus>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PowerSource::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace Status

namespace Order {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::PowerSource::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PowerSource::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

} // namespace Order

namespace Description {

EmberAfStatus Get(chip::EndpointId endpoint, chip::MutableCharSpan value)
{
    uint8_t zclString[60 + 1];
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::PowerSource::Id, Id, zclString, sizeof(zclString));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    size_t length = emberAfStringLength(zclString);
    if (length == NumericAttributeTraits<uint8_t>::kNullValue)
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }

    VerifyOrReturnError(value.size() == 60, EMBER_ZCL_STATUS_INVALID_DATA_TYPE);
    memcpy(value.data(), &zclString[1], 60);
    value.reduce_size(length);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::CharSpan value)
{
    static_assert(60 < NumericAttributeTraits<uint8_t>::kNullValue, "value.size() might be too big");
    VerifyOrReturnError(value.size() <= 60, EMBER_ZCL_STATUS_CONSTRAINT_ERROR);
    uint8_t zclString[60 + 1];
    emberAfCopyInt8u(zclString, 0, static_cast<uint8_t>(value.size()));
    memcpy(&zclString[1], value.data(), value.size());
    return emberAfWriteServerAttribute(endpoint, Clusters::PowerSource::Id, Id, zclString, ZCL_CHAR_STRING_ATTRIBUTE_TYPE);
}

} // namespace Description

namespace WiredAssessedInputVoltage {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint32_t> & value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::PowerSource::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PowerSource::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::PowerSource::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint32_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace WiredAssessedInputVoltage

namespace WiredAssessedInputFrequency {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint16_t> & value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::PowerSource::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PowerSource::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::PowerSource::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint16_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace WiredAssessedInputFrequency

namespace WiredCurrentType {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::PowerSource::WiredCurrentType * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::PowerSource::WiredCurrentType>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::PowerSource::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::app::Clusters::PowerSource::WiredCurrentType value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::PowerSource::WiredCurrentType>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PowerSource::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace WiredCurrentType

namespace WiredAssessedCurrent {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint32_t> & value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::PowerSource::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PowerSource::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::PowerSource::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint32_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace WiredAssessedCurrent

namespace WiredNominalVoltage {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::PowerSource::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PowerSource::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

} // namespace WiredNominalVoltage

namespace WiredMaximumCurrent {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::PowerSource::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PowerSource::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

} // namespace WiredMaximumCurrent

namespace WiredPresent {

EmberAfStatus Get(chip::EndpointId endpoint, bool * value)
{
    using Traits = NumericAttributeTraits<bool>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::PowerSource::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, bool value)
{
    using Traits = NumericAttributeTraits<bool>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PowerSource::Id, Id, writable, ZCL_BOOLEAN_ATTRIBUTE_TYPE);
}

} // namespace WiredPresent

namespace BatVoltage {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint32_t> & value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::PowerSource::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PowerSource::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::PowerSource::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint32_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace BatVoltage

namespace BatPercentRemaining {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint8_t> & value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::PowerSource::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PowerSource::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::PowerSource::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint8_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace BatPercentRemaining

namespace BatTimeRemaining {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint32_t> & value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::PowerSource::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PowerSource::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::PowerSource::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint32_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace BatTimeRemaining

namespace BatChargeLevel {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::PowerSource::BatChargeLevel * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::PowerSource::BatChargeLevel>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::PowerSource::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::app::Clusters::PowerSource::BatChargeLevel value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::PowerSource::BatChargeLevel>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PowerSource::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace BatChargeLevel

namespace BatReplacementNeeded {

EmberAfStatus Get(chip::EndpointId endpoint, bool * value)
{
    using Traits = NumericAttributeTraits<bool>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::PowerSource::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, bool value)
{
    using Traits = NumericAttributeTraits<bool>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PowerSource::Id, Id, writable, ZCL_BOOLEAN_ATTRIBUTE_TYPE);
}

} // namespace BatReplacementNeeded

namespace BatReplaceability {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::PowerSource::BatReplaceability * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::PowerSource::BatReplaceability>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::PowerSource::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::app::Clusters::PowerSource::BatReplaceability value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::PowerSource::BatReplaceability>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PowerSource::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace BatReplaceability

namespace BatPresent {

EmberAfStatus Get(chip::EndpointId endpoint, bool * value)
{
    using Traits = NumericAttributeTraits<bool>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::PowerSource::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, bool value)
{
    using Traits = NumericAttributeTraits<bool>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PowerSource::Id, Id, writable, ZCL_BOOLEAN_ATTRIBUTE_TYPE);
}

} // namespace BatPresent

namespace BatReplacementDescription {

EmberAfStatus Get(chip::EndpointId endpoint, chip::MutableCharSpan value)
{
    uint8_t zclString[60 + 1];
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::PowerSource::Id, Id, zclString, sizeof(zclString));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    size_t length = emberAfStringLength(zclString);
    if (length == NumericAttributeTraits<uint8_t>::kNullValue)
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }

    VerifyOrReturnError(value.size() == 60, EMBER_ZCL_STATUS_INVALID_DATA_TYPE);
    memcpy(value.data(), &zclString[1], 60);
    value.reduce_size(length);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::CharSpan value)
{
    static_assert(60 < NumericAttributeTraits<uint8_t>::kNullValue, "value.size() might be too big");
    VerifyOrReturnError(value.size() <= 60, EMBER_ZCL_STATUS_CONSTRAINT_ERROR);
    uint8_t zclString[60 + 1];
    emberAfCopyInt8u(zclString, 0, static_cast<uint8_t>(value.size()));
    memcpy(&zclString[1], value.data(), value.size());
    return emberAfWriteServerAttribute(endpoint, Clusters::PowerSource::Id, Id, zclString, ZCL_CHAR_STRING_ATTRIBUTE_TYPE);
}

} // namespace BatReplacementDescription

namespace BatCommonDesignation {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::PowerSource::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PowerSource::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

} // namespace BatCommonDesignation

namespace BatANSIDesignation {

EmberAfStatus Get(chip::EndpointId endpoint, chip::MutableCharSpan value)
{
    uint8_t zclString[20 + 1];
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::PowerSource::Id, Id, zclString, sizeof(zclString));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    size_t length = emberAfStringLength(zclString);
    if (length == NumericAttributeTraits<uint8_t>::kNullValue)
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }

    VerifyOrReturnError(value.size() == 20, EMBER_ZCL_STATUS_INVALID_DATA_TYPE);
    memcpy(value.data(), &zclString[1], 20);
    value.reduce_size(length);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::CharSpan value)
{
    static_assert(20 < NumericAttributeTraits<uint8_t>::kNullValue, "value.size() might be too big");
    VerifyOrReturnError(value.size() <= 20, EMBER_ZCL_STATUS_CONSTRAINT_ERROR);
    uint8_t zclString[20 + 1];
    emberAfCopyInt8u(zclString, 0, static_cast<uint8_t>(value.size()));
    memcpy(&zclString[1], value.data(), value.size());
    return emberAfWriteServerAttribute(endpoint, Clusters::PowerSource::Id, Id, zclString, ZCL_CHAR_STRING_ATTRIBUTE_TYPE);
}

} // namespace BatANSIDesignation

namespace BatIECDesignation {

EmberAfStatus Get(chip::EndpointId endpoint, chip::MutableCharSpan value)
{
    uint8_t zclString[20 + 1];
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::PowerSource::Id, Id, zclString, sizeof(zclString));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    size_t length = emberAfStringLength(zclString);
    if (length == NumericAttributeTraits<uint8_t>::kNullValue)
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }

    VerifyOrReturnError(value.size() == 20, EMBER_ZCL_STATUS_INVALID_DATA_TYPE);
    memcpy(value.data(), &zclString[1], 20);
    value.reduce_size(length);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::CharSpan value)
{
    static_assert(20 < NumericAttributeTraits<uint8_t>::kNullValue, "value.size() might be too big");
    VerifyOrReturnError(value.size() <= 20, EMBER_ZCL_STATUS_CONSTRAINT_ERROR);
    uint8_t zclString[20 + 1];
    emberAfCopyInt8u(zclString, 0, static_cast<uint8_t>(value.size()));
    memcpy(&zclString[1], value.data(), value.size());
    return emberAfWriteServerAttribute(endpoint, Clusters::PowerSource::Id, Id, zclString, ZCL_CHAR_STRING_ATTRIBUTE_TYPE);
}

} // namespace BatIECDesignation

namespace BatApprovedChemistry {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::PowerSource::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PowerSource::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

} // namespace BatApprovedChemistry

namespace BatCapacity {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::PowerSource::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PowerSource::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

} // namespace BatCapacity

namespace BatQuantity {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::PowerSource::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PowerSource::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

} // namespace BatQuantity

namespace BatChargeState {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::PowerSource::BatChargeState * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::PowerSource::BatChargeState>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::PowerSource::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::app::Clusters::PowerSource::BatChargeState value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::PowerSource::BatChargeState>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PowerSource::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace BatChargeState

namespace BatTimeToFullCharge {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint32_t> & value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::PowerSource::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PowerSource::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::PowerSource::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint32_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace BatTimeToFullCharge

namespace BatFunctionalWhileCharging {

EmberAfStatus Get(chip::EndpointId endpoint, bool * value)
{
    using Traits = NumericAttributeTraits<bool>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::PowerSource::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, bool value)
{
    using Traits = NumericAttributeTraits<bool>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PowerSource::Id, Id, writable, ZCL_BOOLEAN_ATTRIBUTE_TYPE);
}

} // namespace BatFunctionalWhileCharging

namespace BatChargingCurrent {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint32_t> & value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::PowerSource::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PowerSource::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::PowerSource::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint32_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace BatChargingCurrent

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::PowerSource::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PowerSource::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::PowerSource::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PowerSource::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace PowerSource

namespace GeneralCommissioning {
namespace Attributes {

namespace Breadcrumb {

EmberAfStatus Get(chip::EndpointId endpoint, uint64_t * value)
{
    using Traits = NumericAttributeTraits<uint64_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::GeneralCommissioning::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint64_t value)
{
    using Traits = NumericAttributeTraits<uint64_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::GeneralCommissioning::Id, Id, writable, ZCL_INT64U_ATTRIBUTE_TYPE);
}

} // namespace Breadcrumb

namespace RegulatoryConfig {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::GeneralCommissioning::RegulatoryLocationType * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::GeneralCommissioning::RegulatoryLocationType>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::GeneralCommissioning::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::app::Clusters::GeneralCommissioning::RegulatoryLocationType value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::GeneralCommissioning::RegulatoryLocationType>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::GeneralCommissioning::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace RegulatoryConfig

namespace LocationCapability {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::GeneralCommissioning::RegulatoryLocationType * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::GeneralCommissioning::RegulatoryLocationType>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::GeneralCommissioning::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::app::Clusters::GeneralCommissioning::RegulatoryLocationType value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::GeneralCommissioning::RegulatoryLocationType>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::GeneralCommissioning::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace LocationCapability

namespace SupportsConcurrentConnection {

EmberAfStatus Get(chip::EndpointId endpoint, bool * value)
{
    using Traits = NumericAttributeTraits<bool>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::GeneralCommissioning::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, bool value)
{
    using Traits = NumericAttributeTraits<bool>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::GeneralCommissioning::Id, Id, writable, ZCL_BOOLEAN_ATTRIBUTE_TYPE);
}

} // namespace SupportsConcurrentConnection

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::GeneralCommissioning::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::GeneralCommissioning::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::GeneralCommissioning::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::GeneralCommissioning::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace GeneralCommissioning

namespace NetworkCommissioning {
namespace Attributes {

namespace MaxNetworks {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::NetworkCommissioning::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::NetworkCommissioning::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

} // namespace MaxNetworks

namespace ScanMaxTimeSeconds {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::NetworkCommissioning::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::NetworkCommissioning::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

} // namespace ScanMaxTimeSeconds

namespace ConnectMaxTimeSeconds {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::NetworkCommissioning::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::NetworkCommissioning::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

} // namespace ConnectMaxTimeSeconds

namespace InterfaceEnabled {

EmberAfStatus Get(chip::EndpointId endpoint, bool * value)
{
    using Traits = NumericAttributeTraits<bool>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::NetworkCommissioning::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, bool value)
{
    using Traits = NumericAttributeTraits<bool>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::NetworkCommissioning::Id, Id, writable, ZCL_BOOLEAN_ATTRIBUTE_TYPE);
}

} // namespace InterfaceEnabled

namespace LastNetworkingStatus {

EmberAfStatus Get(chip::EndpointId endpoint,
                  DataModel::Nullable<chip::app::Clusters::NetworkCommissioning::NetworkCommissioningStatus> & value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::NetworkCommissioning::NetworkCommissioningStatus>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::NetworkCommissioning::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::app::Clusters::NetworkCommissioning::NetworkCommissioningStatus value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::NetworkCommissioning::NetworkCommissioningStatus>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::NetworkCommissioning::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::NetworkCommissioning::NetworkCommissioningStatus>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::NetworkCommissioning::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

EmberAfStatus
Set(chip::EndpointId endpoint,
    const chip::app::DataModel::Nullable<chip::app::Clusters::NetworkCommissioning::NetworkCommissioningStatus> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace LastNetworkingStatus

namespace LastNetworkID {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<chip::MutableByteSpan> & value)
{
    uint8_t zclString[32 + 1];
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::NetworkCommissioning::Id, Id, zclString, sizeof(zclString));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    size_t length = emberAfStringLength(zclString);
    if (length == NumericAttributeTraits<uint8_t>::kNullValue)
    {
        value.SetNull();
        return EMBER_ZCL_STATUS_SUCCESS;
    }
    auto & span = value.SetNonNull();

    VerifyOrReturnError(span.size() == 32, EMBER_ZCL_STATUS_INVALID_DATA_TYPE);
    memcpy(span.data(), &zclString[1], 32);
    span.reduce_size(length);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::ByteSpan value)
{
    static_assert(32 < NumericAttributeTraits<uint8_t>::kNullValue, "value.size() might be too big");
    VerifyOrReturnError(value.size() <= 32, EMBER_ZCL_STATUS_CONSTRAINT_ERROR);
    uint8_t zclString[32 + 1];
    emberAfCopyInt8u(zclString, 0, static_cast<uint8_t>(value.size()));
    memcpy(&zclString[1], value.data(), value.size());
    return emberAfWriteServerAttribute(endpoint, Clusters::NetworkCommissioning::Id, Id, zclString,
                                       ZCL_OCTET_STRING_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    uint8_t zclString[1] = { 0xFF };
    return emberAfWriteServerAttribute(endpoint, Clusters::NetworkCommissioning::Id, Id, zclString,
                                       ZCL_OCTET_STRING_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<chip::ByteSpan> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace LastNetworkID

namespace LastConnectErrorValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<int32_t> & value)
{
    using Traits = NumericAttributeTraits<int32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::NetworkCommissioning::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int32_t value)
{
    using Traits = NumericAttributeTraits<int32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::NetworkCommissioning::Id, Id, writable, ZCL_INT32S_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<int32_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::NetworkCommissioning::Id, Id, writable, ZCL_INT32S_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<int32_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace LastConnectErrorValue

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::NetworkCommissioning::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::NetworkCommissioning::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::NetworkCommissioning::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::NetworkCommissioning::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace NetworkCommissioning

namespace DiagnosticLogs {
namespace Attributes {

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::DiagnosticLogs::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::DiagnosticLogs::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::DiagnosticLogs::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::DiagnosticLogs::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace DiagnosticLogs

namespace GeneralDiagnostics {
namespace Attributes {

namespace RebootCount {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::GeneralDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::GeneralDiagnostics::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace RebootCount

namespace UpTime {

EmberAfStatus Get(chip::EndpointId endpoint, uint64_t * value)
{
    using Traits = NumericAttributeTraits<uint64_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::GeneralDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint64_t value)
{
    using Traits = NumericAttributeTraits<uint64_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::GeneralDiagnostics::Id, Id, writable, ZCL_INT64U_ATTRIBUTE_TYPE);
}

} // namespace UpTime

namespace TotalOperationalHours {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::GeneralDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::GeneralDiagnostics::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

} // namespace TotalOperationalHours

namespace BootReasons {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::GeneralDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::GeneralDiagnostics::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace BootReasons

namespace TestEventTriggersEnabled {

EmberAfStatus Get(chip::EndpointId endpoint, bool * value)
{
    using Traits = NumericAttributeTraits<bool>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::GeneralDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, bool value)
{
    using Traits = NumericAttributeTraits<bool>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::GeneralDiagnostics::Id, Id, writable, ZCL_BOOLEAN_ATTRIBUTE_TYPE);
}

} // namespace TestEventTriggersEnabled

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::GeneralDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::GeneralDiagnostics::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::GeneralDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::GeneralDiagnostics::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace GeneralDiagnostics

namespace SoftwareDiagnostics {
namespace Attributes {

namespace CurrentHeapFree {

EmberAfStatus Get(chip::EndpointId endpoint, uint64_t * value)
{
    using Traits = NumericAttributeTraits<uint64_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::SoftwareDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint64_t value)
{
    using Traits = NumericAttributeTraits<uint64_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::SoftwareDiagnostics::Id, Id, writable, ZCL_INT64U_ATTRIBUTE_TYPE);
}

} // namespace CurrentHeapFree

namespace CurrentHeapUsed {

EmberAfStatus Get(chip::EndpointId endpoint, uint64_t * value)
{
    using Traits = NumericAttributeTraits<uint64_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::SoftwareDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint64_t value)
{
    using Traits = NumericAttributeTraits<uint64_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::SoftwareDiagnostics::Id, Id, writable, ZCL_INT64U_ATTRIBUTE_TYPE);
}

} // namespace CurrentHeapUsed

namespace CurrentHeapHighWatermark {

EmberAfStatus Get(chip::EndpointId endpoint, uint64_t * value)
{
    using Traits = NumericAttributeTraits<uint64_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::SoftwareDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint64_t value)
{
    using Traits = NumericAttributeTraits<uint64_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::SoftwareDiagnostics::Id, Id, writable, ZCL_INT64U_ATTRIBUTE_TYPE);
}

} // namespace CurrentHeapHighWatermark

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::SoftwareDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::SoftwareDiagnostics::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::SoftwareDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::SoftwareDiagnostics::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace SoftwareDiagnostics

namespace ThreadNetworkDiagnostics {
namespace Attributes {

namespace Channel {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint16_t> & value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint16_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace Channel

namespace RoutingRole {

EmberAfStatus Get(chip::EndpointId endpoint,
                  DataModel::Nullable<chip::app::Clusters::ThreadNetworkDiagnostics::RoutingRole> & value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::ThreadNetworkDiagnostics::RoutingRole>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::app::Clusters::ThreadNetworkDiagnostics::RoutingRole value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::ThreadNetworkDiagnostics::RoutingRole>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::ThreadNetworkDiagnostics::RoutingRole>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint,
                  const chip::app::DataModel::Nullable<chip::app::Clusters::ThreadNetworkDiagnostics::RoutingRole> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace RoutingRole

namespace NetworkName {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<chip::MutableCharSpan> & value)
{
    uint8_t zclString[16 + 1];
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, zclString, sizeof(zclString));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    size_t length = emberAfStringLength(zclString);
    if (length == NumericAttributeTraits<uint8_t>::kNullValue)
    {
        value.SetNull();
        return EMBER_ZCL_STATUS_SUCCESS;
    }
    auto & span = value.SetNonNull();

    VerifyOrReturnError(span.size() == 16, EMBER_ZCL_STATUS_INVALID_DATA_TYPE);
    memcpy(span.data(), &zclString[1], 16);
    span.reduce_size(length);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::CharSpan value)
{
    static_assert(16 < NumericAttributeTraits<uint8_t>::kNullValue, "value.size() might be too big");
    VerifyOrReturnError(value.size() <= 16, EMBER_ZCL_STATUS_CONSTRAINT_ERROR);
    uint8_t zclString[16 + 1];
    emberAfCopyInt8u(zclString, 0, static_cast<uint8_t>(value.size()));
    memcpy(&zclString[1], value.data(), value.size());
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, zclString,
                                       ZCL_CHAR_STRING_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    uint8_t zclString[1] = { 0xFF };
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, zclString,
                                       ZCL_CHAR_STRING_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<chip::CharSpan> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace NetworkName

namespace PanId {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint16_t> & value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint16_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace PanId

namespace ExtendedPanId {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint64_t> & value)
{
    using Traits = NumericAttributeTraits<uint64_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint64_t value)
{
    using Traits = NumericAttributeTraits<uint64_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT64U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint64_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT64U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint64_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace ExtendedPanId

namespace MeshLocalPrefix {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<chip::MutableByteSpan> & value)
{
    uint8_t zclString[17 + 1];
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, zclString, sizeof(zclString));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    size_t length = emberAfStringLength(zclString);
    if (length == NumericAttributeTraits<uint8_t>::kNullValue)
    {
        value.SetNull();
        return EMBER_ZCL_STATUS_SUCCESS;
    }
    auto & span = value.SetNonNull();

    VerifyOrReturnError(span.size() == 17, EMBER_ZCL_STATUS_INVALID_DATA_TYPE);
    memcpy(span.data(), &zclString[1], 17);
    span.reduce_size(length);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::ByteSpan value)
{
    static_assert(17 < NumericAttributeTraits<uint8_t>::kNullValue, "value.size() might be too big");
    VerifyOrReturnError(value.size() <= 17, EMBER_ZCL_STATUS_CONSTRAINT_ERROR);
    uint8_t zclString[17 + 1];
    emberAfCopyInt8u(zclString, 0, static_cast<uint8_t>(value.size()));
    memcpy(&zclString[1], value.data(), value.size());
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, zclString,
                                       ZCL_OCTET_STRING_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    uint8_t zclString[1] = { 0xFF };
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, zclString,
                                       ZCL_OCTET_STRING_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<chip::ByteSpan> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace MeshLocalPrefix

namespace OverrunCount {

EmberAfStatus Get(chip::EndpointId endpoint, uint64_t * value)
{
    using Traits = NumericAttributeTraits<uint64_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint64_t value)
{
    using Traits = NumericAttributeTraits<uint64_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT64U_ATTRIBUTE_TYPE);
}

} // namespace OverrunCount

namespace PartitionId {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint32_t> & value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint32_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace PartitionId

namespace Weighting {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint8_t> & value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint8_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace Weighting

namespace DataVersion {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint8_t> & value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint8_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace DataVersion

namespace StableDataVersion {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint8_t> & value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint8_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace StableDataVersion

namespace LeaderRouterId {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint8_t> & value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint8_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace LeaderRouterId

namespace DetachedRoleCount {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace DetachedRoleCount

namespace ChildRoleCount {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ChildRoleCount

namespace RouterRoleCount {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace RouterRoleCount

namespace LeaderRoleCount {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace LeaderRoleCount

namespace AttachAttemptCount {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace AttachAttemptCount

namespace PartitionIdChangeCount {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace PartitionIdChangeCount

namespace BetterPartitionAttachAttemptCount {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace BetterPartitionAttachAttemptCount

namespace ParentChangeCount {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ParentChangeCount

namespace TxTotalCount {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

} // namespace TxTotalCount

namespace TxUnicastCount {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

} // namespace TxUnicastCount

namespace TxBroadcastCount {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

} // namespace TxBroadcastCount

namespace TxAckRequestedCount {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

} // namespace TxAckRequestedCount

namespace TxAckedCount {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

} // namespace TxAckedCount

namespace TxNoAckRequestedCount {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

} // namespace TxNoAckRequestedCount

namespace TxDataCount {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

} // namespace TxDataCount

namespace TxDataPollCount {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

} // namespace TxDataPollCount

namespace TxBeaconCount {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

} // namespace TxBeaconCount

namespace TxBeaconRequestCount {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

} // namespace TxBeaconRequestCount

namespace TxOtherCount {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

} // namespace TxOtherCount

namespace TxRetryCount {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

} // namespace TxRetryCount

namespace TxDirectMaxRetryExpiryCount {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

} // namespace TxDirectMaxRetryExpiryCount

namespace TxIndirectMaxRetryExpiryCount {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

} // namespace TxIndirectMaxRetryExpiryCount

namespace TxErrCcaCount {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

} // namespace TxErrCcaCount

namespace TxErrAbortCount {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

} // namespace TxErrAbortCount

namespace TxErrBusyChannelCount {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

} // namespace TxErrBusyChannelCount

namespace RxTotalCount {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

} // namespace RxTotalCount

namespace RxUnicastCount {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

} // namespace RxUnicastCount

namespace RxBroadcastCount {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

} // namespace RxBroadcastCount

namespace RxDataCount {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

} // namespace RxDataCount

namespace RxDataPollCount {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

} // namespace RxDataPollCount

namespace RxBeaconCount {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

} // namespace RxBeaconCount

namespace RxBeaconRequestCount {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

} // namespace RxBeaconRequestCount

namespace RxOtherCount {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

} // namespace RxOtherCount

namespace RxAddressFilteredCount {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

} // namespace RxAddressFilteredCount

namespace RxDestAddrFilteredCount {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

} // namespace RxDestAddrFilteredCount

namespace RxDuplicatedCount {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

} // namespace RxDuplicatedCount

namespace RxErrNoFrameCount {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

} // namespace RxErrNoFrameCount

namespace RxErrUnknownNeighborCount {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

} // namespace RxErrUnknownNeighborCount

namespace RxErrInvalidSrcAddrCount {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

} // namespace RxErrInvalidSrcAddrCount

namespace RxErrSecCount {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

} // namespace RxErrSecCount

namespace RxErrFcsCount {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

} // namespace RxErrFcsCount

namespace RxErrOtherCount {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

} // namespace RxErrOtherCount

namespace ActiveTimestamp {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint64_t> & value)
{
    using Traits = NumericAttributeTraits<uint64_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint64_t value)
{
    using Traits = NumericAttributeTraits<uint64_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT64U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint64_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT64U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint64_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace ActiveTimestamp

namespace PendingTimestamp {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint64_t> & value)
{
    using Traits = NumericAttributeTraits<uint64_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint64_t value)
{
    using Traits = NumericAttributeTraits<uint64_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT64U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint64_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT64U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint64_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace PendingTimestamp

namespace Delay {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint32_t> & value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint32_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace Delay

namespace ChannelPage0Mask {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<chip::MutableByteSpan> & value)
{
    uint8_t zclString[4 + 1];
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, zclString, sizeof(zclString));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    size_t length = emberAfStringLength(zclString);
    if (length == NumericAttributeTraits<uint8_t>::kNullValue)
    {
        value.SetNull();
        return EMBER_ZCL_STATUS_SUCCESS;
    }
    auto & span = value.SetNonNull();

    VerifyOrReturnError(span.size() == 4, EMBER_ZCL_STATUS_INVALID_DATA_TYPE);
    memcpy(span.data(), &zclString[1], 4);
    span.reduce_size(length);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::ByteSpan value)
{
    static_assert(4 < NumericAttributeTraits<uint8_t>::kNullValue, "value.size() might be too big");
    VerifyOrReturnError(value.size() <= 4, EMBER_ZCL_STATUS_CONSTRAINT_ERROR);
    uint8_t zclString[4 + 1];
    emberAfCopyInt8u(zclString, 0, static_cast<uint8_t>(value.size()));
    memcpy(&zclString[1], value.data(), value.size());
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, zclString,
                                       ZCL_OCTET_STRING_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    uint8_t zclString[1] = { 0xFF };
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, zclString,
                                       ZCL_OCTET_STRING_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<chip::ByteSpan> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace ChannelPage0Mask

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace ThreadNetworkDiagnostics

namespace WiFiNetworkDiagnostics {
namespace Attributes {

namespace Bssid {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<chip::MutableByteSpan> & value)
{
    uint8_t zclString[6 + 1];
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::WiFiNetworkDiagnostics::Id, Id, zclString, sizeof(zclString));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    size_t length = emberAfStringLength(zclString);
    if (length == NumericAttributeTraits<uint8_t>::kNullValue)
    {
        value.SetNull();
        return EMBER_ZCL_STATUS_SUCCESS;
    }
    auto & span = value.SetNonNull();

    VerifyOrReturnError(span.size() == 6, EMBER_ZCL_STATUS_INVALID_DATA_TYPE);
    memcpy(span.data(), &zclString[1], 6);
    span.reduce_size(length);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::ByteSpan value)
{
    static_assert(6 < NumericAttributeTraits<uint8_t>::kNullValue, "value.size() might be too big");
    VerifyOrReturnError(value.size() <= 6, EMBER_ZCL_STATUS_CONSTRAINT_ERROR);
    uint8_t zclString[6 + 1];
    emberAfCopyInt8u(zclString, 0, static_cast<uint8_t>(value.size()));
    memcpy(&zclString[1], value.data(), value.size());
    return emberAfWriteServerAttribute(endpoint, Clusters::WiFiNetworkDiagnostics::Id, Id, zclString,
                                       ZCL_OCTET_STRING_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    uint8_t zclString[1] = { 0xFF };
    return emberAfWriteServerAttribute(endpoint, Clusters::WiFiNetworkDiagnostics::Id, Id, zclString,
                                       ZCL_OCTET_STRING_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<chip::ByteSpan> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace Bssid

namespace SecurityType {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<chip::app::Clusters::WiFiNetworkDiagnostics::SecurityType> & value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::WiFiNetworkDiagnostics::SecurityType>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::WiFiNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::app::Clusters::WiFiNetworkDiagnostics::SecurityType value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::WiFiNetworkDiagnostics::SecurityType>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::WiFiNetworkDiagnostics::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::WiFiNetworkDiagnostics::SecurityType>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::WiFiNetworkDiagnostics::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint,
                  const chip::app::DataModel::Nullable<chip::app::Clusters::WiFiNetworkDiagnostics::SecurityType> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace SecurityType

namespace WiFiVersion {

EmberAfStatus Get(chip::EndpointId endpoint,
                  DataModel::Nullable<chip::app::Clusters::WiFiNetworkDiagnostics::WiFiVersionType> & value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::WiFiNetworkDiagnostics::WiFiVersionType>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::WiFiNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::app::Clusters::WiFiNetworkDiagnostics::WiFiVersionType value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::WiFiNetworkDiagnostics::WiFiVersionType>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::WiFiNetworkDiagnostics::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::WiFiNetworkDiagnostics::WiFiVersionType>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::WiFiNetworkDiagnostics::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint,
                  const chip::app::DataModel::Nullable<chip::app::Clusters::WiFiNetworkDiagnostics::WiFiVersionType> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace WiFiVersion

namespace ChannelNumber {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint16_t> & value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::WiFiNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::WiFiNetworkDiagnostics::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::WiFiNetworkDiagnostics::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint16_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace ChannelNumber

namespace Rssi {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<int8_t> & value)
{
    using Traits = NumericAttributeTraits<int8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::WiFiNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int8_t value)
{
    using Traits = NumericAttributeTraits<int8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::WiFiNetworkDiagnostics::Id, Id, writable, ZCL_INT8S_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<int8_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::WiFiNetworkDiagnostics::Id, Id, writable, ZCL_INT8S_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<int8_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace Rssi

namespace BeaconLostCount {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint32_t> & value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::WiFiNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::WiFiNetworkDiagnostics::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::WiFiNetworkDiagnostics::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint32_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace BeaconLostCount

namespace BeaconRxCount {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint32_t> & value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::WiFiNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::WiFiNetworkDiagnostics::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::WiFiNetworkDiagnostics::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint32_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace BeaconRxCount

namespace PacketMulticastRxCount {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint32_t> & value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::WiFiNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::WiFiNetworkDiagnostics::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::WiFiNetworkDiagnostics::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint32_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace PacketMulticastRxCount

namespace PacketMulticastTxCount {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint32_t> & value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::WiFiNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::WiFiNetworkDiagnostics::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::WiFiNetworkDiagnostics::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint32_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace PacketMulticastTxCount

namespace PacketUnicastRxCount {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint32_t> & value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::WiFiNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::WiFiNetworkDiagnostics::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::WiFiNetworkDiagnostics::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint32_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace PacketUnicastRxCount

namespace PacketUnicastTxCount {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint32_t> & value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::WiFiNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::WiFiNetworkDiagnostics::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::WiFiNetworkDiagnostics::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint32_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace PacketUnicastTxCount

namespace CurrentMaxRate {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint64_t> & value)
{
    using Traits = NumericAttributeTraits<uint64_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::WiFiNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint64_t value)
{
    using Traits = NumericAttributeTraits<uint64_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::WiFiNetworkDiagnostics::Id, Id, writable, ZCL_INT64U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint64_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::WiFiNetworkDiagnostics::Id, Id, writable, ZCL_INT64U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint64_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace CurrentMaxRate

namespace OverrunCount {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint64_t> & value)
{
    using Traits = NumericAttributeTraits<uint64_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::WiFiNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint64_t value)
{
    using Traits = NumericAttributeTraits<uint64_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::WiFiNetworkDiagnostics::Id, Id, writable, ZCL_INT64U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint64_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::WiFiNetworkDiagnostics::Id, Id, writable, ZCL_INT64U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint64_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace OverrunCount

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::WiFiNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::WiFiNetworkDiagnostics::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::WiFiNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::WiFiNetworkDiagnostics::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace WiFiNetworkDiagnostics

namespace EthernetNetworkDiagnostics {
namespace Attributes {

namespace PHYRate {

EmberAfStatus Get(chip::EndpointId endpoint,
                  DataModel::Nullable<chip::app::Clusters::EthernetNetworkDiagnostics::PHYRateType> & value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::EthernetNetworkDiagnostics::PHYRateType>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::EthernetNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::app::Clusters::EthernetNetworkDiagnostics::PHYRateType value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::EthernetNetworkDiagnostics::PHYRateType>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::EthernetNetworkDiagnostics::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::EthernetNetworkDiagnostics::PHYRateType>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::EthernetNetworkDiagnostics::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint,
                  const chip::app::DataModel::Nullable<chip::app::Clusters::EthernetNetworkDiagnostics::PHYRateType> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace PHYRate

namespace FullDuplex {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<bool> & value)
{
    using Traits = NumericAttributeTraits<bool>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::EthernetNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, bool value)
{
    using Traits = NumericAttributeTraits<bool>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::EthernetNetworkDiagnostics::Id, Id, writable,
                                       ZCL_BOOLEAN_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<bool>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::EthernetNetworkDiagnostics::Id, Id, writable,
                                       ZCL_BOOLEAN_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<bool> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace FullDuplex

namespace PacketRxCount {

EmberAfStatus Get(chip::EndpointId endpoint, uint64_t * value)
{
    using Traits = NumericAttributeTraits<uint64_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::EthernetNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint64_t value)
{
    using Traits = NumericAttributeTraits<uint64_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::EthernetNetworkDiagnostics::Id, Id, writable, ZCL_INT64U_ATTRIBUTE_TYPE);
}

} // namespace PacketRxCount

namespace PacketTxCount {

EmberAfStatus Get(chip::EndpointId endpoint, uint64_t * value)
{
    using Traits = NumericAttributeTraits<uint64_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::EthernetNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint64_t value)
{
    using Traits = NumericAttributeTraits<uint64_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::EthernetNetworkDiagnostics::Id, Id, writable, ZCL_INT64U_ATTRIBUTE_TYPE);
}

} // namespace PacketTxCount

namespace TxErrCount {

EmberAfStatus Get(chip::EndpointId endpoint, uint64_t * value)
{
    using Traits = NumericAttributeTraits<uint64_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::EthernetNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint64_t value)
{
    using Traits = NumericAttributeTraits<uint64_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::EthernetNetworkDiagnostics::Id, Id, writable, ZCL_INT64U_ATTRIBUTE_TYPE);
}

} // namespace TxErrCount

namespace CollisionCount {

EmberAfStatus Get(chip::EndpointId endpoint, uint64_t * value)
{
    using Traits = NumericAttributeTraits<uint64_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::EthernetNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint64_t value)
{
    using Traits = NumericAttributeTraits<uint64_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::EthernetNetworkDiagnostics::Id, Id, writable, ZCL_INT64U_ATTRIBUTE_TYPE);
}

} // namespace CollisionCount

namespace OverrunCount {

EmberAfStatus Get(chip::EndpointId endpoint, uint64_t * value)
{
    using Traits = NumericAttributeTraits<uint64_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::EthernetNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint64_t value)
{
    using Traits = NumericAttributeTraits<uint64_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::EthernetNetworkDiagnostics::Id, Id, writable, ZCL_INT64U_ATTRIBUTE_TYPE);
}

} // namespace OverrunCount

namespace CarrierDetect {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<bool> & value)
{
    using Traits = NumericAttributeTraits<bool>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::EthernetNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, bool value)
{
    using Traits = NumericAttributeTraits<bool>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::EthernetNetworkDiagnostics::Id, Id, writable,
                                       ZCL_BOOLEAN_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<bool>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::EthernetNetworkDiagnostics::Id, Id, writable,
                                       ZCL_BOOLEAN_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<bool> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace CarrierDetect

namespace TimeSinceReset {

EmberAfStatus Get(chip::EndpointId endpoint, uint64_t * value)
{
    using Traits = NumericAttributeTraits<uint64_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::EthernetNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint64_t value)
{
    using Traits = NumericAttributeTraits<uint64_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::EthernetNetworkDiagnostics::Id, Id, writable, ZCL_INT64U_ATTRIBUTE_TYPE);
}

} // namespace TimeSinceReset

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::EthernetNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::EthernetNetworkDiagnostics::Id, Id, writable,
                                       ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::EthernetNetworkDiagnostics::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::EthernetNetworkDiagnostics::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace EthernetNetworkDiagnostics

namespace TimeSynchronization {
namespace Attributes {

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TimeSynchronization::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TimeSynchronization::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TimeSynchronization::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TimeSynchronization::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace TimeSynchronization

namespace BridgedDeviceBasic {
namespace Attributes {

namespace VendorName {

EmberAfStatus Get(chip::EndpointId endpoint, chip::MutableCharSpan value)
{
    uint8_t zclString[32 + 1];
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::BridgedDeviceBasic::Id, Id, zclString, sizeof(zclString));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    size_t length = emberAfStringLength(zclString);
    if (length == NumericAttributeTraits<uint8_t>::kNullValue)
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }

    VerifyOrReturnError(value.size() == 32, EMBER_ZCL_STATUS_INVALID_DATA_TYPE);
    memcpy(value.data(), &zclString[1], 32);
    value.reduce_size(length);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::CharSpan value)
{
    static_assert(32 < NumericAttributeTraits<uint8_t>::kNullValue, "value.size() might be too big");
    VerifyOrReturnError(value.size() <= 32, EMBER_ZCL_STATUS_CONSTRAINT_ERROR);
    uint8_t zclString[32 + 1];
    emberAfCopyInt8u(zclString, 0, static_cast<uint8_t>(value.size()));
    memcpy(&zclString[1], value.data(), value.size());
    return emberAfWriteServerAttribute(endpoint, Clusters::BridgedDeviceBasic::Id, Id, zclString, ZCL_CHAR_STRING_ATTRIBUTE_TYPE);
}

} // namespace VendorName

namespace VendorID {

EmberAfStatus Get(chip::EndpointId endpoint, chip::VendorId * value)
{
    using Traits = NumericAttributeTraits<chip::VendorId>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::BridgedDeviceBasic::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::VendorId value)
{
    using Traits = NumericAttributeTraits<chip::VendorId>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::BridgedDeviceBasic::Id, Id, writable, ZCL_VENDOR_ID_ATTRIBUTE_TYPE);
}

} // namespace VendorID

namespace ProductName {

EmberAfStatus Get(chip::EndpointId endpoint, chip::MutableCharSpan value)
{
    uint8_t zclString[32 + 1];
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::BridgedDeviceBasic::Id, Id, zclString, sizeof(zclString));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    size_t length = emberAfStringLength(zclString);
    if (length == NumericAttributeTraits<uint8_t>::kNullValue)
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }

    VerifyOrReturnError(value.size() == 32, EMBER_ZCL_STATUS_INVALID_DATA_TYPE);
    memcpy(value.data(), &zclString[1], 32);
    value.reduce_size(length);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::CharSpan value)
{
    static_assert(32 < NumericAttributeTraits<uint8_t>::kNullValue, "value.size() might be too big");
    VerifyOrReturnError(value.size() <= 32, EMBER_ZCL_STATUS_CONSTRAINT_ERROR);
    uint8_t zclString[32 + 1];
    emberAfCopyInt8u(zclString, 0, static_cast<uint8_t>(value.size()));
    memcpy(&zclString[1], value.data(), value.size());
    return emberAfWriteServerAttribute(endpoint, Clusters::BridgedDeviceBasic::Id, Id, zclString, ZCL_CHAR_STRING_ATTRIBUTE_TYPE);
}

} // namespace ProductName

namespace NodeLabel {

EmberAfStatus Get(chip::EndpointId endpoint, chip::MutableCharSpan value)
{
    uint8_t zclString[32 + 1];
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::BridgedDeviceBasic::Id, Id, zclString, sizeof(zclString));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    size_t length = emberAfStringLength(zclString);
    if (length == NumericAttributeTraits<uint8_t>::kNullValue)
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }

    VerifyOrReturnError(value.size() == 32, EMBER_ZCL_STATUS_INVALID_DATA_TYPE);
    memcpy(value.data(), &zclString[1], 32);
    value.reduce_size(length);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::CharSpan value)
{
    static_assert(32 < NumericAttributeTraits<uint8_t>::kNullValue, "value.size() might be too big");
    VerifyOrReturnError(value.size() <= 32, EMBER_ZCL_STATUS_CONSTRAINT_ERROR);
    uint8_t zclString[32 + 1];
    emberAfCopyInt8u(zclString, 0, static_cast<uint8_t>(value.size()));
    memcpy(&zclString[1], value.data(), value.size());
    return emberAfWriteServerAttribute(endpoint, Clusters::BridgedDeviceBasic::Id, Id, zclString, ZCL_CHAR_STRING_ATTRIBUTE_TYPE);
}

} // namespace NodeLabel

namespace HardwareVersion {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::BridgedDeviceBasic::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::BridgedDeviceBasic::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace HardwareVersion

namespace HardwareVersionString {

EmberAfStatus Get(chip::EndpointId endpoint, chip::MutableCharSpan value)
{
    uint8_t zclString[64 + 1];
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::BridgedDeviceBasic::Id, Id, zclString, sizeof(zclString));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    size_t length = emberAfStringLength(zclString);
    if (length == NumericAttributeTraits<uint8_t>::kNullValue)
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }

    VerifyOrReturnError(value.size() == 64, EMBER_ZCL_STATUS_INVALID_DATA_TYPE);
    memcpy(value.data(), &zclString[1], 64);
    value.reduce_size(length);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::CharSpan value)
{
    static_assert(64 < NumericAttributeTraits<uint8_t>::kNullValue, "value.size() might be too big");
    VerifyOrReturnError(value.size() <= 64, EMBER_ZCL_STATUS_CONSTRAINT_ERROR);
    uint8_t zclString[64 + 1];
    emberAfCopyInt8u(zclString, 0, static_cast<uint8_t>(value.size()));
    memcpy(&zclString[1], value.data(), value.size());
    return emberAfWriteServerAttribute(endpoint, Clusters::BridgedDeviceBasic::Id, Id, zclString, ZCL_CHAR_STRING_ATTRIBUTE_TYPE);
}

} // namespace HardwareVersionString

namespace SoftwareVersion {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::BridgedDeviceBasic::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::BridgedDeviceBasic::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

} // namespace SoftwareVersion

namespace SoftwareVersionString {

EmberAfStatus Get(chip::EndpointId endpoint, chip::MutableCharSpan value)
{
    uint8_t zclString[64 + 1];
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::BridgedDeviceBasic::Id, Id, zclString, sizeof(zclString));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    size_t length = emberAfStringLength(zclString);
    if (length == NumericAttributeTraits<uint8_t>::kNullValue)
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }

    VerifyOrReturnError(value.size() == 64, EMBER_ZCL_STATUS_INVALID_DATA_TYPE);
    memcpy(value.data(), &zclString[1], 64);
    value.reduce_size(length);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::CharSpan value)
{
    static_assert(64 < NumericAttributeTraits<uint8_t>::kNullValue, "value.size() might be too big");
    VerifyOrReturnError(value.size() <= 64, EMBER_ZCL_STATUS_CONSTRAINT_ERROR);
    uint8_t zclString[64 + 1];
    emberAfCopyInt8u(zclString, 0, static_cast<uint8_t>(value.size()));
    memcpy(&zclString[1], value.data(), value.size());
    return emberAfWriteServerAttribute(endpoint, Clusters::BridgedDeviceBasic::Id, Id, zclString, ZCL_CHAR_STRING_ATTRIBUTE_TYPE);
}

} // namespace SoftwareVersionString

namespace ManufacturingDate {

EmberAfStatus Get(chip::EndpointId endpoint, chip::MutableCharSpan value)
{
    uint8_t zclString[16 + 1];
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::BridgedDeviceBasic::Id, Id, zclString, sizeof(zclString));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    size_t length = emberAfStringLength(zclString);
    if (length == NumericAttributeTraits<uint8_t>::kNullValue)
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }

    VerifyOrReturnError(value.size() == 16, EMBER_ZCL_STATUS_INVALID_DATA_TYPE);
    memcpy(value.data(), &zclString[1], 16);
    value.reduce_size(length);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::CharSpan value)
{
    static_assert(16 < NumericAttributeTraits<uint8_t>::kNullValue, "value.size() might be too big");
    VerifyOrReturnError(value.size() <= 16, EMBER_ZCL_STATUS_CONSTRAINT_ERROR);
    uint8_t zclString[16 + 1];
    emberAfCopyInt8u(zclString, 0, static_cast<uint8_t>(value.size()));
    memcpy(&zclString[1], value.data(), value.size());
    return emberAfWriteServerAttribute(endpoint, Clusters::BridgedDeviceBasic::Id, Id, zclString, ZCL_CHAR_STRING_ATTRIBUTE_TYPE);
}

} // namespace ManufacturingDate

namespace PartNumber {

EmberAfStatus Get(chip::EndpointId endpoint, chip::MutableCharSpan value)
{
    uint8_t zclString[32 + 1];
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::BridgedDeviceBasic::Id, Id, zclString, sizeof(zclString));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    size_t length = emberAfStringLength(zclString);
    if (length == NumericAttributeTraits<uint8_t>::kNullValue)
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }

    VerifyOrReturnError(value.size() == 32, EMBER_ZCL_STATUS_INVALID_DATA_TYPE);
    memcpy(value.data(), &zclString[1], 32);
    value.reduce_size(length);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::CharSpan value)
{
    static_assert(32 < NumericAttributeTraits<uint8_t>::kNullValue, "value.size() might be too big");
    VerifyOrReturnError(value.size() <= 32, EMBER_ZCL_STATUS_CONSTRAINT_ERROR);
    uint8_t zclString[32 + 1];
    emberAfCopyInt8u(zclString, 0, static_cast<uint8_t>(value.size()));
    memcpy(&zclString[1], value.data(), value.size());
    return emberAfWriteServerAttribute(endpoint, Clusters::BridgedDeviceBasic::Id, Id, zclString, ZCL_CHAR_STRING_ATTRIBUTE_TYPE);
}

} // namespace PartNumber

namespace ProductURL {

EmberAfStatus Get(chip::EndpointId endpoint, chip::MutableCharSpan value)
{
    uint8_t zclString[256 + 2];
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::BridgedDeviceBasic::Id, Id, zclString, sizeof(zclString));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    size_t length = emberAfLongStringLength(zclString);
    if (length == NumericAttributeTraits<uint16_t>::kNullValue)
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }

    VerifyOrReturnError(value.size() == 256, EMBER_ZCL_STATUS_INVALID_DATA_TYPE);
    memcpy(value.data(), &zclString[2], 256);
    value.reduce_size(length);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::CharSpan value)
{
    static_assert(256 < NumericAttributeTraits<uint16_t>::kNullValue, "value.size() might be too big");
    VerifyOrReturnError(value.size() <= 256, EMBER_ZCL_STATUS_CONSTRAINT_ERROR);
    uint8_t zclString[256 + 2];
    emberAfCopyInt16u(zclString, 0, static_cast<uint16_t>(value.size()));
    memcpy(&zclString[2], value.data(), value.size());
    return emberAfWriteServerAttribute(endpoint, Clusters::BridgedDeviceBasic::Id, Id, zclString,
                                       ZCL_LONG_CHAR_STRING_ATTRIBUTE_TYPE);
}

} // namespace ProductURL

namespace ProductLabel {

EmberAfStatus Get(chip::EndpointId endpoint, chip::MutableCharSpan value)
{
    uint8_t zclString[64 + 1];
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::BridgedDeviceBasic::Id, Id, zclString, sizeof(zclString));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    size_t length = emberAfStringLength(zclString);
    if (length == NumericAttributeTraits<uint8_t>::kNullValue)
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }

    VerifyOrReturnError(value.size() == 64, EMBER_ZCL_STATUS_INVALID_DATA_TYPE);
    memcpy(value.data(), &zclString[1], 64);
    value.reduce_size(length);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::CharSpan value)
{
    static_assert(64 < NumericAttributeTraits<uint8_t>::kNullValue, "value.size() might be too big");
    VerifyOrReturnError(value.size() <= 64, EMBER_ZCL_STATUS_CONSTRAINT_ERROR);
    uint8_t zclString[64 + 1];
    emberAfCopyInt8u(zclString, 0, static_cast<uint8_t>(value.size()));
    memcpy(&zclString[1], value.data(), value.size());
    return emberAfWriteServerAttribute(endpoint, Clusters::BridgedDeviceBasic::Id, Id, zclString, ZCL_CHAR_STRING_ATTRIBUTE_TYPE);
}

} // namespace ProductLabel

namespace SerialNumber {

EmberAfStatus Get(chip::EndpointId endpoint, chip::MutableCharSpan value)
{
    uint8_t zclString[32 + 1];
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::BridgedDeviceBasic::Id, Id, zclString, sizeof(zclString));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    size_t length = emberAfStringLength(zclString);
    if (length == NumericAttributeTraits<uint8_t>::kNullValue)
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }

    VerifyOrReturnError(value.size() == 32, EMBER_ZCL_STATUS_INVALID_DATA_TYPE);
    memcpy(value.data(), &zclString[1], 32);
    value.reduce_size(length);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::CharSpan value)
{
    static_assert(32 < NumericAttributeTraits<uint8_t>::kNullValue, "value.size() might be too big");
    VerifyOrReturnError(value.size() <= 32, EMBER_ZCL_STATUS_CONSTRAINT_ERROR);
    uint8_t zclString[32 + 1];
    emberAfCopyInt8u(zclString, 0, static_cast<uint8_t>(value.size()));
    memcpy(&zclString[1], value.data(), value.size());
    return emberAfWriteServerAttribute(endpoint, Clusters::BridgedDeviceBasic::Id, Id, zclString, ZCL_CHAR_STRING_ATTRIBUTE_TYPE);
}

} // namespace SerialNumber

namespace Reachable {

EmberAfStatus Get(chip::EndpointId endpoint, bool * value)
{
    using Traits = NumericAttributeTraits<bool>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::BridgedDeviceBasic::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, bool value)
{
    using Traits = NumericAttributeTraits<bool>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::BridgedDeviceBasic::Id, Id, writable, ZCL_BOOLEAN_ATTRIBUTE_TYPE);
}

} // namespace Reachable

namespace UniqueID {

EmberAfStatus Get(chip::EndpointId endpoint, chip::MutableCharSpan value)
{
    uint8_t zclString[32 + 1];
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::BridgedDeviceBasic::Id, Id, zclString, sizeof(zclString));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    size_t length = emberAfStringLength(zclString);
    if (length == NumericAttributeTraits<uint8_t>::kNullValue)
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }

    VerifyOrReturnError(value.size() == 32, EMBER_ZCL_STATUS_INVALID_DATA_TYPE);
    memcpy(value.data(), &zclString[1], 32);
    value.reduce_size(length);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::CharSpan value)
{
    static_assert(32 < NumericAttributeTraits<uint8_t>::kNullValue, "value.size() might be too big");
    VerifyOrReturnError(value.size() <= 32, EMBER_ZCL_STATUS_CONSTRAINT_ERROR);
    uint8_t zclString[32 + 1];
    emberAfCopyInt8u(zclString, 0, static_cast<uint8_t>(value.size()));
    memcpy(&zclString[1], value.data(), value.size());
    return emberAfWriteServerAttribute(endpoint, Clusters::BridgedDeviceBasic::Id, Id, zclString, ZCL_CHAR_STRING_ATTRIBUTE_TYPE);
}

} // namespace UniqueID

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::BridgedDeviceBasic::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::BridgedDeviceBasic::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::BridgedDeviceBasic::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::BridgedDeviceBasic::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace BridgedDeviceBasic

namespace Switch {
namespace Attributes {

namespace NumberOfPositions {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Switch::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Switch::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

} // namespace NumberOfPositions

namespace CurrentPosition {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Switch::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Switch::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

} // namespace CurrentPosition

namespace MultiPressMax {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Switch::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Switch::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

} // namespace MultiPressMax

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Switch::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Switch::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Switch::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Switch::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace Switch

namespace AdministratorCommissioning {
namespace Attributes {

namespace WindowStatus {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::AdministratorCommissioning::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::AdministratorCommissioning::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

} // namespace WindowStatus

namespace AdminFabricIndex {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<chip::FabricIndex> & value)
{
    using Traits = NumericAttributeTraits<chip::FabricIndex>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::AdministratorCommissioning::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::FabricIndex value)
{
    using Traits = NumericAttributeTraits<chip::FabricIndex>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::AdministratorCommissioning::Id, Id, writable,
                                       ZCL_FABRIC_IDX_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<chip::FabricIndex>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::AdministratorCommissioning::Id, Id, writable,
                                       ZCL_FABRIC_IDX_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<chip::FabricIndex> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace AdminFabricIndex

namespace AdminVendorId {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint16_t> & value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::AdministratorCommissioning::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::AdministratorCommissioning::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::AdministratorCommissioning::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint16_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace AdminVendorId

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::AdministratorCommissioning::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::AdministratorCommissioning::Id, Id, writable,
                                       ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::AdministratorCommissioning::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::AdministratorCommissioning::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace AdministratorCommissioning

namespace OperationalCredentials {
namespace Attributes {

namespace SupportedFabrics {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::OperationalCredentials::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::OperationalCredentials::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

} // namespace SupportedFabrics

namespace CommissionedFabrics {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::OperationalCredentials::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::OperationalCredentials::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

} // namespace CommissionedFabrics

namespace CurrentFabricIndex {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::OperationalCredentials::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::OperationalCredentials::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

} // namespace CurrentFabricIndex

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::OperationalCredentials::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::OperationalCredentials::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::OperationalCredentials::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::OperationalCredentials::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace OperationalCredentials

namespace GroupKeyManagement {
namespace Attributes {

namespace MaxGroupsPerFabric {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::GroupKeyManagement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::GroupKeyManagement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace MaxGroupsPerFabric

namespace MaxGroupKeysPerFabric {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::GroupKeyManagement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::GroupKeyManagement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace MaxGroupKeysPerFabric

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::GroupKeyManagement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::GroupKeyManagement::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::GroupKeyManagement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::GroupKeyManagement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace GroupKeyManagement

namespace FixedLabel {
namespace Attributes {

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::FixedLabel::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::FixedLabel::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::FixedLabel::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::FixedLabel::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace FixedLabel

namespace UserLabel {
namespace Attributes {

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::UserLabel::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::UserLabel::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::UserLabel::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::UserLabel::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace UserLabel

namespace ProxyConfiguration {
namespace Attributes {

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ProxyConfiguration::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ProxyConfiguration::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ProxyConfiguration::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ProxyConfiguration::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace ProxyConfiguration

namespace ProxyDiscovery {
namespace Attributes {

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ProxyDiscovery::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ProxyDiscovery::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ProxyDiscovery::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ProxyDiscovery::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace ProxyDiscovery

namespace ProxyValid {
namespace Attributes {

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ProxyValid::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ProxyValid::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ProxyValid::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ProxyValid::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace ProxyValid

namespace BooleanState {
namespace Attributes {

namespace StateValue {

EmberAfStatus Get(chip::EndpointId endpoint, bool * value)
{
    using Traits = NumericAttributeTraits<bool>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::BooleanState::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, bool value)
{
    using Traits = NumericAttributeTraits<bool>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::BooleanState::Id, Id, writable, ZCL_BOOLEAN_ATTRIBUTE_TYPE);
}

} // namespace StateValue

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::BooleanState::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::BooleanState::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::BooleanState::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::BooleanState::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace BooleanState

namespace ModeSelect {
namespace Attributes {

namespace Description {

EmberAfStatus Get(chip::EndpointId endpoint, chip::MutableCharSpan value)
{
    uint8_t zclString[32 + 1];
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ModeSelect::Id, Id, zclString, sizeof(zclString));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    size_t length = emberAfStringLength(zclString);
    if (length == NumericAttributeTraits<uint8_t>::kNullValue)
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }

    VerifyOrReturnError(value.size() == 32, EMBER_ZCL_STATUS_INVALID_DATA_TYPE);
    memcpy(value.data(), &zclString[1], 32);
    value.reduce_size(length);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::CharSpan value)
{
    static_assert(32 < NumericAttributeTraits<uint8_t>::kNullValue, "value.size() might be too big");
    VerifyOrReturnError(value.size() <= 32, EMBER_ZCL_STATUS_CONSTRAINT_ERROR);
    uint8_t zclString[32 + 1];
    emberAfCopyInt8u(zclString, 0, static_cast<uint8_t>(value.size()));
    memcpy(&zclString[1], value.data(), value.size());
    return emberAfWriteServerAttribute(endpoint, Clusters::ModeSelect::Id, Id, zclString, ZCL_CHAR_STRING_ATTRIBUTE_TYPE);
}

} // namespace Description

namespace StandardNamespace {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint16_t> & value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ModeSelect::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ModeSelect::Id, Id, writable, ZCL_ENUM16_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::ModeSelect::Id, Id, writable, ZCL_ENUM16_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint16_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace StandardNamespace

namespace CurrentMode {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ModeSelect::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ModeSelect::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

} // namespace CurrentMode

namespace StartUpMode {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint8_t> & value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ModeSelect::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ModeSelect::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::ModeSelect::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint8_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace StartUpMode

namespace OnMode {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint8_t> & value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ModeSelect::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ModeSelect::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::ModeSelect::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint8_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace OnMode

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ModeSelect::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ModeSelect::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ModeSelect::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ModeSelect::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace ModeSelect

namespace DoorLock {
namespace Attributes {

namespace LockState {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<chip::app::Clusters::DoorLock::DlLockState> & value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::DoorLock::DlLockState>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::DoorLock::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::app::Clusters::DoorLock::DlLockState value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::DoorLock::DlLockState>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::DoorLock::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::DoorLock::DlLockState>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::DoorLock::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint,
                  const chip::app::DataModel::Nullable<chip::app::Clusters::DoorLock::DlLockState> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace LockState

namespace LockType {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::DoorLock::DlLockType * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::DoorLock::DlLockType>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::DoorLock::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::app::Clusters::DoorLock::DlLockType value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::DoorLock::DlLockType>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::DoorLock::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace LockType

namespace ActuatorEnabled {

EmberAfStatus Get(chip::EndpointId endpoint, bool * value)
{
    using Traits = NumericAttributeTraits<bool>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::DoorLock::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, bool value)
{
    using Traits = NumericAttributeTraits<bool>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::DoorLock::Id, Id, writable, ZCL_BOOLEAN_ATTRIBUTE_TYPE);
}

} // namespace ActuatorEnabled

namespace DoorState {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<chip::app::Clusters::DoorLock::DlDoorState> & value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::DoorLock::DlDoorState>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::DoorLock::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::app::Clusters::DoorLock::DlDoorState value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::DoorLock::DlDoorState>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::DoorLock::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::DoorLock::DlDoorState>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::DoorLock::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint,
                  const chip::app::DataModel::Nullable<chip::app::Clusters::DoorLock::DlDoorState> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace DoorState

namespace DoorOpenEvents {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::DoorLock::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::DoorLock::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

} // namespace DoorOpenEvents

namespace DoorClosedEvents {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::DoorLock::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::DoorLock::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

} // namespace DoorClosedEvents

namespace OpenPeriod {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::DoorLock::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::DoorLock::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace OpenPeriod

namespace NumberOfTotalUsersSupported {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::DoorLock::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::DoorLock::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace NumberOfTotalUsersSupported

namespace NumberOfPINUsersSupported {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::DoorLock::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::DoorLock::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace NumberOfPINUsersSupported

namespace NumberOfRFIDUsersSupported {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::DoorLock::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::DoorLock::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace NumberOfRFIDUsersSupported

namespace NumberOfWeekDaySchedulesSupportedPerUser {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::DoorLock::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::DoorLock::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

} // namespace NumberOfWeekDaySchedulesSupportedPerUser

namespace NumberOfYearDaySchedulesSupportedPerUser {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::DoorLock::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::DoorLock::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

} // namespace NumberOfYearDaySchedulesSupportedPerUser

namespace NumberOfHolidaySchedulesSupported {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::DoorLock::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::DoorLock::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

} // namespace NumberOfHolidaySchedulesSupported

namespace MaxPINCodeLength {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::DoorLock::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::DoorLock::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

} // namespace MaxPINCodeLength

namespace MinPINCodeLength {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::DoorLock::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::DoorLock::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

} // namespace MinPINCodeLength

namespace MaxRFIDCodeLength {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::DoorLock::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::DoorLock::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

} // namespace MaxRFIDCodeLength

namespace MinRFIDCodeLength {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::DoorLock::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::DoorLock::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

} // namespace MinRFIDCodeLength

namespace CredentialRulesSupport {

EmberAfStatus Get(chip::EndpointId endpoint, chip::BitMask<chip::app::Clusters::DoorLock::DlCredentialRuleMask> * value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::DoorLock::DlCredentialRuleMask>>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::DoorLock::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::BitMask<chip::app::Clusters::DoorLock::DlCredentialRuleMask> value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::DoorLock::DlCredentialRuleMask>>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::DoorLock::Id, Id, writable, ZCL_BITMAP8_ATTRIBUTE_TYPE);
}

} // namespace CredentialRulesSupport

namespace NumberOfCredentialsSupportedPerUser {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::DoorLock::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::DoorLock::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

} // namespace NumberOfCredentialsSupportedPerUser

namespace Language {

EmberAfStatus Get(chip::EndpointId endpoint, chip::MutableCharSpan value)
{
    uint8_t zclString[3 + 1];
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::DoorLock::Id, Id, zclString, sizeof(zclString));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    size_t length = emberAfStringLength(zclString);
    if (length == NumericAttributeTraits<uint8_t>::kNullValue)
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }

    VerifyOrReturnError(value.size() == 3, EMBER_ZCL_STATUS_INVALID_DATA_TYPE);
    memcpy(value.data(), &zclString[1], 3);
    value.reduce_size(length);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::CharSpan value)
{
    static_assert(3 < NumericAttributeTraits<uint8_t>::kNullValue, "value.size() might be too big");
    VerifyOrReturnError(value.size() <= 3, EMBER_ZCL_STATUS_CONSTRAINT_ERROR);
    uint8_t zclString[3 + 1];
    emberAfCopyInt8u(zclString, 0, static_cast<uint8_t>(value.size()));
    memcpy(&zclString[1], value.data(), value.size());
    return emberAfWriteServerAttribute(endpoint, Clusters::DoorLock::Id, Id, zclString, ZCL_CHAR_STRING_ATTRIBUTE_TYPE);
}

} // namespace Language

namespace LEDSettings {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::DoorLock::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::DoorLock::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

} // namespace LEDSettings

namespace AutoRelockTime {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::DoorLock::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::DoorLock::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

} // namespace AutoRelockTime

namespace SoundVolume {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::DoorLock::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::DoorLock::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

} // namespace SoundVolume

namespace OperatingMode {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::DoorLock::DlOperatingMode * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::DoorLock::DlOperatingMode>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::DoorLock::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::app::Clusters::DoorLock::DlOperatingMode value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::DoorLock::DlOperatingMode>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::DoorLock::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace OperatingMode

namespace SupportedOperatingModes {

EmberAfStatus Get(chip::EndpointId endpoint, chip::BitMask<chip::app::Clusters::DoorLock::DlSupportedOperatingModes> * value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::DoorLock::DlSupportedOperatingModes>>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::DoorLock::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::BitMask<chip::app::Clusters::DoorLock::DlSupportedOperatingModes> value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::DoorLock::DlSupportedOperatingModes>>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::DoorLock::Id, Id, writable, ZCL_BITMAP16_ATTRIBUTE_TYPE);
}

} // namespace SupportedOperatingModes

namespace DefaultConfigurationRegister {

EmberAfStatus Get(chip::EndpointId endpoint, chip::BitMask<chip::app::Clusters::DoorLock::DlDefaultConfigurationRegister> * value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::DoorLock::DlDefaultConfigurationRegister>>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::DoorLock::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::BitMask<chip::app::Clusters::DoorLock::DlDefaultConfigurationRegister> value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::DoorLock::DlDefaultConfigurationRegister>>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::DoorLock::Id, Id, writable, ZCL_BITMAP16_ATTRIBUTE_TYPE);
}

} // namespace DefaultConfigurationRegister

namespace EnableLocalProgramming {

EmberAfStatus Get(chip::EndpointId endpoint, bool * value)
{
    using Traits = NumericAttributeTraits<bool>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::DoorLock::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, bool value)
{
    using Traits = NumericAttributeTraits<bool>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::DoorLock::Id, Id, writable, ZCL_BOOLEAN_ATTRIBUTE_TYPE);
}

} // namespace EnableLocalProgramming

namespace EnableOneTouchLocking {

EmberAfStatus Get(chip::EndpointId endpoint, bool * value)
{
    using Traits = NumericAttributeTraits<bool>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::DoorLock::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, bool value)
{
    using Traits = NumericAttributeTraits<bool>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::DoorLock::Id, Id, writable, ZCL_BOOLEAN_ATTRIBUTE_TYPE);
}

} // namespace EnableOneTouchLocking

namespace EnableInsideStatusLED {

EmberAfStatus Get(chip::EndpointId endpoint, bool * value)
{
    using Traits = NumericAttributeTraits<bool>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::DoorLock::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, bool value)
{
    using Traits = NumericAttributeTraits<bool>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::DoorLock::Id, Id, writable, ZCL_BOOLEAN_ATTRIBUTE_TYPE);
}

} // namespace EnableInsideStatusLED

namespace EnablePrivacyModeButton {

EmberAfStatus Get(chip::EndpointId endpoint, bool * value)
{
    using Traits = NumericAttributeTraits<bool>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::DoorLock::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, bool value)
{
    using Traits = NumericAttributeTraits<bool>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::DoorLock::Id, Id, writable, ZCL_BOOLEAN_ATTRIBUTE_TYPE);
}

} // namespace EnablePrivacyModeButton

namespace LocalProgrammingFeatures {

EmberAfStatus Get(chip::EndpointId endpoint, chip::BitMask<chip::app::Clusters::DoorLock::DlLocalProgrammingFeatures> * value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::DoorLock::DlLocalProgrammingFeatures>>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::DoorLock::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::BitMask<chip::app::Clusters::DoorLock::DlLocalProgrammingFeatures> value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::DoorLock::DlLocalProgrammingFeatures>>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::DoorLock::Id, Id, writable, ZCL_BITMAP8_ATTRIBUTE_TYPE);
}

} // namespace LocalProgrammingFeatures

namespace WrongCodeEntryLimit {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::DoorLock::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::DoorLock::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

} // namespace WrongCodeEntryLimit

namespace UserCodeTemporaryDisableTime {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::DoorLock::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::DoorLock::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

} // namespace UserCodeTemporaryDisableTime

namespace SendPINOverTheAir {

EmberAfStatus Get(chip::EndpointId endpoint, bool * value)
{
    using Traits = NumericAttributeTraits<bool>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::DoorLock::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, bool value)
{
    using Traits = NumericAttributeTraits<bool>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::DoorLock::Id, Id, writable, ZCL_BOOLEAN_ATTRIBUTE_TYPE);
}

} // namespace SendPINOverTheAir

namespace RequirePINforRemoteOperation {

EmberAfStatus Get(chip::EndpointId endpoint, bool * value)
{
    using Traits = NumericAttributeTraits<bool>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::DoorLock::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, bool value)
{
    using Traits = NumericAttributeTraits<bool>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::DoorLock::Id, Id, writable, ZCL_BOOLEAN_ATTRIBUTE_TYPE);
}

} // namespace RequirePINforRemoteOperation

namespace ExpiringUserTimeout {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::DoorLock::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::DoorLock::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ExpiringUserTimeout

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::DoorLock::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::DoorLock::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::DoorLock::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::DoorLock::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace DoorLock

namespace WindowCovering {
namespace Attributes {

namespace Type {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::WindowCovering::Type * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::WindowCovering::Type>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::WindowCovering::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::app::Clusters::WindowCovering::Type value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::WindowCovering::Type>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::WindowCovering::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace Type

namespace PhysicalClosedLimitLift {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::WindowCovering::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::WindowCovering::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace PhysicalClosedLimitLift

namespace PhysicalClosedLimitTilt {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::WindowCovering::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::WindowCovering::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace PhysicalClosedLimitTilt

namespace CurrentPositionLift {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint16_t> & value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::WindowCovering::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::WindowCovering::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::WindowCovering::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint16_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace CurrentPositionLift

namespace CurrentPositionTilt {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint16_t> & value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::WindowCovering::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::WindowCovering::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::WindowCovering::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint16_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace CurrentPositionTilt

namespace NumberOfActuationsLift {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::WindowCovering::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::WindowCovering::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace NumberOfActuationsLift

namespace NumberOfActuationsTilt {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::WindowCovering::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::WindowCovering::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace NumberOfActuationsTilt

namespace ConfigStatus {

EmberAfStatus Get(chip::EndpointId endpoint, chip::BitMask<chip::app::Clusters::WindowCovering::ConfigStatus> * value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::WindowCovering::ConfigStatus>>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::WindowCovering::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::BitMask<chip::app::Clusters::WindowCovering::ConfigStatus> value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::WindowCovering::ConfigStatus>>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::WindowCovering::Id, Id, writable, ZCL_BITMAP8_ATTRIBUTE_TYPE);
}

} // namespace ConfigStatus

namespace CurrentPositionLiftPercentage {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<chip::Percent> & value)
{
    using Traits = NumericAttributeTraits<chip::Percent>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::WindowCovering::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::Percent value)
{
    using Traits = NumericAttributeTraits<chip::Percent>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::WindowCovering::Id, Id, writable, ZCL_PERCENT_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<chip::Percent>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::WindowCovering::Id, Id, writable, ZCL_PERCENT_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<chip::Percent> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace CurrentPositionLiftPercentage

namespace CurrentPositionTiltPercentage {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<chip::Percent> & value)
{
    using Traits = NumericAttributeTraits<chip::Percent>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::WindowCovering::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::Percent value)
{
    using Traits = NumericAttributeTraits<chip::Percent>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::WindowCovering::Id, Id, writable, ZCL_PERCENT_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<chip::Percent>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::WindowCovering::Id, Id, writable, ZCL_PERCENT_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<chip::Percent> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace CurrentPositionTiltPercentage

namespace OperationalStatus {

EmberAfStatus Get(chip::EndpointId endpoint, chip::BitMask<chip::app::Clusters::WindowCovering::OperationalStatus> * value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::WindowCovering::OperationalStatus>>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::WindowCovering::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::BitMask<chip::app::Clusters::WindowCovering::OperationalStatus> value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::WindowCovering::OperationalStatus>>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::WindowCovering::Id, Id, writable, ZCL_BITMAP8_ATTRIBUTE_TYPE);
}

} // namespace OperationalStatus

namespace TargetPositionLiftPercent100ths {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<chip::Percent100ths> & value)
{
    using Traits = NumericAttributeTraits<chip::Percent100ths>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::WindowCovering::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::Percent100ths value)
{
    using Traits = NumericAttributeTraits<chip::Percent100ths>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::WindowCovering::Id, Id, writable, ZCL_PERCENT100THS_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<chip::Percent100ths>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::WindowCovering::Id, Id, writable, ZCL_PERCENT100THS_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<chip::Percent100ths> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace TargetPositionLiftPercent100ths

namespace TargetPositionTiltPercent100ths {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<chip::Percent100ths> & value)
{
    using Traits = NumericAttributeTraits<chip::Percent100ths>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::WindowCovering::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::Percent100ths value)
{
    using Traits = NumericAttributeTraits<chip::Percent100ths>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::WindowCovering::Id, Id, writable, ZCL_PERCENT100THS_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<chip::Percent100ths>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::WindowCovering::Id, Id, writable, ZCL_PERCENT100THS_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<chip::Percent100ths> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace TargetPositionTiltPercent100ths

namespace EndProductType {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::WindowCovering::EndProductType * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::WindowCovering::EndProductType>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::WindowCovering::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::app::Clusters::WindowCovering::EndProductType value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::WindowCovering::EndProductType>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::WindowCovering::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace EndProductType

namespace CurrentPositionLiftPercent100ths {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<chip::Percent100ths> & value)
{
    using Traits = NumericAttributeTraits<chip::Percent100ths>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::WindowCovering::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::Percent100ths value)
{
    using Traits = NumericAttributeTraits<chip::Percent100ths>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::WindowCovering::Id, Id, writable, ZCL_PERCENT100THS_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<chip::Percent100ths>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::WindowCovering::Id, Id, writable, ZCL_PERCENT100THS_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<chip::Percent100ths> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace CurrentPositionLiftPercent100ths

namespace CurrentPositionTiltPercent100ths {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<chip::Percent100ths> & value)
{
    using Traits = NumericAttributeTraits<chip::Percent100ths>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::WindowCovering::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::Percent100ths value)
{
    using Traits = NumericAttributeTraits<chip::Percent100ths>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::WindowCovering::Id, Id, writable, ZCL_PERCENT100THS_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<chip::Percent100ths>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::WindowCovering::Id, Id, writable, ZCL_PERCENT100THS_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<chip::Percent100ths> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace CurrentPositionTiltPercent100ths

namespace InstalledOpenLimitLift {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::WindowCovering::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::WindowCovering::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace InstalledOpenLimitLift

namespace InstalledClosedLimitLift {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::WindowCovering::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::WindowCovering::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace InstalledClosedLimitLift

namespace InstalledOpenLimitTilt {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::WindowCovering::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::WindowCovering::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace InstalledOpenLimitTilt

namespace InstalledClosedLimitTilt {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::WindowCovering::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::WindowCovering::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace InstalledClosedLimitTilt

namespace Mode {

EmberAfStatus Get(chip::EndpointId endpoint, chip::BitMask<chip::app::Clusters::WindowCovering::Mode> * value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::WindowCovering::Mode>>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::WindowCovering::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::BitMask<chip::app::Clusters::WindowCovering::Mode> value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::WindowCovering::Mode>>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::WindowCovering::Id, Id, writable, ZCL_BITMAP8_ATTRIBUTE_TYPE);
}

} // namespace Mode

namespace SafetyStatus {

EmberAfStatus Get(chip::EndpointId endpoint, chip::BitMask<chip::app::Clusters::WindowCovering::SafetyStatus> * value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::WindowCovering::SafetyStatus>>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::WindowCovering::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::BitMask<chip::app::Clusters::WindowCovering::SafetyStatus> value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::WindowCovering::SafetyStatus>>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::WindowCovering::Id, Id, writable, ZCL_BITMAP16_ATTRIBUTE_TYPE);
}

} // namespace SafetyStatus

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::WindowCovering::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::WindowCovering::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::WindowCovering::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::WindowCovering::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace WindowCovering

namespace BarrierControl {
namespace Attributes {

namespace BarrierMovingState {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::BarrierControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::BarrierControl::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace BarrierMovingState

namespace BarrierSafetyStatus {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::BarrierControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::BarrierControl::Id, Id, writable, ZCL_BITMAP16_ATTRIBUTE_TYPE);
}

} // namespace BarrierSafetyStatus

namespace BarrierCapabilities {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::BarrierControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::BarrierControl::Id, Id, writable, ZCL_BITMAP8_ATTRIBUTE_TYPE);
}

} // namespace BarrierCapabilities

namespace BarrierOpenEvents {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::BarrierControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::BarrierControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace BarrierOpenEvents

namespace BarrierCloseEvents {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::BarrierControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::BarrierControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace BarrierCloseEvents

namespace BarrierCommandOpenEvents {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::BarrierControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::BarrierControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace BarrierCommandOpenEvents

namespace BarrierCommandCloseEvents {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::BarrierControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::BarrierControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace BarrierCommandCloseEvents

namespace BarrierOpenPeriod {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::BarrierControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::BarrierControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace BarrierOpenPeriod

namespace BarrierClosePeriod {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::BarrierControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::BarrierControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace BarrierClosePeriod

namespace BarrierPosition {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::BarrierControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::BarrierControl::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

} // namespace BarrierPosition

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::BarrierControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::BarrierControl::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::BarrierControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::BarrierControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace BarrierControl

namespace PumpConfigurationAndControl {
namespace Attributes {

namespace MaxPressure {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<int16_t> & value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable,
                                       ZCL_INT16S_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable,
                                       ZCL_INT16S_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<int16_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace MaxPressure

namespace MaxSpeed {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint16_t> & value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable,
                                       ZCL_INT16U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable,
                                       ZCL_INT16U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint16_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace MaxSpeed

namespace MaxFlow {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint16_t> & value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable,
                                       ZCL_INT16U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable,
                                       ZCL_INT16U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint16_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace MaxFlow

namespace MinConstPressure {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<int16_t> & value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable,
                                       ZCL_INT16S_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable,
                                       ZCL_INT16S_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<int16_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace MinConstPressure

namespace MaxConstPressure {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<int16_t> & value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable,
                                       ZCL_INT16S_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable,
                                       ZCL_INT16S_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<int16_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace MaxConstPressure

namespace MinCompPressure {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<int16_t> & value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable,
                                       ZCL_INT16S_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable,
                                       ZCL_INT16S_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<int16_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace MinCompPressure

namespace MaxCompPressure {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<int16_t> & value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable,
                                       ZCL_INT16S_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable,
                                       ZCL_INT16S_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<int16_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace MaxCompPressure

namespace MinConstSpeed {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint16_t> & value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable,
                                       ZCL_INT16U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable,
                                       ZCL_INT16U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint16_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace MinConstSpeed

namespace MaxConstSpeed {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint16_t> & value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable,
                                       ZCL_INT16U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable,
                                       ZCL_INT16U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint16_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace MaxConstSpeed

namespace MinConstFlow {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint16_t> & value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable,
                                       ZCL_INT16U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable,
                                       ZCL_INT16U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint16_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace MinConstFlow

namespace MaxConstFlow {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint16_t> & value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable,
                                       ZCL_INT16U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable,
                                       ZCL_INT16U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint16_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace MaxConstFlow

namespace MinConstTemp {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<int16_t> & value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable,
                                       ZCL_INT16S_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable,
                                       ZCL_INT16S_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<int16_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace MinConstTemp

namespace MaxConstTemp {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<int16_t> & value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable,
                                       ZCL_INT16S_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable,
                                       ZCL_INT16S_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<int16_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace MaxConstTemp

namespace PumpStatus {

EmberAfStatus Get(chip::EndpointId endpoint, chip::BitMask<chip::app::Clusters::PumpConfigurationAndControl::PumpStatus> * value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::PumpConfigurationAndControl::PumpStatus>>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::BitMask<chip::app::Clusters::PumpConfigurationAndControl::PumpStatus> value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::PumpConfigurationAndControl::PumpStatus>>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable,
                                       ZCL_BITMAP16_ATTRIBUTE_TYPE);
}

} // namespace PumpStatus

namespace EffectiveOperationMode {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::PumpConfigurationAndControl::PumpOperationMode * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::PumpConfigurationAndControl::PumpOperationMode>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::app::Clusters::PumpConfigurationAndControl::PumpOperationMode value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::PumpConfigurationAndControl::PumpOperationMode>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace EffectiveOperationMode

namespace EffectiveControlMode {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::PumpConfigurationAndControl::PumpControlMode * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::PumpConfigurationAndControl::PumpControlMode>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::app::Clusters::PumpConfigurationAndControl::PumpControlMode value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::PumpConfigurationAndControl::PumpControlMode>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace EffectiveControlMode

namespace Capacity {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<int16_t> & value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable,
                                       ZCL_INT16S_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable,
                                       ZCL_INT16S_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<int16_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace Capacity

namespace Speed {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint16_t> & value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable,
                                       ZCL_INT16U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable,
                                       ZCL_INT16U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint16_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace Speed

namespace LifetimeRunningHours {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint32_t> & value)
{
    using Traits = NumericAttributeTraits<OddSizedInteger<3, false>>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<OddSizedInteger<3, false>>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable,
                                       ZCL_INT24U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<OddSizedInteger<3, false>>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable,
                                       ZCL_INT24U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint32_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace LifetimeRunningHours

namespace Power {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint32_t> & value)
{
    using Traits = NumericAttributeTraits<OddSizedInteger<3, false>>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<OddSizedInteger<3, false>>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable,
                                       ZCL_INT24U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<OddSizedInteger<3, false>>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable,
                                       ZCL_INT24U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint32_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace Power

namespace LifetimeEnergyConsumed {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint32_t> & value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable,
                                       ZCL_INT32U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable,
                                       ZCL_INT32U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint32_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace LifetimeEnergyConsumed

namespace OperationMode {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::PumpConfigurationAndControl::PumpOperationMode * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::PumpConfigurationAndControl::PumpOperationMode>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::app::Clusters::PumpConfigurationAndControl::PumpOperationMode value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::PumpConfigurationAndControl::PumpOperationMode>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace OperationMode

namespace ControlMode {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::PumpConfigurationAndControl::PumpControlMode * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::PumpConfigurationAndControl::PumpControlMode>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::app::Clusters::PumpConfigurationAndControl::PumpControlMode value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::PumpConfigurationAndControl::PumpControlMode>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace ControlMode

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable,
                                       ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable,
                                       ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace PumpConfigurationAndControl

namespace Thermostat {
namespace Attributes {

namespace LocalTemperature {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<int16_t> & value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Thermostat::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<int16_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace LocalTemperature

namespace OutdoorTemperature {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<int16_t> & value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Thermostat::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<int16_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace OutdoorTemperature

namespace Occupancy {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Thermostat::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_BITMAP8_ATTRIBUTE_TYPE);
}

} // namespace Occupancy

namespace AbsMinHeatSetpointLimit {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Thermostat::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace AbsMinHeatSetpointLimit

namespace AbsMaxHeatSetpointLimit {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Thermostat::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace AbsMaxHeatSetpointLimit

namespace AbsMinCoolSetpointLimit {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Thermostat::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace AbsMinCoolSetpointLimit

namespace AbsMaxCoolSetpointLimit {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Thermostat::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace AbsMaxCoolSetpointLimit

namespace PICoolingDemand {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Thermostat::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

} // namespace PICoolingDemand

namespace PIHeatingDemand {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Thermostat::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

} // namespace PIHeatingDemand

namespace HVACSystemTypeConfiguration {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Thermostat::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_BITMAP8_ATTRIBUTE_TYPE);
}

} // namespace HVACSystemTypeConfiguration

namespace LocalTemperatureCalibration {

EmberAfStatus Get(chip::EndpointId endpoint, int8_t * value)
{
    using Traits = NumericAttributeTraits<int8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Thermostat::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int8_t value)
{
    using Traits = NumericAttributeTraits<int8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_INT8S_ATTRIBUTE_TYPE);
}

} // namespace LocalTemperatureCalibration

namespace OccupiedCoolingSetpoint {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Thermostat::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace OccupiedCoolingSetpoint

namespace OccupiedHeatingSetpoint {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Thermostat::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace OccupiedHeatingSetpoint

namespace UnoccupiedCoolingSetpoint {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Thermostat::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace UnoccupiedCoolingSetpoint

namespace UnoccupiedHeatingSetpoint {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Thermostat::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace UnoccupiedHeatingSetpoint

namespace MinHeatSetpointLimit {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Thermostat::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace MinHeatSetpointLimit

namespace MaxHeatSetpointLimit {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Thermostat::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace MaxHeatSetpointLimit

namespace MinCoolSetpointLimit {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Thermostat::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace MinCoolSetpointLimit

namespace MaxCoolSetpointLimit {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Thermostat::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace MaxCoolSetpointLimit

namespace MinSetpointDeadBand {

EmberAfStatus Get(chip::EndpointId endpoint, int8_t * value)
{
    using Traits = NumericAttributeTraits<int8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Thermostat::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int8_t value)
{
    using Traits = NumericAttributeTraits<int8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_INT8S_ATTRIBUTE_TYPE);
}

} // namespace MinSetpointDeadBand

namespace RemoteSensing {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Thermostat::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_BITMAP8_ATTRIBUTE_TYPE);
}

} // namespace RemoteSensing

namespace ControlSequenceOfOperation {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::Thermostat::ThermostatControlSequence * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::Thermostat::ThermostatControlSequence>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Thermostat::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::app::Clusters::Thermostat::ThermostatControlSequence value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::Thermostat::ThermostatControlSequence>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace ControlSequenceOfOperation

namespace SystemMode {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Thermostat::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace SystemMode

namespace ThermostatRunningMode {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Thermostat::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace ThermostatRunningMode

namespace StartOfWeek {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Thermostat::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace StartOfWeek

namespace NumberOfWeeklyTransitions {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Thermostat::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

} // namespace NumberOfWeeklyTransitions

namespace NumberOfDailyTransitions {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Thermostat::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

} // namespace NumberOfDailyTransitions

namespace TemperatureSetpointHold {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Thermostat::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace TemperatureSetpointHold

namespace TemperatureSetpointHoldDuration {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint16_t> & value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Thermostat::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint16_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace TemperatureSetpointHoldDuration

namespace ThermostatProgrammingOperationMode {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Thermostat::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_BITMAP8_ATTRIBUTE_TYPE);
}

} // namespace ThermostatProgrammingOperationMode

namespace ThermostatRunningState {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Thermostat::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_BITMAP16_ATTRIBUTE_TYPE);
}

} // namespace ThermostatRunningState

namespace SetpointChangeSource {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Thermostat::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace SetpointChangeSource

namespace SetpointChangeAmount {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<int16_t> & value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Thermostat::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<int16_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace SetpointChangeAmount

namespace SetpointChangeSourceTimestamp {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Thermostat::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_UTC_ATTRIBUTE_TYPE);
}

} // namespace SetpointChangeSourceTimestamp

namespace OccupiedSetback {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint8_t> & value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Thermostat::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint8_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace OccupiedSetback

namespace OccupiedSetbackMin {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint8_t> & value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Thermostat::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint8_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace OccupiedSetbackMin

namespace OccupiedSetbackMax {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint8_t> & value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Thermostat::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint8_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace OccupiedSetbackMax

namespace UnoccupiedSetback {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint8_t> & value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Thermostat::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint8_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace UnoccupiedSetback

namespace UnoccupiedSetbackMin {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint8_t> & value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Thermostat::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint8_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace UnoccupiedSetbackMin

namespace UnoccupiedSetbackMax {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint8_t> & value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Thermostat::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint8_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace UnoccupiedSetbackMax

namespace EmergencyHeatDelta {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Thermostat::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

} // namespace EmergencyHeatDelta

namespace ACType {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Thermostat::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace ACType

namespace ACCapacity {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Thermostat::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ACCapacity

namespace ACRefrigerantType {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Thermostat::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace ACRefrigerantType

namespace ACCompressorType {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Thermostat::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace ACCompressorType

namespace ACErrorCode {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Thermostat::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace ACErrorCode

namespace ACLouverPosition {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Thermostat::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace ACLouverPosition

namespace ACCoilTemperature {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<int16_t> & value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Thermostat::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<int16_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace ACCoilTemperature

namespace ACCapacityformat {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Thermostat::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace ACCapacityformat

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Thermostat::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Thermostat::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace Thermostat

namespace FanControl {
namespace Attributes {

namespace FanMode {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::FanControl::FanModeType * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::FanControl::FanModeType>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::FanControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::app::Clusters::FanControl::FanModeType value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::FanControl::FanModeType>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::FanControl::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace FanMode

namespace FanModeSequence {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::FanControl::FanModeSequenceType * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::FanControl::FanModeSequenceType>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::FanControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::app::Clusters::FanControl::FanModeSequenceType value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::FanControl::FanModeSequenceType>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::FanControl::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace FanModeSequence

namespace PercentSetting {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint8_t> & value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::FanControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::FanControl::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::FanControl::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint8_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace PercentSetting

namespace PercentCurrent {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::FanControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::FanControl::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

} // namespace PercentCurrent

namespace SpeedMax {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::FanControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::FanControl::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

} // namespace SpeedMax

namespace SpeedSetting {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint8_t> & value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::FanControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::FanControl::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::FanControl::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint8_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace SpeedSetting

namespace SpeedCurrent {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::FanControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::FanControl::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

} // namespace SpeedCurrent

namespace RockSupport {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::FanControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::FanControl::Id, Id, writable, ZCL_BITMAP8_ATTRIBUTE_TYPE);
}

} // namespace RockSupport

namespace RockSetting {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::FanControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::FanControl::Id, Id, writable, ZCL_BITMAP8_ATTRIBUTE_TYPE);
}

} // namespace RockSetting

namespace WindSupport {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::FanControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::FanControl::Id, Id, writable, ZCL_BITMAP8_ATTRIBUTE_TYPE);
}

} // namespace WindSupport

namespace WindSetting {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::FanControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::FanControl::Id, Id, writable, ZCL_BITMAP8_ATTRIBUTE_TYPE);
}

} // namespace WindSetting

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::FanControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::FanControl::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::FanControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::FanControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace FanControl

namespace ThermostatUserInterfaceConfiguration {
namespace Attributes {

namespace TemperatureDisplayMode {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::ThermostatUserInterfaceConfiguration::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThermostatUserInterfaceConfiguration::Id, Id, writable,
                                       ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace TemperatureDisplayMode

namespace KeypadLockout {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::ThermostatUserInterfaceConfiguration::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThermostatUserInterfaceConfiguration::Id, Id, writable,
                                       ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace KeypadLockout

namespace ScheduleProgrammingVisibility {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::ThermostatUserInterfaceConfiguration::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThermostatUserInterfaceConfiguration::Id, Id, writable,
                                       ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace ScheduleProgrammingVisibility

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::ThermostatUserInterfaceConfiguration::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThermostatUserInterfaceConfiguration::Id, Id, writable,
                                       ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::ThermostatUserInterfaceConfiguration::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ThermostatUserInterfaceConfiguration::Id, Id, writable,
                                       ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace ThermostatUserInterfaceConfiguration

namespace ColorControl {
namespace Attributes {

namespace CurrentHue {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ColorControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

} // namespace CurrentHue

namespace CurrentSaturation {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ColorControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

} // namespace CurrentSaturation

namespace RemainingTime {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ColorControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace RemainingTime

namespace CurrentX {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ColorControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace CurrentX

namespace CurrentY {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ColorControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace CurrentY

namespace DriftCompensation {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ColorControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace DriftCompensation

namespace CompensationText {

EmberAfStatus Get(chip::EndpointId endpoint, chip::MutableCharSpan value)
{
    uint8_t zclString[254 + 1];
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ColorControl::Id, Id, zclString, sizeof(zclString));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    size_t length = emberAfStringLength(zclString);
    if (length == NumericAttributeTraits<uint8_t>::kNullValue)
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }

    VerifyOrReturnError(value.size() == 254, EMBER_ZCL_STATUS_INVALID_DATA_TYPE);
    memcpy(value.data(), &zclString[1], 254);
    value.reduce_size(length);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::CharSpan value)
{
    static_assert(254 < NumericAttributeTraits<uint8_t>::kNullValue, "value.size() might be too big");
    VerifyOrReturnError(value.size() <= 254, EMBER_ZCL_STATUS_CONSTRAINT_ERROR);
    uint8_t zclString[254 + 1];
    emberAfCopyInt8u(zclString, 0, static_cast<uint8_t>(value.size()));
    memcpy(&zclString[1], value.data(), value.size());
    return emberAfWriteServerAttribute(endpoint, Clusters::ColorControl::Id, Id, zclString, ZCL_CHAR_STRING_ATTRIBUTE_TYPE);
}

} // namespace CompensationText

namespace ColorTemperature {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ColorControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ColorTemperature

namespace ColorMode {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ColorControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace ColorMode

namespace Options {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ColorControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_BITMAP8_ATTRIBUTE_TYPE);
}

} // namespace Options

namespace NumberOfPrimaries {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint8_t> & value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ColorControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint8_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace NumberOfPrimaries

namespace Primary1X {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ColorControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace Primary1X

namespace Primary1Y {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ColorControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace Primary1Y

namespace Primary1Intensity {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint8_t> & value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ColorControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint8_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace Primary1Intensity

namespace Primary2X {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ColorControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace Primary2X

namespace Primary2Y {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ColorControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace Primary2Y

namespace Primary2Intensity {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint8_t> & value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ColorControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint8_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace Primary2Intensity

namespace Primary3X {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ColorControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace Primary3X

namespace Primary3Y {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ColorControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace Primary3Y

namespace Primary3Intensity {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint8_t> & value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ColorControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint8_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace Primary3Intensity

namespace Primary4X {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ColorControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace Primary4X

namespace Primary4Y {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ColorControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace Primary4Y

namespace Primary4Intensity {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint8_t> & value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ColorControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint8_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace Primary4Intensity

namespace Primary5X {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ColorControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace Primary5X

namespace Primary5Y {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ColorControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace Primary5Y

namespace Primary5Intensity {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint8_t> & value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ColorControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint8_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace Primary5Intensity

namespace Primary6X {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ColorControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace Primary6X

namespace Primary6Y {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ColorControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace Primary6Y

namespace Primary6Intensity {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint8_t> & value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ColorControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint8_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace Primary6Intensity

namespace WhitePointX {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ColorControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace WhitePointX

namespace WhitePointY {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ColorControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace WhitePointY

namespace ColorPointRX {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ColorControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ColorPointRX

namespace ColorPointRY {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ColorControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ColorPointRY

namespace ColorPointRIntensity {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint8_t> & value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ColorControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint8_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace ColorPointRIntensity

namespace ColorPointGX {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ColorControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ColorPointGX

namespace ColorPointGY {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ColorControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ColorPointGY

namespace ColorPointGIntensity {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint8_t> & value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ColorControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint8_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace ColorPointGIntensity

namespace ColorPointBX {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ColorControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ColorPointBX

namespace ColorPointBY {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ColorControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ColorPointBY

namespace ColorPointBIntensity {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint8_t> & value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ColorControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint8_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace ColorPointBIntensity

namespace EnhancedCurrentHue {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ColorControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace EnhancedCurrentHue

namespace EnhancedColorMode {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ColorControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace EnhancedColorMode

namespace ColorLoopActive {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ColorControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

} // namespace ColorLoopActive

namespace ColorLoopDirection {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ColorControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

} // namespace ColorLoopDirection

namespace ColorLoopTime {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ColorControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ColorLoopTime

namespace ColorLoopStartEnhancedHue {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ColorControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ColorLoopStartEnhancedHue

namespace ColorLoopStoredEnhancedHue {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ColorControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ColorLoopStoredEnhancedHue

namespace ColorCapabilities {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ColorControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_BITMAP16_ATTRIBUTE_TYPE);
}

} // namespace ColorCapabilities

namespace ColorTempPhysicalMinMireds {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ColorControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ColorTempPhysicalMinMireds

namespace ColorTempPhysicalMaxMireds {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ColorControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ColorTempPhysicalMaxMireds

namespace CoupleColorTempToLevelMinMireds {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ColorControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace CoupleColorTempToLevelMinMireds

namespace StartUpColorTemperatureMireds {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ColorControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace StartUpColorTemperatureMireds

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ColorControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ColorControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace ColorControl

namespace BallastConfiguration {
namespace Attributes {

namespace PhysicalMinLevel {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::BallastConfiguration::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::BallastConfiguration::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

} // namespace PhysicalMinLevel

namespace PhysicalMaxLevel {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::BallastConfiguration::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::BallastConfiguration::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

} // namespace PhysicalMaxLevel

namespace BallastStatus {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::BallastConfiguration::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::BallastConfiguration::Id, Id, writable, ZCL_BITMAP8_ATTRIBUTE_TYPE);
}

} // namespace BallastStatus

namespace MinLevel {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::BallastConfiguration::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::BallastConfiguration::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

} // namespace MinLevel

namespace MaxLevel {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::BallastConfiguration::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::BallastConfiguration::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

} // namespace MaxLevel

namespace IntrinsicBalanceFactor {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint8_t> & value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::BallastConfiguration::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::BallastConfiguration::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::BallastConfiguration::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint8_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace IntrinsicBalanceFactor

namespace BallastFactorAdjustment {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint8_t> & value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::BallastConfiguration::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::BallastConfiguration::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::BallastConfiguration::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint8_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace BallastFactorAdjustment

namespace LampQuantity {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::BallastConfiguration::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::BallastConfiguration::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

} // namespace LampQuantity

namespace LampType {

EmberAfStatus Get(chip::EndpointId endpoint, chip::MutableCharSpan value)
{
    uint8_t zclString[16 + 1];
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::BallastConfiguration::Id, Id, zclString, sizeof(zclString));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    size_t length = emberAfStringLength(zclString);
    if (length == NumericAttributeTraits<uint8_t>::kNullValue)
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }

    VerifyOrReturnError(value.size() == 16, EMBER_ZCL_STATUS_INVALID_DATA_TYPE);
    memcpy(value.data(), &zclString[1], 16);
    value.reduce_size(length);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::CharSpan value)
{
    static_assert(16 < NumericAttributeTraits<uint8_t>::kNullValue, "value.size() might be too big");
    VerifyOrReturnError(value.size() <= 16, EMBER_ZCL_STATUS_CONSTRAINT_ERROR);
    uint8_t zclString[16 + 1];
    emberAfCopyInt8u(zclString, 0, static_cast<uint8_t>(value.size()));
    memcpy(&zclString[1], value.data(), value.size());
    return emberAfWriteServerAttribute(endpoint, Clusters::BallastConfiguration::Id, Id, zclString, ZCL_CHAR_STRING_ATTRIBUTE_TYPE);
}

} // namespace LampType

namespace LampManufacturer {

EmberAfStatus Get(chip::EndpointId endpoint, chip::MutableCharSpan value)
{
    uint8_t zclString[16 + 1];
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::BallastConfiguration::Id, Id, zclString, sizeof(zclString));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    size_t length = emberAfStringLength(zclString);
    if (length == NumericAttributeTraits<uint8_t>::kNullValue)
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }

    VerifyOrReturnError(value.size() == 16, EMBER_ZCL_STATUS_INVALID_DATA_TYPE);
    memcpy(value.data(), &zclString[1], 16);
    value.reduce_size(length);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::CharSpan value)
{
    static_assert(16 < NumericAttributeTraits<uint8_t>::kNullValue, "value.size() might be too big");
    VerifyOrReturnError(value.size() <= 16, EMBER_ZCL_STATUS_CONSTRAINT_ERROR);
    uint8_t zclString[16 + 1];
    emberAfCopyInt8u(zclString, 0, static_cast<uint8_t>(value.size()));
    memcpy(&zclString[1], value.data(), value.size());
    return emberAfWriteServerAttribute(endpoint, Clusters::BallastConfiguration::Id, Id, zclString, ZCL_CHAR_STRING_ATTRIBUTE_TYPE);
}

} // namespace LampManufacturer

namespace LampRatedHours {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint32_t> & value)
{
    using Traits = NumericAttributeTraits<OddSizedInteger<3, false>>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::BallastConfiguration::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<OddSizedInteger<3, false>>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::BallastConfiguration::Id, Id, writable, ZCL_INT24U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<OddSizedInteger<3, false>>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::BallastConfiguration::Id, Id, writable, ZCL_INT24U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint32_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace LampRatedHours

namespace LampBurnHours {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint32_t> & value)
{
    using Traits = NumericAttributeTraits<OddSizedInteger<3, false>>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::BallastConfiguration::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<OddSizedInteger<3, false>>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::BallastConfiguration::Id, Id, writable, ZCL_INT24U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<OddSizedInteger<3, false>>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::BallastConfiguration::Id, Id, writable, ZCL_INT24U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint32_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace LampBurnHours

namespace LampAlarmMode {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::BallastConfiguration::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::BallastConfiguration::Id, Id, writable, ZCL_BITMAP8_ATTRIBUTE_TYPE);
}

} // namespace LampAlarmMode

namespace LampBurnHoursTripPoint {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint32_t> & value)
{
    using Traits = NumericAttributeTraits<OddSizedInteger<3, false>>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::BallastConfiguration::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<OddSizedInteger<3, false>>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::BallastConfiguration::Id, Id, writable, ZCL_INT24U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<OddSizedInteger<3, false>>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::BallastConfiguration::Id, Id, writable, ZCL_INT24U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint32_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace LampBurnHoursTripPoint

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::BallastConfiguration::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::BallastConfiguration::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::BallastConfiguration::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::BallastConfiguration::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace BallastConfiguration

namespace IlluminanceMeasurement {
namespace Attributes {

namespace MeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint16_t> & value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::IlluminanceMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::IlluminanceMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::IlluminanceMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint16_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace MeasuredValue

namespace MinMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint16_t> & value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::IlluminanceMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::IlluminanceMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::IlluminanceMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint16_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace MinMeasuredValue

namespace MaxMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint16_t> & value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::IlluminanceMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::IlluminanceMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::IlluminanceMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint16_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace MaxMeasuredValue

namespace Tolerance {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::IlluminanceMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::IlluminanceMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace Tolerance

namespace LightSensorType {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint8_t> & value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::IlluminanceMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::IlluminanceMeasurement::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::IlluminanceMeasurement::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint8_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace LightSensorType

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::IlluminanceMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::IlluminanceMeasurement::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::IlluminanceMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::IlluminanceMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace IlluminanceMeasurement

namespace TemperatureMeasurement {
namespace Attributes {

namespace MeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<int16_t> & value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TemperatureMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TemperatureMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::TemperatureMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<int16_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace MeasuredValue

namespace MinMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<int16_t> & value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TemperatureMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TemperatureMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::TemperatureMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<int16_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace MinMeasuredValue

namespace MaxMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<int16_t> & value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TemperatureMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TemperatureMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::TemperatureMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<int16_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace MaxMeasuredValue

namespace Tolerance {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TemperatureMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TemperatureMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace Tolerance

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TemperatureMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TemperatureMeasurement::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TemperatureMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TemperatureMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace TemperatureMeasurement

namespace PressureMeasurement {
namespace Attributes {

namespace MeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<int16_t> & value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::PressureMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PressureMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::PressureMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<int16_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace MeasuredValue

namespace MinMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<int16_t> & value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::PressureMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PressureMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::PressureMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<int16_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace MinMeasuredValue

namespace MaxMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<int16_t> & value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::PressureMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PressureMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::PressureMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<int16_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace MaxMeasuredValue

namespace Tolerance {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::PressureMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PressureMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace Tolerance

namespace ScaledValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<int16_t> & value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::PressureMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PressureMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::PressureMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<int16_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace ScaledValue

namespace MinScaledValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<int16_t> & value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::PressureMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PressureMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::PressureMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<int16_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace MinScaledValue

namespace MaxScaledValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<int16_t> & value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::PressureMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PressureMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::PressureMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<int16_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace MaxScaledValue

namespace ScaledTolerance {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::PressureMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PressureMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ScaledTolerance

namespace Scale {

EmberAfStatus Get(chip::EndpointId endpoint, int8_t * value)
{
    using Traits = NumericAttributeTraits<int8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::PressureMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int8_t value)
{
    using Traits = NumericAttributeTraits<int8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PressureMeasurement::Id, Id, writable, ZCL_INT8S_ATTRIBUTE_TYPE);
}

} // namespace Scale

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::PressureMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PressureMeasurement::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::PressureMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::PressureMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace PressureMeasurement

namespace FlowMeasurement {
namespace Attributes {

namespace MeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint16_t> & value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::FlowMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::FlowMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::FlowMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint16_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace MeasuredValue

namespace MinMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint16_t> & value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::FlowMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::FlowMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::FlowMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint16_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace MinMeasuredValue

namespace MaxMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint16_t> & value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::FlowMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::FlowMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::FlowMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint16_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace MaxMeasuredValue

namespace Tolerance {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::FlowMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::FlowMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace Tolerance

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::FlowMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::FlowMeasurement::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::FlowMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::FlowMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace FlowMeasurement

namespace RelativeHumidityMeasurement {
namespace Attributes {

namespace MeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint16_t> & value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::RelativeHumidityMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::RelativeHumidityMeasurement::Id, Id, writable,
                                       ZCL_INT16U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::RelativeHumidityMeasurement::Id, Id, writable,
                                       ZCL_INT16U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint16_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace MeasuredValue

namespace MinMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint16_t> & value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::RelativeHumidityMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::RelativeHumidityMeasurement::Id, Id, writable,
                                       ZCL_INT16U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::RelativeHumidityMeasurement::Id, Id, writable,
                                       ZCL_INT16U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint16_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace MinMeasuredValue

namespace MaxMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint16_t> & value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::RelativeHumidityMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::RelativeHumidityMeasurement::Id, Id, writable,
                                       ZCL_INT16U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::RelativeHumidityMeasurement::Id, Id, writable,
                                       ZCL_INT16U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint16_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace MaxMeasuredValue

namespace Tolerance {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::RelativeHumidityMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::RelativeHumidityMeasurement::Id, Id, writable,
                                       ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace Tolerance

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::RelativeHumidityMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::RelativeHumidityMeasurement::Id, Id, writable,
                                       ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadServerAttribute(endpoint, Clusters::RelativeHumidityMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::RelativeHumidityMeasurement::Id, Id, writable,
                                       ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace RelativeHumidityMeasurement

namespace OccupancySensing {
namespace Attributes {

namespace Occupancy {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::OccupancySensing::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::OccupancySensing::Id, Id, writable, ZCL_BITMAP8_ATTRIBUTE_TYPE);
}

} // namespace Occupancy

namespace OccupancySensorType {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::OccupancySensing::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::OccupancySensing::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace OccupancySensorType

namespace OccupancySensorTypeBitmap {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::OccupancySensing::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::OccupancySensing::Id, Id, writable, ZCL_BITMAP8_ATTRIBUTE_TYPE);
}

} // namespace OccupancySensorTypeBitmap

namespace PirOccupiedToUnoccupiedDelay {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::OccupancySensing::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::OccupancySensing::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace PirOccupiedToUnoccupiedDelay

namespace PirUnoccupiedToOccupiedDelay {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::OccupancySensing::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::OccupancySensing::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace PirUnoccupiedToOccupiedDelay

namespace PirUnoccupiedToOccupiedThreshold {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::OccupancySensing::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::OccupancySensing::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

} // namespace PirUnoccupiedToOccupiedThreshold

namespace UltrasonicOccupiedToUnoccupiedDelay {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::OccupancySensing::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::OccupancySensing::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace UltrasonicOccupiedToUnoccupiedDelay

namespace UltrasonicUnoccupiedToOccupiedDelay {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::OccupancySensing::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::OccupancySensing::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace UltrasonicUnoccupiedToOccupiedDelay

namespace UltrasonicUnoccupiedToOccupiedThreshold {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::OccupancySensing::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::OccupancySensing::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

} // namespace UltrasonicUnoccupiedToOccupiedThreshold

namespace PhysicalContactOccupiedToUnoccupiedDelay {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::OccupancySensing::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::OccupancySensing::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace PhysicalContactOccupiedToUnoccupiedDelay

namespace PhysicalContactUnoccupiedToOccupiedDelay {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::OccupancySensing::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::OccupancySensing::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace PhysicalContactUnoccupiedToOccupiedDelay

namespace PhysicalContactUnoccupiedToOccupiedThreshold {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::OccupancySensing::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::OccupancySensing::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

} // namespace PhysicalContactUnoccupiedToOccupiedThreshold

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::OccupancySensing::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::OccupancySensing::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::OccupancySensing::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::OccupancySensing::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace OccupancySensing

namespace WakeOnLan {
namespace Attributes {

namespace MACAddress {

EmberAfStatus Get(chip::EndpointId endpoint, chip::MutableCharSpan value)
{
    uint8_t zclString[32 + 1];
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::WakeOnLan::Id, Id, zclString, sizeof(zclString));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    size_t length = emberAfStringLength(zclString);
    if (length == NumericAttributeTraits<uint8_t>::kNullValue)
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }

    VerifyOrReturnError(value.size() == 32, EMBER_ZCL_STATUS_INVALID_DATA_TYPE);
    memcpy(value.data(), &zclString[1], 32);
    value.reduce_size(length);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::CharSpan value)
{
    static_assert(32 < NumericAttributeTraits<uint8_t>::kNullValue, "value.size() might be too big");
    VerifyOrReturnError(value.size() <= 32, EMBER_ZCL_STATUS_CONSTRAINT_ERROR);
    uint8_t zclString[32 + 1];
    emberAfCopyInt8u(zclString, 0, static_cast<uint8_t>(value.size()));
    memcpy(&zclString[1], value.data(), value.size());
    return emberAfWriteServerAttribute(endpoint, Clusters::WakeOnLan::Id, Id, zclString, ZCL_CHAR_STRING_ATTRIBUTE_TYPE);
}

} // namespace MACAddress

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::WakeOnLan::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::WakeOnLan::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::WakeOnLan::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::WakeOnLan::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace WakeOnLan

namespace Channel {
namespace Attributes {

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Channel::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Channel::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::Channel::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::Channel::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace Channel

namespace TargetNavigator {
namespace Attributes {

namespace CurrentTarget {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TargetNavigator::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TargetNavigator::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

} // namespace CurrentTarget

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TargetNavigator::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TargetNavigator::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TargetNavigator::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TargetNavigator::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace TargetNavigator

namespace MediaPlayback {
namespace Attributes {

namespace CurrentState {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::MediaPlayback::PlaybackStateEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::MediaPlayback::PlaybackStateEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::MediaPlayback::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::app::Clusters::MediaPlayback::PlaybackStateEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::MediaPlayback::PlaybackStateEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::MediaPlayback::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace CurrentState

namespace StartTime {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint64_t> & value)
{
    using Traits = NumericAttributeTraits<uint64_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::MediaPlayback::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint64_t value)
{
    using Traits = NumericAttributeTraits<uint64_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::MediaPlayback::Id, Id, writable, ZCL_EPOCH_US_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint64_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::MediaPlayback::Id, Id, writable, ZCL_EPOCH_US_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint64_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace StartTime

namespace Duration {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint64_t> & value)
{
    using Traits = NumericAttributeTraits<uint64_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::MediaPlayback::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint64_t value)
{
    using Traits = NumericAttributeTraits<uint64_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::MediaPlayback::Id, Id, writable, ZCL_INT64U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint64_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::MediaPlayback::Id, Id, writable, ZCL_INT64U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint64_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace Duration

namespace PlaybackSpeed {

EmberAfStatus Get(chip::EndpointId endpoint, float * value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::MediaPlayback::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, float value)
{
    using Traits = NumericAttributeTraits<float>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::MediaPlayback::Id, Id, writable, ZCL_SINGLE_ATTRIBUTE_TYPE);
}

} // namespace PlaybackSpeed

namespace SeekRangeEnd {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint64_t> & value)
{
    using Traits = NumericAttributeTraits<uint64_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::MediaPlayback::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint64_t value)
{
    using Traits = NumericAttributeTraits<uint64_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::MediaPlayback::Id, Id, writable, ZCL_INT64U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint64_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::MediaPlayback::Id, Id, writable, ZCL_INT64U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint64_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace SeekRangeEnd

namespace SeekRangeStart {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint64_t> & value)
{
    using Traits = NumericAttributeTraits<uint64_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::MediaPlayback::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint64_t value)
{
    using Traits = NumericAttributeTraits<uint64_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::MediaPlayback::Id, Id, writable, ZCL_INT64U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint64_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::MediaPlayback::Id, Id, writable, ZCL_INT64U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint64_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace SeekRangeStart

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::MediaPlayback::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::MediaPlayback::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::MediaPlayback::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::MediaPlayback::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace MediaPlayback

namespace MediaInput {
namespace Attributes {

namespace CurrentInput {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::MediaInput::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::MediaInput::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

} // namespace CurrentInput

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::MediaInput::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::MediaInput::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::MediaInput::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::MediaInput::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace MediaInput

namespace LowPower {
namespace Attributes {

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::LowPower::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::LowPower::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::LowPower::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::LowPower::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace LowPower

namespace KeypadInput {
namespace Attributes {

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::KeypadInput::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::KeypadInput::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::KeypadInput::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::KeypadInput::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace KeypadInput

namespace ContentLauncher {
namespace Attributes {

namespace SupportedStreamingProtocols {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ContentLauncher::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ContentLauncher::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace SupportedStreamingProtocols

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ContentLauncher::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ContentLauncher::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ContentLauncher::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ContentLauncher::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace ContentLauncher

namespace AudioOutput {
namespace Attributes {

namespace CurrentOutput {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::AudioOutput::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::AudioOutput::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

} // namespace CurrentOutput

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::AudioOutput::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::AudioOutput::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::AudioOutput::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::AudioOutput::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace AudioOutput

namespace ApplicationLauncher {
namespace Attributes {

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ApplicationLauncher::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ApplicationLauncher::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ApplicationLauncher::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ApplicationLauncher::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace ApplicationLauncher

namespace ApplicationBasic {
namespace Attributes {

namespace VendorName {

EmberAfStatus Get(chip::EndpointId endpoint, chip::MutableCharSpan value)
{
    uint8_t zclString[32 + 1];
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ApplicationBasic::Id, Id, zclString, sizeof(zclString));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    size_t length = emberAfStringLength(zclString);
    if (length == NumericAttributeTraits<uint8_t>::kNullValue)
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }

    VerifyOrReturnError(value.size() == 32, EMBER_ZCL_STATUS_INVALID_DATA_TYPE);
    memcpy(value.data(), &zclString[1], 32);
    value.reduce_size(length);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::CharSpan value)
{
    static_assert(32 < NumericAttributeTraits<uint8_t>::kNullValue, "value.size() might be too big");
    VerifyOrReturnError(value.size() <= 32, EMBER_ZCL_STATUS_CONSTRAINT_ERROR);
    uint8_t zclString[32 + 1];
    emberAfCopyInt8u(zclString, 0, static_cast<uint8_t>(value.size()));
    memcpy(&zclString[1], value.data(), value.size());
    return emberAfWriteServerAttribute(endpoint, Clusters::ApplicationBasic::Id, Id, zclString, ZCL_CHAR_STRING_ATTRIBUTE_TYPE);
}

} // namespace VendorName

namespace VendorID {

EmberAfStatus Get(chip::EndpointId endpoint, chip::VendorId * value)
{
    using Traits = NumericAttributeTraits<chip::VendorId>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ApplicationBasic::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::VendorId value)
{
    using Traits = NumericAttributeTraits<chip::VendorId>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ApplicationBasic::Id, Id, writable, ZCL_VENDOR_ID_ATTRIBUTE_TYPE);
}

} // namespace VendorID

namespace ApplicationName {

EmberAfStatus Get(chip::EndpointId endpoint, chip::MutableCharSpan value)
{
    uint8_t zclString[32 + 1];
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ApplicationBasic::Id, Id, zclString, sizeof(zclString));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    size_t length = emberAfStringLength(zclString);
    if (length == NumericAttributeTraits<uint8_t>::kNullValue)
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }

    VerifyOrReturnError(value.size() == 32, EMBER_ZCL_STATUS_INVALID_DATA_TYPE);
    memcpy(value.data(), &zclString[1], 32);
    value.reduce_size(length);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::CharSpan value)
{
    static_assert(32 < NumericAttributeTraits<uint8_t>::kNullValue, "value.size() might be too big");
    VerifyOrReturnError(value.size() <= 32, EMBER_ZCL_STATUS_CONSTRAINT_ERROR);
    uint8_t zclString[32 + 1];
    emberAfCopyInt8u(zclString, 0, static_cast<uint8_t>(value.size()));
    memcpy(&zclString[1], value.data(), value.size());
    return emberAfWriteServerAttribute(endpoint, Clusters::ApplicationBasic::Id, Id, zclString, ZCL_CHAR_STRING_ATTRIBUTE_TYPE);
}

} // namespace ApplicationName

namespace ProductID {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ApplicationBasic::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ApplicationBasic::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ProductID

namespace Status {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::ApplicationBasic::ApplicationStatusEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::ApplicationBasic::ApplicationStatusEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ApplicationBasic::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::app::Clusters::ApplicationBasic::ApplicationStatusEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::ApplicationBasic::ApplicationStatusEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ApplicationBasic::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace Status

namespace ApplicationVersion {

EmberAfStatus Get(chip::EndpointId endpoint, chip::MutableCharSpan value)
{
    uint8_t zclString[32 + 1];
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ApplicationBasic::Id, Id, zclString, sizeof(zclString));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    size_t length = emberAfStringLength(zclString);
    if (length == NumericAttributeTraits<uint8_t>::kNullValue)
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }

    VerifyOrReturnError(value.size() == 32, EMBER_ZCL_STATUS_INVALID_DATA_TYPE);
    memcpy(value.data(), &zclString[1], 32);
    value.reduce_size(length);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::CharSpan value)
{
    static_assert(32 < NumericAttributeTraits<uint8_t>::kNullValue, "value.size() might be too big");
    VerifyOrReturnError(value.size() <= 32, EMBER_ZCL_STATUS_CONSTRAINT_ERROR);
    uint8_t zclString[32 + 1];
    emberAfCopyInt8u(zclString, 0, static_cast<uint8_t>(value.size()));
    memcpy(&zclString[1], value.data(), value.size());
    return emberAfWriteServerAttribute(endpoint, Clusters::ApplicationBasic::Id, Id, zclString, ZCL_CHAR_STRING_ATTRIBUTE_TYPE);
}

} // namespace ApplicationVersion

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ApplicationBasic::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ApplicationBasic::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ApplicationBasic::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ApplicationBasic::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace ApplicationBasic

namespace AccountLogin {
namespace Attributes {

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::AccountLogin::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::AccountLogin::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::AccountLogin::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::AccountLogin::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace AccountLogin

namespace ElectricalMeasurement {
namespace Attributes {

namespace MeasurementType {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace MeasurementType

namespace DcVoltage {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace DcVoltage

namespace DcVoltageMin {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace DcVoltageMin

namespace DcVoltageMax {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace DcVoltageMax

namespace DcCurrent {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace DcCurrent

namespace DcCurrentMin {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace DcCurrentMin

namespace DcCurrentMax {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace DcCurrentMax

namespace DcPower {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace DcPower

namespace DcPowerMin {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace DcPowerMin

namespace DcPowerMax {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace DcPowerMax

namespace DcVoltageMultiplier {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace DcVoltageMultiplier

namespace DcVoltageDivisor {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace DcVoltageDivisor

namespace DcCurrentMultiplier {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace DcCurrentMultiplier

namespace DcCurrentDivisor {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace DcCurrentDivisor

namespace DcPowerMultiplier {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace DcPowerMultiplier

namespace DcPowerDivisor {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace DcPowerDivisor

namespace AcFrequency {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace AcFrequency

namespace AcFrequencyMin {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace AcFrequencyMin

namespace AcFrequencyMax {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace AcFrequencyMax

namespace NeutralCurrent {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace NeutralCurrent

namespace TotalActivePower {

EmberAfStatus Get(chip::EndpointId endpoint, int32_t * value)
{
    using Traits = NumericAttributeTraits<int32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int32_t value)
{
    using Traits = NumericAttributeTraits<int32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT32S_ATTRIBUTE_TYPE);
}

} // namespace TotalActivePower

namespace TotalReactivePower {

EmberAfStatus Get(chip::EndpointId endpoint, int32_t * value)
{
    using Traits = NumericAttributeTraits<int32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int32_t value)
{
    using Traits = NumericAttributeTraits<int32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT32S_ATTRIBUTE_TYPE);
}

} // namespace TotalReactivePower

namespace TotalApparentPower {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

} // namespace TotalApparentPower

namespace Measured1stHarmonicCurrent {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace Measured1stHarmonicCurrent

namespace Measured3rdHarmonicCurrent {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace Measured3rdHarmonicCurrent

namespace Measured5thHarmonicCurrent {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace Measured5thHarmonicCurrent

namespace Measured7thHarmonicCurrent {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace Measured7thHarmonicCurrent

namespace Measured9thHarmonicCurrent {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace Measured9thHarmonicCurrent

namespace Measured11thHarmonicCurrent {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace Measured11thHarmonicCurrent

namespace MeasuredPhase1stHarmonicCurrent {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace MeasuredPhase1stHarmonicCurrent

namespace MeasuredPhase3rdHarmonicCurrent {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace MeasuredPhase3rdHarmonicCurrent

namespace MeasuredPhase5thHarmonicCurrent {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace MeasuredPhase5thHarmonicCurrent

namespace MeasuredPhase7thHarmonicCurrent {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace MeasuredPhase7thHarmonicCurrent

namespace MeasuredPhase9thHarmonicCurrent {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace MeasuredPhase9thHarmonicCurrent

namespace MeasuredPhase11thHarmonicCurrent {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace MeasuredPhase11thHarmonicCurrent

namespace AcFrequencyMultiplier {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace AcFrequencyMultiplier

namespace AcFrequencyDivisor {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace AcFrequencyDivisor

namespace PowerMultiplier {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

} // namespace PowerMultiplier

namespace PowerDivisor {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

} // namespace PowerDivisor

namespace HarmonicCurrentMultiplier {

EmberAfStatus Get(chip::EndpointId endpoint, int8_t * value)
{
    using Traits = NumericAttributeTraits<int8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int8_t value)
{
    using Traits = NumericAttributeTraits<int8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT8S_ATTRIBUTE_TYPE);
}

} // namespace HarmonicCurrentMultiplier

namespace PhaseHarmonicCurrentMultiplier {

EmberAfStatus Get(chip::EndpointId endpoint, int8_t * value)
{
    using Traits = NumericAttributeTraits<int8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int8_t value)
{
    using Traits = NumericAttributeTraits<int8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT8S_ATTRIBUTE_TYPE);
}

} // namespace PhaseHarmonicCurrentMultiplier

namespace InstantaneousVoltage {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace InstantaneousVoltage

namespace InstantaneousLineCurrent {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace InstantaneousLineCurrent

namespace InstantaneousActiveCurrent {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace InstantaneousActiveCurrent

namespace InstantaneousReactiveCurrent {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace InstantaneousReactiveCurrent

namespace InstantaneousPower {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace InstantaneousPower

namespace RmsVoltage {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace RmsVoltage

namespace RmsVoltageMin {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace RmsVoltageMin

namespace RmsVoltageMax {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace RmsVoltageMax

namespace RmsCurrent {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace RmsCurrent

namespace RmsCurrentMin {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace RmsCurrentMin

namespace RmsCurrentMax {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace RmsCurrentMax

namespace ActivePower {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace ActivePower

namespace ActivePowerMin {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace ActivePowerMin

namespace ActivePowerMax {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace ActivePowerMax

namespace ReactivePower {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace ReactivePower

namespace ApparentPower {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ApparentPower

namespace PowerFactor {

EmberAfStatus Get(chip::EndpointId endpoint, int8_t * value)
{
    using Traits = NumericAttributeTraits<int8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int8_t value)
{
    using Traits = NumericAttributeTraits<int8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT8S_ATTRIBUTE_TYPE);
}

} // namespace PowerFactor

namespace AverageRmsVoltageMeasurementPeriod {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace AverageRmsVoltageMeasurementPeriod

namespace AverageRmsUnderVoltageCounter {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace AverageRmsUnderVoltageCounter

namespace RmsExtremeOverVoltagePeriod {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace RmsExtremeOverVoltagePeriod

namespace RmsExtremeUnderVoltagePeriod {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace RmsExtremeUnderVoltagePeriod

namespace RmsVoltageSagPeriod {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace RmsVoltageSagPeriod

namespace RmsVoltageSwellPeriod {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace RmsVoltageSwellPeriod

namespace AcVoltageMultiplier {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace AcVoltageMultiplier

namespace AcVoltageDivisor {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace AcVoltageDivisor

namespace AcCurrentMultiplier {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace AcCurrentMultiplier

namespace AcCurrentDivisor {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace AcCurrentDivisor

namespace AcPowerMultiplier {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace AcPowerMultiplier

namespace AcPowerDivisor {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace AcPowerDivisor

namespace OverloadAlarmsMask {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_BITMAP8_ATTRIBUTE_TYPE);
}

} // namespace OverloadAlarmsMask

namespace VoltageOverload {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace VoltageOverload

namespace CurrentOverload {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace CurrentOverload

namespace AcOverloadAlarmsMask {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_BITMAP16_ATTRIBUTE_TYPE);
}

} // namespace AcOverloadAlarmsMask

namespace AcVoltageOverload {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace AcVoltageOverload

namespace AcCurrentOverload {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace AcCurrentOverload

namespace AcActivePowerOverload {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace AcActivePowerOverload

namespace AcReactivePowerOverload {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace AcReactivePowerOverload

namespace AverageRmsOverVoltage {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace AverageRmsOverVoltage

namespace AverageRmsUnderVoltage {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace AverageRmsUnderVoltage

namespace RmsExtremeOverVoltage {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace RmsExtremeOverVoltage

namespace RmsExtremeUnderVoltage {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace RmsExtremeUnderVoltage

namespace RmsVoltageSag {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace RmsVoltageSag

namespace RmsVoltageSwell {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace RmsVoltageSwell

namespace LineCurrentPhaseB {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace LineCurrentPhaseB

namespace ActiveCurrentPhaseB {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace ActiveCurrentPhaseB

namespace ReactiveCurrentPhaseB {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace ReactiveCurrentPhaseB

namespace RmsVoltagePhaseB {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace RmsVoltagePhaseB

namespace RmsVoltageMinPhaseB {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace RmsVoltageMinPhaseB

namespace RmsVoltageMaxPhaseB {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace RmsVoltageMaxPhaseB

namespace RmsCurrentPhaseB {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace RmsCurrentPhaseB

namespace RmsCurrentMinPhaseB {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace RmsCurrentMinPhaseB

namespace RmsCurrentMaxPhaseB {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace RmsCurrentMaxPhaseB

namespace ActivePowerPhaseB {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace ActivePowerPhaseB

namespace ActivePowerMinPhaseB {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace ActivePowerMinPhaseB

namespace ActivePowerMaxPhaseB {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace ActivePowerMaxPhaseB

namespace ReactivePowerPhaseB {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace ReactivePowerPhaseB

namespace ApparentPowerPhaseB {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ApparentPowerPhaseB

namespace PowerFactorPhaseB {

EmberAfStatus Get(chip::EndpointId endpoint, int8_t * value)
{
    using Traits = NumericAttributeTraits<int8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int8_t value)
{
    using Traits = NumericAttributeTraits<int8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT8S_ATTRIBUTE_TYPE);
}

} // namespace PowerFactorPhaseB

namespace AverageRmsVoltageMeasurementPeriodPhaseB {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace AverageRmsVoltageMeasurementPeriodPhaseB

namespace AverageRmsOverVoltageCounterPhaseB {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace AverageRmsOverVoltageCounterPhaseB

namespace AverageRmsUnderVoltageCounterPhaseB {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace AverageRmsUnderVoltageCounterPhaseB

namespace RmsExtremeOverVoltagePeriodPhaseB {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace RmsExtremeOverVoltagePeriodPhaseB

namespace RmsExtremeUnderVoltagePeriodPhaseB {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace RmsExtremeUnderVoltagePeriodPhaseB

namespace RmsVoltageSagPeriodPhaseB {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace RmsVoltageSagPeriodPhaseB

namespace RmsVoltageSwellPeriodPhaseB {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace RmsVoltageSwellPeriodPhaseB

namespace LineCurrentPhaseC {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace LineCurrentPhaseC

namespace ActiveCurrentPhaseC {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace ActiveCurrentPhaseC

namespace ReactiveCurrentPhaseC {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace ReactiveCurrentPhaseC

namespace RmsVoltagePhaseC {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace RmsVoltagePhaseC

namespace RmsVoltageMinPhaseC {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace RmsVoltageMinPhaseC

namespace RmsVoltageMaxPhaseC {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace RmsVoltageMaxPhaseC

namespace RmsCurrentPhaseC {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace RmsCurrentPhaseC

namespace RmsCurrentMinPhaseC {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace RmsCurrentMinPhaseC

namespace RmsCurrentMaxPhaseC {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace RmsCurrentMaxPhaseC

namespace ActivePowerPhaseC {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace ActivePowerPhaseC

namespace ActivePowerMinPhaseC {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace ActivePowerMinPhaseC

namespace ActivePowerMaxPhaseC {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace ActivePowerMaxPhaseC

namespace ReactivePowerPhaseC {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace ReactivePowerPhaseC

namespace ApparentPowerPhaseC {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ApparentPowerPhaseC

namespace PowerFactorPhaseC {

EmberAfStatus Get(chip::EndpointId endpoint, int8_t * value)
{
    using Traits = NumericAttributeTraits<int8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int8_t value)
{
    using Traits = NumericAttributeTraits<int8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT8S_ATTRIBUTE_TYPE);
}

} // namespace PowerFactorPhaseC

namespace AverageRmsVoltageMeasurementPeriodPhaseC {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace AverageRmsVoltageMeasurementPeriodPhaseC

namespace AverageRmsOverVoltageCounterPhaseC {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace AverageRmsOverVoltageCounterPhaseC

namespace AverageRmsUnderVoltageCounterPhaseC {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace AverageRmsUnderVoltageCounterPhaseC

namespace RmsExtremeOverVoltagePeriodPhaseC {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace RmsExtremeOverVoltagePeriodPhaseC

namespace RmsExtremeUnderVoltagePeriodPhaseC {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace RmsExtremeUnderVoltagePeriodPhaseC

namespace RmsVoltageSagPeriodPhaseC {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace RmsVoltageSagPeriodPhaseC

namespace RmsVoltageSwellPeriodPhaseC {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace RmsVoltageSwellPeriodPhaseC

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace ElectricalMeasurement

namespace TestCluster {
namespace Attributes {

namespace Boolean {

EmberAfStatus Get(chip::EndpointId endpoint, bool * value)
{
    using Traits = NumericAttributeTraits<bool>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, bool value)
{
    using Traits = NumericAttributeTraits<bool>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_BOOLEAN_ATTRIBUTE_TYPE);
}

} // namespace Boolean

namespace Bitmap8 {

EmberAfStatus Get(chip::EndpointId endpoint, chip::BitMask<chip::app::Clusters::TestCluster::Bitmap8MaskMap> * value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::TestCluster::Bitmap8MaskMap>>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::BitMask<chip::app::Clusters::TestCluster::Bitmap8MaskMap> value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::TestCluster::Bitmap8MaskMap>>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_BITMAP8_ATTRIBUTE_TYPE);
}

} // namespace Bitmap8

namespace Bitmap16 {

EmberAfStatus Get(chip::EndpointId endpoint, chip::BitMask<chip::app::Clusters::TestCluster::Bitmap16MaskMap> * value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::TestCluster::Bitmap16MaskMap>>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::BitMask<chip::app::Clusters::TestCluster::Bitmap16MaskMap> value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::TestCluster::Bitmap16MaskMap>>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_BITMAP16_ATTRIBUTE_TYPE);
}

} // namespace Bitmap16

namespace Bitmap32 {

EmberAfStatus Get(chip::EndpointId endpoint, chip::BitMask<chip::app::Clusters::TestCluster::Bitmap32MaskMap> * value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::TestCluster::Bitmap32MaskMap>>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::BitMask<chip::app::Clusters::TestCluster::Bitmap32MaskMap> value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::TestCluster::Bitmap32MaskMap>>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace Bitmap32

namespace Bitmap64 {

EmberAfStatus Get(chip::EndpointId endpoint, chip::BitMask<chip::app::Clusters::TestCluster::Bitmap64MaskMap> * value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::TestCluster::Bitmap64MaskMap>>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::BitMask<chip::app::Clusters::TestCluster::Bitmap64MaskMap> value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::TestCluster::Bitmap64MaskMap>>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_BITMAP64_ATTRIBUTE_TYPE);
}

} // namespace Bitmap64

namespace Int8u {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

} // namespace Int8u

namespace Int16u {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace Int16u

namespace Int24u {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<OddSizedInteger<3, false>>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<OddSizedInteger<3, false>>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_INT24U_ATTRIBUTE_TYPE);
}

} // namespace Int24u

namespace Int32u {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

} // namespace Int32u

namespace Int40u {

EmberAfStatus Get(chip::EndpointId endpoint, uint64_t * value)
{
    using Traits = NumericAttributeTraits<OddSizedInteger<5, false>>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint64_t value)
{
    using Traits = NumericAttributeTraits<OddSizedInteger<5, false>>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_INT40U_ATTRIBUTE_TYPE);
}

} // namespace Int40u

namespace Int48u {

EmberAfStatus Get(chip::EndpointId endpoint, uint64_t * value)
{
    using Traits = NumericAttributeTraits<OddSizedInteger<6, false>>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint64_t value)
{
    using Traits = NumericAttributeTraits<OddSizedInteger<6, false>>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_INT48U_ATTRIBUTE_TYPE);
}

} // namespace Int48u

namespace Int56u {

EmberAfStatus Get(chip::EndpointId endpoint, uint64_t * value)
{
    using Traits = NumericAttributeTraits<OddSizedInteger<7, false>>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint64_t value)
{
    using Traits = NumericAttributeTraits<OddSizedInteger<7, false>>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_INT56U_ATTRIBUTE_TYPE);
}

} // namespace Int56u

namespace Int64u {

EmberAfStatus Get(chip::EndpointId endpoint, uint64_t * value)
{
    using Traits = NumericAttributeTraits<uint64_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint64_t value)
{
    using Traits = NumericAttributeTraits<uint64_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_INT64U_ATTRIBUTE_TYPE);
}

} // namespace Int64u

namespace Int8s {

EmberAfStatus Get(chip::EndpointId endpoint, int8_t * value)
{
    using Traits = NumericAttributeTraits<int8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int8_t value)
{
    using Traits = NumericAttributeTraits<int8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_INT8S_ATTRIBUTE_TYPE);
}

} // namespace Int8s

namespace Int16s {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace Int16s

namespace Int24s {

EmberAfStatus Get(chip::EndpointId endpoint, int32_t * value)
{
    using Traits = NumericAttributeTraits<OddSizedInteger<3, true>>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int32_t value)
{
    using Traits = NumericAttributeTraits<OddSizedInteger<3, true>>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_INT24S_ATTRIBUTE_TYPE);
}

} // namespace Int24s

namespace Int32s {

EmberAfStatus Get(chip::EndpointId endpoint, int32_t * value)
{
    using Traits = NumericAttributeTraits<int32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int32_t value)
{
    using Traits = NumericAttributeTraits<int32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_INT32S_ATTRIBUTE_TYPE);
}

} // namespace Int32s

namespace Int40s {

EmberAfStatus Get(chip::EndpointId endpoint, int64_t * value)
{
    using Traits = NumericAttributeTraits<OddSizedInteger<5, true>>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int64_t value)
{
    using Traits = NumericAttributeTraits<OddSizedInteger<5, true>>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_INT40S_ATTRIBUTE_TYPE);
}

} // namespace Int40s

namespace Int48s {

EmberAfStatus Get(chip::EndpointId endpoint, int64_t * value)
{
    using Traits = NumericAttributeTraits<OddSizedInteger<6, true>>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int64_t value)
{
    using Traits = NumericAttributeTraits<OddSizedInteger<6, true>>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_INT48S_ATTRIBUTE_TYPE);
}

} // namespace Int48s

namespace Int56s {

EmberAfStatus Get(chip::EndpointId endpoint, int64_t * value)
{
    using Traits = NumericAttributeTraits<OddSizedInteger<7, true>>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int64_t value)
{
    using Traits = NumericAttributeTraits<OddSizedInteger<7, true>>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_INT56S_ATTRIBUTE_TYPE);
}

} // namespace Int56s

namespace Int64s {

EmberAfStatus Get(chip::EndpointId endpoint, int64_t * value)
{
    using Traits = NumericAttributeTraits<int64_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int64_t value)
{
    using Traits = NumericAttributeTraits<int64_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_INT64S_ATTRIBUTE_TYPE);
}

} // namespace Int64s

namespace Enum8 {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace Enum8

namespace Enum16 {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_ENUM16_ATTRIBUTE_TYPE);
}

} // namespace Enum16

namespace FloatSingle {

EmberAfStatus Get(chip::EndpointId endpoint, float * value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, float value)
{
    using Traits = NumericAttributeTraits<float>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_SINGLE_ATTRIBUTE_TYPE);
}

} // namespace FloatSingle

namespace FloatDouble {

EmberAfStatus Get(chip::EndpointId endpoint, double * value)
{
    using Traits = NumericAttributeTraits<double>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, double value)
{
    using Traits = NumericAttributeTraits<double>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_DOUBLE_ATTRIBUTE_TYPE);
}

} // namespace FloatDouble

namespace OctetString {

EmberAfStatus Get(chip::EndpointId endpoint, chip::MutableByteSpan value)
{
    uint8_t zclString[10 + 1];
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, zclString, sizeof(zclString));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    size_t length = emberAfStringLength(zclString);
    if (length == NumericAttributeTraits<uint8_t>::kNullValue)
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }

    VerifyOrReturnError(value.size() == 10, EMBER_ZCL_STATUS_INVALID_DATA_TYPE);
    memcpy(value.data(), &zclString[1], 10);
    value.reduce_size(length);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::ByteSpan value)
{
    static_assert(10 < NumericAttributeTraits<uint8_t>::kNullValue, "value.size() might be too big");
    VerifyOrReturnError(value.size() <= 10, EMBER_ZCL_STATUS_CONSTRAINT_ERROR);
    uint8_t zclString[10 + 1];
    emberAfCopyInt8u(zclString, 0, static_cast<uint8_t>(value.size()));
    memcpy(&zclString[1], value.data(), value.size());
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, zclString, ZCL_OCTET_STRING_ATTRIBUTE_TYPE);
}

} // namespace OctetString

namespace LongOctetString {

EmberAfStatus Get(chip::EndpointId endpoint, chip::MutableByteSpan value)
{
    uint8_t zclString[1000 + 2];
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, zclString, sizeof(zclString));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    size_t length = emberAfLongStringLength(zclString);
    if (length == NumericAttributeTraits<uint16_t>::kNullValue)
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }

    VerifyOrReturnError(value.size() == 1000, EMBER_ZCL_STATUS_INVALID_DATA_TYPE);
    memcpy(value.data(), &zclString[2], 1000);
    value.reduce_size(length);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::ByteSpan value)
{
    static_assert(1000 < NumericAttributeTraits<uint16_t>::kNullValue, "value.size() might be too big");
    VerifyOrReturnError(value.size() <= 1000, EMBER_ZCL_STATUS_CONSTRAINT_ERROR);
    uint8_t zclString[1000 + 2];
    emberAfCopyInt16u(zclString, 0, static_cast<uint16_t>(value.size()));
    memcpy(&zclString[2], value.data(), value.size());
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, zclString, ZCL_LONG_OCTET_STRING_ATTRIBUTE_TYPE);
}

} // namespace LongOctetString

namespace CharString {

EmberAfStatus Get(chip::EndpointId endpoint, chip::MutableCharSpan value)
{
    uint8_t zclString[10 + 1];
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, zclString, sizeof(zclString));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    size_t length = emberAfStringLength(zclString);
    if (length == NumericAttributeTraits<uint8_t>::kNullValue)
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }

    VerifyOrReturnError(value.size() == 10, EMBER_ZCL_STATUS_INVALID_DATA_TYPE);
    memcpy(value.data(), &zclString[1], 10);
    value.reduce_size(length);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::CharSpan value)
{
    static_assert(10 < NumericAttributeTraits<uint8_t>::kNullValue, "value.size() might be too big");
    VerifyOrReturnError(value.size() <= 10, EMBER_ZCL_STATUS_CONSTRAINT_ERROR);
    uint8_t zclString[10 + 1];
    emberAfCopyInt8u(zclString, 0, static_cast<uint8_t>(value.size()));
    memcpy(&zclString[1], value.data(), value.size());
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, zclString, ZCL_CHAR_STRING_ATTRIBUTE_TYPE);
}

} // namespace CharString

namespace LongCharString {

EmberAfStatus Get(chip::EndpointId endpoint, chip::MutableCharSpan value)
{
    uint8_t zclString[1000 + 2];
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, zclString, sizeof(zclString));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    size_t length = emberAfLongStringLength(zclString);
    if (length == NumericAttributeTraits<uint16_t>::kNullValue)
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }

    VerifyOrReturnError(value.size() == 1000, EMBER_ZCL_STATUS_INVALID_DATA_TYPE);
    memcpy(value.data(), &zclString[2], 1000);
    value.reduce_size(length);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::CharSpan value)
{
    static_assert(1000 < NumericAttributeTraits<uint16_t>::kNullValue, "value.size() might be too big");
    VerifyOrReturnError(value.size() <= 1000, EMBER_ZCL_STATUS_CONSTRAINT_ERROR);
    uint8_t zclString[1000 + 2];
    emberAfCopyInt16u(zclString, 0, static_cast<uint16_t>(value.size()));
    memcpy(&zclString[2], value.data(), value.size());
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, zclString, ZCL_LONG_CHAR_STRING_ATTRIBUTE_TYPE);
}

} // namespace LongCharString

namespace EpochUs {

EmberAfStatus Get(chip::EndpointId endpoint, uint64_t * value)
{
    using Traits = NumericAttributeTraits<uint64_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint64_t value)
{
    using Traits = NumericAttributeTraits<uint64_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_EPOCH_US_ATTRIBUTE_TYPE);
}

} // namespace EpochUs

namespace EpochS {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_EPOCH_S_ATTRIBUTE_TYPE);
}

} // namespace EpochS

namespace VendorId {

EmberAfStatus Get(chip::EndpointId endpoint, chip::VendorId * value)
{
    using Traits = NumericAttributeTraits<chip::VendorId>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::VendorId value)
{
    using Traits = NumericAttributeTraits<chip::VendorId>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_VENDOR_ID_ATTRIBUTE_TYPE);
}

} // namespace VendorId

namespace EnumAttr {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::TestCluster::SimpleEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::TestCluster::SimpleEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::app::Clusters::TestCluster::SimpleEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::TestCluster::SimpleEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace EnumAttr

namespace RangeRestrictedInt8u {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

} // namespace RangeRestrictedInt8u

namespace RangeRestrictedInt8s {

EmberAfStatus Get(chip::EndpointId endpoint, int8_t * value)
{
    using Traits = NumericAttributeTraits<int8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int8_t value)
{
    using Traits = NumericAttributeTraits<int8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_INT8S_ATTRIBUTE_TYPE);
}

} // namespace RangeRestrictedInt8s

namespace RangeRestrictedInt16u {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace RangeRestrictedInt16u

namespace RangeRestrictedInt16s {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace RangeRestrictedInt16s

namespace TimedWriteBoolean {

EmberAfStatus Get(chip::EndpointId endpoint, bool * value)
{
    using Traits = NumericAttributeTraits<bool>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, bool value)
{
    using Traits = NumericAttributeTraits<bool>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_BOOLEAN_ATTRIBUTE_TYPE);
}

} // namespace TimedWriteBoolean

namespace GeneralErrorBoolean {

EmberAfStatus Get(chip::EndpointId endpoint, bool * value)
{
    using Traits = NumericAttributeTraits<bool>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, bool value)
{
    using Traits = NumericAttributeTraits<bool>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_BOOLEAN_ATTRIBUTE_TYPE);
}

} // namespace GeneralErrorBoolean

namespace ClusterErrorBoolean {

EmberAfStatus Get(chip::EndpointId endpoint, bool * value)
{
    using Traits = NumericAttributeTraits<bool>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, bool value)
{
    using Traits = NumericAttributeTraits<bool>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_BOOLEAN_ATTRIBUTE_TYPE);
}

} // namespace ClusterErrorBoolean

namespace Unsupported {

EmberAfStatus Get(chip::EndpointId endpoint, bool * value)
{
    using Traits = NumericAttributeTraits<bool>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, bool value)
{
    using Traits = NumericAttributeTraits<bool>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_BOOLEAN_ATTRIBUTE_TYPE);
}

} // namespace Unsupported

namespace NullableBoolean {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<bool> & value)
{
    using Traits = NumericAttributeTraits<bool>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, bool value)
{
    using Traits = NumericAttributeTraits<bool>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_BOOLEAN_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<bool>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_BOOLEAN_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<bool> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace NullableBoolean

namespace NullableBitmap8 {

EmberAfStatus Get(chip::EndpointId endpoint,
                  DataModel::Nullable<chip::BitMask<chip::app::Clusters::TestCluster::Bitmap8MaskMap>> & value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::TestCluster::Bitmap8MaskMap>>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::BitMask<chip::app::Clusters::TestCluster::Bitmap8MaskMap> value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::TestCluster::Bitmap8MaskMap>>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_BITMAP8_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::TestCluster::Bitmap8MaskMap>>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_BITMAP8_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint,
                  const chip::app::DataModel::Nullable<chip::BitMask<chip::app::Clusters::TestCluster::Bitmap8MaskMap>> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace NullableBitmap8

namespace NullableBitmap16 {

EmberAfStatus Get(chip::EndpointId endpoint,
                  DataModel::Nullable<chip::BitMask<chip::app::Clusters::TestCluster::Bitmap16MaskMap>> & value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::TestCluster::Bitmap16MaskMap>>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::BitMask<chip::app::Clusters::TestCluster::Bitmap16MaskMap> value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::TestCluster::Bitmap16MaskMap>>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_BITMAP16_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::TestCluster::Bitmap16MaskMap>>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_BITMAP16_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint,
                  const chip::app::DataModel::Nullable<chip::BitMask<chip::app::Clusters::TestCluster::Bitmap16MaskMap>> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace NullableBitmap16

namespace NullableBitmap32 {

EmberAfStatus Get(chip::EndpointId endpoint,
                  DataModel::Nullable<chip::BitMask<chip::app::Clusters::TestCluster::Bitmap32MaskMap>> & value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::TestCluster::Bitmap32MaskMap>>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::BitMask<chip::app::Clusters::TestCluster::Bitmap32MaskMap> value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::TestCluster::Bitmap32MaskMap>>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::TestCluster::Bitmap32MaskMap>>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint,
                  const chip::app::DataModel::Nullable<chip::BitMask<chip::app::Clusters::TestCluster::Bitmap32MaskMap>> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace NullableBitmap32

namespace NullableBitmap64 {

EmberAfStatus Get(chip::EndpointId endpoint,
                  DataModel::Nullable<chip::BitMask<chip::app::Clusters::TestCluster::Bitmap64MaskMap>> & value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::TestCluster::Bitmap64MaskMap>>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::BitMask<chip::app::Clusters::TestCluster::Bitmap64MaskMap> value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::TestCluster::Bitmap64MaskMap>>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_BITMAP64_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::TestCluster::Bitmap64MaskMap>>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_BITMAP64_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint,
                  const chip::app::DataModel::Nullable<chip::BitMask<chip::app::Clusters::TestCluster::Bitmap64MaskMap>> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace NullableBitmap64

namespace NullableInt8u {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint8_t> & value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint8_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace NullableInt8u

namespace NullableInt16u {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint16_t> & value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint16_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace NullableInt16u

namespace NullableInt24u {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint32_t> & value)
{
    using Traits = NumericAttributeTraits<OddSizedInteger<3, false>>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<OddSizedInteger<3, false>>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_INT24U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<OddSizedInteger<3, false>>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_INT24U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint32_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace NullableInt24u

namespace NullableInt32u {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint32_t> & value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint32_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace NullableInt32u

namespace NullableInt40u {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint64_t> & value)
{
    using Traits = NumericAttributeTraits<OddSizedInteger<5, false>>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint64_t value)
{
    using Traits = NumericAttributeTraits<OddSizedInteger<5, false>>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_INT40U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<OddSizedInteger<5, false>>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_INT40U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint64_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace NullableInt40u

namespace NullableInt48u {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint64_t> & value)
{
    using Traits = NumericAttributeTraits<OddSizedInteger<6, false>>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint64_t value)
{
    using Traits = NumericAttributeTraits<OddSizedInteger<6, false>>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_INT48U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<OddSizedInteger<6, false>>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_INT48U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint64_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace NullableInt48u

namespace NullableInt56u {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint64_t> & value)
{
    using Traits = NumericAttributeTraits<OddSizedInteger<7, false>>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint64_t value)
{
    using Traits = NumericAttributeTraits<OddSizedInteger<7, false>>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_INT56U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<OddSizedInteger<7, false>>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_INT56U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint64_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace NullableInt56u

namespace NullableInt64u {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint64_t> & value)
{
    using Traits = NumericAttributeTraits<uint64_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint64_t value)
{
    using Traits = NumericAttributeTraits<uint64_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_INT64U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint64_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_INT64U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint64_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace NullableInt64u

namespace NullableInt8s {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<int8_t> & value)
{
    using Traits = NumericAttributeTraits<int8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int8_t value)
{
    using Traits = NumericAttributeTraits<int8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_INT8S_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<int8_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_INT8S_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<int8_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace NullableInt8s

namespace NullableInt16s {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<int16_t> & value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<int16_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace NullableInt16s

namespace NullableInt24s {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<int32_t> & value)
{
    using Traits = NumericAttributeTraits<OddSizedInteger<3, true>>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int32_t value)
{
    using Traits = NumericAttributeTraits<OddSizedInteger<3, true>>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_INT24S_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<OddSizedInteger<3, true>>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_INT24S_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<int32_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace NullableInt24s

namespace NullableInt32s {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<int32_t> & value)
{
    using Traits = NumericAttributeTraits<int32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int32_t value)
{
    using Traits = NumericAttributeTraits<int32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_INT32S_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<int32_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_INT32S_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<int32_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace NullableInt32s

namespace NullableInt40s {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<int64_t> & value)
{
    using Traits = NumericAttributeTraits<OddSizedInteger<5, true>>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int64_t value)
{
    using Traits = NumericAttributeTraits<OddSizedInteger<5, true>>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_INT40S_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<OddSizedInteger<5, true>>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_INT40S_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<int64_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace NullableInt40s

namespace NullableInt48s {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<int64_t> & value)
{
    using Traits = NumericAttributeTraits<OddSizedInteger<6, true>>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int64_t value)
{
    using Traits = NumericAttributeTraits<OddSizedInteger<6, true>>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_INT48S_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<OddSizedInteger<6, true>>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_INT48S_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<int64_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace NullableInt48s

namespace NullableInt56s {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<int64_t> & value)
{
    using Traits = NumericAttributeTraits<OddSizedInteger<7, true>>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int64_t value)
{
    using Traits = NumericAttributeTraits<OddSizedInteger<7, true>>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_INT56S_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<OddSizedInteger<7, true>>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_INT56S_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<int64_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace NullableInt56s

namespace NullableInt64s {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<int64_t> & value)
{
    using Traits = NumericAttributeTraits<int64_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int64_t value)
{
    using Traits = NumericAttributeTraits<int64_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_INT64S_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<int64_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_INT64S_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<int64_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace NullableInt64s

namespace NullableEnum8 {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint8_t> & value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint8_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace NullableEnum8

namespace NullableEnum16 {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint16_t> & value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_ENUM16_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_ENUM16_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint16_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace NullableEnum16

namespace NullableFloatSingle {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, float value)
{
    using Traits = NumericAttributeTraits<float>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_SINGLE_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_SINGLE_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<float> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace NullableFloatSingle

namespace NullableFloatDouble {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<double> & value)
{
    using Traits = NumericAttributeTraits<double>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, double value)
{
    using Traits = NumericAttributeTraits<double>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_DOUBLE_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<double>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_DOUBLE_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<double> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace NullableFloatDouble

namespace NullableOctetString {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<chip::MutableByteSpan> & value)
{
    uint8_t zclString[10 + 1];
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, zclString, sizeof(zclString));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    size_t length = emberAfStringLength(zclString);
    if (length == NumericAttributeTraits<uint8_t>::kNullValue)
    {
        value.SetNull();
        return EMBER_ZCL_STATUS_SUCCESS;
    }
    auto & span = value.SetNonNull();

    VerifyOrReturnError(span.size() == 10, EMBER_ZCL_STATUS_INVALID_DATA_TYPE);
    memcpy(span.data(), &zclString[1], 10);
    span.reduce_size(length);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::ByteSpan value)
{
    static_assert(10 < NumericAttributeTraits<uint8_t>::kNullValue, "value.size() might be too big");
    VerifyOrReturnError(value.size() <= 10, EMBER_ZCL_STATUS_CONSTRAINT_ERROR);
    uint8_t zclString[10 + 1];
    emberAfCopyInt8u(zclString, 0, static_cast<uint8_t>(value.size()));
    memcpy(&zclString[1], value.data(), value.size());
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, zclString, ZCL_OCTET_STRING_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    uint8_t zclString[1] = { 0xFF };
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, zclString, ZCL_OCTET_STRING_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<chip::ByteSpan> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace NullableOctetString

namespace NullableCharString {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<chip::MutableCharSpan> & value)
{
    uint8_t zclString[10 + 1];
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, zclString, sizeof(zclString));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    size_t length = emberAfStringLength(zclString);
    if (length == NumericAttributeTraits<uint8_t>::kNullValue)
    {
        value.SetNull();
        return EMBER_ZCL_STATUS_SUCCESS;
    }
    auto & span = value.SetNonNull();

    VerifyOrReturnError(span.size() == 10, EMBER_ZCL_STATUS_INVALID_DATA_TYPE);
    memcpy(span.data(), &zclString[1], 10);
    span.reduce_size(length);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::CharSpan value)
{
    static_assert(10 < NumericAttributeTraits<uint8_t>::kNullValue, "value.size() might be too big");
    VerifyOrReturnError(value.size() <= 10, EMBER_ZCL_STATUS_CONSTRAINT_ERROR);
    uint8_t zclString[10 + 1];
    emberAfCopyInt8u(zclString, 0, static_cast<uint8_t>(value.size()));
    memcpy(&zclString[1], value.data(), value.size());
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, zclString, ZCL_CHAR_STRING_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    uint8_t zclString[1] = { 0xFF };
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, zclString, ZCL_CHAR_STRING_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<chip::CharSpan> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace NullableCharString

namespace NullableEnumAttr {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<chip::app::Clusters::TestCluster::SimpleEnum> & value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::TestCluster::SimpleEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, chip::app::Clusters::TestCluster::SimpleEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::TestCluster::SimpleEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::TestCluster::SimpleEnum>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint,
                  const chip::app::DataModel::Nullable<chip::app::Clusters::TestCluster::SimpleEnum> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace NullableEnumAttr

namespace NullableRangeRestrictedInt8u {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint8_t> & value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint8_t value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint8_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace NullableRangeRestrictedInt8u

namespace NullableRangeRestrictedInt8s {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<int8_t> & value)
{
    using Traits = NumericAttributeTraits<int8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int8_t value)
{
    using Traits = NumericAttributeTraits<int8_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_INT8S_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<int8_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_INT8S_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<int8_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace NullableRangeRestrictedInt8s

namespace NullableRangeRestrictedInt16u {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<uint16_t> & value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<uint16_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace NullableRangeRestrictedInt16u

namespace NullableRangeRestrictedInt16s {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<int16_t> & value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (Traits::IsNullValue(temp))
    {
        value.SetNull();
    }
    else
    {
        value.SetNonNull() = Traits::StorageToWorking(temp);
    }
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, int16_t value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ true, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable<int16_t> & value)
{
    if (value.IsNull())
    {
        return SetNull(endpoint);
    }

    return Set(endpoint, value.Value());
}

} // namespace NullableRangeRestrictedInt16s

namespace FeatureMap {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint32_t value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace FeatureMap

namespace ClusterRevision {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadServerAttribute(endpoint, Clusters::TestCluster::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, status);
    if (!Traits::CanRepresentValue(/* isNullable = */ false, temp))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    *value = Traits::StorageToWorking(temp);
    return status;
}
EmberAfStatus Set(chip::EndpointId endpoint, uint16_t value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteServerAttribute(endpoint, Clusters::TestCluster::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace TestCluster

} // namespace Clusters
} // namespace app
} // namespace chip
