/*
 *
 *    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 = emberAfReadAttribute(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 emberAfWriteAttribute(endpoint, Clusters::Identify::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace IdentifyTime

namespace IdentifyType {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::Identify::IdentifyTypeEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::Identify::IdentifyTypeEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(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, chip::app::Clusters::Identify::IdentifyTypeEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::Identify::IdentifyTypeEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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, chip::BitMask<chip::app::Clusters::Groups::NameSupportBitmap> * value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::Groups::NameSupportBitmap>>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(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, chip::BitMask<chip::app::Clusters::Groups::NameSupportBitmap> value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::Groups::NameSupportBitmap>>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(endpoint, Clusters::LevelControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace MaxFrequency

namespace Options {

EmberAfStatus Get(chip::EndpointId endpoint, chip::BitMask<chip::app::Clusters::LevelControl::LevelControlOptions> * value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::LevelControl::LevelControlOptions>>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(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, chip::BitMask<chip::app::Clusters::LevelControl::LevelControlOptions> value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::LevelControl::LevelControlOptions>>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(endpoint, Clusters::Binding::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace Binding

namespace AccessControl {
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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(endpoint, Clusters::AccessControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace AccessControl

namespace Actions {
namespace Attributes {

namespace SetupURL {

EmberAfStatus Get(chip::EndpointId endpoint, chip::MutableCharSpan value)
{
    uint8_t zclString[512 + 2];
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::Actions::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 emberAfWriteAttribute(endpoint, Clusters::Actions::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 = emberAfReadAttribute(endpoint, Clusters::Actions::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::Actions::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 = emberAfReadAttribute(endpoint, Clusters::Actions::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::Actions::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace Actions

namespace BasicInformation {
namespace Attributes {

namespace NodeLabel {

EmberAfStatus Get(chip::EndpointId endpoint, chip::MutableCharSpan value)
{
    uint8_t zclString[32 + 1];
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::BasicInformation::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 emberAfWriteAttribute(endpoint, Clusters::BasicInformation::Id, Id, zclString, ZCL_CHAR_STRING_ATTRIBUTE_TYPE);
}

} // namespace NodeLabel

namespace LocalConfigDisabled {

EmberAfStatus Get(chip::EndpointId endpoint, bool * value)
{
    using Traits = NumericAttributeTraits<bool>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::BasicInformation::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::BasicInformation::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 = emberAfReadAttribute(endpoint, Clusters::BasicInformation::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::BasicInformation::Id, Id, writable, ZCL_BOOLEAN_ATTRIBUTE_TYPE);
}

} // namespace Reachable

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 = emberAfReadAttribute(endpoint, Clusters::BasicInformation::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::BasicInformation::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 = emberAfReadAttribute(endpoint, Clusters::BasicInformation::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::BasicInformation::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace BasicInformation

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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 =
        emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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::HourFormatEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::TimeFormatLocalization::HourFormatEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(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::HourFormatEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::TimeFormatLocalization::HourFormatEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::TimeFormatLocalization::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace HourFormat

namespace ActiveCalendarType {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::TimeFormatLocalization::CalendarTypeEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::TimeFormatLocalization::CalendarTypeEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(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::CalendarTypeEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::TimeFormatLocalization::CalendarTypeEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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::TempUnitEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::UnitLocalization::TempUnitEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(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::TempUnitEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::UnitLocalization::TempUnitEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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::PowerSourceStatusEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::PowerSource::PowerSourceStatusEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(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::PowerSourceStatusEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::PowerSource::PowerSourceStatusEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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::WiredCurrentTypeEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::PowerSource::WiredCurrentTypeEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(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::WiredCurrentTypeEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::PowerSource::WiredCurrentTypeEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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::BatChargeLevelEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::PowerSource::BatChargeLevelEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(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::BatChargeLevelEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::PowerSource::BatChargeLevelEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(endpoint, Clusters::PowerSource::Id, Id, writable, ZCL_BOOLEAN_ATTRIBUTE_TYPE);
}

} // namespace BatReplacementNeeded

namespace BatReplaceability {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::PowerSource::BatReplaceabilityEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::PowerSource::BatReplaceabilityEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(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::BatReplaceabilityEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::PowerSource::BatReplaceabilityEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(endpoint, Clusters::PowerSource::Id, Id, zclString, ZCL_CHAR_STRING_ATTRIBUTE_TYPE);
}

} // namespace BatReplacementDescription

namespace BatCommonDesignation {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::PowerSource::BatCommonDesignationEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::PowerSource::BatCommonDesignationEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(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::BatCommonDesignationEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::PowerSource::BatCommonDesignationEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::PowerSource::Id, Id, writable, ZCL_ENUM16_ATTRIBUTE_TYPE);
}

} // namespace BatCommonDesignation

namespace BatANSIDesignation {

EmberAfStatus Get(chip::EndpointId endpoint, chip::MutableCharSpan value)
{
    uint8_t zclString[20 + 1];
    EmberAfStatus status = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(endpoint, Clusters::PowerSource::Id, Id, zclString, ZCL_CHAR_STRING_ATTRIBUTE_TYPE);
}

} // namespace BatIECDesignation

namespace BatApprovedChemistry {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::PowerSource::BatApprovedChemistryEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::PowerSource::BatApprovedChemistryEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(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::BatApprovedChemistryEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::PowerSource::BatApprovedChemistryEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::PowerSource::Id, Id, writable, ZCL_ENUM16_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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(endpoint, Clusters::PowerSource::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

} // namespace BatQuantity

namespace BatChargeState {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::PowerSource::BatChargeStateEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::PowerSource::BatChargeStateEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(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::BatChargeStateEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::PowerSource::BatChargeStateEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(endpoint, Clusters::GeneralCommissioning::Id, Id, writable, ZCL_INT64U_ATTRIBUTE_TYPE);
}

} // namespace Breadcrumb

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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(endpoint, Clusters::NetworkCommissioning::Id, Id, zclString, ZCL_OCTET_STRING_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    uint8_t zclString[1] = { 0xFF };
    return emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(endpoint, Clusters::DiagnosticLogs::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace DiagnosticLogs

namespace GeneralDiagnostics {
namespace Attributes {

namespace TestEventTriggersEnabled {

EmberAfStatus Get(chip::EndpointId endpoint, bool * value)
{
    using Traits = NumericAttributeTraits<bool>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(endpoint, Clusters::GeneralDiagnostics::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace GeneralDiagnostics

namespace SoftwareDiagnostics {
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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(endpoint, Clusters::SoftwareDiagnostics::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace SoftwareDiagnostics

namespace ThreadNetworkDiagnostics {
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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(endpoint, Clusters::ThreadNetworkDiagnostics::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace ThreadNetworkDiagnostics

namespace WiFiNetworkDiagnostics {
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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(endpoint, Clusters::WiFiNetworkDiagnostics::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace WiFiNetworkDiagnostics

namespace EthernetNetworkDiagnostics {
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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(endpoint, Clusters::EthernetNetworkDiagnostics::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace EthernetNetworkDiagnostics

namespace TimeSynchronization {
namespace Attributes {

namespace Granularity {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::TimeSynchronization::GranularityEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::TimeSynchronization::GranularityEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(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, chip::app::Clusters::TimeSynchronization::GranularityEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::TimeSynchronization::GranularityEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::TimeSynchronization::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace Granularity

namespace TimeSource {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::TimeSynchronization::TimeSourceEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::TimeSynchronization::TimeSourceEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(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, chip::app::Clusters::TimeSynchronization::TimeSourceEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::TimeSynchronization::TimeSourceEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::TimeSynchronization::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace TimeSource

namespace TimeZoneDatabase {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::TimeSynchronization::TimeZoneDatabaseEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::TimeSynchronization::TimeZoneDatabaseEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(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, chip::app::Clusters::TimeSynchronization::TimeZoneDatabaseEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::TimeSynchronization::TimeZoneDatabaseEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::TimeSynchronization::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace TimeZoneDatabase

namespace NTPServerAvailable {

EmberAfStatus Get(chip::EndpointId endpoint, bool * value)
{
    using Traits = NumericAttributeTraits<bool>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(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, 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 emberAfWriteAttribute(endpoint, Clusters::TimeSynchronization::Id, Id, writable, ZCL_BOOLEAN_ATTRIBUTE_TYPE);
}

} // namespace NTPServerAvailable

namespace TimeZoneListMaxSize {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(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, 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 emberAfWriteAttribute(endpoint, Clusters::TimeSynchronization::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

} // namespace TimeZoneListMaxSize

namespace DSTOffsetListMaxSize {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(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, 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 emberAfWriteAttribute(endpoint, Clusters::TimeSynchronization::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

} // namespace DSTOffsetListMaxSize

namespace SupportsDNSResolve {

EmberAfStatus Get(chip::EndpointId endpoint, bool * value)
{
    using Traits = NumericAttributeTraits<bool>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(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, 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 emberAfWriteAttribute(endpoint, Clusters::TimeSynchronization::Id, Id, writable, ZCL_BOOLEAN_ATTRIBUTE_TYPE);
}

} // namespace SupportsDNSResolve

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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(endpoint, Clusters::TimeSynchronization::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace TimeSynchronization

namespace BridgedDeviceBasicInformation {
namespace Attributes {

namespace VendorName {

EmberAfStatus Get(chip::EndpointId endpoint, chip::MutableCharSpan value)
{
    uint8_t zclString[32 + 1];
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::BridgedDeviceBasicInformation::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 emberAfWriteAttribute(endpoint, Clusters::BridgedDeviceBasicInformation::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 = emberAfReadAttribute(endpoint, Clusters::BridgedDeviceBasicInformation::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::BridgedDeviceBasicInformation::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 =
        emberAfReadAttribute(endpoint, Clusters::BridgedDeviceBasicInformation::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 emberAfWriteAttribute(endpoint, Clusters::BridgedDeviceBasicInformation::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 =
        emberAfReadAttribute(endpoint, Clusters::BridgedDeviceBasicInformation::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 emberAfWriteAttribute(endpoint, Clusters::BridgedDeviceBasicInformation::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 = emberAfReadAttribute(endpoint, Clusters::BridgedDeviceBasicInformation::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::BridgedDeviceBasicInformation::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 =
        emberAfReadAttribute(endpoint, Clusters::BridgedDeviceBasicInformation::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 emberAfWriteAttribute(endpoint, Clusters::BridgedDeviceBasicInformation::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 = emberAfReadAttribute(endpoint, Clusters::BridgedDeviceBasicInformation::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::BridgedDeviceBasicInformation::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 =
        emberAfReadAttribute(endpoint, Clusters::BridgedDeviceBasicInformation::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 emberAfWriteAttribute(endpoint, Clusters::BridgedDeviceBasicInformation::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 =
        emberAfReadAttribute(endpoint, Clusters::BridgedDeviceBasicInformation::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 emberAfWriteAttribute(endpoint, Clusters::BridgedDeviceBasicInformation::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 =
        emberAfReadAttribute(endpoint, Clusters::BridgedDeviceBasicInformation::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 emberAfWriteAttribute(endpoint, Clusters::BridgedDeviceBasicInformation::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 =
        emberAfReadAttribute(endpoint, Clusters::BridgedDeviceBasicInformation::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 emberAfWriteAttribute(endpoint, Clusters::BridgedDeviceBasicInformation::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 =
        emberAfReadAttribute(endpoint, Clusters::BridgedDeviceBasicInformation::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 emberAfWriteAttribute(endpoint, Clusters::BridgedDeviceBasicInformation::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 =
        emberAfReadAttribute(endpoint, Clusters::BridgedDeviceBasicInformation::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 emberAfWriteAttribute(endpoint, Clusters::BridgedDeviceBasicInformation::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 = emberAfReadAttribute(endpoint, Clusters::BridgedDeviceBasicInformation::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::BridgedDeviceBasicInformation::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 =
        emberAfReadAttribute(endpoint, Clusters::BridgedDeviceBasicInformation::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 emberAfWriteAttribute(endpoint, Clusters::BridgedDeviceBasicInformation::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 = emberAfReadAttribute(endpoint, Clusters::BridgedDeviceBasicInformation::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::BridgedDeviceBasicInformation::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 = emberAfReadAttribute(endpoint, Clusters::BridgedDeviceBasicInformation::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::BridgedDeviceBasicInformation::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace BridgedDeviceBasicInformation

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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(endpoint, Clusters::Switch::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace Switch

namespace AdministratorCommissioning {
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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(endpoint, Clusters::AdministratorCommissioning::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace AdministratorCommissioning

namespace OperationalCredentials {
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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(endpoint, Clusters::OperationalCredentials::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace OperationalCredentials

namespace GroupKeyManagement {
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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(endpoint, Clusters::BooleanState::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace BooleanState

namespace IcdManagement {
namespace Attributes {

namespace IdleModeInterval {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::IcdManagement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::IcdManagement::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

} // namespace IdleModeInterval

namespace ActiveModeInterval {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::IcdManagement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::IcdManagement::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

} // namespace ActiveModeInterval

namespace ActiveModeThreshold {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::IcdManagement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::IcdManagement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ActiveModeThreshold

namespace ICDCounter {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::IcdManagement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::IcdManagement::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE);
}

} // namespace ICDCounter

namespace ClientsSupportedPerFabric {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::IcdManagement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::IcdManagement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClientsSupportedPerFabric

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 = emberAfReadAttribute(endpoint, Clusters::IcdManagement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::IcdManagement::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 = emberAfReadAttribute(endpoint, Clusters::IcdManagement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::IcdManagement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace IcdManagement

namespace ModeSelect {
namespace Attributes {

namespace Description {

EmberAfStatus Get(chip::EndpointId endpoint, chip::MutableCharSpan value)
{
    uint8_t zclString[32 + 1];
    EmberAfStatus status = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(endpoint, Clusters::ModeSelect::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace ModeSelect

namespace TemperatureControl {
namespace Attributes {

namespace TemperatureSetpoint {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::TemperatureControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::TemperatureControl::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace TemperatureSetpoint

namespace MinTemperature {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::TemperatureControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::TemperatureControl::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace MinTemperature

namespace MaxTemperature {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::TemperatureControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::TemperatureControl::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace MaxTemperature

namespace Step {

EmberAfStatus Get(chip::EndpointId endpoint, int16_t * value)
{
    using Traits = NumericAttributeTraits<int16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::TemperatureControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::TemperatureControl::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE);
}

} // namespace Step

namespace CurrentTemperatureLevelIndex {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::TemperatureControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::TemperatureControl::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

} // namespace CurrentTemperatureLevelIndex

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 = emberAfReadAttribute(endpoint, Clusters::TemperatureControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::TemperatureControl::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 = emberAfReadAttribute(endpoint, Clusters::TemperatureControl::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::TemperatureControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace TemperatureControl

namespace RefrigeratorAlarm {
namespace Attributes {

namespace Mask {

EmberAfStatus Get(chip::EndpointId endpoint, chip::BitMask<chip::app::Clusters::RefrigeratorAlarm::AlarmMap> * value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::RefrigeratorAlarm::AlarmMap>>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::RefrigeratorAlarm::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::RefrigeratorAlarm::AlarmMap> value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::RefrigeratorAlarm::AlarmMap>>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::RefrigeratorAlarm::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace Mask

namespace Latch {

EmberAfStatus Get(chip::EndpointId endpoint, chip::BitMask<chip::app::Clusters::RefrigeratorAlarm::AlarmMap> * value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::RefrigeratorAlarm::AlarmMap>>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::RefrigeratorAlarm::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::RefrigeratorAlarm::AlarmMap> value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::RefrigeratorAlarm::AlarmMap>>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::RefrigeratorAlarm::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace Latch

namespace State {

EmberAfStatus Get(chip::EndpointId endpoint, chip::BitMask<chip::app::Clusters::RefrigeratorAlarm::AlarmMap> * value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::RefrigeratorAlarm::AlarmMap>>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::RefrigeratorAlarm::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::RefrigeratorAlarm::AlarmMap> value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::RefrigeratorAlarm::AlarmMap>>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::RefrigeratorAlarm::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace State

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 = emberAfReadAttribute(endpoint, Clusters::RefrigeratorAlarm::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::RefrigeratorAlarm::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 = emberAfReadAttribute(endpoint, Clusters::RefrigeratorAlarm::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::RefrigeratorAlarm::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace RefrigeratorAlarm

namespace AirQuality {
namespace Attributes {

namespace AirQuality {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::AirQuality::AirQualityEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::AirQuality::AirQualityEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::AirQuality::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::AirQuality::AirQualityEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::AirQuality::AirQualityEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::AirQuality::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace AirQuality

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 = emberAfReadAttribute(endpoint, Clusters::AirQuality::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::AirQuality::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 = emberAfReadAttribute(endpoint, Clusters::AirQuality::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::AirQuality::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace AirQuality

namespace SmokeCoAlarm {
namespace Attributes {

namespace ExpressedState {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::SmokeCoAlarm::ExpressedStateEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::SmokeCoAlarm::ExpressedStateEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::SmokeCoAlarm::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::SmokeCoAlarm::ExpressedStateEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::SmokeCoAlarm::ExpressedStateEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::SmokeCoAlarm::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace ExpressedState

namespace SmokeState {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::SmokeCoAlarm::AlarmStateEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::SmokeCoAlarm::AlarmStateEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::SmokeCoAlarm::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::SmokeCoAlarm::AlarmStateEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::SmokeCoAlarm::AlarmStateEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::SmokeCoAlarm::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace SmokeState

namespace COState {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::SmokeCoAlarm::AlarmStateEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::SmokeCoAlarm::AlarmStateEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::SmokeCoAlarm::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::SmokeCoAlarm::AlarmStateEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::SmokeCoAlarm::AlarmStateEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::SmokeCoAlarm::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace COState

namespace BatteryAlert {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::SmokeCoAlarm::AlarmStateEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::SmokeCoAlarm::AlarmStateEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::SmokeCoAlarm::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::SmokeCoAlarm::AlarmStateEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::SmokeCoAlarm::AlarmStateEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::SmokeCoAlarm::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace BatteryAlert

namespace DeviceMuted {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::SmokeCoAlarm::MuteStateEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::SmokeCoAlarm::MuteStateEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::SmokeCoAlarm::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::SmokeCoAlarm::MuteStateEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::SmokeCoAlarm::MuteStateEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::SmokeCoAlarm::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace DeviceMuted

namespace TestInProgress {

EmberAfStatus Get(chip::EndpointId endpoint, bool * value)
{
    using Traits = NumericAttributeTraits<bool>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::SmokeCoAlarm::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::SmokeCoAlarm::Id, Id, writable, ZCL_BOOLEAN_ATTRIBUTE_TYPE);
}

} // namespace TestInProgress

namespace HardwareFaultAlert {

EmberAfStatus Get(chip::EndpointId endpoint, bool * value)
{
    using Traits = NumericAttributeTraits<bool>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::SmokeCoAlarm::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::SmokeCoAlarm::Id, Id, writable, ZCL_BOOLEAN_ATTRIBUTE_TYPE);
}

} // namespace HardwareFaultAlert

namespace EndOfServiceAlert {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::SmokeCoAlarm::EndOfServiceEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::SmokeCoAlarm::EndOfServiceEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::SmokeCoAlarm::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::SmokeCoAlarm::EndOfServiceEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::SmokeCoAlarm::EndOfServiceEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::SmokeCoAlarm::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace EndOfServiceAlert

namespace InterconnectSmokeAlarm {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::SmokeCoAlarm::AlarmStateEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::SmokeCoAlarm::AlarmStateEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::SmokeCoAlarm::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::SmokeCoAlarm::AlarmStateEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::SmokeCoAlarm::AlarmStateEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::SmokeCoAlarm::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace InterconnectSmokeAlarm

namespace InterconnectCOAlarm {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::SmokeCoAlarm::AlarmStateEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::SmokeCoAlarm::AlarmStateEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::SmokeCoAlarm::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::SmokeCoAlarm::AlarmStateEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::SmokeCoAlarm::AlarmStateEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::SmokeCoAlarm::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace InterconnectCOAlarm

namespace ContaminationState {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::SmokeCoAlarm::ContaminationStateEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::SmokeCoAlarm::ContaminationStateEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::SmokeCoAlarm::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::SmokeCoAlarm::ContaminationStateEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::SmokeCoAlarm::ContaminationStateEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::SmokeCoAlarm::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace ContaminationState

namespace SensitivityLevel {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::SmokeCoAlarm::SensitivityEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::SmokeCoAlarm::SensitivityEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::SmokeCoAlarm::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::SmokeCoAlarm::SensitivityEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::SmokeCoAlarm::SensitivityEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::SmokeCoAlarm::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace SensitivityLevel

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 = emberAfReadAttribute(endpoint, Clusters::SmokeCoAlarm::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::SmokeCoAlarm::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 = emberAfReadAttribute(endpoint, Clusters::SmokeCoAlarm::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::SmokeCoAlarm::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace SmokeCoAlarm

namespace HepaFilterMonitoring {
namespace Attributes {

namespace Condition {

EmberAfStatus Get(chip::EndpointId endpoint, chip::Percent * value)
{
    using Traits = NumericAttributeTraits<chip::Percent>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::HepaFilterMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::Percent value)
{
    using Traits = NumericAttributeTraits<chip::Percent>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::HepaFilterMonitoring::Id, Id, writable, ZCL_PERCENT_ATTRIBUTE_TYPE);
}

} // namespace Condition

namespace DegradationDirection {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::HepaFilterMonitoring::DegradationDirectionEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::HepaFilterMonitoring::DegradationDirectionEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::HepaFilterMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::HepaFilterMonitoring::DegradationDirectionEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::HepaFilterMonitoring::DegradationDirectionEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::HepaFilterMonitoring::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace DegradationDirection

namespace ChangeIndication {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::HepaFilterMonitoring::ChangeIndicationEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::HepaFilterMonitoring::ChangeIndicationEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::HepaFilterMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::HepaFilterMonitoring::ChangeIndicationEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::HepaFilterMonitoring::ChangeIndicationEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::HepaFilterMonitoring::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace ChangeIndication

namespace InPlaceIndicator {

EmberAfStatus Get(chip::EndpointId endpoint, bool * value)
{
    using Traits = NumericAttributeTraits<bool>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::HepaFilterMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::HepaFilterMonitoring::Id, Id, writable, ZCL_BOOLEAN_ATTRIBUTE_TYPE);
}

} // namespace InPlaceIndicator

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 = emberAfReadAttribute(endpoint, Clusters::HepaFilterMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::HepaFilterMonitoring::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 = emberAfReadAttribute(endpoint, Clusters::HepaFilterMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::HepaFilterMonitoring::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace HepaFilterMonitoring

namespace ActivatedCarbonFilterMonitoring {
namespace Attributes {

namespace Condition {

EmberAfStatus Get(chip::EndpointId endpoint, chip::Percent * value)
{
    using Traits = NumericAttributeTraits<chip::Percent>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::ActivatedCarbonFilterMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::Percent value)
{
    using Traits = NumericAttributeTraits<chip::Percent>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::ActivatedCarbonFilterMonitoring::Id, Id, writable, ZCL_PERCENT_ATTRIBUTE_TYPE);
}

} // namespace Condition

namespace DegradationDirection {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::ActivatedCarbonFilterMonitoring::DegradationDirectionEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::ActivatedCarbonFilterMonitoring::DegradationDirectionEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::ActivatedCarbonFilterMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::ActivatedCarbonFilterMonitoring::DegradationDirectionEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::ActivatedCarbonFilterMonitoring::DegradationDirectionEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::ActivatedCarbonFilterMonitoring::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace DegradationDirection

namespace ChangeIndication {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::ActivatedCarbonFilterMonitoring::ChangeIndicationEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::ActivatedCarbonFilterMonitoring::ChangeIndicationEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::ActivatedCarbonFilterMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::ActivatedCarbonFilterMonitoring::ChangeIndicationEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::ActivatedCarbonFilterMonitoring::ChangeIndicationEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::ActivatedCarbonFilterMonitoring::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace ChangeIndication

namespace InPlaceIndicator {

EmberAfStatus Get(chip::EndpointId endpoint, bool * value)
{
    using Traits = NumericAttributeTraits<bool>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::ActivatedCarbonFilterMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::ActivatedCarbonFilterMonitoring::Id, Id, writable, ZCL_BOOLEAN_ATTRIBUTE_TYPE);
}

} // namespace InPlaceIndicator

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 =
        emberAfReadAttribute(endpoint, Clusters::ActivatedCarbonFilterMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::ActivatedCarbonFilterMonitoring::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 =
        emberAfReadAttribute(endpoint, Clusters::ActivatedCarbonFilterMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::ActivatedCarbonFilterMonitoring::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace ActivatedCarbonFilterMonitoring

namespace CeramicFilterMonitoring {
namespace Attributes {

namespace Condition {

EmberAfStatus Get(chip::EndpointId endpoint, chip::Percent * value)
{
    using Traits = NumericAttributeTraits<chip::Percent>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::CeramicFilterMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::Percent value)
{
    using Traits = NumericAttributeTraits<chip::Percent>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::CeramicFilterMonitoring::Id, Id, writable, ZCL_PERCENT_ATTRIBUTE_TYPE);
}

} // namespace Condition

namespace DegradationDirection {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::CeramicFilterMonitoring::DegradationDirectionEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::CeramicFilterMonitoring::DegradationDirectionEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::CeramicFilterMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::CeramicFilterMonitoring::DegradationDirectionEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::CeramicFilterMonitoring::DegradationDirectionEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::CeramicFilterMonitoring::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace DegradationDirection

namespace ChangeIndication {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::CeramicFilterMonitoring::ChangeIndicationEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::CeramicFilterMonitoring::ChangeIndicationEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::CeramicFilterMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::CeramicFilterMonitoring::ChangeIndicationEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::CeramicFilterMonitoring::ChangeIndicationEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::CeramicFilterMonitoring::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace ChangeIndication

namespace InPlaceIndicator {

EmberAfStatus Get(chip::EndpointId endpoint, bool * value)
{
    using Traits = NumericAttributeTraits<bool>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::CeramicFilterMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::CeramicFilterMonitoring::Id, Id, writable, ZCL_BOOLEAN_ATTRIBUTE_TYPE);
}

} // namespace InPlaceIndicator

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 = emberAfReadAttribute(endpoint, Clusters::CeramicFilterMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::CeramicFilterMonitoring::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 = emberAfReadAttribute(endpoint, Clusters::CeramicFilterMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::CeramicFilterMonitoring::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace CeramicFilterMonitoring

namespace ElectrostaticFilterMonitoring {
namespace Attributes {

namespace Condition {

EmberAfStatus Get(chip::EndpointId endpoint, chip::Percent * value)
{
    using Traits = NumericAttributeTraits<chip::Percent>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::ElectrostaticFilterMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::Percent value)
{
    using Traits = NumericAttributeTraits<chip::Percent>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::ElectrostaticFilterMonitoring::Id, Id, writable, ZCL_PERCENT_ATTRIBUTE_TYPE);
}

} // namespace Condition

namespace DegradationDirection {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::ElectrostaticFilterMonitoring::DegradationDirectionEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::ElectrostaticFilterMonitoring::DegradationDirectionEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::ElectrostaticFilterMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::ElectrostaticFilterMonitoring::DegradationDirectionEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::ElectrostaticFilterMonitoring::DegradationDirectionEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::ElectrostaticFilterMonitoring::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace DegradationDirection

namespace ChangeIndication {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::ElectrostaticFilterMonitoring::ChangeIndicationEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::ElectrostaticFilterMonitoring::ChangeIndicationEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::ElectrostaticFilterMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::ElectrostaticFilterMonitoring::ChangeIndicationEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::ElectrostaticFilterMonitoring::ChangeIndicationEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::ElectrostaticFilterMonitoring::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace ChangeIndication

namespace InPlaceIndicator {

EmberAfStatus Get(chip::EndpointId endpoint, bool * value)
{
    using Traits = NumericAttributeTraits<bool>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::ElectrostaticFilterMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::ElectrostaticFilterMonitoring::Id, Id, writable, ZCL_BOOLEAN_ATTRIBUTE_TYPE);
}

} // namespace InPlaceIndicator

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 = emberAfReadAttribute(endpoint, Clusters::ElectrostaticFilterMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::ElectrostaticFilterMonitoring::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 = emberAfReadAttribute(endpoint, Clusters::ElectrostaticFilterMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::ElectrostaticFilterMonitoring::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace ElectrostaticFilterMonitoring

namespace UvFilterMonitoring {
namespace Attributes {

namespace Condition {

EmberAfStatus Get(chip::EndpointId endpoint, chip::Percent * value)
{
    using Traits = NumericAttributeTraits<chip::Percent>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::UvFilterMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::Percent value)
{
    using Traits = NumericAttributeTraits<chip::Percent>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::UvFilterMonitoring::Id, Id, writable, ZCL_PERCENT_ATTRIBUTE_TYPE);
}

} // namespace Condition

namespace DegradationDirection {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::UvFilterMonitoring::DegradationDirectionEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::UvFilterMonitoring::DegradationDirectionEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::UvFilterMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::UvFilterMonitoring::DegradationDirectionEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::UvFilterMonitoring::DegradationDirectionEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::UvFilterMonitoring::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace DegradationDirection

namespace ChangeIndication {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::UvFilterMonitoring::ChangeIndicationEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::UvFilterMonitoring::ChangeIndicationEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::UvFilterMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::UvFilterMonitoring::ChangeIndicationEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::UvFilterMonitoring::ChangeIndicationEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::UvFilterMonitoring::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace ChangeIndication

namespace InPlaceIndicator {

EmberAfStatus Get(chip::EndpointId endpoint, bool * value)
{
    using Traits = NumericAttributeTraits<bool>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::UvFilterMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::UvFilterMonitoring::Id, Id, writable, ZCL_BOOLEAN_ATTRIBUTE_TYPE);
}

} // namespace InPlaceIndicator

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 = emberAfReadAttribute(endpoint, Clusters::UvFilterMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::UvFilterMonitoring::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 = emberAfReadAttribute(endpoint, Clusters::UvFilterMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::UvFilterMonitoring::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace UvFilterMonitoring

namespace IonizingFilterMonitoring {
namespace Attributes {

namespace Condition {

EmberAfStatus Get(chip::EndpointId endpoint, chip::Percent * value)
{
    using Traits = NumericAttributeTraits<chip::Percent>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::IonizingFilterMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::Percent value)
{
    using Traits = NumericAttributeTraits<chip::Percent>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::IonizingFilterMonitoring::Id, Id, writable, ZCL_PERCENT_ATTRIBUTE_TYPE);
}

} // namespace Condition

namespace DegradationDirection {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::IonizingFilterMonitoring::DegradationDirectionEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::IonizingFilterMonitoring::DegradationDirectionEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::IonizingFilterMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::IonizingFilterMonitoring::DegradationDirectionEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::IonizingFilterMonitoring::DegradationDirectionEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::IonizingFilterMonitoring::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace DegradationDirection

namespace ChangeIndication {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::IonizingFilterMonitoring::ChangeIndicationEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::IonizingFilterMonitoring::ChangeIndicationEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::IonizingFilterMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::IonizingFilterMonitoring::ChangeIndicationEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::IonizingFilterMonitoring::ChangeIndicationEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::IonizingFilterMonitoring::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace ChangeIndication

namespace InPlaceIndicator {

EmberAfStatus Get(chip::EndpointId endpoint, bool * value)
{
    using Traits = NumericAttributeTraits<bool>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::IonizingFilterMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::IonizingFilterMonitoring::Id, Id, writable, ZCL_BOOLEAN_ATTRIBUTE_TYPE);
}

} // namespace InPlaceIndicator

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 = emberAfReadAttribute(endpoint, Clusters::IonizingFilterMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::IonizingFilterMonitoring::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 = emberAfReadAttribute(endpoint, Clusters::IonizingFilterMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::IonizingFilterMonitoring::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace IonizingFilterMonitoring

namespace ZeoliteFilterMonitoring {
namespace Attributes {

namespace Condition {

EmberAfStatus Get(chip::EndpointId endpoint, chip::Percent * value)
{
    using Traits = NumericAttributeTraits<chip::Percent>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::ZeoliteFilterMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::Percent value)
{
    using Traits = NumericAttributeTraits<chip::Percent>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::ZeoliteFilterMonitoring::Id, Id, writable, ZCL_PERCENT_ATTRIBUTE_TYPE);
}

} // namespace Condition

namespace DegradationDirection {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::ZeoliteFilterMonitoring::DegradationDirectionEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::ZeoliteFilterMonitoring::DegradationDirectionEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::ZeoliteFilterMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::ZeoliteFilterMonitoring::DegradationDirectionEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::ZeoliteFilterMonitoring::DegradationDirectionEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::ZeoliteFilterMonitoring::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace DegradationDirection

namespace ChangeIndication {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::ZeoliteFilterMonitoring::ChangeIndicationEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::ZeoliteFilterMonitoring::ChangeIndicationEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::ZeoliteFilterMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::ZeoliteFilterMonitoring::ChangeIndicationEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::ZeoliteFilterMonitoring::ChangeIndicationEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::ZeoliteFilterMonitoring::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace ChangeIndication

namespace InPlaceIndicator {

EmberAfStatus Get(chip::EndpointId endpoint, bool * value)
{
    using Traits = NumericAttributeTraits<bool>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::ZeoliteFilterMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::ZeoliteFilterMonitoring::Id, Id, writable, ZCL_BOOLEAN_ATTRIBUTE_TYPE);
}

} // namespace InPlaceIndicator

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 = emberAfReadAttribute(endpoint, Clusters::ZeoliteFilterMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::ZeoliteFilterMonitoring::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 = emberAfReadAttribute(endpoint, Clusters::ZeoliteFilterMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::ZeoliteFilterMonitoring::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace ZeoliteFilterMonitoring

namespace OzoneFilterMonitoring {
namespace Attributes {

namespace Condition {

EmberAfStatus Get(chip::EndpointId endpoint, chip::Percent * value)
{
    using Traits = NumericAttributeTraits<chip::Percent>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::OzoneFilterMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::Percent value)
{
    using Traits = NumericAttributeTraits<chip::Percent>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::OzoneFilterMonitoring::Id, Id, writable, ZCL_PERCENT_ATTRIBUTE_TYPE);
}

} // namespace Condition

namespace DegradationDirection {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::OzoneFilterMonitoring::DegradationDirectionEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::OzoneFilterMonitoring::DegradationDirectionEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::OzoneFilterMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::OzoneFilterMonitoring::DegradationDirectionEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::OzoneFilterMonitoring::DegradationDirectionEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::OzoneFilterMonitoring::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace DegradationDirection

namespace ChangeIndication {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::OzoneFilterMonitoring::ChangeIndicationEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::OzoneFilterMonitoring::ChangeIndicationEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::OzoneFilterMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::OzoneFilterMonitoring::ChangeIndicationEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::OzoneFilterMonitoring::ChangeIndicationEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::OzoneFilterMonitoring::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace ChangeIndication

namespace InPlaceIndicator {

EmberAfStatus Get(chip::EndpointId endpoint, bool * value)
{
    using Traits = NumericAttributeTraits<bool>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::OzoneFilterMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::OzoneFilterMonitoring::Id, Id, writable, ZCL_BOOLEAN_ATTRIBUTE_TYPE);
}

} // namespace InPlaceIndicator

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 = emberAfReadAttribute(endpoint, Clusters::OzoneFilterMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::OzoneFilterMonitoring::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 = emberAfReadAttribute(endpoint, Clusters::OzoneFilterMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::OzoneFilterMonitoring::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace OzoneFilterMonitoring

namespace WaterTankMonitoring {
namespace Attributes {

namespace Condition {

EmberAfStatus Get(chip::EndpointId endpoint, chip::Percent * value)
{
    using Traits = NumericAttributeTraits<chip::Percent>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::WaterTankMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::Percent value)
{
    using Traits = NumericAttributeTraits<chip::Percent>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::WaterTankMonitoring::Id, Id, writable, ZCL_PERCENT_ATTRIBUTE_TYPE);
}

} // namespace Condition

namespace DegradationDirection {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::WaterTankMonitoring::DegradationDirectionEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::WaterTankMonitoring::DegradationDirectionEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::WaterTankMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::WaterTankMonitoring::DegradationDirectionEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::WaterTankMonitoring::DegradationDirectionEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::WaterTankMonitoring::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace DegradationDirection

namespace ChangeIndication {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::WaterTankMonitoring::ChangeIndicationEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::WaterTankMonitoring::ChangeIndicationEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::WaterTankMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::WaterTankMonitoring::ChangeIndicationEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::WaterTankMonitoring::ChangeIndicationEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::WaterTankMonitoring::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace ChangeIndication

namespace InPlaceIndicator {

EmberAfStatus Get(chip::EndpointId endpoint, bool * value)
{
    using Traits = NumericAttributeTraits<bool>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::WaterTankMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::WaterTankMonitoring::Id, Id, writable, ZCL_BOOLEAN_ATTRIBUTE_TYPE);
}

} // namespace InPlaceIndicator

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 = emberAfReadAttribute(endpoint, Clusters::WaterTankMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::WaterTankMonitoring::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 = emberAfReadAttribute(endpoint, Clusters::WaterTankMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::WaterTankMonitoring::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace WaterTankMonitoring

namespace FuelTankMonitoring {
namespace Attributes {

namespace Condition {

EmberAfStatus Get(chip::EndpointId endpoint, chip::Percent * value)
{
    using Traits = NumericAttributeTraits<chip::Percent>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::FuelTankMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::Percent value)
{
    using Traits = NumericAttributeTraits<chip::Percent>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::FuelTankMonitoring::Id, Id, writable, ZCL_PERCENT_ATTRIBUTE_TYPE);
}

} // namespace Condition

namespace DegradationDirection {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::FuelTankMonitoring::DegradationDirectionEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::FuelTankMonitoring::DegradationDirectionEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::FuelTankMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::FuelTankMonitoring::DegradationDirectionEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::FuelTankMonitoring::DegradationDirectionEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::FuelTankMonitoring::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace DegradationDirection

namespace ChangeIndication {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::FuelTankMonitoring::ChangeIndicationEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::FuelTankMonitoring::ChangeIndicationEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::FuelTankMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::FuelTankMonitoring::ChangeIndicationEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::FuelTankMonitoring::ChangeIndicationEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::FuelTankMonitoring::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace ChangeIndication

namespace InPlaceIndicator {

EmberAfStatus Get(chip::EndpointId endpoint, bool * value)
{
    using Traits = NumericAttributeTraits<bool>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::FuelTankMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::FuelTankMonitoring::Id, Id, writable, ZCL_BOOLEAN_ATTRIBUTE_TYPE);
}

} // namespace InPlaceIndicator

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 = emberAfReadAttribute(endpoint, Clusters::FuelTankMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::FuelTankMonitoring::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 = emberAfReadAttribute(endpoint, Clusters::FuelTankMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::FuelTankMonitoring::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace FuelTankMonitoring

namespace InkCartridgeMonitoring {
namespace Attributes {

namespace Condition {

EmberAfStatus Get(chip::EndpointId endpoint, chip::Percent * value)
{
    using Traits = NumericAttributeTraits<chip::Percent>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::InkCartridgeMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::Percent value)
{
    using Traits = NumericAttributeTraits<chip::Percent>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::InkCartridgeMonitoring::Id, Id, writable, ZCL_PERCENT_ATTRIBUTE_TYPE);
}

} // namespace Condition

namespace DegradationDirection {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::InkCartridgeMonitoring::DegradationDirectionEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::InkCartridgeMonitoring::DegradationDirectionEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::InkCartridgeMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::InkCartridgeMonitoring::DegradationDirectionEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::InkCartridgeMonitoring::DegradationDirectionEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::InkCartridgeMonitoring::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace DegradationDirection

namespace ChangeIndication {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::InkCartridgeMonitoring::ChangeIndicationEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::InkCartridgeMonitoring::ChangeIndicationEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::InkCartridgeMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::InkCartridgeMonitoring::ChangeIndicationEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::InkCartridgeMonitoring::ChangeIndicationEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::InkCartridgeMonitoring::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace ChangeIndication

namespace InPlaceIndicator {

EmberAfStatus Get(chip::EndpointId endpoint, bool * value)
{
    using Traits = NumericAttributeTraits<bool>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::InkCartridgeMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::InkCartridgeMonitoring::Id, Id, writable, ZCL_BOOLEAN_ATTRIBUTE_TYPE);
}

} // namespace InPlaceIndicator

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 = emberAfReadAttribute(endpoint, Clusters::InkCartridgeMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::InkCartridgeMonitoring::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 = emberAfReadAttribute(endpoint, Clusters::InkCartridgeMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::InkCartridgeMonitoring::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace InkCartridgeMonitoring

namespace TonerCartridgeMonitoring {
namespace Attributes {

namespace Condition {

EmberAfStatus Get(chip::EndpointId endpoint, chip::Percent * value)
{
    using Traits = NumericAttributeTraits<chip::Percent>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::TonerCartridgeMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::Percent value)
{
    using Traits = NumericAttributeTraits<chip::Percent>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::TonerCartridgeMonitoring::Id, Id, writable, ZCL_PERCENT_ATTRIBUTE_TYPE);
}

} // namespace Condition

namespace DegradationDirection {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::TonerCartridgeMonitoring::DegradationDirectionEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::TonerCartridgeMonitoring::DegradationDirectionEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::TonerCartridgeMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::TonerCartridgeMonitoring::DegradationDirectionEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::TonerCartridgeMonitoring::DegradationDirectionEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::TonerCartridgeMonitoring::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace DegradationDirection

namespace ChangeIndication {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::TonerCartridgeMonitoring::ChangeIndicationEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::TonerCartridgeMonitoring::ChangeIndicationEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::TonerCartridgeMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::TonerCartridgeMonitoring::ChangeIndicationEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::TonerCartridgeMonitoring::ChangeIndicationEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::TonerCartridgeMonitoring::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace ChangeIndication

namespace InPlaceIndicator {

EmberAfStatus Get(chip::EndpointId endpoint, bool * value)
{
    using Traits = NumericAttributeTraits<bool>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::TonerCartridgeMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::TonerCartridgeMonitoring::Id, Id, writable, ZCL_BOOLEAN_ATTRIBUTE_TYPE);
}

} // namespace InPlaceIndicator

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 = emberAfReadAttribute(endpoint, Clusters::TonerCartridgeMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::TonerCartridgeMonitoring::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 = emberAfReadAttribute(endpoint, Clusters::TonerCartridgeMonitoring::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::TonerCartridgeMonitoring::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace TonerCartridgeMonitoring

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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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::DoorStateEnum> & value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::DoorLock::DoorStateEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(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::DoorStateEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::DoorLock::DoorStateEnum>;
    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 emberAfWriteAttribute(endpoint, Clusters::DoorLock::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

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

EmberAfStatus Set(chip::EndpointId endpoint,
                  const chip::app::DataModel::Nullable<chip::app::Clusters::DoorLock::DoorStateEnum> & 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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(endpoint, Clusters::DoorLock::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

} // namespace SoundVolume

namespace OperatingMode {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::DoorLock::OperatingModeEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::DoorLock::OperatingModeEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(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::OperatingModeEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::DoorLock::OperatingModeEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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::PumpStatusBitmap> * value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::PumpConfigurationAndControl::PumpStatusBitmap>>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(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::PumpStatusBitmap> value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::PumpConfigurationAndControl::PumpStatusBitmap>>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_BITMAP16_ATTRIBUTE_TYPE);
}

} // namespace PumpStatus

namespace EffectiveOperationMode {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::PumpConfigurationAndControl::OperationModeEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::PumpConfigurationAndControl::OperationModeEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(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::OperationModeEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::PumpConfigurationAndControl::OperationModeEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace EffectiveOperationMode

namespace EffectiveControlMode {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::PumpConfigurationAndControl::ControlModeEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::PumpConfigurationAndControl::ControlModeEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(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::ControlModeEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::PumpConfigurationAndControl::ControlModeEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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::OperationModeEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::PumpConfigurationAndControl::OperationModeEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(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::OperationModeEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::PumpConfigurationAndControl::OperationModeEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace OperationMode

namespace ControlMode {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::PumpConfigurationAndControl::ControlModeEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::PumpConfigurationAndControl::ControlModeEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(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::ControlModeEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::PumpConfigurationAndControl::ControlModeEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_EPOCH_S_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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 =
        emberAfReadAttribute(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 emberAfWriteAttribute(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 =
        emberAfReadAttribute(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 emberAfWriteAttribute(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 =
        emberAfReadAttribute(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 emberAfWriteAttribute(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 =
        emberAfReadAttribute(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 emberAfWriteAttribute(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 =
        emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(endpoint, Clusters::ColorControl::Id, Id, zclString, ZCL_CHAR_STRING_ATTRIBUTE_TYPE);
}

} // namespace CompensationText

namespace ColorTemperatureMireds {

EmberAfStatus Get(chip::EndpointId endpoint, uint16_t * value)
{
    using Traits = NumericAttributeTraits<uint16_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(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 emberAfWriteAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ColorTemperatureMireds

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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(endpoint, Clusters::ColorControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace CoupleColorTempToLevelMinMireds

namespace StartUpColorTemperatureMireds {

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 = emberAfReadAttribute(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, 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 emberAfWriteAttribute(endpoint, Clusters::ColorControl::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 emberAfWriteAttribute(endpoint, Clusters::ColorControl::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 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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(endpoint, Clusters::BallastConfiguration::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

} // namespace MaxLevel

namespace IntrinsicBallastFactor {

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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 IntrinsicBallastFactor

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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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, chip::BitMask<chip::app::Clusters::OccupancySensing::OccupancyBitmap> * value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::OccupancySensing::OccupancyBitmap>>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(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, chip::BitMask<chip::app::Clusters::OccupancySensing::OccupancyBitmap> value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::OccupancySensing::OccupancyBitmap>>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::OccupancySensing::Id, Id, writable, ZCL_BITMAP8_ATTRIBUTE_TYPE);
}

} // namespace Occupancy

namespace OccupancySensorType {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::OccupancySensing::OccupancySensorTypeEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::OccupancySensing::OccupancySensorTypeEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(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, chip::app::Clusters::OccupancySensing::OccupancySensorTypeEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::OccupancySensing::OccupancySensorTypeEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::OccupancySensing::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace OccupancySensorType

namespace OccupancySensorTypeBitmap {

EmberAfStatus Get(chip::EndpointId endpoint,
                  chip::BitMask<chip::app::Clusters::OccupancySensing::OccupancySensorTypeBitmap> * value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::OccupancySensing::OccupancySensorTypeBitmap>>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(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, chip::BitMask<chip::app::Clusters::OccupancySensing::OccupancySensorTypeBitmap> value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::OccupancySensing::OccupancySensorTypeBitmap>>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(endpoint, Clusters::OccupancySensing::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace OccupancySensing

namespace CarbonMonoxideConcentrationMeasurement {
namespace Attributes {

namespace MeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::CarbonMonoxideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::CarbonMonoxideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::CarbonMonoxideConcentrationMeasurement::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 MeasuredValue

namespace MinMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::CarbonMonoxideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::CarbonMonoxideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::CarbonMonoxideConcentrationMeasurement::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 MinMeasuredValue

namespace MaxMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::CarbonMonoxideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::CarbonMonoxideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::CarbonMonoxideConcentrationMeasurement::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 MaxMeasuredValue

namespace PeakMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::CarbonMonoxideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::CarbonMonoxideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::CarbonMonoxideConcentrationMeasurement::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 PeakMeasuredValue

namespace PeakMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::CarbonMonoxideConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::CarbonMonoxideConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace PeakMeasuredValueWindow

namespace AverageMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::CarbonMonoxideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::CarbonMonoxideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::CarbonMonoxideConcentrationMeasurement::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 AverageMeasuredValue

namespace AverageMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::CarbonMonoxideConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::CarbonMonoxideConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace AverageMeasuredValueWindow

namespace Uncertainty {

EmberAfStatus Get(chip::EndpointId endpoint, float * value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::CarbonMonoxideConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::CarbonMonoxideConcentrationMeasurement::Id, Id, writable,
                                 ZCL_SINGLE_ATTRIBUTE_TYPE);
}

} // namespace Uncertainty

namespace MeasurementUnit {

EmberAfStatus Get(chip::EndpointId endpoint,
                  chip::app::Clusters::CarbonMonoxideConcentrationMeasurement::MeasurementUnitEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::CarbonMonoxideConcentrationMeasurement::MeasurementUnitEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::CarbonMonoxideConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::CarbonMonoxideConcentrationMeasurement::MeasurementUnitEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::CarbonMonoxideConcentrationMeasurement::MeasurementUnitEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::CarbonMonoxideConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementUnit

namespace MeasurementMedium {

EmberAfStatus Get(chip::EndpointId endpoint,
                  chip::app::Clusters::CarbonMonoxideConcentrationMeasurement::MeasurementMediumEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::CarbonMonoxideConcentrationMeasurement::MeasurementMediumEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::CarbonMonoxideConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::CarbonMonoxideConcentrationMeasurement::MeasurementMediumEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::CarbonMonoxideConcentrationMeasurement::MeasurementMediumEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::CarbonMonoxideConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementMedium

namespace LevelValue {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::CarbonMonoxideConcentrationMeasurement::LevelValueEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::CarbonMonoxideConcentrationMeasurement::LevelValueEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::CarbonMonoxideConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::CarbonMonoxideConcentrationMeasurement::LevelValueEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::CarbonMonoxideConcentrationMeasurement::LevelValueEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::CarbonMonoxideConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace LevelValue

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 =
        emberAfReadAttribute(endpoint, Clusters::CarbonMonoxideConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::CarbonMonoxideConcentrationMeasurement::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 =
        emberAfReadAttribute(endpoint, Clusters::CarbonMonoxideConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::CarbonMonoxideConcentrationMeasurement::Id, Id, writable,
                                 ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace CarbonMonoxideConcentrationMeasurement

namespace CarbonDioxideConcentrationMeasurement {
namespace Attributes {

namespace MeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::CarbonDioxideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::CarbonDioxideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::CarbonDioxideConcentrationMeasurement::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 MeasuredValue

namespace MinMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::CarbonDioxideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::CarbonDioxideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::CarbonDioxideConcentrationMeasurement::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 MinMeasuredValue

namespace MaxMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::CarbonDioxideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::CarbonDioxideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::CarbonDioxideConcentrationMeasurement::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 MaxMeasuredValue

namespace PeakMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::CarbonDioxideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::CarbonDioxideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::CarbonDioxideConcentrationMeasurement::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 PeakMeasuredValue

namespace PeakMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::CarbonDioxideConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::CarbonDioxideConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace PeakMeasuredValueWindow

namespace AverageMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::CarbonDioxideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::CarbonDioxideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::CarbonDioxideConcentrationMeasurement::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 AverageMeasuredValue

namespace AverageMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::CarbonDioxideConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::CarbonDioxideConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace AverageMeasuredValueWindow

namespace Uncertainty {

EmberAfStatus Get(chip::EndpointId endpoint, float * value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::CarbonDioxideConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::CarbonDioxideConcentrationMeasurement::Id, Id, writable,
                                 ZCL_SINGLE_ATTRIBUTE_TYPE);
}

} // namespace Uncertainty

namespace MeasurementUnit {

EmberAfStatus Get(chip::EndpointId endpoint,
                  chip::app::Clusters::CarbonDioxideConcentrationMeasurement::MeasurementUnitEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::CarbonDioxideConcentrationMeasurement::MeasurementUnitEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::CarbonDioxideConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::CarbonDioxideConcentrationMeasurement::MeasurementUnitEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::CarbonDioxideConcentrationMeasurement::MeasurementUnitEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::CarbonDioxideConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementUnit

namespace MeasurementMedium {

EmberAfStatus Get(chip::EndpointId endpoint,
                  chip::app::Clusters::CarbonDioxideConcentrationMeasurement::MeasurementMediumEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::CarbonDioxideConcentrationMeasurement::MeasurementMediumEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::CarbonDioxideConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::CarbonDioxideConcentrationMeasurement::MeasurementMediumEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::CarbonDioxideConcentrationMeasurement::MeasurementMediumEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::CarbonDioxideConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementMedium

namespace LevelValue {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::CarbonDioxideConcentrationMeasurement::LevelValueEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::CarbonDioxideConcentrationMeasurement::LevelValueEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::CarbonDioxideConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::CarbonDioxideConcentrationMeasurement::LevelValueEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::CarbonDioxideConcentrationMeasurement::LevelValueEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::CarbonDioxideConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace LevelValue

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 =
        emberAfReadAttribute(endpoint, Clusters::CarbonDioxideConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::CarbonDioxideConcentrationMeasurement::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 =
        emberAfReadAttribute(endpoint, Clusters::CarbonDioxideConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::CarbonDioxideConcentrationMeasurement::Id, Id, writable,
                                 ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace CarbonDioxideConcentrationMeasurement

namespace EthyleneConcentrationMeasurement {
namespace Attributes {

namespace MeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::EthyleneConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::EthyleneConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::EthyleneConcentrationMeasurement::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 MeasuredValue

namespace MinMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::EthyleneConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::EthyleneConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::EthyleneConcentrationMeasurement::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 MinMeasuredValue

namespace MaxMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::EthyleneConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::EthyleneConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::EthyleneConcentrationMeasurement::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 MaxMeasuredValue

namespace PeakMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::EthyleneConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::EthyleneConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::EthyleneConcentrationMeasurement::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 PeakMeasuredValue

namespace PeakMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::EthyleneConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::EthyleneConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace PeakMeasuredValueWindow

namespace AverageMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::EthyleneConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::EthyleneConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::EthyleneConcentrationMeasurement::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 AverageMeasuredValue

namespace AverageMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::EthyleneConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::EthyleneConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace AverageMeasuredValueWindow

namespace Uncertainty {

EmberAfStatus Get(chip::EndpointId endpoint, float * value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::EthyleneConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::EthyleneConcentrationMeasurement::Id, Id, writable, ZCL_SINGLE_ATTRIBUTE_TYPE);
}

} // namespace Uncertainty

namespace MeasurementUnit {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::EthyleneConcentrationMeasurement::MeasurementUnitEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::EthyleneConcentrationMeasurement::MeasurementUnitEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::EthyleneConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::EthyleneConcentrationMeasurement::MeasurementUnitEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::EthyleneConcentrationMeasurement::MeasurementUnitEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::EthyleneConcentrationMeasurement::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementUnit

namespace MeasurementMedium {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::EthyleneConcentrationMeasurement::MeasurementMediumEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::EthyleneConcentrationMeasurement::MeasurementMediumEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::EthyleneConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::EthyleneConcentrationMeasurement::MeasurementMediumEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::EthyleneConcentrationMeasurement::MeasurementMediumEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::EthyleneConcentrationMeasurement::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementMedium

namespace LevelValue {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::EthyleneConcentrationMeasurement::LevelValueEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::EthyleneConcentrationMeasurement::LevelValueEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::EthyleneConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::EthyleneConcentrationMeasurement::LevelValueEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::EthyleneConcentrationMeasurement::LevelValueEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::EthyleneConcentrationMeasurement::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace LevelValue

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 =
        emberAfReadAttribute(endpoint, Clusters::EthyleneConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::EthyleneConcentrationMeasurement::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 =
        emberAfReadAttribute(endpoint, Clusters::EthyleneConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::EthyleneConcentrationMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace EthyleneConcentrationMeasurement

namespace EthyleneOxideConcentrationMeasurement {
namespace Attributes {

namespace MeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::EthyleneOxideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::EthyleneOxideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::EthyleneOxideConcentrationMeasurement::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 MeasuredValue

namespace MinMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::EthyleneOxideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::EthyleneOxideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::EthyleneOxideConcentrationMeasurement::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 MinMeasuredValue

namespace MaxMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::EthyleneOxideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::EthyleneOxideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::EthyleneOxideConcentrationMeasurement::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 MaxMeasuredValue

namespace PeakMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::EthyleneOxideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::EthyleneOxideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::EthyleneOxideConcentrationMeasurement::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 PeakMeasuredValue

namespace PeakMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::EthyleneOxideConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::EthyleneOxideConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace PeakMeasuredValueWindow

namespace AverageMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::EthyleneOxideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::EthyleneOxideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::EthyleneOxideConcentrationMeasurement::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 AverageMeasuredValue

namespace AverageMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::EthyleneOxideConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::EthyleneOxideConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace AverageMeasuredValueWindow

namespace Uncertainty {

EmberAfStatus Get(chip::EndpointId endpoint, float * value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::EthyleneOxideConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::EthyleneOxideConcentrationMeasurement::Id, Id, writable,
                                 ZCL_SINGLE_ATTRIBUTE_TYPE);
}

} // namespace Uncertainty

namespace MeasurementUnit {

EmberAfStatus Get(chip::EndpointId endpoint,
                  chip::app::Clusters::EthyleneOxideConcentrationMeasurement::MeasurementUnitEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::EthyleneOxideConcentrationMeasurement::MeasurementUnitEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::EthyleneOxideConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::EthyleneOxideConcentrationMeasurement::MeasurementUnitEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::EthyleneOxideConcentrationMeasurement::MeasurementUnitEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::EthyleneOxideConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementUnit

namespace MeasurementMedium {

EmberAfStatus Get(chip::EndpointId endpoint,
                  chip::app::Clusters::EthyleneOxideConcentrationMeasurement::MeasurementMediumEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::EthyleneOxideConcentrationMeasurement::MeasurementMediumEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::EthyleneOxideConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::EthyleneOxideConcentrationMeasurement::MeasurementMediumEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::EthyleneOxideConcentrationMeasurement::MeasurementMediumEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::EthyleneOxideConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementMedium

namespace LevelValue {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::EthyleneOxideConcentrationMeasurement::LevelValueEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::EthyleneOxideConcentrationMeasurement::LevelValueEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::EthyleneOxideConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::EthyleneOxideConcentrationMeasurement::LevelValueEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::EthyleneOxideConcentrationMeasurement::LevelValueEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::EthyleneOxideConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace LevelValue

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 =
        emberAfReadAttribute(endpoint, Clusters::EthyleneOxideConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::EthyleneOxideConcentrationMeasurement::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 =
        emberAfReadAttribute(endpoint, Clusters::EthyleneOxideConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::EthyleneOxideConcentrationMeasurement::Id, Id, writable,
                                 ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace EthyleneOxideConcentrationMeasurement

namespace HydrogenConcentrationMeasurement {
namespace Attributes {

namespace MeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::HydrogenConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::HydrogenConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::HydrogenConcentrationMeasurement::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 MeasuredValue

namespace MinMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::HydrogenConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::HydrogenConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::HydrogenConcentrationMeasurement::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 MinMeasuredValue

namespace MaxMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::HydrogenConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::HydrogenConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::HydrogenConcentrationMeasurement::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 MaxMeasuredValue

namespace PeakMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::HydrogenConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::HydrogenConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::HydrogenConcentrationMeasurement::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 PeakMeasuredValue

namespace PeakMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::HydrogenConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::HydrogenConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace PeakMeasuredValueWindow

namespace AverageMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::HydrogenConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::HydrogenConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::HydrogenConcentrationMeasurement::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 AverageMeasuredValue

namespace AverageMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::HydrogenConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::HydrogenConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace AverageMeasuredValueWindow

namespace Uncertainty {

EmberAfStatus Get(chip::EndpointId endpoint, float * value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::HydrogenConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::HydrogenConcentrationMeasurement::Id, Id, writable, ZCL_SINGLE_ATTRIBUTE_TYPE);
}

} // namespace Uncertainty

namespace MeasurementUnit {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::HydrogenConcentrationMeasurement::MeasurementUnitEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::HydrogenConcentrationMeasurement::MeasurementUnitEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::HydrogenConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::HydrogenConcentrationMeasurement::MeasurementUnitEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::HydrogenConcentrationMeasurement::MeasurementUnitEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::HydrogenConcentrationMeasurement::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementUnit

namespace MeasurementMedium {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::HydrogenConcentrationMeasurement::MeasurementMediumEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::HydrogenConcentrationMeasurement::MeasurementMediumEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::HydrogenConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::HydrogenConcentrationMeasurement::MeasurementMediumEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::HydrogenConcentrationMeasurement::MeasurementMediumEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::HydrogenConcentrationMeasurement::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementMedium

namespace LevelValue {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::HydrogenConcentrationMeasurement::LevelValueEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::HydrogenConcentrationMeasurement::LevelValueEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::HydrogenConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::HydrogenConcentrationMeasurement::LevelValueEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::HydrogenConcentrationMeasurement::LevelValueEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::HydrogenConcentrationMeasurement::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace LevelValue

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 =
        emberAfReadAttribute(endpoint, Clusters::HydrogenConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::HydrogenConcentrationMeasurement::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 =
        emberAfReadAttribute(endpoint, Clusters::HydrogenConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::HydrogenConcentrationMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace HydrogenConcentrationMeasurement

namespace HydrogenSulfideConcentrationMeasurement {
namespace Attributes {

namespace MeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::HydrogenSulfideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::HydrogenSulfideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::HydrogenSulfideConcentrationMeasurement::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 MeasuredValue

namespace MinMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::HydrogenSulfideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::HydrogenSulfideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::HydrogenSulfideConcentrationMeasurement::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 MinMeasuredValue

namespace MaxMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::HydrogenSulfideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::HydrogenSulfideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::HydrogenSulfideConcentrationMeasurement::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 MaxMeasuredValue

namespace PeakMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::HydrogenSulfideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::HydrogenSulfideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::HydrogenSulfideConcentrationMeasurement::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 PeakMeasuredValue

namespace PeakMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::HydrogenSulfideConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::HydrogenSulfideConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace PeakMeasuredValueWindow

namespace AverageMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::HydrogenSulfideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::HydrogenSulfideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::HydrogenSulfideConcentrationMeasurement::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 AverageMeasuredValue

namespace AverageMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::HydrogenSulfideConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::HydrogenSulfideConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace AverageMeasuredValueWindow

namespace Uncertainty {

EmberAfStatus Get(chip::EndpointId endpoint, float * value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::HydrogenSulfideConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::HydrogenSulfideConcentrationMeasurement::Id, Id, writable,
                                 ZCL_SINGLE_ATTRIBUTE_TYPE);
}

} // namespace Uncertainty

namespace MeasurementUnit {

EmberAfStatus Get(chip::EndpointId endpoint,
                  chip::app::Clusters::HydrogenSulfideConcentrationMeasurement::MeasurementUnitEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::HydrogenSulfideConcentrationMeasurement::MeasurementUnitEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::HydrogenSulfideConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::HydrogenSulfideConcentrationMeasurement::MeasurementUnitEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::HydrogenSulfideConcentrationMeasurement::MeasurementUnitEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::HydrogenSulfideConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementUnit

namespace MeasurementMedium {

EmberAfStatus Get(chip::EndpointId endpoint,
                  chip::app::Clusters::HydrogenSulfideConcentrationMeasurement::MeasurementMediumEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::HydrogenSulfideConcentrationMeasurement::MeasurementMediumEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::HydrogenSulfideConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::HydrogenSulfideConcentrationMeasurement::MeasurementMediumEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::HydrogenSulfideConcentrationMeasurement::MeasurementMediumEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::HydrogenSulfideConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementMedium

namespace LevelValue {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::HydrogenSulfideConcentrationMeasurement::LevelValueEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::HydrogenSulfideConcentrationMeasurement::LevelValueEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::HydrogenSulfideConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::HydrogenSulfideConcentrationMeasurement::LevelValueEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::HydrogenSulfideConcentrationMeasurement::LevelValueEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::HydrogenSulfideConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace LevelValue

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 =
        emberAfReadAttribute(endpoint, Clusters::HydrogenSulfideConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::HydrogenSulfideConcentrationMeasurement::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 =
        emberAfReadAttribute(endpoint, Clusters::HydrogenSulfideConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::HydrogenSulfideConcentrationMeasurement::Id, Id, writable,
                                 ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace HydrogenSulfideConcentrationMeasurement

namespace NitricOxideConcentrationMeasurement {
namespace Attributes {

namespace MeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::NitricOxideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::NitricOxideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::NitricOxideConcentrationMeasurement::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 MeasuredValue

namespace MinMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::NitricOxideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::NitricOxideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::NitricOxideConcentrationMeasurement::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 MinMeasuredValue

namespace MaxMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::NitricOxideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::NitricOxideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::NitricOxideConcentrationMeasurement::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 MaxMeasuredValue

namespace PeakMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::NitricOxideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::NitricOxideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::NitricOxideConcentrationMeasurement::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 PeakMeasuredValue

namespace PeakMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::NitricOxideConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::NitricOxideConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace PeakMeasuredValueWindow

namespace AverageMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::NitricOxideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::NitricOxideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::NitricOxideConcentrationMeasurement::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 AverageMeasuredValue

namespace AverageMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::NitricOxideConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::NitricOxideConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace AverageMeasuredValueWindow

namespace Uncertainty {

EmberAfStatus Get(chip::EndpointId endpoint, float * value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::NitricOxideConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::NitricOxideConcentrationMeasurement::Id, Id, writable,
                                 ZCL_SINGLE_ATTRIBUTE_TYPE);
}

} // namespace Uncertainty

namespace MeasurementUnit {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::NitricOxideConcentrationMeasurement::MeasurementUnitEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::NitricOxideConcentrationMeasurement::MeasurementUnitEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::NitricOxideConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::NitricOxideConcentrationMeasurement::MeasurementUnitEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::NitricOxideConcentrationMeasurement::MeasurementUnitEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::NitricOxideConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementUnit

namespace MeasurementMedium {

EmberAfStatus Get(chip::EndpointId endpoint,
                  chip::app::Clusters::NitricOxideConcentrationMeasurement::MeasurementMediumEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::NitricOxideConcentrationMeasurement::MeasurementMediumEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::NitricOxideConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::NitricOxideConcentrationMeasurement::MeasurementMediumEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::NitricOxideConcentrationMeasurement::MeasurementMediumEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::NitricOxideConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementMedium

namespace LevelValue {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::NitricOxideConcentrationMeasurement::LevelValueEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::NitricOxideConcentrationMeasurement::LevelValueEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::NitricOxideConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::NitricOxideConcentrationMeasurement::LevelValueEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::NitricOxideConcentrationMeasurement::LevelValueEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::NitricOxideConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace LevelValue

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 =
        emberAfReadAttribute(endpoint, Clusters::NitricOxideConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::NitricOxideConcentrationMeasurement::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 =
        emberAfReadAttribute(endpoint, Clusters::NitricOxideConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::NitricOxideConcentrationMeasurement::Id, Id, writable,
                                 ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace NitricOxideConcentrationMeasurement

namespace NitrogenDioxideConcentrationMeasurement {
namespace Attributes {

namespace MeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::NitrogenDioxideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::NitrogenDioxideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::NitrogenDioxideConcentrationMeasurement::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 MeasuredValue

namespace MinMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::NitrogenDioxideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::NitrogenDioxideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::NitrogenDioxideConcentrationMeasurement::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 MinMeasuredValue

namespace MaxMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::NitrogenDioxideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::NitrogenDioxideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::NitrogenDioxideConcentrationMeasurement::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 MaxMeasuredValue

namespace PeakMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::NitrogenDioxideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::NitrogenDioxideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::NitrogenDioxideConcentrationMeasurement::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 PeakMeasuredValue

namespace PeakMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::NitrogenDioxideConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::NitrogenDioxideConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace PeakMeasuredValueWindow

namespace AverageMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::NitrogenDioxideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::NitrogenDioxideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::NitrogenDioxideConcentrationMeasurement::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 AverageMeasuredValue

namespace AverageMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::NitrogenDioxideConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::NitrogenDioxideConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace AverageMeasuredValueWindow

namespace Uncertainty {

EmberAfStatus Get(chip::EndpointId endpoint, float * value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::NitrogenDioxideConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::NitrogenDioxideConcentrationMeasurement::Id, Id, writable,
                                 ZCL_SINGLE_ATTRIBUTE_TYPE);
}

} // namespace Uncertainty

namespace MeasurementUnit {

EmberAfStatus Get(chip::EndpointId endpoint,
                  chip::app::Clusters::NitrogenDioxideConcentrationMeasurement::MeasurementUnitEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::NitrogenDioxideConcentrationMeasurement::MeasurementUnitEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::NitrogenDioxideConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::NitrogenDioxideConcentrationMeasurement::MeasurementUnitEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::NitrogenDioxideConcentrationMeasurement::MeasurementUnitEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::NitrogenDioxideConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementUnit

namespace MeasurementMedium {

EmberAfStatus Get(chip::EndpointId endpoint,
                  chip::app::Clusters::NitrogenDioxideConcentrationMeasurement::MeasurementMediumEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::NitrogenDioxideConcentrationMeasurement::MeasurementMediumEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::NitrogenDioxideConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::NitrogenDioxideConcentrationMeasurement::MeasurementMediumEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::NitrogenDioxideConcentrationMeasurement::MeasurementMediumEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::NitrogenDioxideConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementMedium

namespace LevelValue {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::NitrogenDioxideConcentrationMeasurement::LevelValueEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::NitrogenDioxideConcentrationMeasurement::LevelValueEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::NitrogenDioxideConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::NitrogenDioxideConcentrationMeasurement::LevelValueEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::NitrogenDioxideConcentrationMeasurement::LevelValueEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::NitrogenDioxideConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace LevelValue

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 =
        emberAfReadAttribute(endpoint, Clusters::NitrogenDioxideConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::NitrogenDioxideConcentrationMeasurement::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 =
        emberAfReadAttribute(endpoint, Clusters::NitrogenDioxideConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::NitrogenDioxideConcentrationMeasurement::Id, Id, writable,
                                 ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace NitrogenDioxideConcentrationMeasurement

namespace OxygenConcentrationMeasurement {
namespace Attributes {

namespace MeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::OxygenConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::OxygenConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::OxygenConcentrationMeasurement::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 MeasuredValue

namespace MinMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::OxygenConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::OxygenConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::OxygenConcentrationMeasurement::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 MinMeasuredValue

namespace MaxMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::OxygenConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::OxygenConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::OxygenConcentrationMeasurement::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 MaxMeasuredValue

namespace PeakMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::OxygenConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::OxygenConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::OxygenConcentrationMeasurement::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 PeakMeasuredValue

namespace PeakMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::OxygenConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::OxygenConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace PeakMeasuredValueWindow

namespace AverageMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::OxygenConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::OxygenConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::OxygenConcentrationMeasurement::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 AverageMeasuredValue

namespace AverageMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::OxygenConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::OxygenConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace AverageMeasuredValueWindow

namespace Uncertainty {

EmberAfStatus Get(chip::EndpointId endpoint, float * value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::OxygenConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::OxygenConcentrationMeasurement::Id, Id, writable, ZCL_SINGLE_ATTRIBUTE_TYPE);
}

} // namespace Uncertainty

namespace MeasurementUnit {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::OxygenConcentrationMeasurement::MeasurementUnitEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::OxygenConcentrationMeasurement::MeasurementUnitEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::OxygenConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::OxygenConcentrationMeasurement::MeasurementUnitEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::OxygenConcentrationMeasurement::MeasurementUnitEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::OxygenConcentrationMeasurement::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementUnit

namespace MeasurementMedium {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::OxygenConcentrationMeasurement::MeasurementMediumEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::OxygenConcentrationMeasurement::MeasurementMediumEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::OxygenConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::OxygenConcentrationMeasurement::MeasurementMediumEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::OxygenConcentrationMeasurement::MeasurementMediumEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::OxygenConcentrationMeasurement::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementMedium

namespace LevelValue {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::OxygenConcentrationMeasurement::LevelValueEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::OxygenConcentrationMeasurement::LevelValueEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::OxygenConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::OxygenConcentrationMeasurement::LevelValueEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::OxygenConcentrationMeasurement::LevelValueEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::OxygenConcentrationMeasurement::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace LevelValue

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 = emberAfReadAttribute(endpoint, Clusters::OxygenConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::OxygenConcentrationMeasurement::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 = emberAfReadAttribute(endpoint, Clusters::OxygenConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::OxygenConcentrationMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace OxygenConcentrationMeasurement

namespace OzoneConcentrationMeasurement {
namespace Attributes {

namespace MeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::OzoneConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::OzoneConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::OzoneConcentrationMeasurement::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 MeasuredValue

namespace MinMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::OzoneConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::OzoneConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::OzoneConcentrationMeasurement::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 MinMeasuredValue

namespace MaxMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::OzoneConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::OzoneConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::OzoneConcentrationMeasurement::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 MaxMeasuredValue

namespace PeakMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::OzoneConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::OzoneConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::OzoneConcentrationMeasurement::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 PeakMeasuredValue

namespace PeakMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::OzoneConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::OzoneConcentrationMeasurement::Id, Id, writable, ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace PeakMeasuredValueWindow

namespace AverageMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::OzoneConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::OzoneConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::OzoneConcentrationMeasurement::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 AverageMeasuredValue

namespace AverageMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::OzoneConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::OzoneConcentrationMeasurement::Id, Id, writable, ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace AverageMeasuredValueWindow

namespace Uncertainty {

EmberAfStatus Get(chip::EndpointId endpoint, float * value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::OzoneConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::OzoneConcentrationMeasurement::Id, Id, writable, ZCL_SINGLE_ATTRIBUTE_TYPE);
}

} // namespace Uncertainty

namespace MeasurementUnit {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::OzoneConcentrationMeasurement::MeasurementUnitEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::OzoneConcentrationMeasurement::MeasurementUnitEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::OzoneConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::OzoneConcentrationMeasurement::MeasurementUnitEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::OzoneConcentrationMeasurement::MeasurementUnitEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::OzoneConcentrationMeasurement::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementUnit

namespace MeasurementMedium {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::OzoneConcentrationMeasurement::MeasurementMediumEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::OzoneConcentrationMeasurement::MeasurementMediumEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::OzoneConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::OzoneConcentrationMeasurement::MeasurementMediumEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::OzoneConcentrationMeasurement::MeasurementMediumEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::OzoneConcentrationMeasurement::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementMedium

namespace LevelValue {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::OzoneConcentrationMeasurement::LevelValueEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::OzoneConcentrationMeasurement::LevelValueEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::OzoneConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::OzoneConcentrationMeasurement::LevelValueEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::OzoneConcentrationMeasurement::LevelValueEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::OzoneConcentrationMeasurement::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace LevelValue

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 = emberAfReadAttribute(endpoint, Clusters::OzoneConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::OzoneConcentrationMeasurement::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 = emberAfReadAttribute(endpoint, Clusters::OzoneConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::OzoneConcentrationMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace OzoneConcentrationMeasurement

namespace SulfurDioxideConcentrationMeasurement {
namespace Attributes {

namespace MeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::SulfurDioxideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::SulfurDioxideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::SulfurDioxideConcentrationMeasurement::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 MeasuredValue

namespace MinMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::SulfurDioxideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::SulfurDioxideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::SulfurDioxideConcentrationMeasurement::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 MinMeasuredValue

namespace MaxMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::SulfurDioxideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::SulfurDioxideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::SulfurDioxideConcentrationMeasurement::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 MaxMeasuredValue

namespace PeakMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::SulfurDioxideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::SulfurDioxideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::SulfurDioxideConcentrationMeasurement::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 PeakMeasuredValue

namespace PeakMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::SulfurDioxideConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::SulfurDioxideConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace PeakMeasuredValueWindow

namespace AverageMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::SulfurDioxideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::SulfurDioxideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::SulfurDioxideConcentrationMeasurement::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 AverageMeasuredValue

namespace AverageMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::SulfurDioxideConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::SulfurDioxideConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace AverageMeasuredValueWindow

namespace Uncertainty {

EmberAfStatus Get(chip::EndpointId endpoint, float * value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::SulfurDioxideConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::SulfurDioxideConcentrationMeasurement::Id, Id, writable,
                                 ZCL_SINGLE_ATTRIBUTE_TYPE);
}

} // namespace Uncertainty

namespace MeasurementUnit {

EmberAfStatus Get(chip::EndpointId endpoint,
                  chip::app::Clusters::SulfurDioxideConcentrationMeasurement::MeasurementUnitEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::SulfurDioxideConcentrationMeasurement::MeasurementUnitEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::SulfurDioxideConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::SulfurDioxideConcentrationMeasurement::MeasurementUnitEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::SulfurDioxideConcentrationMeasurement::MeasurementUnitEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::SulfurDioxideConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementUnit

namespace MeasurementMedium {

EmberAfStatus Get(chip::EndpointId endpoint,
                  chip::app::Clusters::SulfurDioxideConcentrationMeasurement::MeasurementMediumEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::SulfurDioxideConcentrationMeasurement::MeasurementMediumEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::SulfurDioxideConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::SulfurDioxideConcentrationMeasurement::MeasurementMediumEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::SulfurDioxideConcentrationMeasurement::MeasurementMediumEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::SulfurDioxideConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementMedium

namespace LevelValue {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::SulfurDioxideConcentrationMeasurement::LevelValueEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::SulfurDioxideConcentrationMeasurement::LevelValueEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::SulfurDioxideConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::SulfurDioxideConcentrationMeasurement::LevelValueEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::SulfurDioxideConcentrationMeasurement::LevelValueEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::SulfurDioxideConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace LevelValue

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 =
        emberAfReadAttribute(endpoint, Clusters::SulfurDioxideConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::SulfurDioxideConcentrationMeasurement::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 =
        emberAfReadAttribute(endpoint, Clusters::SulfurDioxideConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::SulfurDioxideConcentrationMeasurement::Id, Id, writable,
                                 ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace SulfurDioxideConcentrationMeasurement

namespace DissolvedOxygenConcentrationMeasurement {
namespace Attributes {

namespace MeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::DissolvedOxygenConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::DissolvedOxygenConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::DissolvedOxygenConcentrationMeasurement::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 MeasuredValue

namespace MinMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::DissolvedOxygenConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::DissolvedOxygenConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::DissolvedOxygenConcentrationMeasurement::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 MinMeasuredValue

namespace MaxMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::DissolvedOxygenConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::DissolvedOxygenConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::DissolvedOxygenConcentrationMeasurement::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 MaxMeasuredValue

namespace PeakMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::DissolvedOxygenConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::DissolvedOxygenConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::DissolvedOxygenConcentrationMeasurement::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 PeakMeasuredValue

namespace PeakMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::DissolvedOxygenConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::DissolvedOxygenConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace PeakMeasuredValueWindow

namespace AverageMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::DissolvedOxygenConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::DissolvedOxygenConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::DissolvedOxygenConcentrationMeasurement::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 AverageMeasuredValue

namespace AverageMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::DissolvedOxygenConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::DissolvedOxygenConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace AverageMeasuredValueWindow

namespace Uncertainty {

EmberAfStatus Get(chip::EndpointId endpoint, float * value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::DissolvedOxygenConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::DissolvedOxygenConcentrationMeasurement::Id, Id, writable,
                                 ZCL_SINGLE_ATTRIBUTE_TYPE);
}

} // namespace Uncertainty

namespace MeasurementUnit {

EmberAfStatus Get(chip::EndpointId endpoint,
                  chip::app::Clusters::DissolvedOxygenConcentrationMeasurement::MeasurementUnitEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::DissolvedOxygenConcentrationMeasurement::MeasurementUnitEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::DissolvedOxygenConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::DissolvedOxygenConcentrationMeasurement::MeasurementUnitEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::DissolvedOxygenConcentrationMeasurement::MeasurementUnitEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::DissolvedOxygenConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementUnit

namespace MeasurementMedium {

EmberAfStatus Get(chip::EndpointId endpoint,
                  chip::app::Clusters::DissolvedOxygenConcentrationMeasurement::MeasurementMediumEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::DissolvedOxygenConcentrationMeasurement::MeasurementMediumEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::DissolvedOxygenConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::DissolvedOxygenConcentrationMeasurement::MeasurementMediumEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::DissolvedOxygenConcentrationMeasurement::MeasurementMediumEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::DissolvedOxygenConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementMedium

namespace LevelValue {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::DissolvedOxygenConcentrationMeasurement::LevelValueEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::DissolvedOxygenConcentrationMeasurement::LevelValueEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::DissolvedOxygenConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::DissolvedOxygenConcentrationMeasurement::LevelValueEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::DissolvedOxygenConcentrationMeasurement::LevelValueEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::DissolvedOxygenConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace LevelValue

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 =
        emberAfReadAttribute(endpoint, Clusters::DissolvedOxygenConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::DissolvedOxygenConcentrationMeasurement::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 =
        emberAfReadAttribute(endpoint, Clusters::DissolvedOxygenConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::DissolvedOxygenConcentrationMeasurement::Id, Id, writable,
                                 ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace DissolvedOxygenConcentrationMeasurement

namespace BromateConcentrationMeasurement {
namespace Attributes {

namespace MeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::BromateConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::BromateConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::BromateConcentrationMeasurement::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 MeasuredValue

namespace MinMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::BromateConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::BromateConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::BromateConcentrationMeasurement::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 MinMeasuredValue

namespace MaxMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::BromateConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::BromateConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::BromateConcentrationMeasurement::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 MaxMeasuredValue

namespace PeakMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::BromateConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::BromateConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::BromateConcentrationMeasurement::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 PeakMeasuredValue

namespace PeakMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::BromateConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::BromateConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace PeakMeasuredValueWindow

namespace AverageMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::BromateConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::BromateConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::BromateConcentrationMeasurement::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 AverageMeasuredValue

namespace AverageMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::BromateConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::BromateConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace AverageMeasuredValueWindow

namespace Uncertainty {

EmberAfStatus Get(chip::EndpointId endpoint, float * value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::BromateConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::BromateConcentrationMeasurement::Id, Id, writable, ZCL_SINGLE_ATTRIBUTE_TYPE);
}

} // namespace Uncertainty

namespace MeasurementUnit {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::BromateConcentrationMeasurement::MeasurementUnitEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::BromateConcentrationMeasurement::MeasurementUnitEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::BromateConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::BromateConcentrationMeasurement::MeasurementUnitEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::BromateConcentrationMeasurement::MeasurementUnitEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::BromateConcentrationMeasurement::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementUnit

namespace MeasurementMedium {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::BromateConcentrationMeasurement::MeasurementMediumEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::BromateConcentrationMeasurement::MeasurementMediumEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::BromateConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::BromateConcentrationMeasurement::MeasurementMediumEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::BromateConcentrationMeasurement::MeasurementMediumEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::BromateConcentrationMeasurement::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementMedium

namespace LevelValue {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::BromateConcentrationMeasurement::LevelValueEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::BromateConcentrationMeasurement::LevelValueEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::BromateConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::BromateConcentrationMeasurement::LevelValueEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::BromateConcentrationMeasurement::LevelValueEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::BromateConcentrationMeasurement::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace LevelValue

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 =
        emberAfReadAttribute(endpoint, Clusters::BromateConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::BromateConcentrationMeasurement::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 =
        emberAfReadAttribute(endpoint, Clusters::BromateConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::BromateConcentrationMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace BromateConcentrationMeasurement

namespace ChloraminesConcentrationMeasurement {
namespace Attributes {

namespace MeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::ChloraminesConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::ChloraminesConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::ChloraminesConcentrationMeasurement::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 MeasuredValue

namespace MinMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::ChloraminesConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::ChloraminesConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::ChloraminesConcentrationMeasurement::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 MinMeasuredValue

namespace MaxMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::ChloraminesConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::ChloraminesConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::ChloraminesConcentrationMeasurement::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 MaxMeasuredValue

namespace PeakMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::ChloraminesConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::ChloraminesConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::ChloraminesConcentrationMeasurement::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 PeakMeasuredValue

namespace PeakMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::ChloraminesConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::ChloraminesConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace PeakMeasuredValueWindow

namespace AverageMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::ChloraminesConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::ChloraminesConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::ChloraminesConcentrationMeasurement::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 AverageMeasuredValue

namespace AverageMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::ChloraminesConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::ChloraminesConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace AverageMeasuredValueWindow

namespace Uncertainty {

EmberAfStatus Get(chip::EndpointId endpoint, float * value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::ChloraminesConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::ChloraminesConcentrationMeasurement::Id, Id, writable,
                                 ZCL_SINGLE_ATTRIBUTE_TYPE);
}

} // namespace Uncertainty

namespace MeasurementUnit {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::ChloraminesConcentrationMeasurement::MeasurementUnitEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::ChloraminesConcentrationMeasurement::MeasurementUnitEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::ChloraminesConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::ChloraminesConcentrationMeasurement::MeasurementUnitEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::ChloraminesConcentrationMeasurement::MeasurementUnitEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::ChloraminesConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementUnit

namespace MeasurementMedium {

EmberAfStatus Get(chip::EndpointId endpoint,
                  chip::app::Clusters::ChloraminesConcentrationMeasurement::MeasurementMediumEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::ChloraminesConcentrationMeasurement::MeasurementMediumEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::ChloraminesConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::ChloraminesConcentrationMeasurement::MeasurementMediumEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::ChloraminesConcentrationMeasurement::MeasurementMediumEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::ChloraminesConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementMedium

namespace LevelValue {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::ChloraminesConcentrationMeasurement::LevelValueEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::ChloraminesConcentrationMeasurement::LevelValueEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::ChloraminesConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::ChloraminesConcentrationMeasurement::LevelValueEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::ChloraminesConcentrationMeasurement::LevelValueEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::ChloraminesConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace LevelValue

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 =
        emberAfReadAttribute(endpoint, Clusters::ChloraminesConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::ChloraminesConcentrationMeasurement::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 =
        emberAfReadAttribute(endpoint, Clusters::ChloraminesConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::ChloraminesConcentrationMeasurement::Id, Id, writable,
                                 ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace ChloraminesConcentrationMeasurement

namespace ChlorineConcentrationMeasurement {
namespace Attributes {

namespace MeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::ChlorineConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::ChlorineConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::ChlorineConcentrationMeasurement::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 MeasuredValue

namespace MinMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::ChlorineConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::ChlorineConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::ChlorineConcentrationMeasurement::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 MinMeasuredValue

namespace MaxMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::ChlorineConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::ChlorineConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::ChlorineConcentrationMeasurement::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 MaxMeasuredValue

namespace PeakMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::ChlorineConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::ChlorineConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::ChlorineConcentrationMeasurement::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 PeakMeasuredValue

namespace PeakMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::ChlorineConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::ChlorineConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace PeakMeasuredValueWindow

namespace AverageMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::ChlorineConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::ChlorineConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::ChlorineConcentrationMeasurement::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 AverageMeasuredValue

namespace AverageMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::ChlorineConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::ChlorineConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace AverageMeasuredValueWindow

namespace Uncertainty {

EmberAfStatus Get(chip::EndpointId endpoint, float * value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::ChlorineConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::ChlorineConcentrationMeasurement::Id, Id, writable, ZCL_SINGLE_ATTRIBUTE_TYPE);
}

} // namespace Uncertainty

namespace MeasurementUnit {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::ChlorineConcentrationMeasurement::MeasurementUnitEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::ChlorineConcentrationMeasurement::MeasurementUnitEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::ChlorineConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::ChlorineConcentrationMeasurement::MeasurementUnitEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::ChlorineConcentrationMeasurement::MeasurementUnitEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::ChlorineConcentrationMeasurement::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementUnit

namespace MeasurementMedium {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::ChlorineConcentrationMeasurement::MeasurementMediumEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::ChlorineConcentrationMeasurement::MeasurementMediumEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::ChlorineConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::ChlorineConcentrationMeasurement::MeasurementMediumEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::ChlorineConcentrationMeasurement::MeasurementMediumEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::ChlorineConcentrationMeasurement::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementMedium

namespace LevelValue {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::ChlorineConcentrationMeasurement::LevelValueEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::ChlorineConcentrationMeasurement::LevelValueEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::ChlorineConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::ChlorineConcentrationMeasurement::LevelValueEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::ChlorineConcentrationMeasurement::LevelValueEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::ChlorineConcentrationMeasurement::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace LevelValue

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 =
        emberAfReadAttribute(endpoint, Clusters::ChlorineConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::ChlorineConcentrationMeasurement::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 =
        emberAfReadAttribute(endpoint, Clusters::ChlorineConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::ChlorineConcentrationMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace ChlorineConcentrationMeasurement

namespace FecalColiformEColiConcentrationMeasurement {
namespace Attributes {

namespace MeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::FecalColiformEColiConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::FecalColiformEColiConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::FecalColiformEColiConcentrationMeasurement::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 MeasuredValue

namespace MinMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::FecalColiformEColiConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::FecalColiformEColiConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::FecalColiformEColiConcentrationMeasurement::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 MinMeasuredValue

namespace MaxMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::FecalColiformEColiConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::FecalColiformEColiConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::FecalColiformEColiConcentrationMeasurement::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 MaxMeasuredValue

namespace PeakMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::FecalColiformEColiConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::FecalColiformEColiConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::FecalColiformEColiConcentrationMeasurement::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 PeakMeasuredValue

namespace PeakMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::FecalColiformEColiConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::FecalColiformEColiConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace PeakMeasuredValueWindow

namespace AverageMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::FecalColiformEColiConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::FecalColiformEColiConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::FecalColiformEColiConcentrationMeasurement::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 AverageMeasuredValue

namespace AverageMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::FecalColiformEColiConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::FecalColiformEColiConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace AverageMeasuredValueWindow

namespace Uncertainty {

EmberAfStatus Get(chip::EndpointId endpoint, float * value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::FecalColiformEColiConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::FecalColiformEColiConcentrationMeasurement::Id, Id, writable,
                                 ZCL_SINGLE_ATTRIBUTE_TYPE);
}

} // namespace Uncertainty

namespace MeasurementUnit {

EmberAfStatus Get(chip::EndpointId endpoint,
                  chip::app::Clusters::FecalColiformEColiConcentrationMeasurement::MeasurementUnitEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::FecalColiformEColiConcentrationMeasurement::MeasurementUnitEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::FecalColiformEColiConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::FecalColiformEColiConcentrationMeasurement::MeasurementUnitEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::FecalColiformEColiConcentrationMeasurement::MeasurementUnitEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::FecalColiformEColiConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementUnit

namespace MeasurementMedium {

EmberAfStatus Get(chip::EndpointId endpoint,
                  chip::app::Clusters::FecalColiformEColiConcentrationMeasurement::MeasurementMediumEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::FecalColiformEColiConcentrationMeasurement::MeasurementMediumEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::FecalColiformEColiConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::FecalColiformEColiConcentrationMeasurement::MeasurementMediumEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::FecalColiformEColiConcentrationMeasurement::MeasurementMediumEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::FecalColiformEColiConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementMedium

namespace LevelValue {

EmberAfStatus Get(chip::EndpointId endpoint,
                  chip::app::Clusters::FecalColiformEColiConcentrationMeasurement::LevelValueEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::FecalColiformEColiConcentrationMeasurement::LevelValueEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::FecalColiformEColiConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::FecalColiformEColiConcentrationMeasurement::LevelValueEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::FecalColiformEColiConcentrationMeasurement::LevelValueEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::FecalColiformEColiConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace LevelValue

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 =
        emberAfReadAttribute(endpoint, Clusters::FecalColiformEColiConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::FecalColiformEColiConcentrationMeasurement::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 =
        emberAfReadAttribute(endpoint, Clusters::FecalColiformEColiConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::FecalColiformEColiConcentrationMeasurement::Id, Id, writable,
                                 ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace FecalColiformEColiConcentrationMeasurement

namespace FluorideConcentrationMeasurement {
namespace Attributes {

namespace MeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::FluorideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::FluorideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::FluorideConcentrationMeasurement::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 MeasuredValue

namespace MinMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::FluorideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::FluorideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::FluorideConcentrationMeasurement::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 MinMeasuredValue

namespace MaxMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::FluorideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::FluorideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::FluorideConcentrationMeasurement::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 MaxMeasuredValue

namespace PeakMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::FluorideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::FluorideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::FluorideConcentrationMeasurement::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 PeakMeasuredValue

namespace PeakMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::FluorideConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::FluorideConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace PeakMeasuredValueWindow

namespace AverageMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::FluorideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::FluorideConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::FluorideConcentrationMeasurement::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 AverageMeasuredValue

namespace AverageMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::FluorideConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::FluorideConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace AverageMeasuredValueWindow

namespace Uncertainty {

EmberAfStatus Get(chip::EndpointId endpoint, float * value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::FluorideConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::FluorideConcentrationMeasurement::Id, Id, writable, ZCL_SINGLE_ATTRIBUTE_TYPE);
}

} // namespace Uncertainty

namespace MeasurementUnit {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::FluorideConcentrationMeasurement::MeasurementUnitEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::FluorideConcentrationMeasurement::MeasurementUnitEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::FluorideConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::FluorideConcentrationMeasurement::MeasurementUnitEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::FluorideConcentrationMeasurement::MeasurementUnitEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::FluorideConcentrationMeasurement::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementUnit

namespace MeasurementMedium {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::FluorideConcentrationMeasurement::MeasurementMediumEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::FluorideConcentrationMeasurement::MeasurementMediumEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::FluorideConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::FluorideConcentrationMeasurement::MeasurementMediumEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::FluorideConcentrationMeasurement::MeasurementMediumEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::FluorideConcentrationMeasurement::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementMedium

namespace LevelValue {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::FluorideConcentrationMeasurement::LevelValueEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::FluorideConcentrationMeasurement::LevelValueEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::FluorideConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::FluorideConcentrationMeasurement::LevelValueEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::FluorideConcentrationMeasurement::LevelValueEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::FluorideConcentrationMeasurement::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace LevelValue

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 =
        emberAfReadAttribute(endpoint, Clusters::FluorideConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::FluorideConcentrationMeasurement::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 =
        emberAfReadAttribute(endpoint, Clusters::FluorideConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::FluorideConcentrationMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace FluorideConcentrationMeasurement

namespace HaloaceticAcidsConcentrationMeasurement {
namespace Attributes {

namespace MeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::HaloaceticAcidsConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::HaloaceticAcidsConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::HaloaceticAcidsConcentrationMeasurement::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 MeasuredValue

namespace MinMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::HaloaceticAcidsConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::HaloaceticAcidsConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::HaloaceticAcidsConcentrationMeasurement::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 MinMeasuredValue

namespace MaxMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::HaloaceticAcidsConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::HaloaceticAcidsConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::HaloaceticAcidsConcentrationMeasurement::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 MaxMeasuredValue

namespace PeakMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::HaloaceticAcidsConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::HaloaceticAcidsConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::HaloaceticAcidsConcentrationMeasurement::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 PeakMeasuredValue

namespace PeakMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::HaloaceticAcidsConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::HaloaceticAcidsConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace PeakMeasuredValueWindow

namespace AverageMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::HaloaceticAcidsConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::HaloaceticAcidsConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::HaloaceticAcidsConcentrationMeasurement::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 AverageMeasuredValue

namespace AverageMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::HaloaceticAcidsConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::HaloaceticAcidsConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace AverageMeasuredValueWindow

namespace Uncertainty {

EmberAfStatus Get(chip::EndpointId endpoint, float * value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::HaloaceticAcidsConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::HaloaceticAcidsConcentrationMeasurement::Id, Id, writable,
                                 ZCL_SINGLE_ATTRIBUTE_TYPE);
}

} // namespace Uncertainty

namespace MeasurementUnit {

EmberAfStatus Get(chip::EndpointId endpoint,
                  chip::app::Clusters::HaloaceticAcidsConcentrationMeasurement::MeasurementUnitEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::HaloaceticAcidsConcentrationMeasurement::MeasurementUnitEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::HaloaceticAcidsConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::HaloaceticAcidsConcentrationMeasurement::MeasurementUnitEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::HaloaceticAcidsConcentrationMeasurement::MeasurementUnitEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::HaloaceticAcidsConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementUnit

namespace MeasurementMedium {

EmberAfStatus Get(chip::EndpointId endpoint,
                  chip::app::Clusters::HaloaceticAcidsConcentrationMeasurement::MeasurementMediumEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::HaloaceticAcidsConcentrationMeasurement::MeasurementMediumEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::HaloaceticAcidsConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::HaloaceticAcidsConcentrationMeasurement::MeasurementMediumEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::HaloaceticAcidsConcentrationMeasurement::MeasurementMediumEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::HaloaceticAcidsConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementMedium

namespace LevelValue {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::HaloaceticAcidsConcentrationMeasurement::LevelValueEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::HaloaceticAcidsConcentrationMeasurement::LevelValueEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::HaloaceticAcidsConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::HaloaceticAcidsConcentrationMeasurement::LevelValueEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::HaloaceticAcidsConcentrationMeasurement::LevelValueEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::HaloaceticAcidsConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace LevelValue

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 =
        emberAfReadAttribute(endpoint, Clusters::HaloaceticAcidsConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::HaloaceticAcidsConcentrationMeasurement::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 =
        emberAfReadAttribute(endpoint, Clusters::HaloaceticAcidsConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::HaloaceticAcidsConcentrationMeasurement::Id, Id, writable,
                                 ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace HaloaceticAcidsConcentrationMeasurement

namespace TotalTrihalomethanesConcentrationMeasurement {
namespace Attributes {

namespace MeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::TotalTrihalomethanesConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::TotalTrihalomethanesConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::TotalTrihalomethanesConcentrationMeasurement::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 MeasuredValue

namespace MinMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::TotalTrihalomethanesConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::TotalTrihalomethanesConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::TotalTrihalomethanesConcentrationMeasurement::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 MinMeasuredValue

namespace MaxMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::TotalTrihalomethanesConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::TotalTrihalomethanesConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::TotalTrihalomethanesConcentrationMeasurement::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 MaxMeasuredValue

namespace PeakMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::TotalTrihalomethanesConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::TotalTrihalomethanesConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::TotalTrihalomethanesConcentrationMeasurement::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 PeakMeasuredValue

namespace PeakMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::TotalTrihalomethanesConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::TotalTrihalomethanesConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace PeakMeasuredValueWindow

namespace AverageMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::TotalTrihalomethanesConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::TotalTrihalomethanesConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::TotalTrihalomethanesConcentrationMeasurement::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 AverageMeasuredValue

namespace AverageMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::TotalTrihalomethanesConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::TotalTrihalomethanesConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace AverageMeasuredValueWindow

namespace Uncertainty {

EmberAfStatus Get(chip::EndpointId endpoint, float * value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::TotalTrihalomethanesConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::TotalTrihalomethanesConcentrationMeasurement::Id, Id, writable,
                                 ZCL_SINGLE_ATTRIBUTE_TYPE);
}

} // namespace Uncertainty

namespace MeasurementUnit {

EmberAfStatus Get(chip::EndpointId endpoint,
                  chip::app::Clusters::TotalTrihalomethanesConcentrationMeasurement::MeasurementUnitEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::TotalTrihalomethanesConcentrationMeasurement::MeasurementUnitEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::TotalTrihalomethanesConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::TotalTrihalomethanesConcentrationMeasurement::MeasurementUnitEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::TotalTrihalomethanesConcentrationMeasurement::MeasurementUnitEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::TotalTrihalomethanesConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementUnit

namespace MeasurementMedium {

EmberAfStatus Get(chip::EndpointId endpoint,
                  chip::app::Clusters::TotalTrihalomethanesConcentrationMeasurement::MeasurementMediumEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::TotalTrihalomethanesConcentrationMeasurement::MeasurementMediumEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::TotalTrihalomethanesConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::TotalTrihalomethanesConcentrationMeasurement::MeasurementMediumEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::TotalTrihalomethanesConcentrationMeasurement::MeasurementMediumEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::TotalTrihalomethanesConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementMedium

namespace LevelValue {

EmberAfStatus Get(chip::EndpointId endpoint,
                  chip::app::Clusters::TotalTrihalomethanesConcentrationMeasurement::LevelValueEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::TotalTrihalomethanesConcentrationMeasurement::LevelValueEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::TotalTrihalomethanesConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::TotalTrihalomethanesConcentrationMeasurement::LevelValueEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::TotalTrihalomethanesConcentrationMeasurement::LevelValueEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::TotalTrihalomethanesConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace LevelValue

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 =
        emberAfReadAttribute(endpoint, Clusters::TotalTrihalomethanesConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::TotalTrihalomethanesConcentrationMeasurement::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 =
        emberAfReadAttribute(endpoint, Clusters::TotalTrihalomethanesConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::TotalTrihalomethanesConcentrationMeasurement::Id, Id, writable,
                                 ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace TotalTrihalomethanesConcentrationMeasurement

namespace TotalColiformBacteriaConcentrationMeasurement {
namespace Attributes {

namespace MeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::TotalColiformBacteriaConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::TotalColiformBacteriaConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::TotalColiformBacteriaConcentrationMeasurement::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 MeasuredValue

namespace MinMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::TotalColiformBacteriaConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::TotalColiformBacteriaConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::TotalColiformBacteriaConcentrationMeasurement::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 MinMeasuredValue

namespace MaxMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::TotalColiformBacteriaConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::TotalColiformBacteriaConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::TotalColiformBacteriaConcentrationMeasurement::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 MaxMeasuredValue

namespace PeakMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::TotalColiformBacteriaConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::TotalColiformBacteriaConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::TotalColiformBacteriaConcentrationMeasurement::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 PeakMeasuredValue

namespace PeakMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::TotalColiformBacteriaConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::TotalColiformBacteriaConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace PeakMeasuredValueWindow

namespace AverageMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::TotalColiformBacteriaConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::TotalColiformBacteriaConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::TotalColiformBacteriaConcentrationMeasurement::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 AverageMeasuredValue

namespace AverageMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::TotalColiformBacteriaConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::TotalColiformBacteriaConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace AverageMeasuredValueWindow

namespace Uncertainty {

EmberAfStatus Get(chip::EndpointId endpoint, float * value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::TotalColiformBacteriaConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::TotalColiformBacteriaConcentrationMeasurement::Id, Id, writable,
                                 ZCL_SINGLE_ATTRIBUTE_TYPE);
}

} // namespace Uncertainty

namespace MeasurementUnit {

EmberAfStatus Get(chip::EndpointId endpoint,
                  chip::app::Clusters::TotalColiformBacteriaConcentrationMeasurement::MeasurementUnitEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::TotalColiformBacteriaConcentrationMeasurement::MeasurementUnitEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::TotalColiformBacteriaConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::TotalColiformBacteriaConcentrationMeasurement::MeasurementUnitEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::TotalColiformBacteriaConcentrationMeasurement::MeasurementUnitEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::TotalColiformBacteriaConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementUnit

namespace MeasurementMedium {

EmberAfStatus Get(chip::EndpointId endpoint,
                  chip::app::Clusters::TotalColiformBacteriaConcentrationMeasurement::MeasurementMediumEnum * value)
{
    using Traits =
        NumericAttributeTraits<chip::app::Clusters::TotalColiformBacteriaConcentrationMeasurement::MeasurementMediumEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::TotalColiformBacteriaConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::TotalColiformBacteriaConcentrationMeasurement::MeasurementMediumEnum value)
{
    using Traits =
        NumericAttributeTraits<chip::app::Clusters::TotalColiformBacteriaConcentrationMeasurement::MeasurementMediumEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::TotalColiformBacteriaConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementMedium

namespace LevelValue {

EmberAfStatus Get(chip::EndpointId endpoint,
                  chip::app::Clusters::TotalColiformBacteriaConcentrationMeasurement::LevelValueEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::TotalColiformBacteriaConcentrationMeasurement::LevelValueEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::TotalColiformBacteriaConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::TotalColiformBacteriaConcentrationMeasurement::LevelValueEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::TotalColiformBacteriaConcentrationMeasurement::LevelValueEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::TotalColiformBacteriaConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace LevelValue

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 =
        emberAfReadAttribute(endpoint, Clusters::TotalColiformBacteriaConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::TotalColiformBacteriaConcentrationMeasurement::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 =
        emberAfReadAttribute(endpoint, Clusters::TotalColiformBacteriaConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::TotalColiformBacteriaConcentrationMeasurement::Id, Id, writable,
                                 ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace TotalColiformBacteriaConcentrationMeasurement

namespace TurbidityConcentrationMeasurement {
namespace Attributes {

namespace MeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::TurbidityConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::TurbidityConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::TurbidityConcentrationMeasurement::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 MeasuredValue

namespace MinMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::TurbidityConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::TurbidityConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::TurbidityConcentrationMeasurement::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 MinMeasuredValue

namespace MaxMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::TurbidityConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::TurbidityConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::TurbidityConcentrationMeasurement::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 MaxMeasuredValue

namespace PeakMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::TurbidityConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::TurbidityConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::TurbidityConcentrationMeasurement::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 PeakMeasuredValue

namespace PeakMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::TurbidityConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::TurbidityConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace PeakMeasuredValueWindow

namespace AverageMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::TurbidityConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::TurbidityConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::TurbidityConcentrationMeasurement::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 AverageMeasuredValue

namespace AverageMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::TurbidityConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::TurbidityConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace AverageMeasuredValueWindow

namespace Uncertainty {

EmberAfStatus Get(chip::EndpointId endpoint, float * value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::TurbidityConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::TurbidityConcentrationMeasurement::Id, Id, writable,
                                 ZCL_SINGLE_ATTRIBUTE_TYPE);
}

} // namespace Uncertainty

namespace MeasurementUnit {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::TurbidityConcentrationMeasurement::MeasurementUnitEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::TurbidityConcentrationMeasurement::MeasurementUnitEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::TurbidityConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::TurbidityConcentrationMeasurement::MeasurementUnitEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::TurbidityConcentrationMeasurement::MeasurementUnitEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::TurbidityConcentrationMeasurement::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementUnit

namespace MeasurementMedium {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::TurbidityConcentrationMeasurement::MeasurementMediumEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::TurbidityConcentrationMeasurement::MeasurementMediumEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::TurbidityConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::TurbidityConcentrationMeasurement::MeasurementMediumEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::TurbidityConcentrationMeasurement::MeasurementMediumEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::TurbidityConcentrationMeasurement::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementMedium

namespace LevelValue {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::TurbidityConcentrationMeasurement::LevelValueEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::TurbidityConcentrationMeasurement::LevelValueEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::TurbidityConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::TurbidityConcentrationMeasurement::LevelValueEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::TurbidityConcentrationMeasurement::LevelValueEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::TurbidityConcentrationMeasurement::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace LevelValue

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 =
        emberAfReadAttribute(endpoint, Clusters::TurbidityConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::TurbidityConcentrationMeasurement::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 =
        emberAfReadAttribute(endpoint, Clusters::TurbidityConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::TurbidityConcentrationMeasurement::Id, Id, writable,
                                 ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace TurbidityConcentrationMeasurement

namespace CopperConcentrationMeasurement {
namespace Attributes {

namespace MeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::CopperConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::CopperConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::CopperConcentrationMeasurement::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 MeasuredValue

namespace MinMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::CopperConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::CopperConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::CopperConcentrationMeasurement::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 MinMeasuredValue

namespace MaxMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::CopperConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::CopperConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::CopperConcentrationMeasurement::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 MaxMeasuredValue

namespace PeakMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::CopperConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::CopperConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::CopperConcentrationMeasurement::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 PeakMeasuredValue

namespace PeakMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::CopperConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::CopperConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace PeakMeasuredValueWindow

namespace AverageMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::CopperConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::CopperConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::CopperConcentrationMeasurement::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 AverageMeasuredValue

namespace AverageMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::CopperConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::CopperConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace AverageMeasuredValueWindow

namespace Uncertainty {

EmberAfStatus Get(chip::EndpointId endpoint, float * value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::CopperConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::CopperConcentrationMeasurement::Id, Id, writable, ZCL_SINGLE_ATTRIBUTE_TYPE);
}

} // namespace Uncertainty

namespace MeasurementUnit {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::CopperConcentrationMeasurement::MeasurementUnitEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::CopperConcentrationMeasurement::MeasurementUnitEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::CopperConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::CopperConcentrationMeasurement::MeasurementUnitEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::CopperConcentrationMeasurement::MeasurementUnitEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::CopperConcentrationMeasurement::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementUnit

namespace MeasurementMedium {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::CopperConcentrationMeasurement::MeasurementMediumEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::CopperConcentrationMeasurement::MeasurementMediumEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::CopperConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::CopperConcentrationMeasurement::MeasurementMediumEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::CopperConcentrationMeasurement::MeasurementMediumEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::CopperConcentrationMeasurement::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementMedium

namespace LevelValue {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::CopperConcentrationMeasurement::LevelValueEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::CopperConcentrationMeasurement::LevelValueEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::CopperConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::CopperConcentrationMeasurement::LevelValueEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::CopperConcentrationMeasurement::LevelValueEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::CopperConcentrationMeasurement::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace LevelValue

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 = emberAfReadAttribute(endpoint, Clusters::CopperConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::CopperConcentrationMeasurement::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 = emberAfReadAttribute(endpoint, Clusters::CopperConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::CopperConcentrationMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace CopperConcentrationMeasurement

namespace LeadConcentrationMeasurement {
namespace Attributes {

namespace MeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::LeadConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::LeadConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::LeadConcentrationMeasurement::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 MeasuredValue

namespace MinMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::LeadConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::LeadConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::LeadConcentrationMeasurement::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 MinMeasuredValue

namespace MaxMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::LeadConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::LeadConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::LeadConcentrationMeasurement::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 MaxMeasuredValue

namespace PeakMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::LeadConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::LeadConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::LeadConcentrationMeasurement::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 PeakMeasuredValue

namespace PeakMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::LeadConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::LeadConcentrationMeasurement::Id, Id, writable, ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace PeakMeasuredValueWindow

namespace AverageMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::LeadConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::LeadConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::LeadConcentrationMeasurement::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 AverageMeasuredValue

namespace AverageMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::LeadConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::LeadConcentrationMeasurement::Id, Id, writable, ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace AverageMeasuredValueWindow

namespace Uncertainty {

EmberAfStatus Get(chip::EndpointId endpoint, float * value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::LeadConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::LeadConcentrationMeasurement::Id, Id, writable, ZCL_SINGLE_ATTRIBUTE_TYPE);
}

} // namespace Uncertainty

namespace MeasurementUnit {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::LeadConcentrationMeasurement::MeasurementUnitEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::LeadConcentrationMeasurement::MeasurementUnitEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::LeadConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::LeadConcentrationMeasurement::MeasurementUnitEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::LeadConcentrationMeasurement::MeasurementUnitEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::LeadConcentrationMeasurement::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementUnit

namespace MeasurementMedium {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::LeadConcentrationMeasurement::MeasurementMediumEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::LeadConcentrationMeasurement::MeasurementMediumEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::LeadConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::LeadConcentrationMeasurement::MeasurementMediumEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::LeadConcentrationMeasurement::MeasurementMediumEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::LeadConcentrationMeasurement::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementMedium

namespace LevelValue {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::LeadConcentrationMeasurement::LevelValueEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::LeadConcentrationMeasurement::LevelValueEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::LeadConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::LeadConcentrationMeasurement::LevelValueEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::LeadConcentrationMeasurement::LevelValueEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::LeadConcentrationMeasurement::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace LevelValue

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 = emberAfReadAttribute(endpoint, Clusters::LeadConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::LeadConcentrationMeasurement::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 = emberAfReadAttribute(endpoint, Clusters::LeadConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::LeadConcentrationMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace LeadConcentrationMeasurement

namespace ManganeseConcentrationMeasurement {
namespace Attributes {

namespace MeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::ManganeseConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::ManganeseConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::ManganeseConcentrationMeasurement::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 MeasuredValue

namespace MinMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::ManganeseConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::ManganeseConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::ManganeseConcentrationMeasurement::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 MinMeasuredValue

namespace MaxMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::ManganeseConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::ManganeseConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::ManganeseConcentrationMeasurement::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 MaxMeasuredValue

namespace PeakMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::ManganeseConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::ManganeseConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::ManganeseConcentrationMeasurement::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 PeakMeasuredValue

namespace PeakMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::ManganeseConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::ManganeseConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace PeakMeasuredValueWindow

namespace AverageMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::ManganeseConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::ManganeseConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::ManganeseConcentrationMeasurement::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 AverageMeasuredValue

namespace AverageMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::ManganeseConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::ManganeseConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace AverageMeasuredValueWindow

namespace Uncertainty {

EmberAfStatus Get(chip::EndpointId endpoint, float * value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::ManganeseConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::ManganeseConcentrationMeasurement::Id, Id, writable,
                                 ZCL_SINGLE_ATTRIBUTE_TYPE);
}

} // namespace Uncertainty

namespace MeasurementUnit {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::ManganeseConcentrationMeasurement::MeasurementUnitEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::ManganeseConcentrationMeasurement::MeasurementUnitEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::ManganeseConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::ManganeseConcentrationMeasurement::MeasurementUnitEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::ManganeseConcentrationMeasurement::MeasurementUnitEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::ManganeseConcentrationMeasurement::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementUnit

namespace MeasurementMedium {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::ManganeseConcentrationMeasurement::MeasurementMediumEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::ManganeseConcentrationMeasurement::MeasurementMediumEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::ManganeseConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::ManganeseConcentrationMeasurement::MeasurementMediumEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::ManganeseConcentrationMeasurement::MeasurementMediumEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::ManganeseConcentrationMeasurement::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementMedium

namespace LevelValue {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::ManganeseConcentrationMeasurement::LevelValueEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::ManganeseConcentrationMeasurement::LevelValueEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::ManganeseConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::ManganeseConcentrationMeasurement::LevelValueEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::ManganeseConcentrationMeasurement::LevelValueEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::ManganeseConcentrationMeasurement::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace LevelValue

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 =
        emberAfReadAttribute(endpoint, Clusters::ManganeseConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::ManganeseConcentrationMeasurement::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 =
        emberAfReadAttribute(endpoint, Clusters::ManganeseConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::ManganeseConcentrationMeasurement::Id, Id, writable,
                                 ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace ManganeseConcentrationMeasurement

namespace SulfateConcentrationMeasurement {
namespace Attributes {

namespace MeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::SulfateConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::SulfateConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::SulfateConcentrationMeasurement::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 MeasuredValue

namespace MinMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::SulfateConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::SulfateConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::SulfateConcentrationMeasurement::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 MinMeasuredValue

namespace MaxMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::SulfateConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::SulfateConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::SulfateConcentrationMeasurement::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 MaxMeasuredValue

namespace PeakMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::SulfateConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::SulfateConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::SulfateConcentrationMeasurement::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 PeakMeasuredValue

namespace PeakMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::SulfateConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::SulfateConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace PeakMeasuredValueWindow

namespace AverageMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::SulfateConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::SulfateConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::SulfateConcentrationMeasurement::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 AverageMeasuredValue

namespace AverageMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::SulfateConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::SulfateConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace AverageMeasuredValueWindow

namespace Uncertainty {

EmberAfStatus Get(chip::EndpointId endpoint, float * value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::SulfateConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::SulfateConcentrationMeasurement::Id, Id, writable, ZCL_SINGLE_ATTRIBUTE_TYPE);
}

} // namespace Uncertainty

namespace MeasurementUnit {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::SulfateConcentrationMeasurement::MeasurementUnitEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::SulfateConcentrationMeasurement::MeasurementUnitEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::SulfateConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::SulfateConcentrationMeasurement::MeasurementUnitEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::SulfateConcentrationMeasurement::MeasurementUnitEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::SulfateConcentrationMeasurement::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementUnit

namespace MeasurementMedium {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::SulfateConcentrationMeasurement::MeasurementMediumEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::SulfateConcentrationMeasurement::MeasurementMediumEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::SulfateConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::SulfateConcentrationMeasurement::MeasurementMediumEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::SulfateConcentrationMeasurement::MeasurementMediumEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::SulfateConcentrationMeasurement::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementMedium

namespace LevelValue {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::SulfateConcentrationMeasurement::LevelValueEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::SulfateConcentrationMeasurement::LevelValueEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::SulfateConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::SulfateConcentrationMeasurement::LevelValueEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::SulfateConcentrationMeasurement::LevelValueEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::SulfateConcentrationMeasurement::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace LevelValue

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 =
        emberAfReadAttribute(endpoint, Clusters::SulfateConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::SulfateConcentrationMeasurement::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 =
        emberAfReadAttribute(endpoint, Clusters::SulfateConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::SulfateConcentrationMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace SulfateConcentrationMeasurement

namespace BromodichloromethaneConcentrationMeasurement {
namespace Attributes {

namespace MeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::BromodichloromethaneConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::BromodichloromethaneConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::BromodichloromethaneConcentrationMeasurement::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 MeasuredValue

namespace MinMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::BromodichloromethaneConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::BromodichloromethaneConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::BromodichloromethaneConcentrationMeasurement::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 MinMeasuredValue

namespace MaxMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::BromodichloromethaneConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::BromodichloromethaneConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::BromodichloromethaneConcentrationMeasurement::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 MaxMeasuredValue

namespace PeakMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::BromodichloromethaneConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::BromodichloromethaneConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::BromodichloromethaneConcentrationMeasurement::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 PeakMeasuredValue

namespace PeakMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::BromodichloromethaneConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::BromodichloromethaneConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace PeakMeasuredValueWindow

namespace AverageMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::BromodichloromethaneConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::BromodichloromethaneConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::BromodichloromethaneConcentrationMeasurement::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 AverageMeasuredValue

namespace AverageMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::BromodichloromethaneConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::BromodichloromethaneConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace AverageMeasuredValueWindow

namespace Uncertainty {

EmberAfStatus Get(chip::EndpointId endpoint, float * value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::BromodichloromethaneConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::BromodichloromethaneConcentrationMeasurement::Id, Id, writable,
                                 ZCL_SINGLE_ATTRIBUTE_TYPE);
}

} // namespace Uncertainty

namespace MeasurementUnit {

EmberAfStatus Get(chip::EndpointId endpoint,
                  chip::app::Clusters::BromodichloromethaneConcentrationMeasurement::MeasurementUnitEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::BromodichloromethaneConcentrationMeasurement::MeasurementUnitEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::BromodichloromethaneConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::BromodichloromethaneConcentrationMeasurement::MeasurementUnitEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::BromodichloromethaneConcentrationMeasurement::MeasurementUnitEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::BromodichloromethaneConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementUnit

namespace MeasurementMedium {

EmberAfStatus Get(chip::EndpointId endpoint,
                  chip::app::Clusters::BromodichloromethaneConcentrationMeasurement::MeasurementMediumEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::BromodichloromethaneConcentrationMeasurement::MeasurementMediumEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::BromodichloromethaneConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::BromodichloromethaneConcentrationMeasurement::MeasurementMediumEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::BromodichloromethaneConcentrationMeasurement::MeasurementMediumEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::BromodichloromethaneConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementMedium

namespace LevelValue {

EmberAfStatus Get(chip::EndpointId endpoint,
                  chip::app::Clusters::BromodichloromethaneConcentrationMeasurement::LevelValueEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::BromodichloromethaneConcentrationMeasurement::LevelValueEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::BromodichloromethaneConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::BromodichloromethaneConcentrationMeasurement::LevelValueEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::BromodichloromethaneConcentrationMeasurement::LevelValueEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::BromodichloromethaneConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace LevelValue

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 =
        emberAfReadAttribute(endpoint, Clusters::BromodichloromethaneConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::BromodichloromethaneConcentrationMeasurement::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 =
        emberAfReadAttribute(endpoint, Clusters::BromodichloromethaneConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::BromodichloromethaneConcentrationMeasurement::Id, Id, writable,
                                 ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace BromodichloromethaneConcentrationMeasurement

namespace BromoformConcentrationMeasurement {
namespace Attributes {

namespace MeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::BromoformConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::BromoformConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::BromoformConcentrationMeasurement::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 MeasuredValue

namespace MinMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::BromoformConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::BromoformConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::BromoformConcentrationMeasurement::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 MinMeasuredValue

namespace MaxMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::BromoformConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::BromoformConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::BromoformConcentrationMeasurement::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 MaxMeasuredValue

namespace PeakMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::BromoformConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::BromoformConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::BromoformConcentrationMeasurement::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 PeakMeasuredValue

namespace PeakMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::BromoformConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::BromoformConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace PeakMeasuredValueWindow

namespace AverageMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::BromoformConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::BromoformConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::BromoformConcentrationMeasurement::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 AverageMeasuredValue

namespace AverageMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::BromoformConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::BromoformConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace AverageMeasuredValueWindow

namespace Uncertainty {

EmberAfStatus Get(chip::EndpointId endpoint, float * value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::BromoformConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::BromoformConcentrationMeasurement::Id, Id, writable,
                                 ZCL_SINGLE_ATTRIBUTE_TYPE);
}

} // namespace Uncertainty

namespace MeasurementUnit {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::BromoformConcentrationMeasurement::MeasurementUnitEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::BromoformConcentrationMeasurement::MeasurementUnitEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::BromoformConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::BromoformConcentrationMeasurement::MeasurementUnitEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::BromoformConcentrationMeasurement::MeasurementUnitEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::BromoformConcentrationMeasurement::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementUnit

namespace MeasurementMedium {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::BromoformConcentrationMeasurement::MeasurementMediumEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::BromoformConcentrationMeasurement::MeasurementMediumEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::BromoformConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::BromoformConcentrationMeasurement::MeasurementMediumEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::BromoformConcentrationMeasurement::MeasurementMediumEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::BromoformConcentrationMeasurement::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementMedium

namespace LevelValue {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::BromoformConcentrationMeasurement::LevelValueEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::BromoformConcentrationMeasurement::LevelValueEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::BromoformConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::BromoformConcentrationMeasurement::LevelValueEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::BromoformConcentrationMeasurement::LevelValueEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::BromoformConcentrationMeasurement::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace LevelValue

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 =
        emberAfReadAttribute(endpoint, Clusters::BromoformConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::BromoformConcentrationMeasurement::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 =
        emberAfReadAttribute(endpoint, Clusters::BromoformConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::BromoformConcentrationMeasurement::Id, Id, writable,
                                 ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace BromoformConcentrationMeasurement

namespace ChlorodibromomethaneConcentrationMeasurement {
namespace Attributes {

namespace MeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::ChlorodibromomethaneConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::ChlorodibromomethaneConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::ChlorodibromomethaneConcentrationMeasurement::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 MeasuredValue

namespace MinMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::ChlorodibromomethaneConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::ChlorodibromomethaneConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::ChlorodibromomethaneConcentrationMeasurement::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 MinMeasuredValue

namespace MaxMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::ChlorodibromomethaneConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::ChlorodibromomethaneConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::ChlorodibromomethaneConcentrationMeasurement::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 MaxMeasuredValue

namespace PeakMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::ChlorodibromomethaneConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::ChlorodibromomethaneConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::ChlorodibromomethaneConcentrationMeasurement::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 PeakMeasuredValue

namespace PeakMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::ChlorodibromomethaneConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::ChlorodibromomethaneConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace PeakMeasuredValueWindow

namespace AverageMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::ChlorodibromomethaneConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::ChlorodibromomethaneConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::ChlorodibromomethaneConcentrationMeasurement::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 AverageMeasuredValue

namespace AverageMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::ChlorodibromomethaneConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::ChlorodibromomethaneConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace AverageMeasuredValueWindow

namespace Uncertainty {

EmberAfStatus Get(chip::EndpointId endpoint, float * value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::ChlorodibromomethaneConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::ChlorodibromomethaneConcentrationMeasurement::Id, Id, writable,
                                 ZCL_SINGLE_ATTRIBUTE_TYPE);
}

} // namespace Uncertainty

namespace MeasurementUnit {

EmberAfStatus Get(chip::EndpointId endpoint,
                  chip::app::Clusters::ChlorodibromomethaneConcentrationMeasurement::MeasurementUnitEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::ChlorodibromomethaneConcentrationMeasurement::MeasurementUnitEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::ChlorodibromomethaneConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::ChlorodibromomethaneConcentrationMeasurement::MeasurementUnitEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::ChlorodibromomethaneConcentrationMeasurement::MeasurementUnitEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::ChlorodibromomethaneConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementUnit

namespace MeasurementMedium {

EmberAfStatus Get(chip::EndpointId endpoint,
                  chip::app::Clusters::ChlorodibromomethaneConcentrationMeasurement::MeasurementMediumEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::ChlorodibromomethaneConcentrationMeasurement::MeasurementMediumEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::ChlorodibromomethaneConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::ChlorodibromomethaneConcentrationMeasurement::MeasurementMediumEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::ChlorodibromomethaneConcentrationMeasurement::MeasurementMediumEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::ChlorodibromomethaneConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementMedium

namespace LevelValue {

EmberAfStatus Get(chip::EndpointId endpoint,
                  chip::app::Clusters::ChlorodibromomethaneConcentrationMeasurement::LevelValueEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::ChlorodibromomethaneConcentrationMeasurement::LevelValueEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::ChlorodibromomethaneConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::ChlorodibromomethaneConcentrationMeasurement::LevelValueEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::ChlorodibromomethaneConcentrationMeasurement::LevelValueEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::ChlorodibromomethaneConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace LevelValue

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 =
        emberAfReadAttribute(endpoint, Clusters::ChlorodibromomethaneConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::ChlorodibromomethaneConcentrationMeasurement::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 =
        emberAfReadAttribute(endpoint, Clusters::ChlorodibromomethaneConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::ChlorodibromomethaneConcentrationMeasurement::Id, Id, writable,
                                 ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace ChlorodibromomethaneConcentrationMeasurement

namespace ChloroformConcentrationMeasurement {
namespace Attributes {

namespace MeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::ChloroformConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::ChloroformConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::ChloroformConcentrationMeasurement::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 MeasuredValue

namespace MinMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::ChloroformConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::ChloroformConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::ChloroformConcentrationMeasurement::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 MinMeasuredValue

namespace MaxMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::ChloroformConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::ChloroformConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::ChloroformConcentrationMeasurement::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 MaxMeasuredValue

namespace PeakMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::ChloroformConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::ChloroformConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::ChloroformConcentrationMeasurement::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 PeakMeasuredValue

namespace PeakMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::ChloroformConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::ChloroformConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace PeakMeasuredValueWindow

namespace AverageMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::ChloroformConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::ChloroformConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::ChloroformConcentrationMeasurement::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 AverageMeasuredValue

namespace AverageMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::ChloroformConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::ChloroformConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace AverageMeasuredValueWindow

namespace Uncertainty {

EmberAfStatus Get(chip::EndpointId endpoint, float * value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::ChloroformConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::ChloroformConcentrationMeasurement::Id, Id, writable,
                                 ZCL_SINGLE_ATTRIBUTE_TYPE);
}

} // namespace Uncertainty

namespace MeasurementUnit {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::ChloroformConcentrationMeasurement::MeasurementUnitEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::ChloroformConcentrationMeasurement::MeasurementUnitEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::ChloroformConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::ChloroformConcentrationMeasurement::MeasurementUnitEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::ChloroformConcentrationMeasurement::MeasurementUnitEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::ChloroformConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementUnit

namespace MeasurementMedium {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::ChloroformConcentrationMeasurement::MeasurementMediumEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::ChloroformConcentrationMeasurement::MeasurementMediumEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::ChloroformConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::ChloroformConcentrationMeasurement::MeasurementMediumEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::ChloroformConcentrationMeasurement::MeasurementMediumEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::ChloroformConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementMedium

namespace LevelValue {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::ChloroformConcentrationMeasurement::LevelValueEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::ChloroformConcentrationMeasurement::LevelValueEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::ChloroformConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::ChloroformConcentrationMeasurement::LevelValueEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::ChloroformConcentrationMeasurement::LevelValueEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::ChloroformConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace LevelValue

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 =
        emberAfReadAttribute(endpoint, Clusters::ChloroformConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::ChloroformConcentrationMeasurement::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 =
        emberAfReadAttribute(endpoint, Clusters::ChloroformConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::ChloroformConcentrationMeasurement::Id, Id, writable,
                                 ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace ChloroformConcentrationMeasurement

namespace SodiumConcentrationMeasurement {
namespace Attributes {

namespace MeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::SodiumConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::SodiumConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::SodiumConcentrationMeasurement::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 MeasuredValue

namespace MinMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::SodiumConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::SodiumConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::SodiumConcentrationMeasurement::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 MinMeasuredValue

namespace MaxMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::SodiumConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::SodiumConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::SodiumConcentrationMeasurement::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 MaxMeasuredValue

namespace PeakMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::SodiumConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::SodiumConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::SodiumConcentrationMeasurement::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 PeakMeasuredValue

namespace PeakMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::SodiumConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::SodiumConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace PeakMeasuredValueWindow

namespace AverageMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::SodiumConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::SodiumConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::SodiumConcentrationMeasurement::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 AverageMeasuredValue

namespace AverageMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::SodiumConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::SodiumConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace AverageMeasuredValueWindow

namespace Uncertainty {

EmberAfStatus Get(chip::EndpointId endpoint, float * value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::SodiumConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::SodiumConcentrationMeasurement::Id, Id, writable, ZCL_SINGLE_ATTRIBUTE_TYPE);
}

} // namespace Uncertainty

namespace MeasurementUnit {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::SodiumConcentrationMeasurement::MeasurementUnitEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::SodiumConcentrationMeasurement::MeasurementUnitEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::SodiumConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::SodiumConcentrationMeasurement::MeasurementUnitEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::SodiumConcentrationMeasurement::MeasurementUnitEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::SodiumConcentrationMeasurement::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementUnit

namespace MeasurementMedium {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::SodiumConcentrationMeasurement::MeasurementMediumEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::SodiumConcentrationMeasurement::MeasurementMediumEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::SodiumConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::SodiumConcentrationMeasurement::MeasurementMediumEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::SodiumConcentrationMeasurement::MeasurementMediumEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::SodiumConcentrationMeasurement::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementMedium

namespace LevelValue {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::SodiumConcentrationMeasurement::LevelValueEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::SodiumConcentrationMeasurement::LevelValueEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::SodiumConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::SodiumConcentrationMeasurement::LevelValueEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::SodiumConcentrationMeasurement::LevelValueEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::SodiumConcentrationMeasurement::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace LevelValue

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 = emberAfReadAttribute(endpoint, Clusters::SodiumConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::SodiumConcentrationMeasurement::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 = emberAfReadAttribute(endpoint, Clusters::SodiumConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::SodiumConcentrationMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace SodiumConcentrationMeasurement

namespace Pm25ConcentrationMeasurement {
namespace Attributes {

namespace MeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::Pm25ConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::Pm25ConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::Pm25ConcentrationMeasurement::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 MeasuredValue

namespace MinMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::Pm25ConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::Pm25ConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::Pm25ConcentrationMeasurement::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 MinMeasuredValue

namespace MaxMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::Pm25ConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::Pm25ConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::Pm25ConcentrationMeasurement::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 MaxMeasuredValue

namespace PeakMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::Pm25ConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::Pm25ConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::Pm25ConcentrationMeasurement::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 PeakMeasuredValue

namespace PeakMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::Pm25ConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::Pm25ConcentrationMeasurement::Id, Id, writable, ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace PeakMeasuredValueWindow

namespace AverageMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::Pm25ConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::Pm25ConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::Pm25ConcentrationMeasurement::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 AverageMeasuredValue

namespace AverageMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::Pm25ConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::Pm25ConcentrationMeasurement::Id, Id, writable, ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace AverageMeasuredValueWindow

namespace Uncertainty {

EmberAfStatus Get(chip::EndpointId endpoint, float * value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::Pm25ConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::Pm25ConcentrationMeasurement::Id, Id, writable, ZCL_SINGLE_ATTRIBUTE_TYPE);
}

} // namespace Uncertainty

namespace MeasurementUnit {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::Pm25ConcentrationMeasurement::MeasurementUnitEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::Pm25ConcentrationMeasurement::MeasurementUnitEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::Pm25ConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::Pm25ConcentrationMeasurement::MeasurementUnitEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::Pm25ConcentrationMeasurement::MeasurementUnitEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::Pm25ConcentrationMeasurement::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementUnit

namespace MeasurementMedium {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::Pm25ConcentrationMeasurement::MeasurementMediumEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::Pm25ConcentrationMeasurement::MeasurementMediumEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::Pm25ConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::Pm25ConcentrationMeasurement::MeasurementMediumEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::Pm25ConcentrationMeasurement::MeasurementMediumEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::Pm25ConcentrationMeasurement::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementMedium

namespace LevelValue {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::Pm25ConcentrationMeasurement::LevelValueEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::Pm25ConcentrationMeasurement::LevelValueEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::Pm25ConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::Pm25ConcentrationMeasurement::LevelValueEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::Pm25ConcentrationMeasurement::LevelValueEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::Pm25ConcentrationMeasurement::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace LevelValue

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 = emberAfReadAttribute(endpoint, Clusters::Pm25ConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::Pm25ConcentrationMeasurement::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 = emberAfReadAttribute(endpoint, Clusters::Pm25ConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::Pm25ConcentrationMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace Pm25ConcentrationMeasurement

namespace FormaldehydeConcentrationMeasurement {
namespace Attributes {

namespace MeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::FormaldehydeConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::FormaldehydeConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::FormaldehydeConcentrationMeasurement::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 MeasuredValue

namespace MinMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::FormaldehydeConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::FormaldehydeConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::FormaldehydeConcentrationMeasurement::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 MinMeasuredValue

namespace MaxMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::FormaldehydeConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::FormaldehydeConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::FormaldehydeConcentrationMeasurement::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 MaxMeasuredValue

namespace PeakMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::FormaldehydeConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::FormaldehydeConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::FormaldehydeConcentrationMeasurement::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 PeakMeasuredValue

namespace PeakMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::FormaldehydeConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::FormaldehydeConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace PeakMeasuredValueWindow

namespace AverageMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::FormaldehydeConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::FormaldehydeConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::FormaldehydeConcentrationMeasurement::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 AverageMeasuredValue

namespace AverageMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::FormaldehydeConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::FormaldehydeConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace AverageMeasuredValueWindow

namespace Uncertainty {

EmberAfStatus Get(chip::EndpointId endpoint, float * value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::FormaldehydeConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::FormaldehydeConcentrationMeasurement::Id, Id, writable,
                                 ZCL_SINGLE_ATTRIBUTE_TYPE);
}

} // namespace Uncertainty

namespace MeasurementUnit {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::FormaldehydeConcentrationMeasurement::MeasurementUnitEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::FormaldehydeConcentrationMeasurement::MeasurementUnitEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::FormaldehydeConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::FormaldehydeConcentrationMeasurement::MeasurementUnitEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::FormaldehydeConcentrationMeasurement::MeasurementUnitEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::FormaldehydeConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementUnit

namespace MeasurementMedium {

EmberAfStatus Get(chip::EndpointId endpoint,
                  chip::app::Clusters::FormaldehydeConcentrationMeasurement::MeasurementMediumEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::FormaldehydeConcentrationMeasurement::MeasurementMediumEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::FormaldehydeConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::FormaldehydeConcentrationMeasurement::MeasurementMediumEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::FormaldehydeConcentrationMeasurement::MeasurementMediumEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::FormaldehydeConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementMedium

namespace LevelValue {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::FormaldehydeConcentrationMeasurement::LevelValueEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::FormaldehydeConcentrationMeasurement::LevelValueEnum>;
    Traits::StorageType temp;
    uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status =
        emberAfReadAttribute(endpoint, Clusters::FormaldehydeConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::FormaldehydeConcentrationMeasurement::LevelValueEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::FormaldehydeConcentrationMeasurement::LevelValueEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::FormaldehydeConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace LevelValue

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 =
        emberAfReadAttribute(endpoint, Clusters::FormaldehydeConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::FormaldehydeConcentrationMeasurement::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 =
        emberAfReadAttribute(endpoint, Clusters::FormaldehydeConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::FormaldehydeConcentrationMeasurement::Id, Id, writable,
                                 ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace FormaldehydeConcentrationMeasurement

namespace Pm1ConcentrationMeasurement {
namespace Attributes {

namespace MeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::Pm1ConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::Pm1ConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::Pm1ConcentrationMeasurement::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 MeasuredValue

namespace MinMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::Pm1ConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::Pm1ConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::Pm1ConcentrationMeasurement::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 MinMeasuredValue

namespace MaxMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::Pm1ConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::Pm1ConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::Pm1ConcentrationMeasurement::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 MaxMeasuredValue

namespace PeakMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::Pm1ConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::Pm1ConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::Pm1ConcentrationMeasurement::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 PeakMeasuredValue

namespace PeakMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::Pm1ConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::Pm1ConcentrationMeasurement::Id, Id, writable, ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace PeakMeasuredValueWindow

namespace AverageMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::Pm1ConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::Pm1ConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::Pm1ConcentrationMeasurement::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 AverageMeasuredValue

namespace AverageMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::Pm1ConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::Pm1ConcentrationMeasurement::Id, Id, writable, ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace AverageMeasuredValueWindow

namespace Uncertainty {

EmberAfStatus Get(chip::EndpointId endpoint, float * value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::Pm1ConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::Pm1ConcentrationMeasurement::Id, Id, writable, ZCL_SINGLE_ATTRIBUTE_TYPE);
}

} // namespace Uncertainty

namespace MeasurementUnit {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::Pm1ConcentrationMeasurement::MeasurementUnitEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::Pm1ConcentrationMeasurement::MeasurementUnitEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::Pm1ConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::Pm1ConcentrationMeasurement::MeasurementUnitEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::Pm1ConcentrationMeasurement::MeasurementUnitEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::Pm1ConcentrationMeasurement::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementUnit

namespace MeasurementMedium {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::Pm1ConcentrationMeasurement::MeasurementMediumEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::Pm1ConcentrationMeasurement::MeasurementMediumEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::Pm1ConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::Pm1ConcentrationMeasurement::MeasurementMediumEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::Pm1ConcentrationMeasurement::MeasurementMediumEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::Pm1ConcentrationMeasurement::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementMedium

namespace LevelValue {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::Pm1ConcentrationMeasurement::LevelValueEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::Pm1ConcentrationMeasurement::LevelValueEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::Pm1ConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::Pm1ConcentrationMeasurement::LevelValueEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::Pm1ConcentrationMeasurement::LevelValueEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::Pm1ConcentrationMeasurement::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace LevelValue

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 = emberAfReadAttribute(endpoint, Clusters::Pm1ConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::Pm1ConcentrationMeasurement::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 = emberAfReadAttribute(endpoint, Clusters::Pm1ConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::Pm1ConcentrationMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace Pm1ConcentrationMeasurement

namespace Pm10ConcentrationMeasurement {
namespace Attributes {

namespace MeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::Pm10ConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::Pm10ConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::Pm10ConcentrationMeasurement::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 MeasuredValue

namespace MinMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::Pm10ConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::Pm10ConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::Pm10ConcentrationMeasurement::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 MinMeasuredValue

namespace MaxMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::Pm10ConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::Pm10ConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::Pm10ConcentrationMeasurement::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 MaxMeasuredValue

namespace PeakMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::Pm10ConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::Pm10ConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::Pm10ConcentrationMeasurement::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 PeakMeasuredValue

namespace PeakMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::Pm10ConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::Pm10ConcentrationMeasurement::Id, Id, writable, ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace PeakMeasuredValueWindow

namespace AverageMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::Pm10ConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::Pm10ConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::Pm10ConcentrationMeasurement::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 AverageMeasuredValue

namespace AverageMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::Pm10ConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::Pm10ConcentrationMeasurement::Id, Id, writable, ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace AverageMeasuredValueWindow

namespace Uncertainty {

EmberAfStatus Get(chip::EndpointId endpoint, float * value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::Pm10ConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::Pm10ConcentrationMeasurement::Id, Id, writable, ZCL_SINGLE_ATTRIBUTE_TYPE);
}

} // namespace Uncertainty

namespace MeasurementUnit {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::Pm10ConcentrationMeasurement::MeasurementUnitEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::Pm10ConcentrationMeasurement::MeasurementUnitEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::Pm10ConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::Pm10ConcentrationMeasurement::MeasurementUnitEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::Pm10ConcentrationMeasurement::MeasurementUnitEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::Pm10ConcentrationMeasurement::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementUnit

namespace MeasurementMedium {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::Pm10ConcentrationMeasurement::MeasurementMediumEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::Pm10ConcentrationMeasurement::MeasurementMediumEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::Pm10ConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::Pm10ConcentrationMeasurement::MeasurementMediumEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::Pm10ConcentrationMeasurement::MeasurementMediumEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::Pm10ConcentrationMeasurement::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementMedium

namespace LevelValue {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::Pm10ConcentrationMeasurement::LevelValueEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::Pm10ConcentrationMeasurement::LevelValueEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::Pm10ConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::Pm10ConcentrationMeasurement::LevelValueEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::Pm10ConcentrationMeasurement::LevelValueEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::Pm10ConcentrationMeasurement::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace LevelValue

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 = emberAfReadAttribute(endpoint, Clusters::Pm10ConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::Pm10ConcentrationMeasurement::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 = emberAfReadAttribute(endpoint, Clusters::Pm10ConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::Pm10ConcentrationMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace Pm10ConcentrationMeasurement

namespace TotalVolatileOrganicCompoundsConcentrationMeasurement {
namespace Attributes {

namespace MeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::TotalVolatileOrganicCompoundsConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::TotalVolatileOrganicCompoundsConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::TotalVolatileOrganicCompoundsConcentrationMeasurement::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 MeasuredValue

namespace MinMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::TotalVolatileOrganicCompoundsConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::TotalVolatileOrganicCompoundsConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::TotalVolatileOrganicCompoundsConcentrationMeasurement::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 MinMeasuredValue

namespace MaxMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::TotalVolatileOrganicCompoundsConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::TotalVolatileOrganicCompoundsConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::TotalVolatileOrganicCompoundsConcentrationMeasurement::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 MaxMeasuredValue

namespace PeakMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::TotalVolatileOrganicCompoundsConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::TotalVolatileOrganicCompoundsConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::TotalVolatileOrganicCompoundsConcentrationMeasurement::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 PeakMeasuredValue

namespace PeakMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::TotalVolatileOrganicCompoundsConcentrationMeasurement::Id, Id,
                                                readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::TotalVolatileOrganicCompoundsConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace PeakMeasuredValueWindow

namespace AverageMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::TotalVolatileOrganicCompoundsConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::TotalVolatileOrganicCompoundsConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::TotalVolatileOrganicCompoundsConcentrationMeasurement::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 AverageMeasuredValue

namespace AverageMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::TotalVolatileOrganicCompoundsConcentrationMeasurement::Id, Id,
                                                readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::TotalVolatileOrganicCompoundsConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace AverageMeasuredValueWindow

namespace Uncertainty {

EmberAfStatus Get(chip::EndpointId endpoint, float * value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::TotalVolatileOrganicCompoundsConcentrationMeasurement::Id, Id,
                                                readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::TotalVolatileOrganicCompoundsConcentrationMeasurement::Id, Id, writable,
                                 ZCL_SINGLE_ATTRIBUTE_TYPE);
}

} // namespace Uncertainty

namespace MeasurementUnit {

EmberAfStatus Get(chip::EndpointId endpoint,
                  chip::app::Clusters::TotalVolatileOrganicCompoundsConcentrationMeasurement::MeasurementUnitEnum * value)
{
    using Traits =
        NumericAttributeTraits<chip::app::Clusters::TotalVolatileOrganicCompoundsConcentrationMeasurement::MeasurementUnitEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::TotalVolatileOrganicCompoundsConcentrationMeasurement::Id, Id,
                                                readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::TotalVolatileOrganicCompoundsConcentrationMeasurement::MeasurementUnitEnum value)
{
    using Traits =
        NumericAttributeTraits<chip::app::Clusters::TotalVolatileOrganicCompoundsConcentrationMeasurement::MeasurementUnitEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::TotalVolatileOrganicCompoundsConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementUnit

namespace MeasurementMedium {

EmberAfStatus Get(chip::EndpointId endpoint,
                  chip::app::Clusters::TotalVolatileOrganicCompoundsConcentrationMeasurement::MeasurementMediumEnum * value)
{
    using Traits =
        NumericAttributeTraits<chip::app::Clusters::TotalVolatileOrganicCompoundsConcentrationMeasurement::MeasurementMediumEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::TotalVolatileOrganicCompoundsConcentrationMeasurement::Id, Id,
                                                readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::TotalVolatileOrganicCompoundsConcentrationMeasurement::MeasurementMediumEnum value)
{
    using Traits =
        NumericAttributeTraits<chip::app::Clusters::TotalVolatileOrganicCompoundsConcentrationMeasurement::MeasurementMediumEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::TotalVolatileOrganicCompoundsConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementMedium

namespace LevelValue {

EmberAfStatus Get(chip::EndpointId endpoint,
                  chip::app::Clusters::TotalVolatileOrganicCompoundsConcentrationMeasurement::LevelValueEnum * value)
{
    using Traits =
        NumericAttributeTraits<chip::app::Clusters::TotalVolatileOrganicCompoundsConcentrationMeasurement::LevelValueEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::TotalVolatileOrganicCompoundsConcentrationMeasurement::Id, Id,
                                                readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::TotalVolatileOrganicCompoundsConcentrationMeasurement::LevelValueEnum value)
{
    using Traits =
        NumericAttributeTraits<chip::app::Clusters::TotalVolatileOrganicCompoundsConcentrationMeasurement::LevelValueEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::TotalVolatileOrganicCompoundsConcentrationMeasurement::Id, Id, writable,
                                 ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace LevelValue

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 = emberAfReadAttribute(endpoint, Clusters::TotalVolatileOrganicCompoundsConcentrationMeasurement::Id, Id,
                                                readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::TotalVolatileOrganicCompoundsConcentrationMeasurement::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 = emberAfReadAttribute(endpoint, Clusters::TotalVolatileOrganicCompoundsConcentrationMeasurement::Id, Id,
                                                readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::TotalVolatileOrganicCompoundsConcentrationMeasurement::Id, Id, writable,
                                 ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace TotalVolatileOrganicCompoundsConcentrationMeasurement

namespace RadonConcentrationMeasurement {
namespace Attributes {

namespace MeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::RadonConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::RadonConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::RadonConcentrationMeasurement::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 MeasuredValue

namespace MinMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::RadonConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::RadonConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::RadonConcentrationMeasurement::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 MinMeasuredValue

namespace MaxMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::RadonConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::RadonConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::RadonConcentrationMeasurement::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 MaxMeasuredValue

namespace PeakMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::RadonConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::RadonConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::RadonConcentrationMeasurement::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 PeakMeasuredValue

namespace PeakMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::RadonConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::RadonConcentrationMeasurement::Id, Id, writable, ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace PeakMeasuredValueWindow

namespace AverageMeasuredValue {

EmberAfStatus Get(chip::EndpointId endpoint, DataModel::Nullable<float> & value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::RadonConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::RadonConcentrationMeasurement::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 emberAfWriteAttribute(endpoint, Clusters::RadonConcentrationMeasurement::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 AverageMeasuredValue

namespace AverageMeasuredValueWindow {

EmberAfStatus Get(chip::EndpointId endpoint, uint32_t * value)
{
    using Traits = NumericAttributeTraits<uint32_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::RadonConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::RadonConcentrationMeasurement::Id, Id, writable, ZCL_ELAPSED_S_ATTRIBUTE_TYPE);
}

} // namespace AverageMeasuredValueWindow

namespace Uncertainty {

EmberAfStatus Get(chip::EndpointId endpoint, float * value)
{
    using Traits = NumericAttributeTraits<float>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::RadonConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::RadonConcentrationMeasurement::Id, Id, writable, ZCL_SINGLE_ATTRIBUTE_TYPE);
}

} // namespace Uncertainty

namespace MeasurementUnit {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::RadonConcentrationMeasurement::MeasurementUnitEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::RadonConcentrationMeasurement::MeasurementUnitEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::RadonConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::RadonConcentrationMeasurement::MeasurementUnitEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::RadonConcentrationMeasurement::MeasurementUnitEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::RadonConcentrationMeasurement::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementUnit

namespace MeasurementMedium {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::RadonConcentrationMeasurement::MeasurementMediumEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::RadonConcentrationMeasurement::MeasurementMediumEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::RadonConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::RadonConcentrationMeasurement::MeasurementMediumEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::RadonConcentrationMeasurement::MeasurementMediumEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::RadonConcentrationMeasurement::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace MeasurementMedium

namespace LevelValue {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::RadonConcentrationMeasurement::LevelValueEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::RadonConcentrationMeasurement::LevelValueEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::RadonConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::RadonConcentrationMeasurement::LevelValueEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::RadonConcentrationMeasurement::LevelValueEnum>;
    if (!Traits::CanRepresentValue(/* isNullable = */ false, value))
    {
        return EMBER_ZCL_STATUS_CONSTRAINT_ERROR;
    }
    Traits::StorageType storageValue;
    Traits::WorkingToStorage(value, storageValue);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue);
    return emberAfWriteAttribute(endpoint, Clusters::RadonConcentrationMeasurement::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

} // namespace LevelValue

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 = emberAfReadAttribute(endpoint, Clusters::RadonConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::RadonConcentrationMeasurement::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 = emberAfReadAttribute(endpoint, Clusters::RadonConcentrationMeasurement::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::RadonConcentrationMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace RadonConcentrationMeasurement

namespace WakeOnLan {
namespace Attributes {

namespace MACAddress {

EmberAfStatus Get(chip::EndpointId endpoint, chip::MutableCharSpan value)
{
    uint8_t zclString[32 + 1];
    EmberAfStatus status = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(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 = emberAfReadAttribute(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 emberAfWriteAttribute(endpoint, Clusters::ElectricalMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace ElectricalMeasurement

namespace UnitTesting {
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 = emberAfReadAttribute(endpoint, Clusters::UnitTesting::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::Id, Id, writable, ZCL_BOOLEAN_ATTRIBUTE_TYPE);
}

} // namespace Boolean

namespace Bitmap8 {

EmberAfStatus Get(chip::EndpointId endpoint, chip::BitMask<chip::app::Clusters::UnitTesting::Bitmap8MaskMap> * value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::UnitTesting::Bitmap8MaskMap>>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::UnitTesting::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::UnitTesting::Bitmap8MaskMap> value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::Id, Id, writable, ZCL_BITMAP8_ATTRIBUTE_TYPE);
}

} // namespace Bitmap8

namespace Bitmap16 {

EmberAfStatus Get(chip::EndpointId endpoint, chip::BitMask<chip::app::Clusters::UnitTesting::Bitmap16MaskMap> * value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::UnitTesting::Bitmap16MaskMap>>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::UnitTesting::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::UnitTesting::Bitmap16MaskMap> value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::Id, Id, writable, ZCL_BITMAP16_ATTRIBUTE_TYPE);
}

} // namespace Bitmap16

namespace Bitmap32 {

EmberAfStatus Get(chip::EndpointId endpoint, chip::BitMask<chip::app::Clusters::UnitTesting::Bitmap32MaskMap> * value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::UnitTesting::Bitmap32MaskMap>>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::UnitTesting::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::UnitTesting::Bitmap32MaskMap> value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

} // namespace Bitmap32

namespace Bitmap64 {

EmberAfStatus Get(chip::EndpointId endpoint, chip::BitMask<chip::app::Clusters::UnitTesting::Bitmap64MaskMap> * value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::UnitTesting::Bitmap64MaskMap>>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::UnitTesting::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::UnitTesting::Bitmap64MaskMap> value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 = emberAfReadAttribute(endpoint, Clusters::UnitTesting::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 = emberAfReadAttribute(endpoint, Clusters::UnitTesting::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 = emberAfReadAttribute(endpoint, Clusters::UnitTesting::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 = emberAfReadAttribute(endpoint, Clusters::UnitTesting::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 = emberAfReadAttribute(endpoint, Clusters::UnitTesting::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 = emberAfReadAttribute(endpoint, Clusters::UnitTesting::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 = emberAfReadAttribute(endpoint, Clusters::UnitTesting::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 = emberAfReadAttribute(endpoint, Clusters::UnitTesting::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 = emberAfReadAttribute(endpoint, Clusters::UnitTesting::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 = emberAfReadAttribute(endpoint, Clusters::UnitTesting::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 = emberAfReadAttribute(endpoint, Clusters::UnitTesting::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 = emberAfReadAttribute(endpoint, Clusters::UnitTesting::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 = emberAfReadAttribute(endpoint, Clusters::UnitTesting::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 = emberAfReadAttribute(endpoint, Clusters::UnitTesting::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 = emberAfReadAttribute(endpoint, Clusters::UnitTesting::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 = emberAfReadAttribute(endpoint, Clusters::UnitTesting::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 = emberAfReadAttribute(endpoint, Clusters::UnitTesting::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 = emberAfReadAttribute(endpoint, Clusters::UnitTesting::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 = emberAfReadAttribute(endpoint, Clusters::UnitTesting::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 = emberAfReadAttribute(endpoint, Clusters::UnitTesting::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 = emberAfReadAttribute(endpoint, Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 = emberAfReadAttribute(endpoint, Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 = emberAfReadAttribute(endpoint, Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 = emberAfReadAttribute(endpoint, Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 = emberAfReadAttribute(endpoint, Clusters::UnitTesting::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 = emberAfReadAttribute(endpoint, Clusters::UnitTesting::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 = emberAfReadAttribute(endpoint, Clusters::UnitTesting::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::Id, Id, writable, ZCL_VENDOR_ID_ATTRIBUTE_TYPE);
}

} // namespace VendorId

namespace EnumAttr {

EmberAfStatus Get(chip::EndpointId endpoint, chip::app::Clusters::UnitTesting::SimpleEnum * value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::UnitTesting::SimpleEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::UnitTesting::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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::UnitTesting::SimpleEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 = emberAfReadAttribute(endpoint, Clusters::UnitTesting::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 = emberAfReadAttribute(endpoint, Clusters::UnitTesting::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 = emberAfReadAttribute(endpoint, Clusters::UnitTesting::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 = emberAfReadAttribute(endpoint, Clusters::UnitTesting::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 = emberAfReadAttribute(endpoint, Clusters::UnitTesting::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::Id, Id, writable, ZCL_BOOLEAN_ATTRIBUTE_TYPE);
}

} // namespace TimedWriteBoolean

namespace Unsupported {

EmberAfStatus Get(chip::EndpointId endpoint, bool * value)
{
    using Traits = NumericAttributeTraits<bool>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::UnitTesting::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 = emberAfReadAttribute(endpoint, Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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::UnitTesting::Bitmap8MaskMap>> & value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::UnitTesting::Bitmap8MaskMap>>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::UnitTesting::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::UnitTesting::Bitmap8MaskMap> value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::Id, Id, writable, ZCL_BITMAP8_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::UnitTesting::Bitmap8MaskMap>>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteAttribute(endpoint, Clusters::UnitTesting::Id, Id, writable, ZCL_BITMAP8_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint,
                  const chip::app::DataModel::Nullable<chip::BitMask<chip::app::Clusters::UnitTesting::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::UnitTesting::Bitmap16MaskMap>> & value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::UnitTesting::Bitmap16MaskMap>>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::UnitTesting::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::UnitTesting::Bitmap16MaskMap> value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::Id, Id, writable, ZCL_BITMAP16_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::UnitTesting::Bitmap16MaskMap>>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteAttribute(endpoint, Clusters::UnitTesting::Id, Id, writable, ZCL_BITMAP16_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint,
                  const chip::app::DataModel::Nullable<chip::BitMask<chip::app::Clusters::UnitTesting::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::UnitTesting::Bitmap32MaskMap>> & value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::UnitTesting::Bitmap32MaskMap>>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::UnitTesting::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::UnitTesting::Bitmap32MaskMap> value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::UnitTesting::Bitmap32MaskMap>>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteAttribute(endpoint, Clusters::UnitTesting::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint,
                  const chip::app::DataModel::Nullable<chip::BitMask<chip::app::Clusters::UnitTesting::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::UnitTesting::Bitmap64MaskMap>> & value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::UnitTesting::Bitmap64MaskMap>>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::UnitTesting::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::UnitTesting::Bitmap64MaskMap> value)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::Id, Id, writable, ZCL_BITMAP64_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    using Traits = NumericAttributeTraits<chip::BitMask<chip::app::Clusters::UnitTesting::Bitmap64MaskMap>>;
    Traits::StorageType value;
    Traits::SetNull(value);
    uint8_t * writable = Traits::ToAttributeStoreRepresentation(value);
    return emberAfWriteAttribute(endpoint, Clusters::UnitTesting::Id, Id, writable, ZCL_BITMAP64_ATTRIBUTE_TYPE);
}

EmberAfStatus Set(chip::EndpointId endpoint,
                  const chip::app::DataModel::Nullable<chip::BitMask<chip::app::Clusters::UnitTesting::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 = emberAfReadAttribute(endpoint, Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 = emberAfReadAttribute(endpoint, Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 = emberAfReadAttribute(endpoint, Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 = emberAfReadAttribute(endpoint, Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 = emberAfReadAttribute(endpoint, Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 = emberAfReadAttribute(endpoint, Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 = emberAfReadAttribute(endpoint, Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 = emberAfReadAttribute(endpoint, Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 = emberAfReadAttribute(endpoint, Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 = emberAfReadAttribute(endpoint, Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 = emberAfReadAttribute(endpoint, Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 = emberAfReadAttribute(endpoint, Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 = emberAfReadAttribute(endpoint, Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 = emberAfReadAttribute(endpoint, Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 = emberAfReadAttribute(endpoint, Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 = emberAfReadAttribute(endpoint, Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 = emberAfReadAttribute(endpoint, Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 = emberAfReadAttribute(endpoint, Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 = emberAfReadAttribute(endpoint, Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 = emberAfReadAttribute(endpoint, Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 = emberAfReadAttribute(endpoint, Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::Id, Id, zclString, ZCL_OCTET_STRING_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    uint8_t zclString[1] = { 0xFF };
    return emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 = emberAfReadAttribute(endpoint, Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::Id, Id, zclString, ZCL_CHAR_STRING_ATTRIBUTE_TYPE);
}

EmberAfStatus SetNull(chip::EndpointId endpoint)
{
    uint8_t zclString[1] = { 0xFF };
    return emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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::UnitTesting::SimpleEnum> & value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::UnitTesting::SimpleEnum>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::UnitTesting::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::UnitTesting::SimpleEnum value)
{
    using Traits = NumericAttributeTraits<chip::app::Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE);
}

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

EmberAfStatus Set(chip::EndpointId endpoint,
                  const chip::app::DataModel::Nullable<chip::app::Clusters::UnitTesting::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 = emberAfReadAttribute(endpoint, Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 = emberAfReadAttribute(endpoint, Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 = emberAfReadAttribute(endpoint, Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 = emberAfReadAttribute(endpoint, Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 WriteOnlyInt8u {

EmberAfStatus Get(chip::EndpointId endpoint, uint8_t * value)
{
    using Traits = NumericAttributeTraits<uint8_t>;
    Traits::StorageType temp;
    uint8_t * readable   = Traits::ToAttributeStoreRepresentation(temp);
    EmberAfStatus status = emberAfReadAttribute(endpoint, Clusters::UnitTesting::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE);
}

} // namespace WriteOnlyInt8u

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 = emberAfReadAttribute(endpoint, Clusters::UnitTesting::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::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 = emberAfReadAttribute(endpoint, Clusters::UnitTesting::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::UnitTesting::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace UnitTesting

namespace FaultInjection {
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 = emberAfReadAttribute(endpoint, Clusters::FaultInjection::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::FaultInjection::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 = emberAfReadAttribute(endpoint, Clusters::FaultInjection::Id, Id, readable, sizeof(temp));
    VerifyOrReturnError(EMBER_ZCL_STATUS_SUCCESS == status, 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 emberAfWriteAttribute(endpoint, Clusters::FaultInjection::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE);
}

} // namespace ClusterRevision

} // namespace Attributes
} // namespace FaultInjection

} // namespace Clusters
} // namespace app
} // namespace chip
